diff --git a/src/modules/admin/components/courses/CreateUnitDialog.jsx b/src/modules/admin/components/courses/CreateUnitDialog.jsx index c8c90a8..7b5fce6 100644 --- a/src/modules/admin/components/courses/CreateUnitDialog.jsx +++ b/src/modules/admin/components/courses/CreateUnitDialog.jsx @@ -1,22 +1,27 @@ // modules/admin/components/courses/CreateUnitDialog.jsx // Lightweight "create a brand-new unit and attach it to this course" dialog — // the create-new counterpart to AttachUnitsDialog's attach-existing flow. +// Two steps (Details -> Completion Requirements) to match the other two +// create-unit surfaces (AddUnit.jsx, AddLibraryUnit.jsx) — same capability, +// just condensed into a dialog since this one runs inline in a wizard. -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; +import { ChevronLeft } from "lucide-react"; import { useCourses } from "@/contexts/AdminCoursesContext"; import { useAuth } from "@/contexts/AuthContext"; import { - Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogClose, + Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; import { Spinner } from "@/components/ui/spinner"; +import DraftRequirementsEditor from "./DraftRequirementsEditor"; const schema = z.object({ title: z.string().min(1, "Title is required."), @@ -25,19 +30,33 @@ const schema = z.object({ }); export default function CreateUnitDialog({ open, onOpenChange, courseId, nextOrder = 0, onCreated, draftMode = false }) { - const { createUnit, loading } = useCourses(); + const { createUnit, syncUnitRequirements, loading } = useCourses(); const { user } = useAuth(); - const { register, handleSubmit, reset, formState: { errors } } = useForm({ + const [step, setStep] = useState(0); + const [requirements, setRequirements] = useState([]); + + const { register, handleSubmit, trigger, reset, formState: { errors } } = useForm({ resolver: zodResolver(schema), defaultValues: { title: "", description: "", order: nextOrder }, }); useEffect(() => { - if (open) reset({ title: "", description: "", order: nextOrder }); + if (open) { + reset({ title: "", description: "", order: nextOrder }); + setStep(0); + setRequirements([]); + } }, [open, nextOrder, reset]); + const handleNext = async () => { + const valid = await trigger(); + if (valid) setStep(1); + }; + const onValid = async (values) => { + const clean = requirements.map(({ _key, ...r }) => r); + if (draftMode) { onCreated?.({ unit_id: null, @@ -46,6 +65,7 @@ export default function CreateUnitDialog({ open, onOpenChange, courseId, nextOrd description: values.description, order_index: values.order, lessons: [], + requirements: clean, }); onOpenChange(false); return; @@ -54,6 +74,11 @@ export default function CreateUnitDialog({ open, onOpenChange, courseId, nextOrd const result = await createUnit(courseId, { ...values, createdBy: user?.user_id }); const unit = result?.data?.data ?? null; if (!unit) return; + + if (clean.length > 0) { + await syncUnitRequirements(courseId, unit.unit_id, clean); + } + onCreated?.(unit); onOpenChange(false); }; @@ -63,35 +88,63 @@ export default function CreateUnitDialog({ open, onOpenChange, courseId, nextOrd New Unit + + Creates a new unit in the shared Units Library and attaches it to this course. +
-
- - - {errors.title &&

{errors.title.message}

} -
+ {step === 0 && ( + <> +
+ + + {errors.title &&

{errors.title.message}

} +
-
- -