From cdc8cfe46e7d4468f76993ddc703628d8db53bc5 Mon Sep 17 00:00:00 2001 From: Tiago Ribeiro Date: Mon, 20 Nov 2023 23:30:47 +0000 Subject: [PATCH] Updated more of the exam generation --- .../(generation)/ListeningGeneration.tsx | 121 ++++++++++++------ src/pages/(generation)/ReadingGeneration.tsx | 19 +-- src/pages/(generation)/WritingGeneration.tsx | 114 +++++++++++++++++ src/pages/admin.tsx | 2 +- .../api/exam/[module]/generate/[endpoint].ts | 5 +- src/pages/generation.tsx | 2 + 6 files changed, 209 insertions(+), 54 deletions(-) create mode 100644 src/pages/(generation)/WritingGeneration.tsx diff --git a/src/pages/(generation)/ListeningGeneration.tsx b/src/pages/(generation)/ListeningGeneration.tsx index 0366f3b7..e0a6b012 100644 --- a/src/pages/(generation)/ListeningGeneration.tsx +++ b/src/pages/(generation)/ListeningGeneration.tsx @@ -1,11 +1,78 @@ import Input from "@/components/Low/Input"; import {ListeningPart} from "@/interfaces/exam"; +import {convertCamelCaseToReadable} from "@/utils/string"; import {Tab} from "@headlessui/react"; import axios from "axios"; import clsx from "clsx"; import {useState} from "react"; +import {BsArrowRepeat} from "react-icons/bs"; import {toast} from "react-toastify"; +const PartTab = ({part, types, index, setPart}: {part?: ListeningPart; types: string[]; index: number; setPart: (part?: ListeningPart) => void}) => { + const [topic, setTopic] = useState(""); + const [isLoading, setIsLoading] = useState(false); + + const generate = () => { + const url = new URLSearchParams(); + if (topic) url.append("topic", topic); + if (types) types.forEach((t) => url.append("exercises", t)); + + setPart(undefined); + setIsLoading(true); + axios + .get(`/api/exam/listening/generate/listening_passage_${index}${topic || types ? `?${url.toString()}` : ""}`) + .then((result) => setPart(result.data)) + .catch((error) => { + console.log(error); + toast.error("Something went wrong!"); + }) + .finally(() => setIsLoading(false)); + }; + + return ( + +
+ + +
+ {isLoading && ( +
+ + Generating... +
+ )} + {part && ( +
+
+ {part.exercises.map((x) => ( + + {x.type && convertCamelCaseToReadable(x.type)} + + ))} +
+
+ )} +
+ ); +}; + const ListeningGeneration = () => { const [part1, setPart1] = useState(); const [part2, setPart2] = useState(); @@ -21,47 +88,6 @@ const ListeningGeneration = () => { const toggleType = (type: string) => setTypes((prev) => (prev.includes(type) ? [...prev.filter((x) => x !== type)] : [...prev, type])); - const PartTab = ({part, index, setPart}: {part?: ListeningPart; index: number; setPart: (part: ListeningPart) => void}) => { - const [topic, setTopic] = useState(""); - const [isLoading, setIsLoading] = useState(false); - - const generate = () => { - setIsLoading(true); - axios - .get(`/api/exam/listening/generate/listening_passage_${index}?topic=${topic}&exercises=${types.join("&exercises=")}`) - .then((result) => setPart(result.data)) - .catch((error) => { - console.log(error); - toast.error("Something went wrong!"); - }) - .finally(() => setIsLoading(false)); - }; - - return ( - -
- - -
- {isLoading && ( -
- - Generating... -
- )} -
- ); - }; - return ( <>
@@ -126,10 +152,21 @@ const ListeningGeneration = () => { {part: part2, setPart: setPart2}, {part: part3, setPart: setPart3}, ].map(({part, setPart}, index) => ( - + ))} + ); }; diff --git a/src/pages/(generation)/ReadingGeneration.tsx b/src/pages/(generation)/ReadingGeneration.tsx index b95253d8..4796636a 100644 --- a/src/pages/(generation)/ReadingGeneration.tsx +++ b/src/pages/(generation)/ReadingGeneration.tsx @@ -8,14 +8,19 @@ import {useState} from "react"; import {BsArrowRepeat} from "react-icons/bs"; import {toast} from "react-toastify"; -const PartTab = ({part, types, index, setPart}: {part?: ReadingPart; types: string[]; index: number; setPart: (part: ReadingPart) => void}) => { +const PartTab = ({part, types, index, setPart}: {part?: ReadingPart; types: string[]; index: number; setPart: (part?: ReadingPart) => void}) => { const [topic, setTopic] = useState(""); const [isLoading, setIsLoading] = useState(false); const generate = () => { + const url = new URLSearchParams(); + if (topic) url.append("topic", topic); + if (types) types.forEach((t) => url.append("exercises", t)); + + setPart(undefined); setIsLoading(true); axios - .get(`/api/exam/reading/generate/reading_passage_${index}?topic=${topic}&exercises=${types.join("&exercises=")}`) + .get(`/api/exam/reading/generate/reading_passage_${index}${topic || types ? `?${url.toString()}` : ""}`) .then((result) => setPart(result.data)) .catch((error) => { console.log(error); @@ -30,17 +35,13 @@ const PartTab = ({part, types, index, setPart}: {part?: ReadingPart; types: stri +
+ {isLoading && ( +
+ + Generating... +
+ )} + {task && ( +
+ {task} +
+ )} + + ); + }; + + return ( + <> + + + + clsx( + "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-writing/70", + "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-writing focus:outline-none focus:ring-2", + "transition duration-300 ease-in-out", + selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-writing", + ) + }> + Task 1 + + + clsx( + "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-writing/70", + "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-writing focus:outline-none focus:ring-2", + "transition duration-300 ease-in-out", + selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-writing", + ) + }> + Task 2 + + + + {[ + {task: task1, setTask: setTask1}, + {task: task2, setTask: setTask2}, + ].map(({task, setTask}, index) => ( + + ))} + + + + + ); +}; + +export default WritingGeneration; diff --git a/src/pages/admin.tsx b/src/pages/admin.tsx index f44a6011..04f6a75b 100644 --- a/src/pages/admin.tsx +++ b/src/pages/admin.tsx @@ -62,7 +62,7 @@ export default function Admin() { {user && (
- {user.email === "tiago.ribeiro@ecrop.dev" ? : } +
diff --git a/src/pages/api/exam/[module]/generate/[endpoint].ts b/src/pages/api/exam/[module]/generate/[endpoint].ts index 56f3ac5e..1a6b4118 100644 --- a/src/pages/api/exam/[module]/generate/[endpoint].ts +++ b/src/pages/api/exam/[module]/generate/[endpoint].ts @@ -25,9 +25,10 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { return; } - const {endpoint, topic, exercises} = req.query as {module: Module; endpoint: string; topic: string; exercises: string[]}; + const {endpoint, topic, exercises} = req.query as {module: Module; endpoint: string; topic?: string; exercises?: string[]}; + const url = `${process.env.BACKEND_URL}/${endpoint}`; - const result = await axios.get(`${process.env.BACKEND_URL}/${endpoint}?topic=${topic.toLowerCase()}&exercises=${exercises.join("&exercises=")}`, { + const result = await axios.get(`${url}${topic && exercises ? `?topic=${topic.toLowerCase()}&exercises=${exercises.join("&exercises=")}` : ""}`, { headers: {Authorization: `Bearer ${process.env.BACKEND_JWT}`}, }); diff --git a/src/pages/generation.tsx b/src/pages/generation.tsx index aa111d1d..82894b4f 100644 --- a/src/pages/generation.tsx +++ b/src/pages/generation.tsx @@ -18,6 +18,7 @@ import Input from "@/components/Low/Input"; import axios from "axios"; import ReadingGeneration from "./(generation)/ReadingGeneration"; import ListeningGeneration from "./(generation)/ListeningGeneration"; +import WritingGeneration from "./(generation)/WritingGeneration"; export const getServerSideProps = withIronSessionSsr(({req, res}) => { const user = req.session.user; @@ -112,6 +113,7 @@ export default function Generation() { {module === "reading" && } {module === "listening" && } + {module === "writing" && }
)}