Files
latosa-escrima/frontend/components/event-dialog.tsx

400 lines
9.7 KiB
TypeScript

"use client";
import * as React from "react";
import { CalendarIcon } from "lucide-react";
import { format } from "date-fns";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { Checkbox } from "@/components/ui/checkbox";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { useForm } from "react-hook-form";
import { useEffect } from "react";
export const eventFormSchema = z.object({
title: z.string().min(1, "Titre requis"),
startDate: z.date({ required_error: "Date de début requise" }),
startTime: z.string(),
endDate: z.date({ required_error: "Date finale requise" }),
endTime: z.string(),
fullDay: z.boolean().default(false),
frequency: z.enum(["unique", "quotidien", "hebdomadaire", "mensuel"]),
frequencyEndDate: z.date().optional(),
isVisible: z.boolean().default(true),
});
export type EventFormValues = z.infer<typeof eventFormSchema>;
const frequencies = [
{ label: "Unique", value: "unique" },
{ label: "Quotidien", value: "quotidien" },
{ label: "Hebdomadaire", value: "hebdomadaire" },
{ label: "Mensuel", value: "mensuel" },
];
export const EventForm: React.FC<{
event: any;
setForm: React.Dispatch<
React.SetStateAction<
ReturnType<typeof useForm<EventFormValues>> | undefined
>
>;
}> = ({ event, setForm }) => {
const _start = new Date(event.start ?? Date.now());
const _end = new Date(event.end ?? Date.now());
const form = useForm<EventFormValues>({
resolver: zodResolver(eventFormSchema),
defaultValues: {
title: event.title || "",
startDate: _start,
startTime: format(_start, "HH:mm"),
endDate: _end,
endTime: format(_end, "HH:mm"),
fullDay: event.fullday ?? false,
frequency: "unique",
isVisible: event.isVisible ?? true,
},
});
useEffect(() => {
setForm(form);
}, [form, setForm]);
const frequency = form.watch("frequency");
return (
<Form {...form}>
<form className="w-full max-w-md space-y-4">
<FormField
control={form.control}
name="title"
render={({ field }) => (
<FormItem>
<FormLabel>Titre</FormLabel>
<FormControl>
<Input
placeholder="Ajouter un titre"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="grid grid-cols-[1fr,auto,1fr] items-end gap-2">
{/* Simplified startDate without FormField */}
<FormItem className="flex flex-col">
<FormLabel>Début</FormLabel>
<Popover>
<PopoverTrigger asChild>
<Button
variant="outline"
className={cn(
"w-full pl-3 text-left font-normal",
!form.getValues("startDate") &&
"text-muted-foreground",
)}
>
{form.getValues("startDate") ? (
format(
form.getValues("startDate"),
"dd/MM/yyyy",
)
) : (
<span>Choisis une date</span>
)}
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent
className="w-auto p-0"
align="start"
>
<div style={{ pointerEvents: "auto" }}>
{/* Force interactivity */}
<Calendar
mode="single"
selected={form.getValues("startDate")}
onSelect={(date) => {
console.log(
"Start date selected:",
date,
);
if (date) {
form.setValue(
"startDate",
date,
{ shouldValidate: true },
);
console.log(
"Updated startDate:",
form.getValues("startDate"),
);
}
}}
initialFocus
/>
</div>
</PopoverContent>
</Popover>
<FormMessage />
</FormItem>
<FormField
control={form.control}
name="startTime"
render={({ field }) => (
<FormItem>
<FormControl>
<Input
type="time"
{...field}
className="w-[120px]"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<span className="invisible">Until</span>
{/* Simplified endDate */}
<FormItem className="flex flex-col">
<FormLabel>Fin</FormLabel>
<Popover>
<PopoverTrigger asChild>
<Button
variant="outline"
className={cn(
"w-full pl-3 text-left font-normal",
!form.getValues("endDate") &&
"text-muted-foreground",
)}
>
{form.getValues("endDate") ? (
format(
form.getValues("endDate"),
"dd/MM/yyyy",
)
) : (
<span>Choisis une date</span>
)}
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent
className="w-auto p-0"
align="start"
>
<div style={{ pointerEvents: "auto" }}>
<Calendar
mode="single"
selected={form.getValues("endDate")}
onSelect={(date) => {
console.log(
"End date selected:",
date,
);
if (date) {
form.setValue("endDate", date, {
shouldValidate: true,
});
console.log(
"Updated endDate:",
form.getValues("endDate"),
);
}
}}
initialFocus
/>
</div>
</PopoverContent>
</Popover>
<FormMessage />
</FormItem>
<FormField
control={form.control}
name="endTime"
render={({ field }) => (
<FormItem>
<FormControl>
<Input
type="time"
{...field}
className="w-[120px]"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<FormField
control={form.control}
name="fullDay"
render={({ field }) => (
<FormItem className="flex flex-row items-start space-x-3 space-y-0">
<FormControl>
<Checkbox
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
<FormLabel>Journée complète</FormLabel>
<FormMessage />
</FormItem>
)}
/>
<div className="flex gap-4 items-end">
<FormField
control={form.control}
name="frequency"
render={({ field }) => (
<FormItem className="flex-1">
<FormLabel>Fréquence</FormLabel>
<Select
onValueChange={field.onChange}
defaultValue={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Selectionner Fréquence" />
</SelectTrigger>
</FormControl>
<SelectContent>
{frequencies.map((frequency) => (
<SelectItem
key={frequency.value}
value={frequency.value}
>
{frequency.label}
</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
{frequency !== "unique" && (
<FormItem className="flex-1">
<FormLabel>Jusqu'au</FormLabel>
<Popover>
<PopoverTrigger asChild>
<Button
variant="outline"
className={cn(
"w-full pl-3 text-left font-normal",
!form.getValues(
"frequencyEndDate",
) && "text-muted-foreground",
)}
>
{form.getValues("frequencyEndDate") ? (
format(
form.getValues(
"frequencyEndDate",
)!,
"dd/MM/yyyy",
)
) : (
<span>Choisis une date</span>
)}
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent
className="w-auto p-0"
align="start"
>
<div style={{ pointerEvents: "auto" }}>
<Calendar
mode="single"
selected={form.getValues(
"frequencyEndDate",
)}
onSelect={(date) => {
console.log(
"Frequency end date selected:",
date,
);
if (date) {
form.setValue(
"frequencyEndDate",
date,
{
shouldValidate:
true,
},
);
console.log(
"Updated frequencyEndDate:",
form.getValues(
"frequencyEndDate",
),
);
}
}}
initialFocus
/>
</div>
</PopoverContent>
</Popover>
<FormMessage />
</FormItem>
)}
</div>
<FormField
control={form.control}
name="isVisible"
render={({ field }) => (
<FormItem className="flex-1">
<FormLabel className="align-sub">
Evènement visible ?
</FormLabel>
<FormControl>
<Checkbox
className="m-3 align-top justify-center"
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</form>
</Form>
);
};