- Next.js SPA mit Bun Runtime - Prisma mit SQLite Datenbank - Vollständige CRUD-Operationen für Fahrräder, Verschleißteile und Wartungshistorie - Warnsystem für bevorstehende Wartungen - Statistik-Features (Gesamtkosten, durchschnittliche Lebensdauer) - Zod-Validierung für alle API-Requests - Umfassende Test-Suite (41 Tests)
57 lines
1.7 KiB
TypeScript
57 lines
1.7 KiB
TypeScript
'use client'
|
|
|
|
import { BikeWithParts } from '@/types'
|
|
import { calculateTotalCosts, calculateAverageLifespan } from '@/lib/utils'
|
|
import { formatCurrency } from '@/lib/utils'
|
|
|
|
interface StatsCardProps {
|
|
bikes: BikeWithParts[]
|
|
}
|
|
|
|
export default function StatsCard({ bikes }: StatsCardProps) {
|
|
const allParts = bikes.flatMap((bike) => bike.wearParts)
|
|
const totalCosts = calculateTotalCosts(allParts)
|
|
const avgLifespan = calculateAverageLifespan(allParts)
|
|
const totalBikes = bikes.length
|
|
const totalParts = allParts.length
|
|
|
|
return (
|
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-8">
|
|
<div className="bg-white rounded-lg shadow-md p-6">
|
|
<h3 className="text-sm font-medium text-gray-500 mb-2">
|
|
Fahrräder
|
|
</h3>
|
|
<p className="text-3xl font-bold text-gray-900">{totalBikes}</p>
|
|
</div>
|
|
|
|
<div className="bg-white rounded-lg shadow-md p-6">
|
|
<h3 className="text-sm font-medium text-gray-500 mb-2">
|
|
Verschleißteile
|
|
</h3>
|
|
<p className="text-3xl font-bold text-gray-900">{totalParts}</p>
|
|
</div>
|
|
|
|
<div className="bg-white rounded-lg shadow-md p-6">
|
|
<h3 className="text-sm font-medium text-gray-500 mb-2">
|
|
Gesamtkosten
|
|
</h3>
|
|
<p className="text-3xl font-bold text-gray-900">
|
|
{formatCurrency(totalCosts)}
|
|
</p>
|
|
</div>
|
|
|
|
<div className="bg-white rounded-lg shadow-md p-6">
|
|
<h3 className="text-sm font-medium text-gray-500 mb-2">
|
|
Ø Lebensdauer
|
|
</h3>
|
|
<p className="text-3xl font-bold text-gray-900">
|
|
{avgLifespan
|
|
? `${Math.round(avgLifespan)} km`
|
|
: 'N/A'}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|