Added the ability for assignments to use partial exams as well

This commit is contained in:
Tiago Ribeiro
2024-01-26 16:16:28 +00:00
parent 4e199931aa
commit 13401562fb
4 changed files with 20 additions and 7 deletions

View File

@@ -19,6 +19,7 @@ import {toast} from "react-toastify";
import {uuidv4} from "@firebase/util"; import {uuidv4} from "@firebase/util";
import {Assignment} from "@/interfaces/results"; import {Assignment} from "@/interfaces/results";
import Checkbox from "@/components/Low/Checkbox"; import Checkbox from "@/components/Low/Checkbox";
import {Variant} from "@/interfaces/exam";
interface Props { interface Props {
isCreating: boolean; isCreating: boolean;
@@ -38,6 +39,7 @@ export default function AssignmentCreator({isCreating, assignment, assigner, gro
const [endDate, setEndDate] = useState<Date | null>( const [endDate, setEndDate] = useState<Date | null>(
assignment ? moment(assignment.endDate).toDate() : moment().hours(23).minutes(59).add(8, "day").toDate(), assignment ? moment(assignment.endDate).toDate() : moment().hours(23).minutes(59).add(8, "day").toDate(),
); );
const [variant, setVariant] = useState<Variant>("full");
// creates a new exam for each assignee or just one exam for all assignees // creates a new exam for each assignee or just one exam for all assignees
const [generateMultiple, setGenerateMultiple] = useState<boolean>(false); const [generateMultiple, setGenerateMultiple] = useState<boolean>(false);
@@ -60,6 +62,7 @@ export default function AssignmentCreator({isCreating, assignment, assigner, gro
endDate, endDate,
selectedModules, selectedModules,
generateMultiple, generateMultiple,
variant,
}) })
.then(() => { .then(() => {
toast.success(`The assignment "${name}" has been ${assignment ? "updated" : "created"} successfully!`); toast.success(`The assignment "${name}" has been ${assignment ? "updated" : "created"} successfully!`);
@@ -279,7 +282,10 @@ export default function AssignmentCreator({isCreating, assignment, assigner, gro
))} ))}
</div> </div>
</section> </section>
<div className="flex gap-4 w-full justify-end"> <div className="flex flex-col gap-4 w-full items-end">
<Checkbox isChecked={variant === "full"} onChange={() => setVariant((prev) => (prev === "full" ? "partial" : "full"))}>
Full length exams
</Checkbox>
<Checkbox isChecked={generateMultiple} onChange={() => setGenerateMultiple((d) => !d)}> <Checkbox isChecked={generateMultiple} onChange={() => setGenerateMultiple((d) => !d)}>
Generate different exams Generate different exams
</Checkbox> </Checkbox>

View File

@@ -1,7 +1,7 @@
import {Module} from "."; import {Module} from ".";
export type Exam = ReadingExam | ListeningExam | WritingExam | SpeakingExam | LevelExam; export type Exam = ReadingExam | ListeningExam | WritingExam | SpeakingExam | LevelExam;
export type Variant = "full" | "diagnostic" | "partial"; export type Variant = "full" | "partial";
export interface ReadingExam { export interface ReadingExam {
parts: ReadingPart[]; parts: ReadingPart[];

View File

@@ -7,7 +7,7 @@ import {sessionOptions} from "@/lib/session";
import {uuidv4} from "@firebase/util"; import {uuidv4} from "@firebase/util";
import {Module} from "@/interfaces"; import {Module} from "@/interfaces";
import {getExams} from "@/utils/exams.be"; import {getExams} from "@/utils/exams.be";
import {Exam} from "@/interfaces/exam"; import {Exam, Variant} from "@/interfaces/exam";
import {capitalize, flatten} from "lodash"; import {capitalize, flatten} from "lodash";
import {User} from "@/interfaces/user"; import {User} from "@/interfaces/user";
import moment from "moment"; import moment from "moment";
@@ -52,13 +52,18 @@ function getRandomIndex(arr: any[]): number {
return randomIndex; return randomIndex;
} }
const generateExams = async (generateMultiple: Boolean, selectedModules: Module[], assignees: string[]): Promise<ExamWithUser[]> => { const generateExams = async (
generateMultiple: Boolean,
selectedModules: Module[],
assignees: string[],
variant?: Variant,
): Promise<ExamWithUser[]> => {
if (generateMultiple) { if (generateMultiple) {
// for optimization purposes, it would be better to create a new endpoint that returned the answers for all users at once // for optimization purposes, it would be better to create a new endpoint that returned the answers for all users at once
const allExams = await assignees.map(async (assignee) => { const allExams = await assignees.map(async (assignee) => {
const selectedModulePromises = await selectedModules.map(async (module: Module) => { const selectedModulePromises = await selectedModules.map(async (module: Module) => {
try { try {
const exams: Exam[] = await getExams(db, module, "true", assignee); const exams: Exam[] = await getExams(db, module, "true", assignee, variant);
const exam = exams[getRandomIndex(exams)]; const exam = exams[getRandomIndex(exams)];
if (exam) { if (exam) {
@@ -101,6 +106,7 @@ async function POST(req: NextApiRequest, res: NextApiResponse) {
// Generate multiple true would generate an unique exam for each user // Generate multiple true would generate an unique exam for each user
// false would generate the same exam for all users // false would generate the same exam for all users
generateMultiple = false, generateMultiple = false,
variant,
...body ...body
} = req.body as { } = req.body as {
selectedModules: Module[]; selectedModules: Module[];
@@ -109,9 +115,10 @@ async function POST(req: NextApiRequest, res: NextApiResponse) {
name: string; name: string;
startDate: string; startDate: string;
endDate: string; endDate: string;
variant?: Variant;
}; };
const exams: ExamWithUser[] = await generateExams(generateMultiple, selectedModules, assignees); const exams: ExamWithUser[] = await generateExams(generateMultiple, selectedModules, assignees, variant);
if (exams.length === 0) { if (exams.length === 0) {
res.status(400).json({ok: false, error: "No exams found for the selected modules"}); res.status(400).json({ok: false, error: "No exams found for the selected modules"});

View File

@@ -176,7 +176,7 @@ export default function Home({envVariables}: {envVariables: {[key: string]: stri
{user.type === "corporate" && <CorporateDashboard user={user} />} {user.type === "corporate" && <CorporateDashboard user={user} />}
{user.type === "agent" && <AgentDashboard user={user} />} {user.type === "agent" && <AgentDashboard user={user} />}
{user.type === "admin" && <AdminDashboard user={user} />} {user.type === "admin" && <AdminDashboard user={user} />}
{user.type === "developer" && <AdminDashboard user={user} />} {user.type === "developer" && <TeacherDashboard user={user} />}
</Layout> </Layout>
)} )}
</> </>