diff --git a/apps/web/src/app/create/worksheets/components/config-panel/RuleThermometer.tsx b/apps/web/src/app/create/worksheets/components/config-panel/RuleThermometer.tsx index 35e6a1fe..b8e45c14 100644 --- a/apps/web/src/app/create/worksheets/components/config-panel/RuleThermometer.tsx +++ b/apps/web/src/app/create/worksheets/components/config-panel/RuleThermometer.tsx @@ -9,6 +9,8 @@ export interface RuleThermometerProps { value: RuleMode onChange: (value: RuleMode) => void isDark?: boolean + /** When value is 'auto', this shows which value 'auto' resolves to */ + resolvedValue?: RuleMode } const RULE_OPTIONS: Array<{ value: RuleMode; label: string; short: string }> = [ @@ -26,8 +28,10 @@ export function RuleThermometer({ value, onChange, isDark = false, + resolvedValue, }: RuleThermometerProps) { const selectedIndex = RULE_OPTIONS.findIndex((opt) => opt.value === value) + const isAutoSelected = value === 'auto' return (
{RULE_OPTIONS.map((option, index) => { const isSelected = value === option.value + // When 'auto' is selected, show which value it resolves to with secondary color + const isAutoResolved = isAutoSelected && resolvedValue === option.value const isLeftmost = index === 0 const isRightmost = index === RULE_OPTIONS.length - 1 @@ -82,16 +88,31 @@ export function RuleThermometer({ key={option.value} type="button" onClick={() => onChange(option.value)} - title={option.label} + title={isAutoResolved ? `${option.label} (currently selected by Auto)` : option.label} className={css({ flex: 1, px: '2', py: '1.5', fontSize: '2xs', - fontWeight: isSelected ? 'bold' : 'medium', - color: isSelected ? (isDark ? 'white' : 'white') : isDark ? 'gray.400' : 'gray.600', - bg: isSelected ? 'brand.500' : 'transparent', - border: 'none', + fontWeight: isSelected ? 'bold' : isAutoResolved ? 'semibold' : 'medium', + color: isSelected + ? 'white' + : isAutoResolved + ? isDark + ? 'green.300' + : 'green.700' + : isDark + ? 'gray.400' + : 'gray.600', + bg: isSelected + ? 'brand.500' + : isAutoResolved + ? isDark + ? 'green.900/30' + : 'green.100' + : 'transparent', + border: isAutoResolved ? '1px solid' : 'none', + borderColor: isAutoResolved ? (isDark ? 'green.700' : 'green.300') : 'transparent', borderTopLeftRadius: isLeftmost ? 'md' : '0', borderBottomLeftRadius: isLeftmost ? 'md' : '0', borderTopRightRadius: isRightmost ? 'md' : '0', @@ -99,7 +120,15 @@ export function RuleThermometer({ cursor: 'pointer', transition: 'all 0.15s', _hover: { - bg: isSelected ? 'brand.600' : isDark ? 'gray.600' : 'gray.200', + bg: isSelected + ? 'brand.600' + : isAutoResolved + ? isDark + ? 'green.800/40' + : 'green.200' + : isDark + ? 'gray.600' + : 'gray.200', color: isSelected ? 'white' : isDark ? 'gray.200' : 'gray.800', }, })} diff --git a/apps/web/src/app/create/worksheets/components/config-sidebar/ScaffoldingTab.tsx b/apps/web/src/app/create/worksheets/components/config-sidebar/ScaffoldingTab.tsx index afb9aff0..a28ef613 100644 --- a/apps/web/src/app/create/worksheets/components/config-sidebar/ScaffoldingTab.tsx +++ b/apps/web/src/app/create/worksheets/components/config-sidebar/ScaffoldingTab.tsx @@ -7,6 +7,7 @@ import { useTheme } from '@/contexts/ThemeContext' import { RuleThermometer } from '../config-panel/RuleThermometer' import type { DisplayRules } from '../../displayRules' import { defaultAdditionConfig } from '@/app/create/worksheets/config-schemas' +import { getSkillById } from '../../skills' export function ScaffoldingTab() { const { formState, onChange } = useWorksheetConfig() @@ -18,6 +19,33 @@ export function ScaffoldingTab() { // Check if we're in mastery+mixed mode (needs operator-specific rules) const isMasteryMixed = formState.mode === 'mastery' && formState.operator === 'mixed' + // Get resolved display rules for showing what 'auto' defers to + let resolvedDisplayRules: DisplayRules | undefined + + if (formState.mode === 'mastery') { + const operator = formState.operator ?? 'addition' + + if (operator === 'mixed') { + // Mixed mode: Use addition skill's recommendations for now (could show both) + const skillId = formState.currentAdditionSkillId + if (skillId) { + const skill = getSkillById(skillId as any) + resolvedDisplayRules = skill?.recommendedScaffolding + } + } else { + // Single operator: Use its skill's recommendations + const skillId = + operator === 'addition' + ? formState.currentAdditionSkillId + : formState.currentSubtractionSkillId + + if (skillId) { + const skill = getSkillById(skillId as any) + resolvedDisplayRules = skill?.recommendedScaffolding + } + } + } + const updateRule = (key: keyof DisplayRules, value: DisplayRules[keyof DisplayRules]) => { const newDisplayRules = { ...displayRules, @@ -199,6 +227,7 @@ export function ScaffoldingTab() { value={displayRules.answerBoxes} onChange={(value) => updateRule('answerBoxes', value)} isDark={isDark} + resolvedValue={resolvedDisplayRules?.answerBoxes} /> updateRule('placeValueColors', value)} isDark={isDark} + resolvedValue={resolvedDisplayRules?.placeValueColors} /> updateRule('carryBoxes', value)} isDark={isDark} + resolvedValue={resolvedDisplayRules?.carryBoxes} /> {(formState.operator === 'subtraction' || formState.operator === 'mixed') && ( @@ -236,6 +267,7 @@ export function ScaffoldingTab() { value={displayRules.borrowNotation} onChange={(value) => updateRule('borrowNotation', value)} isDark={isDark} + resolvedValue={resolvedDisplayRules?.borrowNotation} /> )} @@ -246,6 +278,7 @@ export function ScaffoldingTab() { value={displayRules.borrowingHints} onChange={(value) => updateRule('borrowingHints', value)} isDark={isDark} + resolvedValue={resolvedDisplayRules?.borrowingHints} /> )} @@ -255,6 +288,7 @@ export function ScaffoldingTab() { value={displayRules.tenFrames} onChange={(value) => updateRule('tenFrames', value)} isDark={isDark} + resolvedValue={resolvedDisplayRules?.tenFrames} />
)