Story 5 van PBI "Alle dialogen conform docs/patterns/dialog.md". - lib/schemas/sprint.ts — gedeelde zod-schemas (create/dates/goal) - actions/sprints.ts — code+fieldErrors voor 422; code: 403 voor auth/demo errors - StartSprintButton dialog: useDirtyCloseGuard, useDialogSubmitShortcut, entityDialog* layout-classes; DemoTooltip op trigger; veld-niveau errors via fieldErrors - SprintHeader's date- en complete-dialogen: zelfde behandeling; date- dialog krijgt dirty-guard, complete-dialog krijgt DemoTooltip op bevestigen - docs/specs/dialogs/sprint.md — entity-profile dat alle drie de modes documenteert; consolidatie naar één SprintDialog component bewust uitgesteld - Sprint-dates tests aangepast aan nieuwe action-shape Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
import { z } from 'zod'
|
|
|
|
const dateField = z.string().optional().nullable().transform(v => (v && v.trim() !== '' ? new Date(v) : null))
|
|
|
|
export function validateDateOrder(
|
|
data: { start_date: Date | null; end_date: Date | null },
|
|
ctx: z.RefinementCtx,
|
|
) {
|
|
if (data.start_date && data.end_date && data.end_date < data.start_date) {
|
|
ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['end_date'], message: 'Einddatum moet na startdatum liggen' })
|
|
}
|
|
}
|
|
|
|
export const createSprintSchema = z
|
|
.object({
|
|
productId: z.string(),
|
|
sprint_goal: z.string().min(1, 'Sprint Goal is verplicht').max(500),
|
|
start_date: dateField,
|
|
end_date: dateField,
|
|
})
|
|
.superRefine(validateDateOrder)
|
|
|
|
export const updateSprintDatesSchema = z
|
|
.object({
|
|
id: z.string(),
|
|
start_date: dateField,
|
|
end_date: dateField,
|
|
})
|
|
.superRefine(validateDateOrder)
|
|
|
|
export const updateSprintGoalSchema = z.object({
|
|
id: z.string(),
|
|
sprint_goal: z.string().min(1, 'Sprint Goal is verplicht').max(500),
|
|
})
|
|
|
|
export type CreateSprintInput = z.infer<typeof createSprintSchema>
|
|
export type UpdateSprintDatesInput = z.infer<typeof updateSprintDatesSchema>
|
|
export type UpdateSprintGoalInput = z.infer<typeof updateSprintGoalSchema>
|