safak / full-stack-school

115 stars 111 forks source link

issue with formModal #4

Open loggy7 opened 2 hours ago

loggy7 commented 2 hours ago

Unhandled Runtime Error TypeError: forms[table] is not a function

Source src\components\FormModal.tsx (151:20) @ setOpen

149 | 150 | ) : type === "create" || type === "update" ? (

151 | forms[table](setOpen, type, data, relatedData) | ^ 152 | ) : ( 153 | "Form not found!" 154 | );

loggy7 commented 2 hours ago

the correct code "use client";

import { deleteClass, deleteExam, deleteStudent, deleteSubject, deleteTeacher, } from "@/lib/actions"; import dynamic from "next/dynamic"; import Image from "next/image"; import { useRouter } from "next/navigation"; import { Dispatch, SetStateAction, useEffect, useState } from "react"; import { useFormState } from "react-dom"; import { toast } from "react-toastify";

// Définition des types pour les fonctions de suppression type DeleteFunction = typeof deleteSubject;

const deleteActionMap: Record<string, DeleteFunction> = { subject: deleteSubject, class: deleteClass, teacher: deleteTeacher, student: deleteStudent, exam: deleteExam, // Placeholders pour les futures implémentations parent: deleteSubject, lesson: deleteSubject, assignment: deleteSubject, result: deleteSubject, attendance: deleteSubject, event: deleteSubject, announcement: deleteSubject, };

// Chargement dynamique des formulaires const TeacherForm = dynamic(() => import("./forms/TeacherForm"), { loading: () =>

Loading...

, }); const StudentForm = dynamic(() => import("./forms/StudentForm"), { loading: () =>

Loading...

, }); const SubjectForm = dynamic(() => import("./forms/SubjectForm"), { loading: () =>

Loading...

, }); const ClassForm = dynamic(() => import("./forms/ClassForm"), { loading: () =>

Loading...

, }); const ExamForm = dynamic(() => import("./forms/ExamForm"), { loading: () =>

Loading...

, });

// Définition des types pour les fonctions de formulaire type FormFunction = ( setOpen: Dispatch<SetStateAction>, type: "create" | "update", data?: any, relatedData?: any ) => JSX.Element;

// Objet contenant les fonctions de formulaire const forms: Record<string, FormFunction> = { subject: (setOpen, type, data, relatedData) => ( <SubjectForm type={type} data={data} setOpen={setOpen} relatedData={relatedData} /> ), class: (setOpen, type, data, relatedData) => ( <ClassForm type={type} data={data} setOpen={setOpen} relatedData={relatedData} /> ), teacher: (setOpen, type, data, relatedData) => ( <TeacherForm type={type} data={data} setOpen={setOpen} relatedData={relatedData} /> ), student: (setOpen, type, data, relatedData) => ( <StudentForm type={type} data={data} setOpen={setOpen} relatedData={relatedData} /> ), exam: (setOpen, type, data, relatedData) => ( <ExamForm type={type} data={data} setOpen={setOpen} relatedData={relatedData} /> ), };

// Type pour les tables valides type ValidTableType = keyof typeof forms;

// Props pour le composant FormModal interface FormModalProps { table: ValidTableType; type: "create" | "update" | "delete"; data?: any; id?: string | number; relatedData?: any; }

const FormModal = ({ table, type, data, id, relatedData, }: FormModalProps) => { const size = type === "create" ? "w-8 h-8" : "w-7 h-7"; const bgColor = type === "create" ? "bg-lamaYellow" : type === "update" ? "bg-lamaSky" : "bg-lamaPurple";

const [open, setOpen] = useState(false);

const Form = () => { const [state, formAction] = useFormState(deleteActionMap[table], { success: false, error: false, });

const router = useRouter();

useEffect(() => {
  if (state.success) {
    toast(`${table} has been deleted!`);
    setOpen(false);
    router.refresh();
  }
}, [state, router]);

if (type === "delete" && id) {
  return (
    <form action={formAction} className="p-4 flex flex-col gap-4">
      <input type="text" name="id" value={id} hidden readOnly />
      <span className="text-center font-medium">
        All data will be lost. Are you sure you want to delete this {table}?
      </span>
      <button className="bg-red-700 text-white py-2 px-4 rounded-md border-none w-max self-center">
        Delete
      </button>
    </form>
  );
}

if (type === "create" || type === "update") {
  const FormComponent = forms[table];
  return FormComponent ? (
    FormComponent(setOpen, type, data, relatedData)
  ) : (
    <p>Form not yet implemented for {table}</p>
  );
}

return <p>Invalid form type</p>;

};

return ( <> <button className={${size} flex items-center justify-center rounded-full ${bgColor}} onClick={() => setOpen(true)}

<Image src={/${type}.png} alt="" width={16} height={16} /> {open && (

setOpen(false)}

)} </> ); };

export default FormModal;