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

281 lines
6.5 KiB
TypeScript

import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "./ui/select";
const memberSchema = z.object({
userId: z.string().optional(),
firstname: z.string().min(1, "Prénom est requis."),
lastname: z.string().min(1, "Nom de famille est requis."),
email: z.string().email("Adresse email invalide."),
password: z
.string()
.min(6, "Le mot de passe doit avoir au moins 6 caractères.")
.optional(),
phone: z.string().regex(/^\d{10}$/, "Le numéro doit avoir 10 chiffres."),
role: z.string().min(1, "Le rôle est requis."),
});
const updateMemberSchema = memberSchema.partial();
export type Member = z.infer<typeof memberSchema>;
interface MemberDialogProps {
isOpen: boolean;
onClose: () => void;
member: Member | null;
onSave: (member: Member) => void;
}
export default function MemberDialog({
isOpen,
onClose,
member,
onSave,
}: MemberDialogProps) {
const schema = member?.userId ? updateMemberSchema : memberSchema;
const form = useForm<Member>({
resolver: zodResolver(schema),
defaultValues: member?.userId
? member
: {
userId: "",
firstname: "",
lastname: "",
email: "",
password: "",
phone: "",
role: "",
},
});
useEffect(() => {
if (member) {
form.reset(member);
} else {
form.reset({
userId: "",
firstname: "",
lastname: "",
email: "",
password: "",
phone: "",
role: "",
});
}
}, [member, form]);
const onSubmit = (data: Member) => {
onSave(data);
onClose();
};
return (
<Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent>
<DialogHeader>
<DialogTitle>
{member
? "Mise à jour du membre"
: "Créer un nouveau membre"}
</DialogTitle>
</DialogHeader>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-8"
>
<div className="grid gap-4">
{/* Firstname Field */}
<FormField
control={form.control}
name="firstname"
render={({ field }) => (
<FormItem className="grid gap-2">
<FormLabel htmlFor="name">
Prénom
</FormLabel>
<FormControl>
<Input
id="firstname"
placeholder="John Doe"
type="text"
autoComplete="firstname"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="grid gap-4">
{/* Firstname Field */}
<FormField
control={form.control}
name="lastname"
render={({ field }) => (
<FormItem className="grid gap-2">
<FormLabel htmlFor="lastname">
Nom
</FormLabel>
<FormControl>
<Input
id="lastname"
placeholder="John Doe"
type="text"
autoComplete="lastname"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{/* Email Field */}
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem className="grid gap-2">
<FormLabel htmlFor="email">
Email
</FormLabel>
<FormControl>
<Input
id="email"
placeholder="johndoe@mail.com"
type="email"
autoComplete="email webauthn"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{/* Password Field */}
{!member?.userId && (
<FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem className="grid gap-2">
<FormLabel htmlFor="password">
Mot de passe
</FormLabel>
<FormControl>
<Input
id="password"
placeholder=""
type="password"
autoComplete="new-password webauthn"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
)}
<FormField
control={form.control}
name="role"
render={({ field }) => (
<FormItem className="grid gap-2">
<FormLabel htmlFor="role">
Role
</FormLabel>
<FormControl>
<Select
value={field.value}
onValueChange={(
value: string,
) => field.onChange(value)}
>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Séléctionner un rôle" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>
Role
</SelectLabel>
<SelectItem value="admin">
Administrateur
</SelectItem>
<SelectItem value="user">
Utilisateur
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{/* Phone Field */}
<FormField
control={form.control}
name="phone"
render={({ field }) => (
<FormItem className="grid gap-2">
<FormLabel htmlFor="phone">
Phone number
</FormLabel>
<FormControl>
<Input
id="phone"
placeholder="0648265441"
type="tel"
autoComplete="phone"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</div>
<DialogFooter>
<Button type="submit">
{member ? "Actualiser" : "Ajouter"}
</Button>
</DialogFooter>
</form>
</Form>
</DialogContent>
</Dialog>
);
}