121 lines
4.6 KiB
TypeScript
121 lines
4.6 KiB
TypeScript
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 { 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";
|
|
|
|
interface Props {
|
|
sectionId: number;
|
|
exercise: WritingExercise;
|
|
}
|
|
|
|
const Writing: React.FC<Props> = ({ sectionId }) => {
|
|
const { currentModule, dispatch } = useExamEditorStore();
|
|
const { edit } = useExamEditorStore((store) => store.modules[currentModule]);
|
|
const { generating, genResult, state } = useExamEditorStore(
|
|
(state) => state.modules[currentModule].sections.find((section) => section.sectionId === sectionId)!
|
|
);
|
|
|
|
const exercise = state as WritingExercise;
|
|
|
|
const [local, setLocal] = useState(exercise);
|
|
const [prompt, setPrompt] = useState(exercise.prompt);
|
|
const [loading, setLoading] = useState(generating && generating == "exercises");
|
|
const [alerts, setAlerts] = useState<AlertItem[]>([]);
|
|
|
|
const updateModule = useCallback((updates: Partial<ModuleState>) => {
|
|
dispatch({ type: 'UPDATE_MODULE', payload: { updates } });
|
|
}, [dispatch]);
|
|
|
|
const { editing, handleSave, handleDiscard, modeHandle, setEditing } = useSectionEdit({
|
|
sectionId,
|
|
onSave: () => {
|
|
const newExercise = { ...local } as WritingExercise;
|
|
newExercise.prompt = prompt;
|
|
setAlerts([]);
|
|
setEditing(false);
|
|
dispatch({ type: "UPDATE_SECTION_STATE", payload: { sectionId: sectionId, update: newExercise } });
|
|
},
|
|
onDiscard: () => {
|
|
setLocal(exercise);
|
|
},
|
|
});
|
|
|
|
useEffect(() => {
|
|
const loading = generating && generating == "context";
|
|
setLoading(loading);
|
|
|
|
if (loading) {
|
|
updateModule({ edit: Array.from(new Set(edit).add(sectionId)) });
|
|
}
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [generating, updateModule]);
|
|
|
|
useEffect(() => {
|
|
if (genResult !== undefined && generating === "context") {
|
|
setEditing(true);
|
|
setPrompt(genResult[0].prompt);
|
|
dispatch({ type: "UPDATE_SECTION_SINGLE_FIELD", payload: { sectionId, module: currentModule, field: "genResult", value: undefined } })
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [genResult, dispatch, sectionId, setEditing, currentModule]);
|
|
|
|
useEffect(() => {
|
|
setLocal(state as WritingExercise);
|
|
}, [state]);
|
|
|
|
useEffect(() => {
|
|
setEditingAlert(prompt !== local.prompt, setAlerts);
|
|
}, [prompt, local.prompt]);
|
|
|
|
return (
|
|
<>
|
|
<div className='relative pb-4'>
|
|
<Header
|
|
title={`Task ${sectionId} Instructions`}
|
|
description='Generate or edit the instructions for the task'
|
|
editing={editing}
|
|
handleSave={handleSave}
|
|
modeHandle={modeHandle}
|
|
handleDiscard={handleDiscard}
|
|
mode="edit"
|
|
module={"writing"}
|
|
/>
|
|
{alerts.length !== 0 && <Alert alerts={alerts} />}
|
|
</div>
|
|
<div className="mt-4">
|
|
{loading ?
|
|
<GenLoader module={currentModule} /> :
|
|
(
|
|
editing ? (
|
|
<div className="text-gray-600 p-4">
|
|
<AutoExpandingTextArea
|
|
value={prompt}
|
|
onChange={(text) => setPrompt(text)}
|
|
placeholder="Instructions ..."
|
|
/>
|
|
</div>
|
|
) : (
|
|
<p className={
|
|
clsx("w-full px-7 py-8 border-2 bg-white rounded-3xl whitespace-pre-line",
|
|
prompt === "" ? "text-gray-600/50" : "text-gray-600"
|
|
)
|
|
}>
|
|
{prompt === "" ? "Instructions ..." : prompt}
|
|
</p>
|
|
)
|
|
)}
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Writing;
|