Initial commit

This commit is contained in:
2026-06-01 16:48:21 +02:00
commit 53d157535a
159 changed files with 13641 additions and 0 deletions
@@ -0,0 +1,55 @@
import { describe, it, expect } from 'vitest'
import { render, screen } from '@testing-library/react'
import { OverviewMetrics } from './OverviewMetrics'
describe('OverviewMetrics', () => {
it('renders metrics section', () => {
render(<OverviewMetrics metrics={[]} />)
expect(screen.getByTestId('overview-metrics')).toBeInTheDocument()
})
it('renders default title', () => {
render(<OverviewMetrics metrics={[]} />)
expect(screen.getByTestId('metrics-title')).toHaveTextContent('Overview')
})
it('renders custom title', () => {
render(<OverviewMetrics metrics={[]} title="Custom Title" />)
expect(screen.getByTestId('metrics-title')).toHaveTextContent('Custom Title')
})
it('renders metrics list with items', () => {
const metrics = [
{ label: 'Days Used', value: '10', testId: 'days-used' },
{ label: 'Days Left', value: '15', testId: 'days-left' },
]
render(<OverviewMetrics metrics={metrics} />)
expect(screen.getByTestId('metric-label-0')).toHaveTextContent('Days Used:')
expect(screen.getByTestId('metric-value-0')).toHaveTextContent('10')
expect(screen.getByTestId('metric-label-1')).toHaveTextContent('Days Left:')
expect(screen.getByTestId('metric-value-1')).toHaveTextContent('15')
})
it('renders empty metrics list', () => {
render(<OverviewMetrics metrics={[]} />)
expect(screen.getByTestId('metrics-list')).toBeInTheDocument()
})
it('uses custom test ids when provided', () => {
const metrics = [{ label: 'Test', value: '100', testId: 'custom-test-id' }]
render(<OverviewMetrics metrics={metrics} />)
expect(screen.getByTestId('custom-test-id')).toBeInTheDocument()
})
it('has proper accessibility structure', () => {
const metrics = [{ label: 'Metric', value: '50' }]
render(<OverviewMetrics metrics={metrics} title="Metrics Section" />)
const section = screen.getByTestId('overview-metrics')
expect(section).toHaveAttribute('role', 'region')
expect(section).toHaveAttribute('aria-label', 'Metrics Section')
expect(screen.getByTestId('metrics-list')).toHaveAttribute('role', 'list')
})
})
@@ -0,0 +1,33 @@
import { ReactNode } from 'react'
interface Metric {
label: string
value: string | number
testId?: string
}
interface OverviewMetricsProps {
metrics: Metric[]
title?: string
}
export function OverviewMetrics({ metrics, title = 'Overview' }: OverviewMetricsProps): ReactNode {
return (
<section role="region" aria-label={title} data-testid="overview-metrics">
<h2 data-testid="metrics-title">{title}</h2>
<div role="list" data-testid="metrics-list">
{metrics.map((metric, index) => (
<div
key={index}
role="listitem"
data-testid={metric.testId || `metric-${index}`}
data-label={metric.label}
>
<span data-testid={`metric-label-${index}`}>{metric.label}:</span>
<span data-testid={`metric-value-${index}`}>{metric.value}</span>
</div>
))}
</div>
</section>
)
}