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:
@@ -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>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user