import { AlertDialog, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/shadcn/components/ui/alert-dialog"; import { ScrollArea } from "@/shadcn/components/ui/scroll-area"; import { Button } from "@/shadcn/components/ui/button"; import { TextInput } from "@mantine/core"; import { Label } from "@/shadcn/components/ui/label"; import { useForm } from "@mantine/form"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { getRouteApi } from "@tanstack/react-router"; import { createAspect, updateAspect, getAspectByIdQueryOptions } from "../queries/aspectQueries"; import { useEffect, useState } from "react"; import { notifications } from "@mantine/notifications"; import FormResponseError from "@/errors/FormResponseError"; import { createId } from "@paralleldrive/cuid2"; // Initialize route API const routeApi = getRouteApi("/_dashboardLayout/aspect/"); export default function AspectFormModal() { const queryClient = useQueryClient(); const navigate = routeApi.useNavigate(); const searchParams = routeApi.useSearch(); const dataId = searchParams.detail || searchParams.edit; const isDialogOpen = Boolean(dataId || searchParams.create); const formType = searchParams.detail ? "detail" : searchParams.edit ? "ubah" : "tambah"; // Fetch aspect data if ubahing or viewing details const aspectQuery = useQuery(getAspectByIdQueryOptions(dataId)); const modalTitle = `${formType.charAt(0).toUpperCase() + formType.slice(1)} Aspek`; const form = useForm({ initialValues: { id: "", name: "", subAspects: [{ id: "", name: "", questionCount: 0 }] as { id: string; name: string; questionCount: number }[], }, }); useEffect(() => { const data = aspectQuery.data; if (!data) { form.reset(); return; } form.setValues({ id: data.id, name: data.name, subAspects: data.subAspects?.map(subAspect => ({ id: subAspect.id || "", name: subAspect.name, questionCount: subAspect.questionCount || 0, })) || [], }); form.setErrors({}); }, [aspectQuery.data]); const mutation = useMutation({ mutationKey: ["aspectMutation"], mutationFn: async ( options: | { action: "ubah"; data: Parameters[0] } | { action: "tambah"; data: Parameters[0] } ) => { return options.action === "ubah" ? await updateAspect(options.data) : await createAspect(options.data); }, onError: (error: unknown) => { if (error instanceof FormResponseError) { form.setErrors(error.formErrors); return; } if (error instanceof Error) { notifications.show({ message: error.message, color: "red", }); } }, }); type CreateAspectPayload = { name: string; subAspects?: string; }; type EditAspectPayload = { id: string; name: string; subAspects?: string; }; const [isSubmitting, setIsSubmitting] = useState(false); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); const values = form.values; try { // Start submit process setIsSubmitting(true); // Name field validation if (values.name.trim() === "") { form.setErrors({ name: "Nama aspek harus diisi" }); setIsSubmitting(false); return; } let payload: CreateAspectPayload | EditAspectPayload; if (formType === "tambah") { payload = { name: values.name, subAspects: values.subAspects.length > 0 ? JSON.stringify( values.subAspects .filter(subAspect => subAspect.name.trim() !== "") .map(subAspect => subAspect.name) ) : "", }; await createAspect(payload); } else if (formType === "ubah") { payload = { id: values.id, name: values.name, subAspects: values.subAspects.length > 0 ? JSON.stringify( values.subAspects .filter(subAspect => subAspect.name.trim() !== "") .map(subAspect => ({ id: subAspect.id || "", name: subAspect.name, questionCount: subAspect.questionCount || 0, })) ) : "", }; await updateAspect(payload); } queryClient.invalidateQueries({ queryKey: ["management-aspect"] }); notifications.show({ message: `Aspek ${formType === "tambah" ? "berhasil dibuat" : "berhasil diubah"}`, }); navigate({ search: {} }); } catch (error) { console.error("Error during submit:", error); if (error instanceof Error && error.message === "Aspect name already exists") { notifications.show({ message: "Nama aspek sudah ada. Silakan gunakan nama lain.", color: "red", }); } else { notifications.show({ message: "Nama Sub Aspek sudah ada. Silakan gunakan nama lain.", color: "red", }); } } finally { setIsSubmitting(false); } }; return ( !isOpen && navigate({ search: {} })}> {modalTitle} {formType === "detail" ? "Detail dari aspek." : "Silakan isi data aspek di bawah ini."}
{form.values.subAspects.map((subAspect, index) => (
{ if (formType !== "detail" && !mutation.isPending) { const newSubAspects = [...form.values.subAspects]; newSubAspects[index] = { ...newSubAspects[index], name: event.target.value }; form.setValues({ subAspects: newSubAspects }); } }} disabled={formType === "detail" || isSubmitting} />
{formType === "detail" && (
)} {formType !== "detail" && ( )}
))} {formType !== "detail" && ( )}
Tutup {formType !== "detail" && ( )}
); }