Initial commit: Fahrrad Verschleißteile Tracker
- 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)
This commit is contained in:
56
app/components/StatsCard.tsx
Normal file
56
app/components/StatsCard.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
'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>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user