Fix: Verschleißteil-Formular Datumsvalidierung und Schriftfarbe

- installDate Schema akzeptiert jetzt YYYY-MM-DD Format (HTML date input)
- maintenanceHistorySchema date akzeptiert jetzt YYYY-MM-DD Format
- Transform konvertiert Datumsstrings automatisch zu Date-Objekten
- API-Routes verwenden validierte Date-Objekte direkt
- Alle Formularfelder haben jetzt schwarze Schriftfarbe (text-black)
- Optional-Felder werden getrimmt (brand, model, notes)
This commit is contained in:
Denis Urs Rudolph
2025-12-05 22:30:45 +01:00
parent 5663fec6a6
commit 81edc206e0
6 changed files with 65 additions and 27 deletions

View File

@@ -72,22 +72,60 @@ export const bikeSchema = z.object({
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()),
brand: z.string().optional().transform((val) => val?.trim() || undefined),
model: z.string().optional().transform((val) => val?.trim() || undefined),
installDate: z
.union([z.date(), z.string()])
.transform((val) => {
if (!val) return new Date() // Default to today if not provided
if (val instanceof Date) {
return isNaN(val.getTime()) ? new Date() : 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()) ? new Date() : date
}
// Handle ISO datetime format or any other parseable date string
const date = new Date(val)
return isNaN(date.getTime()) ? new Date() : date
}
return new Date()
})
.pipe(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(),
notes: z.string().optional().transform((val) => val?.trim() || undefined),
})
export const maintenanceHistorySchema = z.object({
wearPartId: z.string().min(1, 'Verschleißteil-ID ist erforderlich'),
date: z.string().datetime().or(z.date()),
date: z
.union([z.date(), z.string()])
.transform((val) => {
if (!val) return new Date() // Default to today if not provided
if (val instanceof Date) {
return isNaN(val.getTime()) ? new Date() : 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()) ? new Date() : date
}
// Handle ISO datetime format or any other parseable date string
const date = new Date(val)
return isNaN(date.getTime()) ? new Date() : date
}
return new Date()
})
.pipe(z.date()),
mileage: z.number().int().min(0),
action: MaintenanceAction,
notes: z.string().optional(),
notes: z.string().optional().transform((val) => val?.trim() || undefined),
cost: z.number().positive().optional(),
})