import Option from "@/interfaces/option"; import { AnimatePresence, Reorder } from "framer-motion"; import { useEffect, useState } from "react"; import { FaRegCheckCircle } from "react-icons/fa"; import { IoIosAddCircleOutline } from "react-icons/io"; import Button from "../Low/Button"; import WorkflowEditableStepComponent from "./WorkflowEditableStepComponent"; import { ApprovalWorkflow, WorkflowStep } from "@/interfaces/approval.workflow"; import { CorporateUser, TeacherUser } from "@/interfaces/user"; // Variants for animating steps when they are added/removed const itemVariants = { initial: { opacity: 0, y: -20 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, x: 20 }, }; interface Props { workflow: ApprovalWorkflow; onWorkflowChange: (workflow: ApprovalWorkflow) => void; entityTeachers: TeacherUser[]; entityCorporates: CorporateUser[]; } export default function WorkflowForm({ workflow, onWorkflowChange, entityTeachers, entityCorporates }: Props) { const [steps, setSteps] = useState(workflow.steps); const [stepCounter, setStepCounter] = useState(3); // to guarantee unique keys used for animations const lastStep = steps[steps.length - 1]; useEffect(() => { setSteps(workflow.steps); }, [workflow]); useEffect(() => { const updatedWorkflow = { ...workflow, steps }; onWorkflowChange(updatedWorkflow); }, [steps]); const renumberSteps = (steps: WorkflowStep[]): WorkflowStep[] => { return steps.map((step, index) => ({ ...step, stepNumber: index + 1, })); }; const addStep = () => { setSteps((prev) => { const newStep: WorkflowStep = { key: stepCounter, stepType: "approval-by", stepNumber: steps.length, completed: false, assignees: [null], }; setStepCounter((count) => count + 1); const updatedSteps = [...prev.slice(0, -1), newStep, lastStep]; return renumberSteps(updatedSteps); }); }; const handleDelete = (key: number | undefined) => { if (key) { setSteps((prev) => { const updatedSteps = prev.filter((step) => step.key !== key); return renumberSteps(updatedSteps); }); } }; const handleSelectChange = (key: number | undefined, numberOfSelects: number, index: number, selectedOption: Option | null) => { if (key === undefined) return; setSteps((prevSteps) => prevSteps.map((step) => { if (step.key !== key) return step; const assignees = step.assignees ?? []; let newAssignees = [...assignees]; if (numberOfSelects === assignees.length) { // means no new select was added and instead one was changed newAssignees[index] = selectedOption?.value; } else if (numberOfSelects === assignees.length + 1) { // means a new select was added newAssignees.push(selectedOption?.value || null); } return { ...step, assignees: newAssignees }; }) ); }; const handleReorder = (newOrder: WorkflowStep[]) => { const firstIndex = newOrder.findIndex((s) => s.firstStep); if (firstIndex !== -1 && firstIndex !== 0) { const [first] = newOrder.splice(firstIndex, 1); newOrder.unshift(first); } const finalIndex = newOrder.findIndex((s) => s.finalStep); if (finalIndex !== -1 && finalIndex !== newOrder.length - 1) { const [final] = newOrder.splice(finalIndex, 1); newOrder.push(final); } setSteps(renumberSteps(newOrder)); }; return (
{steps.map((step, index) => ( handleDelete(step.key)} onSelectChange={(numberOfSelects, idx, option) => handleSelectChange(step.key, numberOfSelects, idx, option)} entityTeachers={entityTeachers} entityCorporates={entityCorporates} /> {step.finalStep && } ))}
); };