feat: move layout controls to OrientationPanel with toggles

Move Problem Numbers and Cell Borders controls from standalone section
to OrientationPanel component as simple checkbox toggles. This groups
all layout-related options together in one place.

Changes:
- Add problemNumbers/cellBorders props to OrientationPanel
- Add Layout Options section as Row 3 with divider
- Use checkboxes for simple on/off control (not thermometers)
- Update AdditionWorksheetClient to pass displayRules props

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock 2025-11-10 18:12:17 -06:00
parent 95101f4c73
commit 995966ffbc
2 changed files with 140 additions and 0 deletions

View File

@ -13,12 +13,15 @@ import { WorksheetPreview } from './WorksheetPreview'
import { OrientationPanel } from './OrientationPanel'
import { GenerateButton } from './GenerateButton'
import { GenerationErrorDisplay } from './GenerationErrorDisplay'
import { RuleThermometer } from './config-panel/RuleThermometer'
import { useWorksheetState } from '../hooks/useWorksheetState'
import { useWorksheetGeneration } from '../hooks/useWorksheetGeneration'
import { useWorksheetAutoSave } from '../hooks/useWorksheetAutoSave'
import { getDefaultDate } from '../utils/dateFormatting'
import { calculateDerivedState } from '../utils/layoutCalculations'
import type { WorksheetFormState } from '../types'
import type { DisplayRules } from '../displayRules'
import { defaultAdditionConfig } from '@/app/create/worksheets/config-schemas'
interface AdditionWorksheetClientProps {
initialSettings: Omit<WorksheetFormState, 'date' | 'rows' | 'total'>
@ -201,6 +204,32 @@ export function AdditionWorksheetClient({
onProblemsPerPageChange={handleProblemsPerPageChange}
onPagesChange={handlePagesChange}
isDark={isDark}
problemNumbers={
(formState.displayRules ?? defaultAdditionConfig.displayRules).problemNumbers
}
cellBorders={
(formState.displayRules ?? defaultAdditionConfig.displayRules).cellBorders
}
onProblemNumbersChange={(value) => {
const displayRules: DisplayRules =
formState.displayRules ?? defaultAdditionConfig.displayRules
updateFormState({
displayRules: {
...displayRules,
problemNumbers: value,
},
})
}}
onCellBordersChange={(value) => {
const displayRules: DisplayRules =
formState.displayRules ?? defaultAdditionConfig.displayRules
updateFormState({
displayRules: {
...displayRules,
cellBorders: value,
},
})
}}
/>
<GenerateButton status={status} onGenerate={handleGenerate} isDark={isDark} />

View File

@ -17,6 +17,11 @@ interface OrientationPanelProps {
onProblemsPerPageChange: (problemsPerPage: number, cols: number) => void
onPagesChange: (pages: number) => void
isDark?: boolean
// Layout options
problemNumbers?: 'always' | 'never'
cellBorders?: 'always' | 'never'
onProblemNumbersChange?: (value: 'always' | 'never') => void
onCellBordersChange?: (value: 'always' | 'never') => void
}
/**
@ -32,6 +37,10 @@ export function OrientationPanel({
onProblemsPerPageChange,
onPagesChange,
isDark = false,
problemNumbers = 'always',
cellBorders = 'always',
onProblemNumbersChange,
onCellBordersChange,
}: OrientationPanelProps) {
const handleOrientationChange = (newOrientation: 'portrait' | 'landscape') => {
const newProblemsPerPage = newOrientation === 'portrait' ? 15 : 20
@ -425,6 +434,108 @@ export function OrientationPanel({
</div>
</div>
</div>
{/* Row 3: Layout Options */}
<div className={css({ borderTop: '1px solid', borderColor: isDark ? 'gray.700' : 'gray.200', pt: '3', mt: '1' })}>
<div
className={css({
fontSize: '2xs',
fontWeight: 'semibold',
color: isDark ? 'gray.400' : 'gray.500',
textTransform: 'uppercase',
letterSpacing: 'wider',
mb: '2',
})}
>
Layout Options
</div>
<div className={css({ display: 'flex', flexDirection: 'column', gap: '2' })}>
{/* Problem Numbers Toggle */}
<label
className={css({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
cursor: 'pointer',
})}
>
<div>
<div
className={css({
fontSize: 'sm',
fontWeight: 'medium',
color: isDark ? 'gray.200' : 'gray.800',
})}
>
Problem Numbers
</div>
<div
className={css({
fontSize: 'xs',
color: isDark ? 'gray.400' : 'gray.600',
})}
>
Show problem numbers for reference
</div>
</div>
<input
type="checkbox"
checked={problemNumbers === 'always'}
onChange={(e) => {
onProblemNumbersChange?.(e.target.checked ? 'always' : 'never')
}}
className={css({
w: '12',
h: '6',
cursor: 'pointer',
})}
/>
</label>
{/* Cell Borders Toggle */}
<label
className={css({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
cursor: 'pointer',
})}
>
<div>
<div
className={css({
fontSize: 'sm',
fontWeight: 'medium',
color: isDark ? 'gray.200' : 'gray.800',
})}
>
Cell Borders
</div>
<div
className={css({
fontSize: 'xs',
color: isDark ? 'gray.400' : 'gray.600',
})}
>
Show borders around answer cells
</div>
</div>
<input
type="checkbox"
checked={cellBorders === 'always'}
onChange={(e) => {
onCellBordersChange?.(e.target.checked ? 'always' : 'never')
}}
className={css({
w: '12',
h: '6',
cursor: 'pointer',
})}
/>
</label>
</div>
</div>
</div>
</div>
)