mirror of
https://github.com/xtr-dev/payload-notifications.git
synced 2025-12-10 19:03:23 +00:00
Add initial plugin implementation and development setup
This commit is contained in:
123
src/collections/push-subscriptions.ts
Normal file
123
src/collections/push-subscriptions.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
import type { NotificationAccess, NotificationsPluginOptions } from '../types'
|
||||
|
||||
/**
|
||||
* Creates a collection to store web push subscriptions
|
||||
* Each user can have multiple subscriptions (different devices/browsers)
|
||||
*/
|
||||
export function createPushSubscriptionsCollection(access: NotificationAccess = {}, options: NotificationsPluginOptions = {}): CollectionConfig {
|
||||
const defaultAccess: NotificationAccess = {
|
||||
read: ({ req }: { req: any }) => Boolean(req.user),
|
||||
create: ({ req }: { req: any }) => Boolean(req.user),
|
||||
update: ({ req }: { req: any }) => Boolean(req.user),
|
||||
delete: ({ req }: { req: any }) => Boolean(req.user),
|
||||
}
|
||||
|
||||
return {
|
||||
slug: 'push-subscriptions',
|
||||
labels: {
|
||||
singular: 'Push Subscription',
|
||||
plural: 'Push Subscriptions',
|
||||
},
|
||||
admin: {
|
||||
useAsTitle: 'endpoint',
|
||||
defaultColumns: ['user', 'endpoint', 'createdAt'],
|
||||
description: 'Web push notification subscriptions for users',
|
||||
// hidden: true, // Hide from main navigation
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'user',
|
||||
type: 'relationship',
|
||||
relationTo: 'users',
|
||||
label: 'User',
|
||||
required: true,
|
||||
admin: {
|
||||
description: 'The user this push subscription belongs to',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'endpoint',
|
||||
type: 'text',
|
||||
label: 'Endpoint',
|
||||
required: true,
|
||||
unique: true,
|
||||
admin: {
|
||||
description: 'Push service endpoint URL',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'p256dh',
|
||||
type: 'text',
|
||||
label: 'P256DH Key',
|
||||
required: true,
|
||||
admin: {
|
||||
description: 'User agent public key for encryption',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'auth',
|
||||
type: 'text',
|
||||
label: 'Auth Secret',
|
||||
required: true,
|
||||
admin: {
|
||||
description: 'User agent authentication secret',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'userAgent',
|
||||
type: 'text',
|
||||
label: 'User Agent',
|
||||
admin: {
|
||||
description: 'Browser/device information',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'channels',
|
||||
type: 'select',
|
||||
label: 'Subscribed Channels',
|
||||
options: options.channels && options.channels.length > 0
|
||||
? options.channels.map(channel => ({
|
||||
label: channel.name,
|
||||
value: channel.id,
|
||||
}))
|
||||
: [{ label: 'All Notifications', value: 'all' }],
|
||||
hasMany: true,
|
||||
defaultValue: options.channels && options.channels.length > 0
|
||||
? options.channels.filter(channel => channel.defaultEnabled !== false).map(channel => channel.id)
|
||||
: ['all'],
|
||||
admin: {
|
||||
description: 'Channels this subscription is subscribed to - leave empty for all notifications',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'isActive',
|
||||
type: 'checkbox',
|
||||
label: 'Active',
|
||||
defaultValue: true,
|
||||
admin: {
|
||||
description: 'Whether this subscription is still active',
|
||||
position: 'sidebar',
|
||||
},
|
||||
},
|
||||
],
|
||||
access: {
|
||||
read: access.read || defaultAccess.read!,
|
||||
create: access.create || defaultAccess.create!,
|
||||
update: access.update || defaultAccess.update!,
|
||||
delete: access.delete || defaultAccess.delete!,
|
||||
},
|
||||
timestamps: true,
|
||||
hooks: {
|
||||
beforeChange: [
|
||||
({ req, data }: { req: any; data: any }) => {
|
||||
// For user-based subscriptions, default to current user
|
||||
if (req.user && !data.user) {
|
||||
data.user = req.user.id
|
||||
}
|
||||
return data
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user