bugsfixed and design changes for generation 13'' screen

This commit is contained in:
José Lima
2025-02-23 18:47:57 +00:00
parent fec3b51553
commit 340ff5a30a
29 changed files with 2292 additions and 1680 deletions

View File

@@ -1,11 +1,10 @@
import clsx from "clsx";
import SectionRenderer from "./SectionRenderer";
import Checkbox from "../Low/Checkbox";
import Input from "../Low/Input";
import Select from "../Low/Select";
import { capitalize } from "lodash";
import { AccessType, ACCESSTYPE, Difficulty } from "@/interfaces/exam";
import { useCallback, useEffect, useState } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { toast } from "react-toastify";
import { ModuleState, SectionState } from "@/stores/examEditor/types";
import { Module } from "@/interfaces";
@@ -21,13 +20,36 @@ import Button from "../Low/Button";
import ResetModule from "./Standalone/ResetModule";
import ListeningInstructions from "./Standalone/ListeningInstructions";
import { EntityWithRoles } from "@/interfaces/entity";
import Option from "../../interfaces/option";
const DIFFICULTIES: Difficulty[] = ["A1", "A2", "B1", "B2", "C1", "C2"];
const DIFFICULTIES: Option[] = [
{ value: "A1", label: "A1" },
{ value: "A2", label: "A2" },
{ value: "B1", label: "B1" },
{ value: "B2", label: "B2" },
{ value: "C1", label: "C1" },
{ value: "C2", label: "C2" },
];
const ModuleSettings: Record<Module, React.ComponentType> = {
reading: ReadingSettings,
writing: WritingSettings,
speaking: SpeakingSettings,
listening: ListeningSettings,
level: LevelSettings,
};
const ExamEditor: React.FC<{
levelParts?: number;
entitiesAllowEditPrivacy: EntityWithRoles[];
}> = ({ levelParts = 0, entitiesAllowEditPrivacy = [] }) => {
entitiesAllowConfExams: EntityWithRoles[];
entitiesAllowPublicExams: EntityWithRoles[];
}> = ({
levelParts = 0,
entitiesAllowEditPrivacy = [],
entitiesAllowConfExams = [],
entitiesAllowPublicExams = [],
}) => {
const { currentModule, dispatch } = useExamEditorStore();
const {
sections,
@@ -111,7 +133,10 @@ const ExamEditor: React.FC<{
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [numberOfLevelParts]);
const sectionIds = sections.map((section) => section.sectionId);
const sectionIds = useMemo(
() => sections.map((section) => section.sectionId),
[sections]
);
const updateModule = useCallback(
(updates: Partial<ModuleState>) => {
@@ -120,29 +145,42 @@ const ExamEditor: React.FC<{
[dispatch]
);
const toggleSection = (sectionId: number) => {
if (expandedSections.length === 1 && sectionIds.includes(sectionId)) {
toast.error("Include at least one section!");
return;
const toggleSection = useCallback(
(sectionId: number) => {
if (expandedSections.length === 1 && sectionIds.includes(sectionId)) {
toast.error("Include at least one section!");
return;
}
dispatch({ type: "TOGGLE_SECTION", payload: { sectionId } });
},
[dispatch, expandedSections, sectionIds]
);
const Settings = useMemo(
() => ModuleSettings[currentModule],
[currentModule]
);
const showImport = useMemo(
() =>
importModule && ["reading", "listening", "level"].includes(currentModule),
[importModule, currentModule]
);
const accessTypeOptions = useMemo(() => {
let options: Option[] = [{ value: "private", label: "Private" }];
if (entitiesAllowConfExams.length > 0) {
options.push({ value: "confidential", label: "Confidential" });
}
dispatch({ type: "TOGGLE_SECTION", payload: { sectionId } });
};
if (entitiesAllowPublicExams.length > 0) {
options.push({ value: "public", label: "Public" });
}
return options;
}, [entitiesAllowConfExams.length, entitiesAllowPublicExams.length]);
const ModuleSettings: Record<Module, React.ComponentType> = {
reading: ReadingSettings,
writing: WritingSettings,
speaking: SpeakingSettings,
listening: ListeningSettings,
level: LevelSettings,
};
const Settings = ModuleSettings[currentModule];
const showImport =
importModule && ["reading", "listening", "level"].includes(currentModule);
const updateLevelParts = (parts: number) => {
const updateLevelParts = useCallback((parts: number) => {
setNumberOfLevelParts(parts);
};
}, []);
return (
<>
@@ -161,9 +199,14 @@ const ExamEditor: React.FC<{
setNumberOfLevelParts={setNumberOfLevelParts}
/>
)}
<div className="flex gap-4 w-full items-center -xl:flex-col">
<div className="flex flex-row gap-3 w-full">
<div className="flex flex-col gap-3">
<div
className={clsx(
"flex gap-4 w-full",
sectionLabels.length > 3 ? "-2xl:flex-col" : "-xl:flex-col"
)}
>
<div className="flex flex-row gap-3">
<div className="flex flex-col gap-3 ">
<label className="font-normal text-base text-mti-gray-dim">
Timer
</label>
@@ -176,19 +219,16 @@ const ExamEditor: React.FC<{
})
}
value={minTimer}
className="max-w-[300px]"
className="max-w-[125px] min-w-[100px] w-min"
/>
</div>
<div className="flex flex-col gap-3 flex-grow">
<div className="flex flex-col gap-3 ">
<label className="font-normal text-base text-mti-gray-dim">
Difficulty
</label>
<Select
isMulti={true}
options={DIFFICULTIES.map((x) => ({
value: x,
label: capitalize(x),
}))}
options={DIFFICULTIES}
onChange={(values) => {
const selectedDifficulties = values
? values.map((v) => v.value as Difficulty)
@@ -214,12 +254,12 @@ const ExamEditor: React.FC<{
<label className="font-normal text-base text-mti-gray-dim">
{sectionLabels[0].label.split(" ")[0]}
</label>
<div className="flex flex-row gap-8">
<div className="flex flex-row gap-3">
{sectionLabels.map(({ id, label }) => (
<span
key={id}
className={clsx(
"px-6 py-4 w-48 h-[72px] flex justify-center items-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer",
"px-6 py-4 w-40 2xl:w-48 h-[72px] flex justify-center items-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer",
"transition duration-300 ease-in-out",
sectionIds.includes(id)
? `bg-ielts-${currentModule}/70 border-ielts-${currentModule} text-white`
@@ -246,22 +286,24 @@ const ExamEditor: React.FC<{
/>
</div>
)}
</div>
<div className="flex flex-row gap-3 w-64">
<Select
label="Access Type"
options={ACCESSTYPE.map((item) => ({
value: item,
label: capitalize(item),
}))}
onChange={(value) => {
if (value?.value) {
updateModule({ access: value.value! as AccessType });
<div className="max-w-[200px] w-full">
<Select
label="Access Type"
disabled={
accessTypeOptions.length === 0 ||
entitiesAllowEditPrivacy.length === 0
}
}}
value={{ value: access, label: capitalize(access) }}
/>
options={accessTypeOptions}
onChange={(value) => {
if (value?.value) {
updateModule({ access: value.value! as AccessType });
}
}}
value={{ value: access, label: capitalize(access) }}
/>
</div>
</div>
<div className="flex flex-row gap-3 w-full">
<div className="flex flex-col gap-3 flex-grow">
<label className="font-normal text-base text-mti-gray-dim">
@@ -286,7 +328,7 @@ const ExamEditor: React.FC<{
Reset Module
</Button>
</div>
<div className="flex flex-row gap-8 -2xl:flex-col">
<div className="flex flex-row gap-8 -xl:flex-col">
<Settings />
<div className="flex-grow max-w-[66%] -2xl:max-w-full">
<SectionRenderer />