425e29ea21
New components (all with .tsx + .test.tsx, 90%+ coverage): - CalendarDay: day cell with event badges - CalendarEvent: colored event chip with dismiss option - DaysBreakdown: table of days by type - ProgressChart: progress bar toward age-4 deadline - TipCard: optimization tip card with severity badges - VacationDaysInput: number input with min/max validation - ParentProfileInput: dual selects for salary type & employment status - PlanningGoalSelector: radio buttons for planning goal - BreakPeriodsInput: list manager with inline add/edit form All components follow existing patterns from Header/Footer: - Typed props interfaces (exported) - Semantic HTML with data-testid & ARIA attributes - No business logic, purely presentational - Comprehensive test coverage including edge cases npm test: 22 files, 167 tests passing npx tsc --noEmit: clean Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
37 lines
954 B
TypeScript
37 lines
954 B
TypeScript
import { ReactNode } from 'react'
|
|
|
|
export interface DaysBreakdownProps {
|
|
breakdown: Array<{ type: string; count: number }>
|
|
}
|
|
|
|
export function DaysBreakdown({ breakdown }: DaysBreakdownProps): ReactNode {
|
|
if (!breakdown || breakdown.length === 0) {
|
|
return (
|
|
<div data-testid="days-breakdown" className="days-breakdown">
|
|
<p className="days-breakdown__empty">No days recorded yet</p>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div data-testid="days-breakdown" className="days-breakdown">
|
|
<table className="days-breakdown__table">
|
|
<thead>
|
|
<tr>
|
|
<th>Leave Type</th>
|
|
<th>Days</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{breakdown.map((item, idx) => (
|
|
<tr key={idx} data-testid={`breakdown-row-${item.type}`}>
|
|
<td>{item.type}</td>
|
|
<td>{item.count}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
)
|
|
}
|