Fixed creation of users + better frontend handling of permissions

This commit is contained in:
cdricms
2025-03-06 17:34:52 +01:00
parent 3c6038bce1
commit 7cb633b4c6
46 changed files with 1511 additions and 909 deletions

View File

@@ -30,25 +30,14 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import {
SubmitErrorHandler,
SubmitHandler,
useForm,
UseFormReturn,
} from "react-hook-form";
import { CalendarEventExternal } from "@schedule-x/calendar";
import ICalendarEvent from "@/interfaces/ICalendarEvent";
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",
}),
startDate: z.date({ required_error: "Date de début requise" }),
startTime: z.string(),
endDate: z.date({
required_error: "Date finale requise",
}),
endDate: z.date({ required_error: "Date finale requise" }),
endTime: z.string(),
fullDay: z.boolean().default(false),
frequency: z.enum(["unique", "quotidien", "hebdomadaire", "mensuel"]),
@@ -65,37 +54,34 @@ const frequencies = [
{ label: "Mensuel", value: "mensuel" },
];
const isCalendarEventExternal = (
event: CalendarEventExternal | Omit<CalendarEventExternal, "id">,
): event is CalendarEventExternal => {
return (event as CalendarEventExternal).id !== undefined;
};
export const EventForm: React.FC<{
event: ICalendarEvent | Omit<ICalendarEvent, "id">;
event: any;
setForm: React.Dispatch<
React.SetStateAction<UseFormReturn<EventFormValues> | undefined>
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 ? event.title : "",
startDate: _start, // event.start),
title: event.title || "",
startDate: _start,
startTime: format(_start, "HH:mm"),
endDate: _end, // event.end),
endDate: _end,
endTime: format(_end, "HH:mm"),
fullDay: event.fullday,
fullDay: event.fullday ?? false,
frequency: "unique",
isVisible: event.isVisible,
isVisible: event.isVisible ?? true,
},
});
useEffect(() => {
setForm(form);
}, []);
}, [form, setForm]);
const frequency = form.watch("frequency");
@@ -120,53 +106,63 @@ export const EventForm: React.FC<{
/>
<div className="grid grid-cols-[1fr,auto,1fr] items-end gap-2">
<FormField
control={form.control}
name="startDate"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Début</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
<Button
variant="outline"
className={cn(
"w-full pl-3 text-left font-normal",
!field.value &&
"text-muted-foreground",
)}
>
{field.value ? (
format(
field.value,
"dd/MM/yyyy",
)
) : (
<span>
Choisis une date
</span>
)}
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent
className="w-auto p-0"
align="start"
>
<Calendar
mode="single"
selected={field.value}
onSelect={field.onChange}
initialFocus
/>
</PopoverContent>
</Popover>
<FormMessage />
</FormItem>
)}
/>
{/* 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}
@@ -187,53 +183,60 @@ export const EventForm: React.FC<{
<span className="invisible">Until</span>
<FormField
control={form.control}
name="endDate"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Fin</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
<Button
variant="outline"
className={cn(
"w-full pl-3 text-left font-normal",
!field.value &&
"text-muted-foreground",
)}
>
{field.value ? (
format(
field.value,
"dd/MM/yyyy",
)
) : (
<span>
Choisis une date
</span>
)}
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent
className="w-auto p-0"
align="start"
>
<Calendar
mode="single"
selected={field.value}
onSelect={field.onChange}
initialFocus
/>
</PopoverContent>
</Popover>
<FormMessage />
</FormItem>
)}
/>
{/* 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}
@@ -303,53 +306,71 @@ export const EventForm: React.FC<{
/>
{frequency !== "unique" && (
<FormField
control={form.control}
name="frequencyEndDate"
render={({ field }) => (
<FormItem className="flex-1">
<FormLabel>Jusqu'au</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
<Button
variant="outline"
className={cn(
"w-full pl-3 text-left font-normal",
!field.value &&
"text-muted-foreground",
)}
>
{field.value ? (
format(
field.value,
"dd/MM/yyyy",
)
) : (
<span>
Choisis une date
</span>
)}
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent
className="w-auto p-0"
align="start"
>
<Calendar
mode="single"
selected={field.value}
onSelect={field.onChange}
initialFocus
/>
</PopoverContent>
</Popover>
<FormMessage />
</FormItem>
)}
/>
<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>