import { z } from 'zod' export const WearPartType = z.enum([ 'CHAIN', 'BRAKE_PADS', 'TIRE', 'CASSETTE', 'CHAINRING', 'DERAILLEUR', 'BRAKE_CABLE', 'SHIFT_CABLE', 'BRAKE_ROTOR', 'PEDAL', 'CRANKSET', 'BOTTOM_BRACKET', 'HEADSET', 'WHEEL', 'HUB', 'SPOKE', 'OTHER', ]) export const WearPartStatus = z.enum([ 'ACTIVE', 'NEEDS_SERVICE', 'REPLACED', 'INACTIVE', ]) export const MaintenanceAction = z.enum([ 'INSTALL', 'REPLACE', 'SERVICE', 'CHECK', 'ADJUST', ]) export const bikeSchema = z.object({ name: z .string() .min(1, 'Name ist erforderlich') .trim() .min(1, 'Name darf nicht nur aus Leerzeichen bestehen'), brand: z.string().optional().transform((val) => val?.trim() || undefined), model: z.string().optional().transform((val) => val?.trim() || undefined), purchaseDate: z .union([z.date(), z.string()]) .optional() .transform((val) => { if (!val || val === undefined) return undefined if (val instanceof Date) { return isNaN(val.getTime()) ? undefined : val } if (typeof val === 'string') { // Handle YYYY-MM-DD format (from HTML date input) if (/^\d{4}-\d{2}-\d{2}$/.test(val)) { const date = new Date(val + 'T00:00:00.000Z') return isNaN(date.getTime()) ? undefined : date } // Handle ISO datetime format or any other parseable date string const date = new Date(val) return isNaN(date.getTime()) ? undefined : date } return undefined }) .refine((val) => val === undefined || val instanceof Date, { message: 'Ungültiges Datumsformat', }), notes: z.string().optional().transform((val) => val?.trim() || undefined), }) export const wearPartSchema = z.object({ bikeId: z.string().min(1, 'Fahrrad-ID ist erforderlich'), type: WearPartType, brand: z.string().optional(), model: z.string().optional(), installDate: z.string().datetime().or(z.date()), installMileage: z.number().int().min(0).default(0), serviceInterval: z.number().int().min(1, 'Service-Intervall muss mindestens 1 km sein'), status: WearPartStatus.default('ACTIVE'), cost: z.number().positive().optional(), notes: z.string().optional(), }) export const maintenanceHistorySchema = z.object({ wearPartId: z.string().min(1, 'Verschleißteil-ID ist erforderlich'), date: z.string().datetime().or(z.date()), mileage: z.number().int().min(0), action: MaintenanceAction, notes: z.string().optional(), cost: z.number().positive().optional(), }) export type BikeInput = z.infer export type WearPartInput = z.infer export type MaintenanceHistoryInput = z.infer