Exam generation rework, batch user tables, fastapi endpoint switch

This commit is contained in:
Carlos-Mesquita
2024-11-04 23:29:14 +00:00
parent a2bc997e8f
commit 15c9c4d4bd
148 changed files with 11348 additions and 3901 deletions

View File

@@ -0,0 +1,119 @@
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 }})
}
}, [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;