Spaces:
Sleeping
Sleeping
| import { useState } from "react"; | |
| import { zodResolver } from "@hookform/resolvers/zod"; | |
| import { useForm } from "react-hook-form"; | |
| import * as z from "zod"; | |
| import { Button } from "@/components/ui/button"; | |
| import { | |
| Dialog, | |
| DialogContent, | |
| DialogDescription, | |
| DialogFooter, | |
| DialogHeader, | |
| DialogTitle, | |
| } from "@/components/ui/dialog"; | |
| import { Textarea } from "@/components/ui/textarea"; | |
| import { | |
| Form, | |
| FormControl, | |
| FormField, | |
| FormItem, | |
| FormLabel, | |
| FormMessage, | |
| } from "@/components/ui/form"; | |
| import { | |
| Select, | |
| SelectContent, | |
| SelectItem, | |
| SelectTrigger, | |
| SelectValue, | |
| } from "@/components/ui/select"; | |
| import { | |
| Role, | |
| AssessmentArea, | |
| RoleAssessmentQuestion, | |
| RoleAssessmentQuestionCreateRequest, | |
| RoleAssessmentQuestionUpdateRequest | |
| } from "@/types"; | |
| // Define form schema | |
| const formSchema = z.object({ | |
| roleId: z.number().min(1, { message: "Please select a role." }), | |
| areaId: z.number().min(1, { message: "Please select an assessment area." }), | |
| questionText: z.string().min(5, { message: "Question text must be at least 5 characters." }), | |
| }); | |
| interface RoleAssessmentQuestionDialogProps { | |
| open: boolean; | |
| onOpenChange: (open: boolean) => void; | |
| onSubmit: (data: RoleAssessmentQuestionCreateRequest | RoleAssessmentQuestionUpdateRequest) => void; | |
| questionToEdit?: RoleAssessmentQuestion; | |
| roles: Role[]; | |
| assessmentAreas: AssessmentArea[]; | |
| isLoading?: boolean; | |
| } | |
| export function RoleAssessmentQuestionDialog({ | |
| open, | |
| onOpenChange, | |
| onSubmit, | |
| questionToEdit, | |
| roles, | |
| assessmentAreas, | |
| isLoading = false, | |
| }: RoleAssessmentQuestionDialogProps) { | |
| const [error, setError] = useState<string | null>(null); | |
| const form = useForm<z.infer<typeof formSchema>>({ | |
| resolver: zodResolver(formSchema), | |
| defaultValues: { | |
| roleId: questionToEdit?.roleId || undefined, | |
| areaId: questionToEdit?.areaId || undefined, | |
| questionText: questionToEdit?.questionText || "", | |
| }, | |
| }); | |
| function handleSubmit(values: z.infer<typeof formSchema>) { | |
| setError(null); | |
| if (questionToEdit) { | |
| onSubmit({ | |
| questionId: questionToEdit.questionId, | |
| roleId: values.roleId, | |
| areaId: values.areaId, | |
| questionText: values.questionText, | |
| }); | |
| } else { | |
| onSubmit({ | |
| roleId: values.roleId, | |
| areaId: values.areaId, | |
| questionText: values.questionText, | |
| }); | |
| } | |
| } | |
| return ( | |
| <Dialog open={open} onOpenChange={onOpenChange}> | |
| <DialogContent className="sm:max-w-[425px]"> | |
| <DialogHeader> | |
| <DialogTitle>{questionToEdit ? "Edit Assessment Question" : "Create Assessment Question"}</DialogTitle> | |
| <DialogDescription> | |
| {questionToEdit | |
| ? "Edit the details of this assessment question." | |
| : "Add a new assessment question for a specific role." | |
| } | |
| </DialogDescription> | |
| </DialogHeader> | |
| <Form {...form}> | |
| <form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-4"> | |
| <FormField | |
| control={form.control} | |
| name="roleId" | |
| render={({ field }) => ( | |
| <FormItem> | |
| <FormLabel>Role</FormLabel> | |
| <Select | |
| onValueChange={(value) => field.onChange(parseInt(value, 10))} | |
| value={field.value?.toString()} | |
| disabled={questionToEdit !== undefined} | |
| > | |
| <FormControl> | |
| <SelectTrigger> | |
| <SelectValue placeholder="Select a role" /> | |
| </SelectTrigger> | |
| </FormControl> | |
| <SelectContent> | |
| {roles.map((role) => ( | |
| <SelectItem | |
| key={role.roleId} | |
| value={role.roleId.toString()} | |
| > | |
| {role.roleName} | |
| </SelectItem> | |
| ))} | |
| </SelectContent> | |
| </Select> | |
| <FormMessage /> | |
| </FormItem> | |
| )} | |
| /> | |
| <FormField | |
| control={form.control} | |
| name="areaId" | |
| render={({ field }) => ( | |
| <FormItem> | |
| <FormLabel>Assessment Area</FormLabel> | |
| <Select | |
| onValueChange={(value) => field.onChange(parseInt(value, 10))} | |
| value={field.value?.toString()} | |
| > | |
| <FormControl> | |
| <SelectTrigger> | |
| <SelectValue placeholder="Select an assessment area" /> | |
| </SelectTrigger> | |
| </FormControl> | |
| <SelectContent> | |
| {assessmentAreas.map((area) => ( | |
| <SelectItem | |
| key={area.areaId} | |
| value={area.areaId.toString()} | |
| > | |
| {area.title} | |
| </SelectItem> | |
| ))} | |
| </SelectContent> | |
| </Select> | |
| <FormMessage /> | |
| </FormItem> | |
| )} | |
| /> | |
| <FormField | |
| control={form.control} | |
| name="questionText" | |
| render={({ field }) => ( | |
| <FormItem> | |
| <FormLabel>Question Text</FormLabel> | |
| <FormControl> | |
| <Textarea | |
| placeholder="Describe your key achievements in the last appraisal period" | |
| className="min-h-[100px]" | |
| {...field} | |
| /> | |
| </FormControl> | |
| <FormMessage /> | |
| </FormItem> | |
| )} | |
| /> | |
| {error && <p className="text-sm font-medium text-destructive">{error}</p>} | |
| <DialogFooter> | |
| <Button | |
| type="button" | |
| variant="outline" | |
| onClick={() => onOpenChange(false)} | |
| disabled={isLoading} | |
| > | |
| Cancel | |
| </Button> | |
| <Button type="submit" disabled={isLoading}> | |
| {isLoading ? "Saving..." : questionToEdit ? "Update" : "Create"} | |
| </Button> | |
| </DialogFooter> | |
| </form> | |
| </Form> | |
| </DialogContent> | |
| </Dialog> | |
| ); | |
| } |