Untitled
// components/overview-cards.tsx "use client" import { useMetrics } from "@/hooks/useMetrics" import { useBinConfig } from "@/hooks/use-bin-config" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Gauge, Clock, Trash2, TrendingUp } from "lucide-react" import { Badge } from "@/components/ui/badge" import { format, differenceInHours, differenceInDays, subDays } from "date-fns" export function OverviewCards() { const { metrics } = useMetrics() const { bins } = useBinConfig() // Card 1: Proactive emptying count const proactiveEmptyings = metrics?.proactive_emptying?.count || 0 const totalEmptyings = metrics?.basic_metrics?.bin_emptying_counts ? Object.values(metrics.basic_metrics.bin_emptying_counts).reduce((a, b) => a + b, 0) : 0 const proactivePercentage = totalEmptyings > 0 ? Math.round((proactiveEmptyings / totalEmptyings) * 100) : 0 // Card 2: Next full bin prediction const predictions = metrics?.fill_predictions || {} const nextFullBin = Object.entries(predictions).reduce((acc, [binId, prediction]) => { const predictedTime = new Date(prediction.predicted_full_time) return (!acc || predictedTime < acc.predictedTime) ? { binId, predictedTime, currentLevel: prediction.current_level, binName: bins.find(b => b.id === binId)?.name || `Mülleimer ${binId.slice(-1)}` } : acc }, null as { binId: string binName: string predictedTime: Date currentLevel: number } | null) // Card 3: Average fill level at emptying const fillLevels = metrics?.fill_level_history ? Object.values(metrics.fill_level_history).flatMap(h => h.fill_levels_at_empty) : [] const averageFillLevel = fillLevels.length > 0 ? Math.round(fillLevels.reduce((a, b) => a + b, 0) / fillLevels.length) : null // Card 4: Total emptyings count with weekly calculation const totalEmptyingsLastWeek = metrics?.fill_level_history ? Object.values(metrics.fill_level_history).reduce((total, binHistory) => { const lastWeek = subDays(new Date(), 7) return binHistory.emptying_timestamps.filter(t => new Date(t) > lastWeek ).length + total }, 0) : 0 // Format time remaining display const formatTimeRemaining = (endDate: Date) => { const hours = differenceInHours(endDate, new Date()) if (hours >= 24) { const days = (hours / 24).toFixed(1) return `${days} Tage verbleibend` } return `${hours} Stunden verbleibend` } return ( <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6"> {/* Proactive Emptying Card */} <Card> <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2"> <CardTitle className="text-sm font-medium">Proaktive Leerungen</CardTitle> <Trash2 className="h-4 w-4 text-muted-foreground" /> </CardHeader> <CardContent> <div className="text-2xl font-bold">{proactiveEmptyings}</div> <p className="text-xs text-muted-foreground"> {totalEmptyings} Gesamtleerungen ({proactivePercentage}%) </p> </CardContent> </Card> {/* Next Full Bin Card */} <Card> <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2"> <CardTitle className="text-sm font-medium">Nächste volle Tonne</CardTitle> <Clock className="h-4 w-4 text-muted-foreground" /> </CardHeader> <CardContent> {nextFullBin ? ( <> <div className="text-2xl font-bold mb-1"> {nextFullBin.binName} </div> <div className="text-xs text-muted-foreground"> Aktuell: {Math.round(nextFullBin.currentLevel)}% voll </div> <div className="text-xs text-muted-foreground"> {format(nextFullBin.predictedTime, "dd.MM.yyyy HH:mm")} </div> <div className="text-xs text-muted-foreground mt-1"> {formatTimeRemaining(nextFullBin.predictedTime)} </div> </> ) : ( <div className="text-sm text-muted-foreground">Keine Vorhersagen</div> )} </CardContent> </Card> {/* Average Fill Level Card */} <Card> <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2"> <CardTitle className="text-sm font-medium">Durchschn. Füllstand</CardTitle> <Gauge className="h-4 w-4 text-muted-foreground" /> </CardHeader> <CardContent> <div className="text-2xl font-bold"> {averageFillLevel !== null ? `${averageFillLevel}%` : "N/A"} </div> <p className="text-xs text-muted-foreground"> Bei Leerungen </p> </CardContent> </Card> {/* Total Emptyings Card */} <Card> <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2"> <CardTitle className="text-sm font-medium">Leerungen gesamt</CardTitle> <Trash2 className="h-4 w-4 text-muted-foreground" /> </CardHeader> <CardContent> <div className="text-2xl font-bold">{totalEmptyings}</div> <p className="text-xs text-muted-foreground"> +{totalEmptyingsLastWeek} letzte Woche </p> </CardContent> </Card> </div> ) }
Leave a Comment