feat: add prev/next navigation buttons to mixed mode mini skill panes

Add navigation buttons to each mini skill card in mixed mode:

**Changes:**
- Wrapped each mini skill card in flex column container
- Added button row below each skill card with "← Prev" and "Next →" buttons
- Buttons disabled when at start/end of skill list
- Clicking prev/next updates appropriate skill ID (currentAdditionSkillId or currentSubtractionSkillId)
- Styled buttons to match compact theme (0.375rem padding, 0.75rem font)

**UX Benefits:**
- Direct navigation between skills without leaving mixed mode
- Clear visual separation between addition and subtraction skill progression
- Maintains compact design while adding functionality

🤖 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 13:29:45 -06:00
parent 59712e1021
commit 498df2ca5a

View File

@@ -275,58 +275,141 @@ export function MasteryModePanel({ formState, onChange, isDark = false }: Master
data-skill-card="addition-mini" data-skill-card="addition-mini"
className={css({ className={css({
flex: 1, flex: 1,
padding: '0.625rem', display: 'flex',
borderRadius: '4px', flexDirection: 'column',
border: '1px solid',
borderColor: isDark ? 'gray.600' : 'gray.300',
backgroundColor: isDark ? 'gray.600' : 'white',
})} })}
> >
<div <div
className={css({ className={css({
fontSize: '0.625rem', flex: 1,
fontWeight: '600', padding: '0.625rem',
color: isDark ? 'gray.400' : 'gray.500', borderRadius: '4px',
marginBottom: '0.25rem', border: '1px solid',
textTransform: 'uppercase', borderColor: isDark ? 'gray.600' : 'gray.300',
letterSpacing: '0.025em', backgroundColor: isDark ? 'gray.600' : 'white',
})} })}
> >
Addition <div
</div>
<div className={css({ display: 'flex', alignItems: 'center', gap: '0.375rem' })}>
<h4
className={css({ className={css({
fontSize: '0.8125rem', fontSize: '0.625rem',
fontWeight: '600', fontWeight: '600',
color: isDark ? 'white' : 'gray.900', color: isDark ? 'gray.400' : 'gray.500',
lineHeight: '1.2', marginBottom: '0.25rem',
textTransform: 'uppercase',
letterSpacing: '0.025em',
})} })}
> >
{currentAdditionSkill.name} Addition
</h4> </div>
{additionMastered && ( <div className={css({ display: 'flex', alignItems: 'center', gap: '0.375rem' })}>
<span <h4
className={css({ className={css({
fontSize: '0.8125rem', fontSize: '0.8125rem',
lineHeight: '1', fontWeight: '600',
color: isDark ? 'white' : 'gray.900',
lineHeight: '1.2',
})} })}
title="Mastered"
> >
{currentAdditionSkill.name}
</span> </h4>
)} {additionMastered && (
<span
className={css({
fontSize: '0.8125rem',
lineHeight: '1',
})}
title="Mastered"
>
</span>
)}
</div>
<p
className={css({
fontSize: '0.6875rem',
color: isDark ? 'gray.400' : 'gray.600',
marginTop: '0.25rem',
lineHeight: '1.3',
})}
>
{currentAdditionSkill.description}
</p>
</div>
{/* Addition Nav Buttons */}
<div className={css({ display: 'flex', gap: '0.5rem', marginTop: '0.5rem' })}>
<button
type="button"
onClick={() => {
const currentIndex = additionSkills.findIndex(
(s) => s.id === currentAdditionSkill.id
)
if (currentIndex > 0) {
onChange({
currentAdditionSkillId: additionSkills[currentIndex - 1].id,
} as Partial<WorksheetFormState>)
}
}}
disabled={additionSkills.findIndex((s) => s.id === currentAdditionSkill.id) === 0}
className={css({
flex: 1,
padding: '0.375rem',
fontSize: '0.75rem',
borderRadius: '3px',
border: '1px solid',
borderColor: isDark ? 'gray.500' : 'gray.300',
backgroundColor: isDark ? 'gray.600' : 'white',
color: isDark ? 'gray.200' : 'gray.700',
cursor: 'pointer',
_disabled: {
opacity: 0.5,
cursor: 'not-allowed',
},
_hover: {
backgroundColor: isDark ? 'gray.500' : 'gray.50',
},
})}
>
Prev
</button>
<button
type="button"
onClick={() => {
const currentIndex = additionSkills.findIndex(
(s) => s.id === currentAdditionSkill.id
)
if (currentIndex < additionSkills.length - 1) {
onChange({
currentAdditionSkillId: additionSkills[currentIndex + 1].id,
} as Partial<WorksheetFormState>)
}
}}
disabled={
additionSkills.findIndex((s) => s.id === currentAdditionSkill.id) ===
additionSkills.length - 1
}
className={css({
flex: 1,
padding: '0.375rem',
fontSize: '0.75rem',
borderRadius: '3px',
border: '1px solid',
borderColor: isDark ? 'gray.500' : 'gray.300',
backgroundColor: isDark ? 'gray.600' : 'white',
color: isDark ? 'gray.200' : 'gray.700',
cursor: 'pointer',
_disabled: {
opacity: 0.5,
cursor: 'not-allowed',
},
_hover: {
backgroundColor: isDark ? 'gray.500' : 'gray.50',
},
})}
>
Next
</button>
</div> </div>
<p
className={css({
fontSize: '0.6875rem',
color: isDark ? 'gray.400' : 'gray.600',
marginTop: '0.25rem',
lineHeight: '1.3',
})}
>
{currentAdditionSkill.description}
</p>
</div> </div>
{/* Subtraction Skill - Mini */} {/* Subtraction Skill - Mini */}
@@ -334,58 +417,143 @@ export function MasteryModePanel({ formState, onChange, isDark = false }: Master
data-skill-card="subtraction-mini" data-skill-card="subtraction-mini"
className={css({ className={css({
flex: 1, flex: 1,
padding: '0.625rem', display: 'flex',
borderRadius: '4px', flexDirection: 'column',
border: '1px solid',
borderColor: isDark ? 'gray.600' : 'gray.300',
backgroundColor: isDark ? 'gray.600' : 'white',
})} })}
> >
<div <div
className={css({ className={css({
fontSize: '0.625rem', flex: 1,
fontWeight: '600', padding: '0.625rem',
color: isDark ? 'gray.400' : 'gray.500', borderRadius: '4px',
marginBottom: '0.25rem', border: '1px solid',
textTransform: 'uppercase', borderColor: isDark ? 'gray.600' : 'gray.300',
letterSpacing: '0.025em', backgroundColor: isDark ? 'gray.600' : 'white',
})} })}
> >
Subtraction <div
</div>
<div className={css({ display: 'flex', alignItems: 'center', gap: '0.375rem' })}>
<h4
className={css({ className={css({
fontSize: '0.8125rem', fontSize: '0.625rem',
fontWeight: '600', fontWeight: '600',
color: isDark ? 'white' : 'gray.900', color: isDark ? 'gray.400' : 'gray.500',
lineHeight: '1.2', marginBottom: '0.25rem',
textTransform: 'uppercase',
letterSpacing: '0.025em',
})} })}
> >
{currentSubtractionSkill.name} Subtraction
</h4> </div>
{subtractionMastered && ( <div className={css({ display: 'flex', alignItems: 'center', gap: '0.375rem' })}>
<span <h4
className={css({ className={css({
fontSize: '0.8125rem', fontSize: '0.8125rem',
lineHeight: '1', fontWeight: '600',
color: isDark ? 'white' : 'gray.900',
lineHeight: '1.2',
})} })}
title="Mastered"
> >
{currentSubtractionSkill.name}
</span> </h4>
)} {subtractionMastered && (
<span
className={css({
fontSize: '0.8125rem',
lineHeight: '1',
})}
title="Mastered"
>
</span>
)}
</div>
<p
className={css({
fontSize: '0.6875rem',
color: isDark ? 'gray.400' : 'gray.600',
marginTop: '0.25rem',
lineHeight: '1.3',
})}
>
{currentSubtractionSkill.description}
</p>
</div>
{/* Subtraction Nav Buttons */}
<div className={css({ display: 'flex', gap: '0.5rem', marginTop: '0.5rem' })}>
<button
type="button"
onClick={() => {
const currentIndex = subtractionSkills.findIndex(
(s) => s.id === currentSubtractionSkill.id
)
if (currentIndex > 0) {
onChange({
currentSubtractionSkillId: subtractionSkills[currentIndex - 1].id,
} as Partial<WorksheetFormState>)
}
}}
disabled={
subtractionSkills.findIndex((s) => s.id === currentSubtractionSkill.id) === 0
}
className={css({
flex: 1,
padding: '0.375rem',
fontSize: '0.75rem',
borderRadius: '3px',
border: '1px solid',
borderColor: isDark ? 'gray.500' : 'gray.300',
backgroundColor: isDark ? 'gray.600' : 'white',
color: isDark ? 'gray.200' : 'gray.700',
cursor: 'pointer',
_disabled: {
opacity: 0.5,
cursor: 'not-allowed',
},
_hover: {
backgroundColor: isDark ? 'gray.500' : 'gray.50',
},
})}
>
Prev
</button>
<button
type="button"
onClick={() => {
const currentIndex = subtractionSkills.findIndex(
(s) => s.id === currentSubtractionSkill.id
)
if (currentIndex < subtractionSkills.length - 1) {
onChange({
currentSubtractionSkillId: subtractionSkills[currentIndex + 1].id,
} as Partial<WorksheetFormState>)
}
}}
disabled={
subtractionSkills.findIndex((s) => s.id === currentSubtractionSkill.id) ===
subtractionSkills.length - 1
}
className={css({
flex: 1,
padding: '0.375rem',
fontSize: '0.75rem',
borderRadius: '3px',
border: '1px solid',
borderColor: isDark ? 'gray.500' : 'gray.300',
backgroundColor: isDark ? 'gray.600' : 'white',
color: isDark ? 'gray.200' : 'gray.700',
cursor: 'pointer',
_disabled: {
opacity: 0.5,
cursor: 'not-allowed',
},
_hover: {
backgroundColor: isDark ? 'gray.500' : 'gray.50',
},
})}
>
Next
</button>
</div> </div>
<p
className={css({
fontSize: '0.6875rem',
color: isDark ? 'gray.400' : 'gray.600',
marginTop: '0.25rem',
lineHeight: '1.3',
})}
>
{currentSubtractionSkill.description}
</p>
</div> </div>
</div> </div>