ENCOA-228 Now when user navigates between modules the generation items persist. Reading, listening and writing added to level module

This commit is contained in:
Carlos-Mesquita
2024-11-12 14:17:54 +00:00
parent 696c968ebc
commit fdf411d133
66 changed files with 2546 additions and 1635 deletions

View File

@@ -1,18 +1,24 @@
import { Exercise, LevelExam, LevelPart } from "@/interfaces/exam";
import { Exercise, InteractiveSpeakingExercise, LevelExam, LevelPart, SpeakingExercise } from "@/interfaces/exam";
import SettingsEditor from ".";
import Option from "@/interfaces/option";
import Dropdown from "@/components/Dropdown";
import clsx from "clsx";
import ExercisePicker from "../Shared/ExercisePicker";
import ExercisePicker from "../ExercisePicker";
import useExamEditorStore from "@/stores/examEditor";
import useSettingsState from "../Hooks/useSettingsState";
import { SectionSettings } from "@/stores/examEditor/types";
import { LevelSectionSettings, SectionSettings } from "@/stores/examEditor/types";
import { toast } from "react-toastify";
import axios from "axios";
import { playSound } from "@/utils/sound";
import { useRouter } from "next/router";
import { usePersistentExamStore } from "@/stores/examStore";
import openDetachedTab from "@/utils/popout";
import ListeningComponents from "./listening/components";
import ReadingComponents from "./reading/components";
import WritingComponents from "./writing/components";
import SpeakingComponents from "./speaking/components";
import SectionPicker from "./Shared/SectionPicker";
import SettingsDropdown from "./Shared/SettingsDropdown";
const LevelSettings: React.FC = () => {
@@ -26,8 +32,8 @@ const LevelSettings: React.FC = () => {
setQuestionIndex,
setBgColor,
} = usePersistentExamStore();
const {currentModule, title } = useExamEditorStore();
const { currentModule, title } = useExamEditorStore();
const {
focusedSection,
difficulty,
@@ -36,15 +42,18 @@ const LevelSettings: React.FC = () => {
isPrivate,
} = useExamEditorStore(state => state.modules[currentModule]);
const { localSettings, updateLocalAndScheduleGlobal } = useSettingsState<SectionSettings>(
const { localSettings, updateLocalAndScheduleGlobal } = useSettingsState<LevelSectionSettings>(
currentModule,
focusedSection
);
const section = sections.find((section) => section.sectionId == focusedSection);
const focusedExercise = section?.focusedExercise;
if (section === undefined) return <></>;
const currentSection = section.state as LevelPart;
const readingSection = section.readingSection;
const listeningSection = section.listeningSection;
const canPreview = currentSection.exercises.length > 0;
@@ -105,6 +114,8 @@ const LevelSettings: React.FC = () => {
openDetachedTab("popout?type=Exam&module=level", router)
}
const speakingExercise = focusedExercise === undefined ? undefined : currentSection.exercises[focusedExercise] as SpeakingExercise | InteractiveSpeakingExercise;
return (
<SettingsEditor
sectionLabel={`Part ${focusedSection}`}
@@ -117,26 +128,147 @@ const LevelSettings: React.FC = () => {
submitModule={submitLevel}
>
<div>
<Dropdown title="Add Exercises" className={
<Dropdown title="Add Level Exercises" className={
clsx(
"w-full font-semibold flex justify-between items-center p-4 bg-gradient-to-r border",
"bg-ielts-level/70 border-ielts-level hover:bg-ielts-level",
"text-white shadow-md transition-all duration-300",
localSettings.isExerciseDropdownOpen ? "rounded-t-lg" : "rounded-lg"
localSettings.isLevelDropdownOpen ? "rounded-t-lg" : "rounded-lg"
)
}
contentWrapperClassName={"pt-4 px-2 bg-white rounded-b-lg shadow-md transition-all duration-300 ease-in-out"}
open={localSettings.isExerciseDropdownOpen}
setIsOpen={(isOpen: boolean) => updateLocalAndScheduleGlobal({ isExerciseDropdownOpen: isOpen }, false)}
open={localSettings.isLevelDropdownOpen}
setIsOpen={(isOpen: boolean) => updateLocalAndScheduleGlobal({ isLevelDropdownOpen: isOpen }, false)}
>
<ExercisePicker
module="level"
sectionId={focusedSection}
difficulty={difficulty}
/>
module="level"
sectionId={focusedSection}
difficulty={difficulty}
/>
</Dropdown>
</div>
</SettingsEditor>
<div>
<Dropdown title="Add Reading Exercises" className={
clsx(
"w-full font-semibold flex justify-between items-center p-4 bg-gradient-to-r border",
"bg-ielts-reading/70 border-ielts-reading hover:bg-ielts-reading",
"text-white shadow-md transition-all duration-300",
localSettings.isReadingDropdownOpen ? "rounded-t-lg" : "rounded-lg"
)
}
contentWrapperClassName={"pt-4 px-2 bg-white rounded-b-lg shadow-md transition-all duration-300 ease-in-out"}
open={localSettings.isReadingDropdownOpen}
setIsOpen={(isOpen: boolean) => updateLocalAndScheduleGlobal({ isReadingDropdownOpen: isOpen }, false)}
>
<div className="space-y-2 px-2 pb-2">
<SectionPicker {...{ module: "reading", sectionId: focusedSection, localSettings, updateLocalAndScheduleGlobal }} />
<ReadingComponents
{...{ localSettings, updateLocalAndScheduleGlobal, currentSection, generatePassageDisabled: readingSection === undefined, levelId: readingSection, level: true }}
/>
</div>
</Dropdown>
</div>
<div>
<Dropdown title="Add Listening Exercises" className={
clsx(
"w-full font-semibold flex justify-between items-center p-4 bg-gradient-to-r border",
"bg-ielts-listening/70 border-ielts-listening hover:bg-ielts-listening",
"text-white shadow-md transition-all duration-300",
localSettings.isListeningDropdownOpen ? "rounded-t-lg" : "rounded-lg"
)
}
contentWrapperClassName={"pt-4 px-2 bg-white rounded-b-lg shadow-md transition-all duration-300 ease-in-out"}
open={localSettings.isListeningDropdownOpen}
setIsOpen={(isOpen: boolean) => updateLocalAndScheduleGlobal({ isListeningDropdownOpen: isOpen }, false)}
>
<div className="space-y-2 px-2 pb-2">
<SectionPicker {...{ module: "listening", sectionId: focusedSection, localSettings, updateLocalAndScheduleGlobal }} />
<ListeningComponents
{...{ localSettings, updateLocalAndScheduleGlobal, currentSection, audioContextDisabled: listeningSection === undefined, levelId: listeningSection, level: true }}
/>
</div>
</Dropdown>
</div>
<div>
<Dropdown title="Add Writing Exercises" className={
clsx(
"w-full font-semibold flex justify-between items-center p-4 bg-gradient-to-r border",
"bg-ielts-writing/70 border-ielts-writing hover:bg-ielts-writing",
"text-white shadow-md transition-all duration-300",
localSettings.isWritingDropdownOpen ? "rounded-t-lg" : "rounded-lg"
)
}
contentWrapperClassName={"pt-4 px-2 bg-white rounded-b-lg shadow-md transition-all duration-300 ease-in-out"}
open={localSettings.isWritingDropdownOpen}
setIsOpen={(isOpen: boolean) => updateLocalAndScheduleGlobal({ isWritingDropdownOpen: isOpen }, false)}
>
<ExercisePicker
module="writing"
sectionId={focusedSection}
difficulty={difficulty}
levelSectionId={focusedSection}
level
/>
</Dropdown>
</div >
<div>
<Dropdown title="Add Speaking Exercises" className={
clsx(
"w-full font-semibold flex justify-between items-center p-4 bg-gradient-to-r border",
"bg-ielts-speaking/70 border-ielts-speaking hover:bg-ielts-speaking",
"text-white shadow-md transition-all duration-300",
localSettings.isSpeakingDropdownOpen ? "rounded-t-lg" : "rounded-lg"
)
}
contentWrapperClassName={"pt-4 px-2 bg-white rounded-b-lg shadow-md transition-all duration-300 ease-in-out"}
open={localSettings.isSpeakingDropdownOpen}
setIsOpen={(isOpen: boolean) => updateLocalAndScheduleGlobal({ isSpeakingDropdownOpen: isOpen }, false)}
>
<Dropdown title="Exercises" className={
clsx(
"w-full font-semibold flex justify-between items-center p-4 bg-gradient-to-r border",
"bg-ielts-speaking/70 border-ielts-speaking hover:bg-ielts-speaking",
"text-white shadow-md transition-all duration-300",
localSettings.isSpeakingDropdownOpen ? "rounded-t-lg" : "rounded-lg"
)
}
contentWrapperClassName={"pt-4 px-2 bg-white rounded-b-lg shadow-md transition-all duration-300 ease-in-out border border-ielts-speaking"}
open={localSettings.isSpeakingDropdownOpen}
setIsOpen={(isOpen: boolean) => updateLocalAndScheduleGlobal({ isSpeakingDropdownOpen: isOpen }, false)}
>
<div className="space-y-2 px-2 pb-2">
<ExercisePicker
module="speaking"
sectionId={focusedSection}
difficulty={difficulty}
levelSectionId={focusedSection}
level
/>
</div>
</Dropdown>
{speakingExercise !== undefined &&
<Dropdown title="Configure Speaking Exercise" className={
clsx(
"w-full font-semibold flex justify-between items-center p-4 bg-gradient-to-r border",
"bg-ielts-speaking/70 border-ielts-speaking hover:bg-ielts-speaking",
"text-white shadow-md transition-all duration-300",
localSettings.isSpeakingDropdownOpen ? "rounded-t-lg" : "rounded-lg"
)
}
contentWrapperClassName={"pt-4 px-2 bg-white rounded-b-lg shadow-md transition-all duration-300 ease-in-out border border-ielts-speaking"}
open={localSettings.isSpeakingDropdownOpen}
setIsOpen={(isOpen: boolean) => updateLocalAndScheduleGlobal({ isSpeakingDropdownOpen: isOpen }, false)}
>
<SpeakingComponents
{...{ localSettings, updateLocalAndScheduleGlobal, section: speakingExercise }}
level
/>
</Dropdown>
}
</Dropdown>
</div>
</SettingsEditor >
);
};