From 0b7382f1b652a01ac9edb851029c4f98005d0071 Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Mon, 10 Nov 2025 18:12:18 -0600 Subject: [PATCH] feat: create unified difficulty interface with 2-tab selector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace 3-way mode tabs (Smart/Manual/Mastery) with unified interface: - Smart and Mastery are now "quick presets" via 2-tab selector - Manual controls (thermometers) always visible for customization - All modes share same displayRules system (1:1 correspondence) Changes: - Add DifficultyMethodSelector component with tab-style UI - Update ConfigPanel to use 2-tab selector - Smart/Mastery populate the always-visible display controls - Preserve displayRules when switching between methods 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../addition/components/ConfigPanel.tsx | 89 ++++----------- .../components/DifficultyMethodSelector.tsx | 104 ++++++++++++++++++ 2 files changed, 128 insertions(+), 65 deletions(-) create mode 100644 apps/web/src/app/create/worksheets/addition/components/DifficultyMethodSelector.tsx diff --git a/apps/web/src/app/create/worksheets/addition/components/ConfigPanel.tsx b/apps/web/src/app/create/worksheets/addition/components/ConfigPanel.tsx index 2c57e74d..aef665dd 100644 --- a/apps/web/src/app/create/worksheets/addition/components/ConfigPanel.tsx +++ b/apps/web/src/app/create/worksheets/addition/components/ConfigPanel.tsx @@ -3,14 +3,13 @@ import { stack } from '../../../../../../styled-system/patterns' import type { WorksheetFormState } from '../types' import { defaultAdditionConfig } from '@/app/create/worksheets/config-schemas' -import { ModeSelector } from './ModeSelector' +import { DifficultyMethodSelector } from './DifficultyMethodSelector' import { StudentNameInput } from './config-panel/StudentNameInput' -import { DigitRangeSection } from './config-panel/DigitRangeSection' import { OperatorSection } from './config-panel/OperatorSection' import { ProgressiveDifficultyToggle } from './config-panel/ProgressiveDifficultyToggle' import { SmartModeControls } from './config-panel/SmartModeControls' -import { ManualModeControls } from './config-panel/ManualModeControls' import { MasteryModePanel } from './config-panel/MasteryModePanel' +import { DisplayControlsPanel } from './DisplayControlsPanel' interface ConfigPanelProps { formState: WorksheetFormState @@ -19,55 +18,23 @@ interface ConfigPanelProps { } export function ConfigPanel({ formState, onChange, isDark = false }: ConfigPanelProps) { - // Handler for mode switching - const handleModeChange = (newMode: 'smart' | 'manual' | 'mastery') => { - if (formState.mode === newMode) { + // Handler for difficulty method switching (smart vs mastery) + const handleMethodChange = (newMethod: 'smart' | 'mastery') => { + const currentMethod = formState.mode === 'mastery' ? 'mastery' : 'smart' + if (currentMethod === newMethod) { return // No change needed } - if (newMode === 'smart') { - // Switching to Smart mode - // Use current displayRules if available, otherwise default to earlyLearner - const displayRules = formState.displayRules ?? defaultAdditionConfig.displayRules + // Preserve displayRules when switching + const displayRules = formState.displayRules ?? defaultAdditionConfig.displayRules + + if (newMethod === 'smart') { onChange({ mode: 'smart', displayRules, difficultyProfile: 'earlyLearner', } as unknown as Partial) - } else if (newMode === 'manual') { - // Switching to Manual mode - // Convert current displayRules to boolean flags if available - let booleanFlags = { - showCarryBoxes: true, - showAnswerBoxes: true, - showPlaceValueColors: true, - showTenFrames: false, - showProblemNumbers: true, - showCellBorder: true, - showTenFramesForAll: false, - } - - if (formState.displayRules) { - // Convert 'always' to true, everything else to false - booleanFlags = { - showCarryBoxes: formState.displayRules.carryBoxes === 'always', - showAnswerBoxes: formState.displayRules.answerBoxes === 'always', - showPlaceValueColors: formState.displayRules.placeValueColors === 'always', - showTenFrames: formState.displayRules.tenFrames === 'always', - showProblemNumbers: formState.displayRules.problemNumbers === 'always', - showCellBorder: formState.displayRules.cellBorders === 'always', - showTenFramesForAll: false, - } - } - - onChange({ - mode: 'manual', - ...booleanFlags, - } as unknown as Partial) } else { - // Switching to Mastery mode - // Mastery mode uses Smart mode under the hood with skill-based configuration - const displayRules = formState.displayRules ?? defaultAdditionConfig.displayRules onChange({ mode: 'mastery', displayRules, @@ -75,6 +42,9 @@ export function ConfigPanel({ formState, onChange, isDark = false }: ConfigPanel } } + // Determine current method for selector + const currentMethod = formState.mode === 'mastery' ? 'mastery' : 'smart' + return (
{/* Student Name */} @@ -84,13 +54,6 @@ export function ConfigPanel({ formState, onChange, isDark = false }: ConfigPanel isDark={isDark} /> - {/* Digit Range Selector */} - onChange({ digitRange })} - isDark={isDark} - /> - {/* Operator Selector */} - {/* Progressive Difficulty Toggle - Available for all modes */} + {/* Progressive Difficulty Toggle */} onChange({ interpolate })} isDark={isDark} /> - {/* Mode Selector Tabs with description */} - + + {/* Difficulty Method Selector (Smart vs Mastery) */} + - {/* Mode-specific controls - no wrapper, let controls style themselves */} - {/* Smart Mode Controls */} - {(!formState.mode || formState.mode === 'smart') && ( + {/* Method-specific preset controls */} + {currentMethod === 'smart' && ( )} - {/* Manual Mode Controls */} - {formState.mode === 'manual' && ( - - )} - - {/* Mastery Mode Controls */} - {formState.mode === 'mastery' && ( + {currentMethod === 'mastery' && ( )}
diff --git a/apps/web/src/app/create/worksheets/addition/components/DifficultyMethodSelector.tsx b/apps/web/src/app/create/worksheets/addition/components/DifficultyMethodSelector.tsx new file mode 100644 index 00000000..9c12dd24 --- /dev/null +++ b/apps/web/src/app/create/worksheets/addition/components/DifficultyMethodSelector.tsx @@ -0,0 +1,104 @@ +'use client' + +import { css } from '../../../../../../styled-system/css' + +interface DifficultyMethodSelectorProps { + currentMethod: 'smart' | 'mastery' + onChange: (method: 'smart' | 'mastery') => void + isDark?: boolean +} + +export function DifficultyMethodSelector({ + currentMethod, + onChange, + isDark = false, +}: DifficultyMethodSelectorProps) { + return ( +
+ {/* Tab buttons */} +
+ {/* Smart Difficulty Tab */} + + + {/* Mastery Progression Tab */} + +
+ + {/* Description text */} +
+ {currentMethod === 'smart' + ? 'Choose a difficulty preset, then customize display options below' + : 'Follow a structured skill progression with recommended scaffolding'} +
+
+ ) +}