Reverted Level to only utas placement test exercises, Speaking, bug fixes, placeholder
This commit is contained in:
@@ -122,22 +122,50 @@ const ExerciseWizard: React.FC<Props> = ({
|
||||
size={28}
|
||||
color={!currentValue ? `#F3F4F6` : `#1F2937`}
|
||||
/>
|
||||
|
||||
|
||||
|
||||
<Tooltip id={`${exerciseIndex}`} className="z-50 bg-white shadow-md rounded-sm" />
|
||||
<a data-tooltip-id={`${exerciseIndex}`} data-tooltip-html="Generate or use placeholder?" className='ml-1 flex items-center justify-center'>
|
||||
<Image src="/mat-icon-info.svg" width={24} height={24} alt={"AI Generated?"} />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if ('type' in param && param.type === 'text') {
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<label className="text-sm font-medium text-white">
|
||||
{param.label}
|
||||
</label>
|
||||
{param.tooltip && (
|
||||
<>
|
||||
<Tooltip id={config.type} className="z-50 bg-white shadow-md rounded-sm" />
|
||||
<a data-tooltip-id={config.type} data-tooltip-html={param.tooltip} className='ml-1 flex items-center justify-center'>
|
||||
<Image src="/mat-icon-info.svg" width={24} height={24} alt={param.tooltip} />
|
||||
</a>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
value={config.params[param.param || ''] as string}
|
||||
onChange={(e) => handleParameterChange(
|
||||
exerciseIndex,
|
||||
param.param || '',
|
||||
e.target.value
|
||||
)}
|
||||
className="px-3 py-2 shadow-lg rounded-md text-mti-gray-dim w-full"
|
||||
placeholder="Enter here..."
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const inputValue = Number(config.params[param.param || '1'].toString());
|
||||
|
||||
const isParagraphMatch = config.type.split("?name=")[1] === "paragraphMatch";
|
||||
const maxParagraphs = isParagraphMatch ? extraArgs!.text.split("\n\n").length : 50;
|
||||
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -183,7 +211,8 @@ const ExerciseWizard: React.FC<Props> = ({
|
||||
<exercise.icon className="h-5 w-5" />
|
||||
<h3 className="font-medium text-lg">{exercise.label}</h3>
|
||||
</div>
|
||||
{generateParam && renderParameterInput(generateParam, exerciseIndex, config)}
|
||||
{/* when placeholders are done uncomment this*/}
|
||||
{/*generateParam && renderParameterInput(generateParam, exerciseIndex, config)*/}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -209,21 +209,29 @@ const listening = (section: number) => {
|
||||
}
|
||||
|
||||
const EXERCISES: ExerciseGen[] = [
|
||||
{
|
||||
/*{
|
||||
label: "Multiple Choice",
|
||||
type: "multipleChoice",
|
||||
icon: FaListUl,
|
||||
extra: [
|
||||
{
|
||||
param: "name",
|
||||
value: "multipleChoice"
|
||||
},
|
||||
quantity(10, "Amount"),
|
||||
generate()
|
||||
],
|
||||
module: "level"
|
||||
},
|
||||
},*/
|
||||
{
|
||||
label: "Multiple Choice - Blank Space",
|
||||
type: "mcBlank",
|
||||
icon: FaEdit,
|
||||
extra: [
|
||||
{
|
||||
param: "name",
|
||||
value: "mcBlank"
|
||||
},
|
||||
quantity(10, "Amount"),
|
||||
generate()
|
||||
],
|
||||
@@ -234,6 +242,10 @@ const EXERCISES: ExerciseGen[] = [
|
||||
type: "mcUnderline",
|
||||
icon: FaUnderline,
|
||||
extra: [
|
||||
{
|
||||
param: "name",
|
||||
value: "mcUnderline"
|
||||
},
|
||||
quantity(10, "Amount"),
|
||||
generate()
|
||||
],
|
||||
@@ -255,10 +267,14 @@ const EXERCISES: ExerciseGen[] = [
|
||||
module: "level"
|
||||
},*/
|
||||
{
|
||||
label: "Fill Blanks: MC",
|
||||
label: "Fill Blanks: Multiple Choice",
|
||||
type: "fillBlanksMC",
|
||||
icon: FaPen,
|
||||
extra: [
|
||||
{
|
||||
param: "name",
|
||||
value: "fillBlanksMC"
|
||||
},
|
||||
quantity(10, "Nº of Blanks"),
|
||||
{
|
||||
label: "Passage Word Size",
|
||||
@@ -270,25 +286,26 @@ const EXERCISES: ExerciseGen[] = [
|
||||
module: "level"
|
||||
},
|
||||
{
|
||||
label: "Reading Passage",
|
||||
label: "Reading Passage: Multiple Choice",
|
||||
type: "passageUtas",
|
||||
icon: FaBookOpen,
|
||||
extra: [
|
||||
{
|
||||
param: "name",
|
||||
value: "passageUtas"
|
||||
},
|
||||
// in the utas exam there was only mc so I'm assuming short answers are deprecated
|
||||
/*{
|
||||
label: "Short Answers",
|
||||
param: "sa_qty",
|
||||
value: "10"
|
||||
},*/
|
||||
{
|
||||
label: "Multiple Choice Quantity",
|
||||
param: "mc_qty",
|
||||
value: "10"
|
||||
},
|
||||
quantity(10, "Multiple Choice Quantity"),
|
||||
{
|
||||
label: "Reading Passage Topic",
|
||||
param: "topic",
|
||||
value: ""
|
||||
value: "",
|
||||
type: "text"
|
||||
},
|
||||
{
|
||||
label: "Passage Word Size",
|
||||
|
||||
@@ -17,6 +17,6 @@ export interface ExerciseGen {
|
||||
type: string;
|
||||
icon: IconType;
|
||||
sectionId?: number;
|
||||
extra?: { param?: string; value?: string | number | boolean; label?: string; tooltip?: string}[];
|
||||
extra?: { param?: string; value?: string | number | boolean; label?: string; tooltip?: string, type?: string}[];
|
||||
module: string
|
||||
}
|
||||
|
||||
@@ -23,13 +23,15 @@ const ExercisePicker: React.FC<ExercisePickerProps> = ({
|
||||
extraArgs = undefined,
|
||||
}) => {
|
||||
const { currentModule, dispatch } = useExamEditorStore();
|
||||
const { difficulty} = useExamEditorStore((store) => store.modules[currentModule]);
|
||||
const section = useExamEditorStore((store) => store.modules[currentModule].sections.find((s) => s.sectionId == sectionId)!);
|
||||
const { state, selectedExercises } = section;
|
||||
|
||||
const { difficulty } = useExamEditorStore((store) => store.modules[currentModule]);
|
||||
const section = useExamEditorStore((store) => store.modules[currentModule].sections.find((s) => s.sectionId == sectionId));
|
||||
|
||||
const [pickerOpen, setPickerOpen] = useState(false);
|
||||
|
||||
if (section === undefined) return;
|
||||
|
||||
const { state, selectedExercises } = section;
|
||||
|
||||
const getFullExerciseType = (exercise: ExerciseGen): string => {
|
||||
if (exercise.extra && exercise.extra.length > 0) {
|
||||
const extraValue = exercise.extra.find(e => e.param === 'name')?.value;
|
||||
@@ -48,7 +50,7 @@ const ExercisePicker: React.FC<ExercisePickerProps> = ({
|
||||
dispatch({ type: "UPDATE_SECTION_SINGLE_FIELD", payload: { module: currentModule, sectionId, field: "selectedExercises", value: newSelected } })
|
||||
};
|
||||
|
||||
const moduleExercises = module === 'level' ? EXERCISES : (sectionId ? EXERCISES.filter((ex) => ex.module === module && ex.sectionId == sectionId) : EXERCISES.filter((ex) => ex.module === module));
|
||||
const moduleExercises = (sectionId && module !== "level" ? EXERCISES.filter((ex) => ex.module === module && ex.sectionId == sectionId) : EXERCISES.filter((ex) => ex.module === module));
|
||||
|
||||
const onModuleSpecific = (configurations: ExerciseConfig[]) => {
|
||||
const exercises = configurations.map(config => {
|
||||
@@ -119,7 +121,15 @@ const ExercisePicker: React.FC<ExercisePickerProps> = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal isOpen={pickerOpen} onClose={() => setPickerOpen(false)} title="Exercise Wizard">
|
||||
<Modal isOpen={pickerOpen} onClose={() => setPickerOpen(false)} title="Exercise Wizard"
|
||||
titleClassName={clsx(
|
||||
"text-2xl font-semibold text-center py-4",
|
||||
`bg-ielts-${module} text-white`,
|
||||
"shadow-sm",
|
||||
"-mx-6 -mt-6",
|
||||
"mb-6"
|
||||
)}
|
||||
>
|
||||
<ExerciseWizard
|
||||
sectionId={sectionId}
|
||||
exercises={moduleExercises}
|
||||
@@ -165,8 +175,8 @@ const ExercisePicker: React.FC<ExercisePickerProps> = ({
|
||||
>
|
||||
{section.generating === "exercises" ? (
|
||||
<div key={`section-${sectionId}`} className="flex items-center justify-center">
|
||||
<BsArrowRepeat className="text-white animate-spin" size={25} />
|
||||
</div>
|
||||
<BsArrowRepeat className="text-white animate-spin" size={25} />
|
||||
</div>
|
||||
) : (
|
||||
<>Set Up Exercises ({selectedExercises.length}) </>
|
||||
)}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { capitalize } from 'lodash';
|
||||
import { Module } from '@/interfaces';
|
||||
import { toast } from 'react-toastify';
|
||||
import useExamEditorStore from '@/stores/examEditor';
|
||||
import { ReadingPart } from '@/interfaces/exam';
|
||||
import { LevelPart, ReadingPart } from '@/interfaces/exam';
|
||||
import { defaultSectionSettings } from '@/stores/examEditor/defaults';
|
||||
|
||||
const WordUploader: React.FC<{ module: Module }> = ({ module }) => {
|
||||
@@ -72,7 +72,7 @@ const WordUploader: React.FC<{ module: Module }> = ({ module }) => {
|
||||
setShowUploaders(false);
|
||||
|
||||
switch (currentModule) {
|
||||
case 'reading':
|
||||
case 'reading': {
|
||||
const newSectionsStates = data.parts.map(
|
||||
(part: ReadingPart, index: number) => defaultSectionSettings(module, index + 1, part)
|
||||
);
|
||||
@@ -88,6 +88,28 @@ const WordUploader: React.FC<{ module: Module }> = ({ module }) => {
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'level': {
|
||||
const newSectionsStates = data.parts.map(
|
||||
(part: LevelPart, index: number) => defaultSectionSettings(module, index + 1, part)
|
||||
);
|
||||
dispatch({
|
||||
type: "UPDATE_MODULE", payload: {
|
||||
updates: {
|
||||
sections: newSectionsStates,
|
||||
minTimer: data.minTimer,
|
||||
importModule: false,
|
||||
importing: false,
|
||||
sectionLabels: Array.from({ length: newSectionsStates.length }, (_, index) => ({
|
||||
id: index + 1,
|
||||
label: `Part ${index + 1}`
|
||||
}))
|
||||
},
|
||||
module
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error(`An unknown error has occured while import ${module} exam!`);
|
||||
|
||||
@@ -1,40 +1,49 @@
|
||||
import { useState } from "react";
|
||||
import Dropdown from "@/components/Dropdown";
|
||||
import clsx from "clsx";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
content: string;
|
||||
open: boolean;
|
||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
title: string;
|
||||
content: string;
|
||||
open?: boolean;
|
||||
setIsOpen?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const Passage: React.FC<Props> = ({ title, content, open, setIsOpen}) => {
|
||||
const paragraphs = content.split('\n\n');
|
||||
const Passage: React.FC<Props> = ({ title, content, open: externalOpen, setIsOpen: externalSetIsOpen }) => {
|
||||
const [internalOpen, setInternalOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
title={title}
|
||||
const isOpen = externalOpen ?? internalOpen;
|
||||
const setIsOpen = externalSetIsOpen ?? setInternalOpen;
|
||||
|
||||
const paragraphs = content.split('\n\n');
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
title={title}
|
||||
className={clsx(
|
||||
"bg-white p-6 w-full items-center",
|
||||
isOpen ? "rounded-t-lg border-b border-gray-200" : "rounded-lg shadow-lg"
|
||||
)}
|
||||
titleClassName="text-2xl font-semibold text-gray-800"
|
||||
contentWrapperClassName="p-6 bg-white rounded-b-lg shadow-md transition-all duration-300 ease-in-out"
|
||||
open={isOpen}
|
||||
setIsOpen={setIsOpen}
|
||||
>
|
||||
<div>
|
||||
{paragraphs.map((paragraph, index) => (
|
||||
<p
|
||||
key={index}
|
||||
className={clsx(
|
||||
"bg-white p-6 w-full items-center",
|
||||
open ? "rounded-t-lg border-b border-gray-200" : "rounded-lg shadow-lg"
|
||||
"text-justify",
|
||||
index < paragraphs.length - 1 ? 'mb-4' : 'mb-6'
|
||||
)}
|
||||
titleClassName="text-2xl font-semibold text-gray-800"
|
||||
contentWrapperClassName="p-6 bg-white rounded-b-lg shadow-md transition-all duration-300 ease-in-out"
|
||||
open={open}
|
||||
setIsOpen={setIsOpen}
|
||||
>
|
||||
<div>
|
||||
{paragraphs.map((paragraph, index) => (
|
||||
<p
|
||||
key={index}
|
||||
className={clsx("text-justify", index < paragraphs.length - 1 ? 'mb-4' : 'mb-6')}
|
||||
>
|
||||
{paragraph.trim()}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
</Dropdown>
|
||||
);
|
||||
>
|
||||
{paragraph.trim()}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
|
||||
export default Passage;
|
||||
|
||||
Reference in New Issue
Block a user