feature: new collections

This commit is contained in:
Benno Tielen 2024-08-23 16:20:50 +02:00
parent 66f9e07111
commit f645c01ac0
12 changed files with 626 additions and 108 deletions

View file

@ -1,4 +1,5 @@
import { CollectionConfig } from 'payload'
import { isAdminOrEmployee } from '@/collections/access/admin'
export const Churches: CollectionConfig = {
slug: 'church',
@ -33,5 +34,8 @@ export const Churches: CollectionConfig = {
},
access: {
read: () => true,
create: isAdminOrEmployee(),
update: isAdminOrEmployee(),
delete: isAdminOrEmployee(),
},
}

View file

@ -0,0 +1,62 @@
import { CollectionConfig } from 'payload'
import { isAdminOrEmployee } from '@/collections/access/admin'
export const Employees: CollectionConfig = {
slug: 'employees',
labels: {
singular: {
de: 'Mitarbeiter',
},
plural: 'Mitarbeiter',
},
fields: [
{
name: 'photo',
label: {
de: 'Foto',
},
type: 'upload',
relationTo: 'media',
},
{
name: 'name',
type: 'text',
label: {
de: 'Name',
},
required: true,
},
{
name: 'occupation',
type: 'text',
label: {
de: 'Tätigkeit',
},
required: true,
},
{
name: 'email',
type: 'email',
label: {
de: 'Email',
},
},
{
name: 'telephone',
type: 'text',
label: {
de: 'Telefon',
},
required: false,
},
],
admin: {
useAsTitle: 'name',
},
access: {
read: () => true,
create: isAdminOrEmployee(),
update: isAdminOrEmployee(),
delete: isAdminOrEmployee(),
},
}

122
src/collections/Events.ts Normal file
View file

@ -0,0 +1,122 @@
import { CollectionConfig } from 'payload'
import { isAdminOrEmployee } from '@/collections/access/admin'
export const Events: CollectionConfig = {
slug: 'event',
labels: {
singular: {
de: 'Veranstaltung',
},
plural: {
de: 'Veranstaltungen',
},
},
fields: [
{
name: 'photo',
label: {
de: 'Foto',
},
type: 'upload',
relationTo: 'media',
},
{
name: 'title',
type: 'text',
required: true,
label: {
de: 'Titel',
},
},
{
name: 'datum',
type: 'date',
required: true,
label: {
de: 'Datum',
},
admin: {
date: {
pickerAppearance: 'dayAndTime',
},
},
},
{
name: 'parish',
type: 'relationship',
relationTo: 'parish',
hasMany: true,
label: {
de: 'Gemeinde',
},
validate: (value, options) => {
let user = options.req.user
if (!user) {
return 'You are not allowed to do this'
}
if (user.roles === 'user' && value) {
return 'Sie sind nur erlaubt Veranstaltungen für Gruppen zu erstellen.'
}
return true
},
},
{
name: 'group',
type: 'relationship',
relationTo: 'group',
label: {
de: 'Gruppe',
},
validate: (value, options) => {
let user = options.req.user
if (!user) {
return 'You are not allowed to do this'
}
if (user.roles === 'user') {
if (!user.groups || (user.groups && !user.groups.includes(value))) {
return 'Sie können nur Veranstaltungen für Ihre eigene Gruppen erstellen!'
}
}
return true
},
},
{
name: 'shortDescription',
type: 'textarea',
required: true,
label: {
de: 'Kurzumschreibung',
},
},
{
name: 'description',
type: 'richText',
required: true,
label: {
de: 'Umschreibung',
},
},
{
name: 'cancelled',
type: 'checkbox',
required: true,
label: {
de: 'Abgesagt',
},
defaultValue: false,
},
],
admin: {
useAsTitle: 'title',
},
access: {
read: () => true,
delete: isAdminOrEmployee(),
},
}

66
src/collections/Groups.ts Normal file
View file

@ -0,0 +1,66 @@
import { CollectionConfig } from 'payload'
import { isAdminOrEmployee } from '@/collections/access/admin'
export const Groups: CollectionConfig = {
slug: 'group',
labels: {
singular: {
de: 'Gruppe',
},
plural: {
de: 'Gruppen',
},
},
fields: [
{
name: 'photo',
label: {
de: 'Foto',
},
type: 'upload',
relationTo: 'media',
},
{
name: 'name',
type: 'text',
label: {
de: 'Name',
},
required: true,
},
{
name: 'description',
type: 'textarea',
label: {
de: 'Umschreibung',
},
required: true,
},
],
admin: {
useAsTitle: 'name',
},
access: {
read: () => true,
create: isAdminOrEmployee(),
update: ({ req, id }) => {
if (!req.user) {
return false
}
if (
req.user.roles === 'user' &&
id &&
req.user.groups?.find(
(group) =>
group === id || (typeof group === 'object' && group.id === id),
) === undefined
) {
return false
}
return true
},
delete: isAdminOrEmployee(),
},
}

91
src/collections/Parish.ts Normal file
View file

@ -0,0 +1,91 @@
import { CollectionConfig } from 'payload'
import { isAdmin, isAdminOrEmployee } from '@/collections/access/admin'
export const Parish: CollectionConfig = {
slug: 'parish',
labels: {
singular: {
de: 'Gemeinde',
},
plural: {
de: 'Gemeinden',
},
},
fields: [
{
name: 'name',
label: {
de: 'Name',
},
type: 'text',
required: true,
},
{
name: 'churches',
label: {
de: 'Kirchengebäuden',
},
type: 'relationship',
relationTo: 'church',
hasMany: true,
required: true,
admin: {
allowCreate: false,
},
},
{
name: 'employees',
label: {
de: 'Mitarbeiter',
},
type: 'relationship',
relationTo: 'employees',
hasMany: true,
required: true,
},
{
name: 'contact',
label: {
de: 'Kontaktinformation',
},
type: 'textarea',
required: true,
admin: {
rows: 10,
},
},
{
name: 'title',
label: {
de: 'Titel',
},
type: 'text',
required: true,
},
{
name: 'description',
label: {
de: 'Umschreibung',
},
type: 'textarea',
required: true,
admin: {
rows: 15,
},
},
{
name: 'photo',
type: 'upload',
relationTo: 'media',
},
],
admin: {
useAsTitle: 'name',
},
access: {
read: () => true,
create: isAdmin(),
update: isAdminOrEmployee(),
delete: isAdmin(),
},
}

View file

@ -1,4 +1,5 @@
import { CollectionConfig } from 'payload'
import { isAdminOrEmployee } from '@/collections/access/admin'
export const Testimony: CollectionConfig = {
slug: 'testimony',
@ -52,5 +53,8 @@ export const Testimony: CollectionConfig = {
],
access: {
read: () => true,
create: isAdminOrEmployee(),
update: isAdminOrEmployee(),
delete: isAdminOrEmployee(),
},
}

View file

@ -1,4 +1,5 @@
import type { CollectionConfig } from 'payload'
import { isAdminOrEmployee } from '@/collections/access/admin'
export const Users: CollectionConfig = {
slug: 'users',
@ -7,7 +8,61 @@ export const Users: CollectionConfig = {
},
auth: true,
fields: [
// Email added by default
// Add more fields as needed
{
name: 'name',
label: {
de: 'Name',
},
type: 'text',
required: true,
defaultValue: '',
},
{
name: 'roles',
label: {
de: 'Rolle',
},
type: 'select',
required: true,
options: [
{
value: 'user',
label: 'Gläubiger',
},
{
value: 'employee',
label: 'Mitarbeiter',
},
{
value: 'admin',
label: 'Administrator',
},
],
defaultValue: 'user',
access: {
// Do not allow to upgrade role
create: ({ req, data }) => {
return !(req.user?.roles !== 'admin' && data?.roles === 'admin')
},
update: ({ req, data }) => {
return !(req.user?.roles !== 'admin' && data?.roles === 'admin')
},
},
},
{
name: 'groups',
label: {
de: 'Mitgliedschaft',
},
type: 'relationship',
relationTo: 'group',
hasMany: true,
maxDepth: 0,
},
],
access: {
create: isAdminOrEmployee(),
update: isAdminOrEmployee(),
delete: isAdminOrEmployee(),
},
}

View file

@ -1,4 +1,5 @@
import { CollectionConfig } from 'payload'
import { isAdminOrEmployee } from '@/collections/access/admin'
export const Worship: CollectionConfig = {
slug: 'worship',
@ -82,5 +83,8 @@ export const Worship: CollectionConfig = {
],
access: {
read: () => true,
create: isAdminOrEmployee(),
update: isAdminOrEmployee(),
delete: isAdminOrEmployee(),
},
}

View file

@ -0,0 +1,17 @@
import type { Access } from 'payload'
export const isAdmin =
(): Access =>
({ req: { user } }) => {
return user?.roles === 'admin'
}
export const isAdminOrEmployee =
(): Access =>
({ req: { user } }) => {
if (!user) {
return false
}
return user.roles === 'admin' || user.roles === 'employee'
}

View file

@ -69,7 +69,7 @@ export const HomeBanner = forwardRef<HomeBannerHandle, HomeBannerProps>(
context.shadowBlur = 10
context.shadowColor = 'white'
setTimeout(() => drawStar(context), i * 100);
setTimeout(() => drawStar(context), i * 100)
}
}
}, [drawStar, stars])

View file

@ -8,162 +8,241 @@
export interface Config {
auth: {
users: UserAuthOperations;
};
users: UserAuthOperations
}
collections: {
users: User;
media: Media;
worship: Worship;
church: Church;
testimony: Testimony;
'payload-preferences': PayloadPreference;
'payload-migrations': PayloadMigration;
};
parish: Parish
church: Church
worship: Worship
event: Event
group: Group
employees: Employee
testimony: Testimony
users: User
media: Media
'payload-preferences': PayloadPreference
'payload-migrations': PayloadMigration
}
db: {
defaultIDType: string;
};
globals: {};
locale: null;
defaultIDType: string
}
globals: {}
locale: null
user: User & {
collection: 'users';
};
collection: 'users'
}
}
export interface UserAuthOperations {
forgotPassword: {
email: string;
password: string;
};
email: string
password: string
}
login: {
email: string;
password: string;
};
email: string
password: string
}
registerFirstUser: {
email: string;
password: string;
};
email: string
password: string
}
unlock: {
email: string;
password: string;
};
email: string
password: string
}
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "users".
* via the `definition` "parish".
*/
export interface User {
id: string;
updatedAt: string;
createdAt: string;
email: string;
resetPasswordToken?: string | null;
resetPasswordExpiration?: string | null;
salt?: string | null;
hash?: string | null;
loginAttempts?: number | null;
lockUntil?: string | null;
password?: string | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "media".
*/
export interface Media {
id: string;
alt: string;
updatedAt: string;
createdAt: string;
url?: string | null;
thumbnailURL?: string | null;
filename?: string | null;
mimeType?: string | null;
filesize?: number | null;
width?: number | null;
height?: number | null;
focalX?: number | null;
focalY?: number | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "worship".
*/
export interface Worship {
id: string;
date: string;
location: string | Church;
type: 'MASS' | 'FAMILY' | 'WORD';
cancelled: boolean;
title?: string | null;
description?: string | null;
updatedAt: string;
createdAt: string;
export interface Parish {
id: string
name: string
churches: (string | Church)[]
employees: (string | Employee)[]
contact: string
title: string
description: string
photo?: string | Media | null
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "church".
*/
export interface Church {
id: string;
name: string;
address: string;
updatedAt: string;
createdAt: string;
id: string
name: string
address: string
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "employees".
*/
export interface Employee {
id: string
photo?: string | Media | null
name: string
occupation: string
email?: string | null
telephone?: string | null
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "media".
*/
export interface Media {
id: string
alt: string
updatedAt: string
createdAt: string
url?: string | null
thumbnailURL?: string | null
filename?: string | null
mimeType?: string | null
filesize?: number | null
width?: number | null
height?: number | null
focalX?: number | null
focalY?: number | null
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "worship".
*/
export interface Worship {
id: string
date: string
location: string | Church
type: 'MASS' | 'FAMILY' | 'WORD'
cancelled: boolean
title?: string | null
description?: string | null
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "event".
*/
export interface Event {
id: string
photo?: string | Media | null
title: string
datum: string
parish?: (string | Parish)[] | null
group?: (string | null) | Group
shortDescription: string
description: {
root: {
type: string
children: {
type: string
version: number
[k: string]: unknown
}[]
direction: ('ltr' | 'rtl') | null
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''
indent: number
version: number
}
[k: string]: unknown
}
cancelled: boolean
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "group".
*/
export interface Group {
id: string
photo?: string | Media | null
name: string
description: string
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "testimony".
*/
export interface Testimony {
id: string;
testimony: string;
name: string;
occupation?: string | null;
category: 'EUCHARIST';
updatedAt: string;
createdAt: string;
id: string
testimony: string
name: string
occupation?: string | null
category: 'EUCHARIST'
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "users".
*/
export interface User {
id: string
name: string
roles: 'user' | 'employee' | 'admin'
groups?: (string | Group)[] | null
updatedAt: string
createdAt: string
email: string
resetPasswordToken?: string | null
resetPasswordExpiration?: string | null
salt?: string | null
hash?: string | null
loginAttempts?: number | null
lockUntil?: string | null
password?: string | null
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-preferences".
*/
export interface PayloadPreference {
id: string;
id: string
user: {
relationTo: 'users';
value: string | User;
};
key?: string | null;
relationTo: 'users'
value: string | User
}
key?: string | null
value?:
| {
[k: string]: unknown;
[k: string]: unknown
}
| unknown[]
| string
| number
| boolean
| null;
updatedAt: string;
createdAt: string;
| null
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-migrations".
*/
export interface PayloadMigration {
id: string;
name?: string | null;
batch?: number | null;
updatedAt: string;
createdAt: string;
id: string
name?: string | null
batch?: number | null
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "auth".
*/
export interface Auth {
[k: string]: unknown;
[k: string]: unknown
}
declare module 'payload' {
export interface GeneratedTypes extends Config {}
}

View file

@ -12,6 +12,10 @@ import { Worship } from '@/collections/Worship'
import { Churches } from '@/collections/Churches'
import { de } from '@payloadcms/translations/languages/de'
import { Testimony } from '@/collections/Testimony'
import { Parish } from '@/collections/Parish'
import { Employees } from '@/collections/Employees'
import { Groups } from '@/collections/Groups'
import { Events } from '@/collections/Events'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
@ -20,7 +24,17 @@ export default buildConfig({
admin: {
user: Users.slug,
},
collections: [Users, Media, Worship, Churches, Testimony],
collections: [
Parish,
Churches,
Worship,
Events,
Groups,
Employees,
Testimony,
Users,
Media,
],
editor: lexicalEditor(),
secret: process.env.PAYLOAD_SECRET || '',
typescript: {