import { useCallback, useEffect, useState } from "react"; import useExamEditorStore from "@/stores/examEditor"; import ExamEditorStore, { ModuleState } from "@/stores/examEditor/types"; import AutoExpandingTextArea from "@/components/Low/AutoExpandingTextarea"; import { Difficulty, LevelPart, WritingExercise } from "@/interfaces/exam"; import Header from "../../Shared/Header"; import Alert, { AlertItem } from "../Shared/Alert"; import clsx from "clsx"; import useSectionEdit from "../../Hooks/useSectionEdit"; import GenLoader from "../Shared/GenLoader"; import setEditingAlert from "../Shared/setEditingAlert"; import { Module } from "@/interfaces"; interface Props { sectionId: number; exercise: WritingExercise; module: Module; index?: number; } const Writing: React.FC = ({ sectionId, exercise, module, index }) => { const { currentModule, dispatch } = useExamEditorStore(); const difficulty = useExamEditorStore((state) => state.modules[currentModule].difficulty); const { type, academic_url } = useExamEditorStore( (state) => state.modules[currentModule] ); const { generating, genResult, state } = useExamEditorStore( (state) => state.modules[currentModule].sections.find((section) => section.sectionId === sectionId)! ); const [local, setLocal] = useState(exercise); const [prompt, setPrompt] = useState(exercise.prompt); const [loading, setLoading] = useState(generating && generating == "exercises"); const [alerts, setAlerts] = useState([]); const level = module === "level"; const { editing, handleSave, handleDiscard, handleDelete, handlePractice, handleEdit, setEditing } = useSectionEdit({ sectionId, onSave: () => { const newExercise = { ...local } as WritingExercise; newExercise.prompt = prompt; newExercise.difficulty = exercise.difficulty; setAlerts([]); setEditing(false); if (!level) { dispatch({ type: "UPDATE_SECTION_STATE", payload: { sectionId: sectionId, update: newExercise, module } }); } if (genResult) { dispatch({ type: "UPDATE_SECTION_SINGLE_FIELD", payload: { sectionId, module: currentModule, field: "genResult", value: undefined } }) } }, onDiscard: () => { setEditing(false); setLocal(exercise); setPrompt(exercise.prompt); }, onDelete: () => { if (level) { dispatch({ type: "UPDATE_SECTION_STATE", payload: { sectionId: sectionId, update: { exercises: (state as LevelPart).exercises.filter((_, i) => i !== index) }, module } }); } }, onPractice: () => { const newState = { ...state, isPractice: !local.isPractice }; setLocal((prev) => ({ ...prev, isPractice: !local.isPractice })) dispatch({ type: 'UPDATE_SECTION_STATE', payload: { sectionId, update: newState, module: currentModule } }); } }); useEffect(() => { const loading = generating && generating == "writing"; setLoading(loading); // eslint-disable-next-line react-hooks/exhaustive-deps }, [generating]); useEffect(() => { if (genResult) { setEditing(true); setPrompt(genResult.result[0].prompt); if (!difficulty.includes(genResult.result[0].difficulty)) { dispatch({ type: 'UPDATE_MODULE', payload: { updates: { difficulty: [...difficulty, genResult.result[0].difficulty]} } }); } const updatedExercise = { ...exercise, difficulty: genResult.result[0].difficulty }; dispatch({ type: 'UPDATE_SECTION_STATE', payload: { sectionId, update: updatedExercise, module: currentModule } }); dispatch({ type: "UPDATE_SECTION_SINGLE_FIELD", payload: { sectionId, module: currentModule, field: "generating", value: undefined } }) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [genResult, dispatch, sectionId, setEditing, currentModule]); useEffect(() => { setEditingAlert(prompt !== local.prompt, setAlerts); }, [prompt, local.prompt]); const saveDifficulty = useCallback((diff: Difficulty)=> { if (!difficulty.includes(diff)) { dispatch({ type: 'UPDATE_MODULE', payload: { updates: { difficulty: [...difficulty, diff]} } }); } if (!level) { const updatedExercise = { ...exercise, difficulty: diff }; dispatch({ type: 'UPDATE_SECTION_STATE', payload: { sectionId, update: updatedExercise, module: currentModule } }); } else { const updatedExercise = { ...exercise, difficulty: diff }; const newState = { ...state as LevelPart }; newState.exercises = (newState as LevelPart).exercises.map((ex) => ex.id === exercise.id ? updatedExercise : ex ); dispatch({ type: 'UPDATE_SECTION_STATE', payload: { sectionId, update: newState, module: currentModule } }); } }, [currentModule, difficulty, dispatch, exercise, level, sectionId, state]); return ( <>
{alerts.length !== 0 && }
{loading ? : <> { editing ? (
setPrompt(text)} placeholder="Instructions ..." />
) : (

{prompt === "" ? "Instructions ..." : prompt}

) } {academic_url && sectionId == 1 && (
{/* eslint-disable-next-line @next/next/no-img-element */} Visual Information
)} }
); }; export default Writing;