Added title to the exam generate

This commit is contained in:
Joao Ramos
2024-08-06 19:24:43 +01:00
parent cf64a91651
commit 95c3f89911
7 changed files with 94 additions and 19 deletions

View File

@@ -230,7 +230,11 @@ const TaskTab = ({section, setSection}: {section: LevelSection; setSection: (sec
);
};
const LevelGeneration = () => {
interface Props {
id: string;
}
const LevelGeneration = ({ id } : Props) => {
const [generatedExam, setGeneratedExam] = useState<LevelExam>();
const [isLoading, setIsLoading] = useState(false);
const [resultingExam, setResultingExam] = useState<LevelExam>();
@@ -420,10 +424,16 @@ const LevelGeneration = () => {
return;
}
if(!id) {
toast.error("Please insert a title before submitting");
return;
}
setIsLoading(true);
const exam = {
...generatedExam,
id,
parts: generatedExam.parts.map((p, i) => ({...p, exercises: parts[i].part!.exercises})),
};

View File

@@ -228,7 +228,11 @@ interface ListeningPart {
| string;
}
const ListeningGeneration = () => {
interface Props {
id: string;
}
const ListeningGeneration = ({ id } : Props) => {
const [part1, setPart1] = useState<ListeningPart>();
const [part2, setPart2] = useState<ListeningPart>();
const [part3, setPart3] = useState<ListeningPart>();
@@ -258,11 +262,16 @@ const ListeningGeneration = () => {
console.log({parts});
if (parts.length === 0) return toast.error("Please generate at least one section!");
if(!id) {
toast.error("Please insert a title before submitting");
return;
}
setIsLoading(true);
axios
.post(`/api/exam/listening/generate/listening`, {
id: generate({minLength: 4, maxLength: 8, min: 3, max: 5, join: " ", formatter: capitalize}),
id,
parts,
minTimer,
difficulty,

View File

@@ -258,7 +258,11 @@ const PartTab = ({
);
};
const ReadingGeneration = () => {
interface Props {
id: string;
}
const ReadingGeneration = ({ id } : Props) => {
const [part1, setPart1] = useState<ReadingPart>();
const [part2, setPart2] = useState<ReadingPart>();
const [part3, setPart3] = useState<ReadingPart>();
@@ -300,13 +304,18 @@ const ReadingGeneration = () => {
return;
}
if(!id) {
toast.error("Please insert a title before submitting");
return;
}
setIsLoading(true);
const exam: ReadingExam = {
parts,
isDiagnostic: false,
minTimer,
module: "reading",
id: generate({minLength: 4, maxLength: 8, min: 3, max: 5, join: " ", formatter: capitalize}),
id,
type: "academic",
variant: parts.length === 3 ? "full" : "partial",
difficulty,
@@ -328,7 +337,7 @@ const ReadingGeneration = () => {
})
.catch((error) => {
console.log(error);
toast.error("Something went wrong while generating, please try again later.");
toast.error(error.response.data.error || "Something went wrong while generating, please try again later.");
})
.finally(() => setIsLoading(false));
};

View File

@@ -221,7 +221,11 @@ interface SpeakingPart {
avatar?: (typeof AVATARS)[number];
}
const SpeakingGeneration = () => {
interface Props {
id: string;
}
const SpeakingGeneration = ({ id } : Props) => {
const [part1, setPart1] = useState<SpeakingPart>();
const [part2, setPart2] = useState<SpeakingPart>();
const [part3, setPart3] = useState<SpeakingPart>();
@@ -243,6 +247,11 @@ const SpeakingGeneration = () => {
const submitExam = () => {
if (!part1?.result && !part2?.result && !part3?.result) return toast.error("Please generate at least one task!");
if(!id) {
toast.error("Please insert a title before submitting");
return;
}
setIsLoading(true);
const genders = [part1?.gender, part2?.gender, part3?.gender].filter((x) => !!x);
@@ -256,7 +265,7 @@ const SpeakingGeneration = () => {
}));
const exam: SpeakingExam = {
id: generate({minLength: 4, maxLength: 8, min: 3, max: 5, join: " ", formatter: capitalize}),
id,
isDiagnostic: false,
exercises: exercises as (SpeakingExercise | InteractiveSpeakingExercise)[],
minTimer,

View File

@@ -75,7 +75,11 @@ const TaskTab = ({task, index, difficulty, setTask}: {task?: string; difficulty:
);
};
const WritingGeneration = () => {
interface Props {
id: string;
}
const WritingGeneration = ({ id } : Props) => {
const [task1, setTask1] = useState<string>();
const [task2, setTask2] = useState<string>();
const [minTimer, setMinTimer] = useState(60);
@@ -116,6 +120,11 @@ const WritingGeneration = () => {
return;
}
if(!id) {
toast.error("Please insert a title before submitting");
return;
}
const exercise1 = task1
? ({
id: v4(),
@@ -152,7 +161,7 @@ const WritingGeneration = () => {
minTimer,
module: "writing",
exercises: [...(exercise1 ? [exercise1] : []), ...(exercise2 ? [exercise2] : [])],
id: generate({minLength: 4, maxLength: 8, min: 3, max: 5, join: " ", formatter: capitalize}),
id,
variant: exercise1 && exercise2 ? "full" : "partial",
difficulty,
};

View File

@@ -1,7 +1,7 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type {NextApiRequest, NextApiResponse} from "next";
import {app} from "@/firebase";
import {getFirestore, setDoc, doc} from "firebase/firestore";
import {getFirestore, setDoc, doc, runTransaction, collection, query, where, getDocs} from "firebase/firestore";
import {withIronSessionApiRoute} from "iron-session/next";
import {sessionOptions} from "@/lib/session";
import {Exam, InstructorGender, Variant} from "@/interfaces/exam";
@@ -47,8 +47,25 @@ async function POST(req: NextApiRequest, res: NextApiResponse) {
}
const {module} = req.query as {module: string};
const exam = {...req.body, module: module};
await setDoc(doc(db, module, req.body.id), exam);
try {
const exam = {...req.body, module: module};
await runTransaction(db, async (transaction) => {
res.status(200).json(exam);
const docRef = doc(db, module, req.body.id);
const docSnap = await transaction.get(docRef);
if (docSnap.exists()) {
throw new Error('Name already exists');
}
const newDocRef = doc(db, module, req.body.id);
transaction.set(newDocRef, exam);
});
res.status(200).json(exam);
} catch (error) {
console.error("Transaction failed: ", error);
res.status(500).json({ok: false, error: (error as any).message});
}
}

View File

@@ -57,6 +57,7 @@ export default function Generation() {
const { user } = useUser({ redirectTo: "/login" });
const [title, setTitle] = useState<string>("");
return (
<>
<Head>
@@ -73,6 +74,17 @@ export default function Generation() {
<Layout user={user} className="gap-6">
<h1 className="text-2xl font-semibold">Exam Generation</h1>
<div className="flex flex-col gap-3">
<Input
type="text"
placeholder="Insert a title here"
name="title"
label="Title"
onChange={setTitle}
roundness="xl"
defaultValue={title}
required
/>
<label className="font-normal text-base text-mti-gray-dim">
Module
</label>
@@ -117,11 +129,11 @@ export default function Generation() {
))}
</RadioGroup>
</div>
{module === "reading" && <ReadingGeneration />}
{module === "listening" && <ListeningGeneration />}
{module === "writing" && <WritingGeneration />}
{module === "speaking" && <SpeakingGeneration />}
{module === "level" && <LevelGeneration />}
{module === "reading" && <ReadingGeneration id={title} />}
{module === "listening" && <ListeningGeneration id={title} />}
{module === "writing" && <WritingGeneration id={title} />}
{module === "speaking" && <SpeakingGeneration id={title} />}
{module === "level" && <LevelGeneration id={title} />}
</Layout>
)}
</>