diff --git a/.gitignore b/.gitignore index 5ef6a52..98aa3d8 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,4 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts +.cursor/mcp.json diff --git a/src/app/dashboard/add-child/page.tsx b/src/app/dashboard/add-child/page.tsx index 875b245..71021ba 100644 --- a/src/app/dashboard/add-child/page.tsx +++ b/src/app/dashboard/add-child/page.tsx @@ -40,6 +40,7 @@ const formSchema = z.object({ birthDate: z.date({ required_error: "Bitte wähle ein Geburtsdatum", }), + birthTime: z.string().regex(/^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/, "Ungültiges Zeitformat (HH:MM)").optional(), gender: z.enum(["male", "female"], { required_error: "Bitte wähle das Geschlecht", }), @@ -50,12 +51,14 @@ type FormValues = z.infer; export default function AddChildPage() { const router = useRouter(); const [isLoading, setIsLoading] = useState(false); + const [dateInputValue, setDateInputValue] = useState(""); const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { name: "", gender: "male", + birthTime: "", }, }); @@ -78,9 +81,34 @@ export default function AddChildPage() { function onSubmit(values: FormValues) { setIsLoading(true); + + // Create a date with the selected time or default to noon + let birthDateTime = values.birthDate; + if (values.birthTime) { + const [hours, minutes] = values.birthTime.split(':').map(Number); + birthDateTime = new Date(Date.UTC( + values.birthDate.getUTCFullYear(), + values.birthDate.getUTCMonth(), + values.birthDate.getUTCDate(), + hours, + minutes, + 0 + )); + } else { + // Default to noon if no time is specified + birthDateTime = new Date(Date.UTC( + values.birthDate.getUTCFullYear(), + values.birthDate.getUTCMonth(), + values.birthDate.getUTCDate(), + 12, + 0, + 0 + )); + } + addChild.mutate({ name: values.name, - birthDate: values.birthDate.toISOString(), + birthDate: birthDateTime.toISOString(), gender: values.gender, }); } @@ -119,20 +147,58 @@ export default function AddChildPage() { -
+
{ - const date = new Date(e.target.value); - if (!isNaN(date.getTime())) { - field.onChange(date); + setDateInputValue(e.target.value); + }} + onBlur={(e) => { + const inputValue = e.target.value; + + // Allow empty input + if (!inputValue) { + field.onChange(null); + return; + } + + // Check if the input matches the expected format (DD.MM.YYYY) + const dateRegex = /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/; + const match = inputValue.match(dateRegex); + + if (match) { + const day = parseInt(match[1], 10); + const month = parseInt(match[2], 10) - 1; // JavaScript months are 0-indexed + const year = parseInt(match[3], 10); + + // Create a date object and validate it + // Set the time to noon UTC to avoid timezone issues + const date = new Date(Date.UTC(year, month, day, 12, 0, 0)); + + // Check if the date is valid (e.g., not February 30th) + if ( + date.getUTCDate() === day && + date.getUTCMonth() === month && + date.getUTCFullYear() === year && + date <= new Date() && + date >= new Date("1900-01-01") + ) { + field.onChange(date); + setDateInputValue(format(date, "dd.MM.yyyy")); + } else { + // If invalid, reset to the last valid value + setDateInputValue(field.value ? format(field.value, "dd.MM.yyyy") : ""); + } + } else { + // If format is wrong, reset to the last valid value + setDateInputValue(field.value ? format(field.value, "dd.MM.yyyy") : ""); } }} /> - +
@@ -140,7 +206,14 @@ export default function AddChildPage() { { + field.onChange(date); + if (date) { + setDateInputValue(format(date, "dd.MM.yyyy")); + } else { + setDateInputValue(""); + } + }} disabled={(date) => date > new Date() || date < new Date("1900-01-01") } @@ -153,6 +226,25 @@ export default function AddChildPage() { )} /> + ( + + Geburtszeit (optional) + + + + + + )} + /> +