import { z } from 'zod'; import { SchedulingPollStatus, PollVoteValue } from '@prisma/client'; export const createPollSchema = z.object({ title: z.string().min(1, 'Title is required').max(200), description: z.string().max(2000).optional(), location: z.string().max(500).optional(), timezone: z.string().default('America/Edmonton'), allowAnonymous: z.boolean().optional().default(true), isPrivate: z.boolean().optional().default(false), notifyOnVote: z.boolean().optional().default(true), votingDeadline: z.string().datetime().optional(), autoFinalize: z.boolean().optional().default(false), autoFinalizeThreshold: z.number().int().min(1).max(100).nullable().optional(), autoConvertToCalendar: z.boolean().optional().default(false), autoConvertToGancio: z.boolean().optional().default(false), autoConvertToShift: z.boolean().optional().default(false), tieBreaker: z.enum(['earliest', 'organizer_choice']).optional().default('earliest'), autoEnrollVoters: z.boolean().optional().default(true), options: z.array(z.object({ date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be YYYY-MM-DD'), startTime: z.string().regex(/^\d{2}:\d{2}$/, 'Start time must be HH:MM'), endTime: z.string().regex(/^\d{2}:\d{2}$/, 'End time must be HH:MM'), })).min(1, 'At least 1 option required').max(20, 'Maximum 20 options'), }); export const updatePollSchema = z.object({ title: z.string().min(1).max(200).optional(), description: z.string().max(2000).nullable().optional(), location: z.string().max(500).nullable().optional(), timezone: z.string().optional(), allowAnonymous: z.boolean().optional(), isPrivate: z.boolean().optional(), notifyOnVote: z.boolean().optional(), votingDeadline: z.string().datetime().nullable().optional(), status: z.nativeEnum(SchedulingPollStatus).optional(), autoFinalize: z.boolean().optional(), autoFinalizeThreshold: z.number().int().min(1).max(100).nullable().optional(), autoConvertToCalendar: z.boolean().optional(), autoConvertToGancio: z.boolean().optional(), autoConvertToShift: z.boolean().optional(), tieBreaker: z.enum(['earliest', 'organizer_choice']).optional(), autoEnrollVoters: z.boolean().optional(), }); export const addOptionsSchema = z.object({ options: z.array(z.object({ date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be YYYY-MM-DD'), startTime: z.string().regex(/^\d{2}:\d{2}$/, 'Start time must be HH:MM'), endTime: z.string().regex(/^\d{2}:\d{2}$/, 'End time must be HH:MM'), })).min(1).max(20), }); export const participantNeedsInlineSchema = z.object({ needsWheelchair: z.boolean().optional(), needsGroundFloor: z.boolean().optional(), needsHearingLoop: z.boolean().optional(), needsSignLanguage: z.boolean().optional(), otherAccessibility: z.string().max(1000).nullable().optional(), isVegan: z.boolean().optional(), isVegetarian: z.boolean().optional(), isGlutenFree: z.boolean().optional(), isHalal: z.boolean().optional(), isKosher: z.boolean().optional(), hasNutAllergy: z.boolean().optional(), otherDietary: z.string().max(1000).nullable().optional(), needsChildcare: z.boolean().optional(), childcareDetails: z.string().max(1000).nullable().optional(), needsTransportation: z.boolean().optional(), transportationNotes: z.string().max(1000).nullable().optional(), preferredLanguage: z.string().max(10).nullable().optional(), needsTranslation: z.boolean().optional(), translationLanguage: z.string().max(100).nullable().optional(), visibilityConsent: z.enum(['organizer_only', 'shared_with_hosts', 'public']).optional().default('organizer_only'), }).optional(); export const submitVotesSchema = z.object({ voterName: z.string().min(1, 'Name is required').max(100), voterEmail: z.preprocess( (val) => (typeof val === 'string' && val.trim() === '' ? undefined : val), z.string().email('Please enter a valid email address').max(200).optional(), ), voterToken: z.string().optional(), votes: z.array(z.object({ optionId: z.string().min(1), value: z.nativeEnum(PollVoteValue), })).min(1, 'At least one vote required'), participantNeeds: participantNeedsInlineSchema, }); export const submitCommentSchema = z.object({ authorName: z.string().min(1, 'Name is required').max(100), content: z.string().min(1, 'Comment is required').max(2000), }); export const finalizePollSchema = z.object({ optionId: z.string().min(1, 'Option ID is required'), }); export const convertToShiftSchema = z.object({ maxVolunteers: z.number().int().min(1).default(10), isPublic: z.boolean().optional().default(true), cutId: z.string().optional(), }); export const updateOptionSchema = z.object({ date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be YYYY-MM-DD').optional(), startTime: z.string().regex(/^\d{2}:\d{2}$/, 'Start time must be HH:MM').optional(), endTime: z.string().regex(/^\d{2}:\d{2}$/, 'End time must be HH:MM').optional(), }); export const listPollsSchema = z.object({ page: z.coerce.number().int().positive().default(1), limit: z.coerce.number().int().positive().max(100).default(20), search: z.string().optional(), status: z.nativeEnum(SchedulingPollStatus).optional(), }); export type CreatePollInput = z.infer; export type UpdatePollInput = z.infer; export type AddOptionsInput = z.infer; export type SubmitVotesInput = z.infer; export type SubmitCommentInput = z.infer; export type FinalizePollInput = z.infer; export type ConvertToShiftInput = z.infer; export type UpdateOptionInput = z.infer; export type ListPollsInput = z.infer;