feat: add room and service management
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import { z } from 'zod';
|
||||
import { idSchema, moneyGbp, positiveInt, requiredText } from './shared.schema';
|
||||
|
||||
export const roomTypes = ['meeting_room', 'private_office', 'coworking_desk'] as const;
|
||||
|
||||
const optionalPositiveInt = (label: string) =>
|
||||
z.preprocess((value) => (value === '' ? undefined : value), positiveInt(label).optional());
|
||||
|
||||
const typeFields = {
|
||||
meeting_room: [
|
||||
'sqFt',
|
||||
'internalPricePerHourGbp',
|
||||
'externalPricePerHourGbp',
|
||||
'internalPricePerDayGbp',
|
||||
'externalPricePerDayGbp',
|
||||
'maxAttendees'
|
||||
],
|
||||
private_office: ['sqFt', 'workstations', 'pricePerMonthGbp'],
|
||||
coworking_desk: [
|
||||
'internalPricePerHourGbp',
|
||||
'externalPricePerHourGbp',
|
||||
'internalPricePerDayGbp',
|
||||
'externalPricePerDayGbp'
|
||||
]
|
||||
} as const satisfies Record<(typeof roomTypes)[number], readonly string[]>;
|
||||
|
||||
const fieldLabels: Record<string, string> = {
|
||||
sqFt: 'Sq ft.',
|
||||
internalPricePerHourGbp: 'Internal price per hour',
|
||||
externalPricePerHourGbp: 'External price per hour',
|
||||
internalPricePerDayGbp: 'Internal price per day',
|
||||
externalPricePerDayGbp: 'External price per day',
|
||||
maxAttendees: 'Max attendees',
|
||||
workstations: 'Number of workstations',
|
||||
pricePerMonthGbp: 'Price per month'
|
||||
};
|
||||
|
||||
export const roomCreateSchema = z
|
||||
.object({
|
||||
name: requiredText('Room name'),
|
||||
type: z.enum(roomTypes).default('meeting_room'),
|
||||
sqFt: optionalPositiveInt('Sq ft.'),
|
||||
internalPricePerHourGbp: moneyGbp,
|
||||
externalPricePerHourGbp: moneyGbp,
|
||||
internalPricePerDayGbp: moneyGbp,
|
||||
externalPricePerDayGbp: moneyGbp,
|
||||
maxAttendees: optionalPositiveInt('Max attendees'),
|
||||
workstations: optionalPositiveInt('Number of workstations'),
|
||||
pricePerMonthGbp: moneyGbp
|
||||
})
|
||||
.superRefine((data, ctx) => {
|
||||
for (const field of typeFields[data.type]) {
|
||||
const value = data[field as keyof typeof data];
|
||||
|
||||
if (value === undefined || value === null || value === '') {
|
||||
ctx.addIssue({
|
||||
code: 'custom',
|
||||
path: [field],
|
||||
message: `${fieldLabels[field]} is required.`
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const roomEditSchema = roomCreateSchema.extend(idSchema.shape);
|
||||
@@ -0,0 +1,12 @@
|
||||
import { z } from 'zod';
|
||||
import { idSchema, moneyGbp, optionalText, requiredText } from './shared.schema';
|
||||
|
||||
export const serviceCreateSchema = z.object({
|
||||
name: requiredText('Service name'),
|
||||
category: optionalText(120),
|
||||
unit: requiredText('Unit', 80).default('each'),
|
||||
priceGbp: moneyGbp,
|
||||
description: optionalText(1000)
|
||||
});
|
||||
|
||||
export const serviceEditSchema = serviceCreateSchema.extend(idSchema.shape);
|
||||
Reference in New Issue
Block a user