import React, { useEffect, useState } from 'react'; import { Tooltip } from 'react-tooltip'; import { ExerciseGen } from './generatedExercises'; import Image from 'next/image'; import clsx from 'clsx'; import { GiBrain } from 'react-icons/gi'; import { IoTextOutline } from 'react-icons/io5'; import { Switch } from '@headlessui/react'; import useExamEditorStore from '@/stores/examEditor'; import { Module } from '@/interfaces'; import { capitalize } from 'lodash'; import Select from '@/components/Low/Select'; import { Difficulty } from '@/interfaces/exam'; interface Props { module: Module; sectionId: number; exercises: ExerciseGen[]; extraArgs?: Record; onSubmit: (configurations: ExerciseConfig[]) => void; onDiscard: () => void; selectedExercises: string[]; } export interface ExerciseConfig { type: string; params: { [key: string]: string | number | boolean; }; } const ExerciseWizard: React.FC = ({ module, exercises, extraArgs, sectionId, selectedExercises, onSubmit, onDiscard, }) => { const [configurations, setConfigurations] = useState([]); const { currentModule } = useExamEditorStore(); const { difficulty } = useExamEditorStore(state => state.modules[currentModule]); const randomDiff = difficulty.length === 1 ? capitalize(difficulty[0]) : `Random (${difficulty.map(dif => capitalize(dif)).join(", ")})` as Difficulty; const DIFFICULTIES = difficulty.length === 1 ? ["A1", "A2", "B1", "B2", "C1", "C2"] : ["A1", "A2", "B1", "B2", "C1", "C2", randomDiff]; useEffect(() => { const initialConfigs = selectedExercises.map(exerciseType => { const exercise = exercises.find(ex => { const fullType = ex.extra?.find(e => e.param === 'name')?.value ? `${ex.type}/?name=${ex.extra.find(e => e.param === 'name')?.value}` : ex.type; return fullType === exerciseType; }); const params: { [key: string]: string | number | boolean } = {}; exercise?.extra?.forEach(param => { if (param.param !== 'name') { if (exerciseType.includes('paragraphMatch') && param.param === 'quantity') { params[param.param] = extraArgs?.text.split("\n\n").length || 1; } else { params[param.param || ''] = param.value ?? ''; } } }); return { type: exerciseType, params }; }); setConfigurations(initialConfigs); // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedExercises, exercises]); const handleParameterChange = ( exerciseIndex: number, paramName: string, value: string | number | boolean ) => { setConfigurations(prev => { const newConfigs = [...prev]; newConfigs[exerciseIndex] = { ...newConfigs[exerciseIndex], params: { ...newConfigs[exerciseIndex].params, [paramName]: value } }; return newConfigs; }); }; const renderParameterInput = ( param: NonNullable[0], exerciseIndex: number, config: ExerciseConfig ) => { if (typeof param.value === 'boolean') { const currentValue = Boolean(config.params[param.param || '']); return (
handleParameterChange( exerciseIndex, param.param || '', value )} className={clsx( "relative inline-flex h-[30px] w-[58px] shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-white/75", currentValue ? `bg-[#F3F4F6]` : `bg-[#1F2937]` )} > {"AI
); } if ('type' in param && param.type === 'text') { return (
{param.tooltip && ( <> {param.tooltip} )}
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..." />
); } const inputValue = Number(config.params[param.param || '1'].toString()) || config.params[param.param!]; const isParagraphMatch = config.type.split("?name=")[1] === "paragraphMatch"; const maxParagraphs = isParagraphMatch ? extraArgs!.text.split("\n\n").length : 50; return (
{param.tooltip && ( <> {param.tooltip} )}
{param.param === "difficulty" ? handleParameterChange( exerciseIndex, param.param || '', e.target.value ? Number(e.target.value) : '' )} className="px-3 py-2 shadow-lg rounded-md text-mti-gray-dim w-full" min={1} max={maxParagraphs} /> }
); }; const renderExerciseHeader = ( exercise: ExerciseGen, exerciseIndex: number, config: ExerciseConfig, extraParams: boolean, ) => { const generateParam = exercise.extra?.find(param => param.param === 'generate'); return (

{exercise.label}

{/* when placeholders are done uncomment this*/} {/*generateParam && renderParameterInput(generateParam, exerciseIndex, config)*/}
); }; return (
{configurations.map((config, exerciseIndex) => { const exercise = exercises.find(ex => { const fullType = ex.extra?.find(e => e.param === 'name')?.value ? `${ex.type}/?name=${ex.extra.find(e => e.param === 'name')?.value}` : ex.type; return fullType === config.type; }); if (!exercise) return null; const nonGenerateParams = exercise.extra?.filter( param => param.param !== 'name' && param.param !== 'generate' ); return (
{renderExerciseHeader(exercise, exerciseIndex, config, (exercise.extra || []).length > 2)} {nonGenerateParams && nonGenerateParams.length > 0 && (
{nonGenerateParams.map(param => (
{renderParameterInput(param, exerciseIndex, config)}
))}
)}
); })}
); }; export default ExerciseWizard;