Untitled
"use client" import { useState, useMemo } from "react" import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts" import { useMetrics } from "@/hooks/useMetrics" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "@/components/ui/card" import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent, } from "@/components/ui/chart" const fillLevelRanges = [ { label: "0-20%", min: 0, max: 20 }, { label: "21-40%", min: 21, max: 40 }, { label: "41-60%", min: 41, max: 60 }, { label: "61-80%", min: 61, max: 80 }, { label: "81-100%", min: 81, max: 100 }, ] export function ProactiveEmptyingChart() { const { metrics, helpers } = useMetrics() const [selectedPeriod, setSelectedPeriod] = useState("all") const [selectedBin, setSelectedBin] = useState("all") const [selectedType, setSelectedType] = useState("all") const chartData = useMemo(() => { if (!metrics || !helpers) return [] // Calculate time range filter const now = new Date() let startDate = new Date(0) switch (selectedPeriod) { case "24h": startDate = new Date(now.getTime() - 24 * 60 * 60 * 1000) break case "week": startDate = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000) break case "month": startDate = new Date(now.getFullYear(), now.getMonth() - 1, now.getDate()) break case "year": startDate = new Date(now.getFullYear() - 1, now.getMonth(), now.getDate()) break } // Get and filter emptying events const events = helpers.getEmptyingEvents( selectedBin === "all" ? undefined : selectedBin, selectedPeriod === "all" ? undefined : { start: startDate, end: now } ) // Process events into range counts const rangeCounts = fillLevelRanges.map(range => ({ range: range.label, proactive: 0, normal: 0, })) events.forEach(event => { const range = fillLevelRanges.find(r => event.fill_level > r.min && event.fill_level <= r.max ) if (!range) return const idx = fillLevelRanges.indexOf(range) const isProactive = event.fill_level < 80 if (selectedType === "proactive" && isProactive) { rangeCounts[idx].proactive++ } else if (selectedType === "normal" && !isProactive) { rangeCounts[idx].normal++ } else { isProactive ? rangeCounts[idx].proactive++ : rangeCounts[idx].normal++ } }) return rangeCounts.map(item => ({ ...item, total: item.proactive + item.normal, })) }, [metrics, selectedPeriod, selectedBin, selectedType, helpers]) const activeBins = helpers?.getActiveBinIds() || [] const chartConfig = { ...(selectedType !== "normal" && { proactive: { label: "Proactive", color: "hsl(var(--chart-1))" }}), ...(selectedType !== "proactive" && { normal: { label: "Normal", color: "hsl(var(--chart-2))" }}), } satisfies ChartConfig return ( <Card> <CardHeader className="flex flex-row items-center justify-between gap-4"> <div> <CardTitle>Emptying Statistics</CardTitle> <CardDescription>Distribution of emptying events by fill level</CardDescription> </div> <div className="flex gap-2"> <Select value={selectedPeriod} onValueChange={setSelectedPeriod}> <SelectTrigger className="w-[120px]"> <SelectValue placeholder="Period" /> </SelectTrigger> <SelectContent> <SelectItem value="all">All Time</SelectItem> <SelectItem value="24h">Last 24h</SelectItem> <SelectItem value="week">Last Week</SelectItem> <SelectItem value="month">Last Month</SelectItem> <SelectItem value="year">Last Year</SelectItem> </SelectContent> </Select> <Select value={selectedBin} onValueChange={setSelectedBin}> <SelectTrigger className="w-[100px]"> <SelectValue placeholder="Bin" /> </SelectTrigger> <SelectContent> <SelectItem value="all">All</SelectItem> {activeBins.map(bin => ( <SelectItem key={bin} value={bin}>{bin}</SelectItem> ))} </SelectContent> </Select> <Select value={selectedType} onValueChange={setSelectedType}> <SelectTrigger className="w-[120px]"> <SelectValue placeholder="Type" /> </SelectTrigger> <SelectContent> <SelectItem value="all">All</SelectItem> <SelectItem value="proactive">Proactive</SelectItem> <SelectItem value="normal">Normal</SelectItem> </SelectContent> </Select> </div> </CardHeader> <CardContent> <ChartContainer config={chartConfig} className="min-h-[300px]"> <BarChart data={chartData}> <CartesianGrid vertical={false} /> <XAxis dataKey="range" tickLine={false} axisLine={false} tickMargin={10} /> <YAxis tickLine={false} axisLine={false} tickFormatter={(value) => `${value}`} /> <ChartTooltip content={<ChartTooltipContent />} /> {selectedType !== "normal" && ( <Bar dataKey="proactive" fill="var(--color-proactive)" radius={4} stackId="a" /> )} {selectedType !== "proactive" && ( <Bar dataKey="normal" fill="var(--color-normal)" radius={4} stackId="a" /> )} </BarChart> </ChartContainer> </CardContent> <CardFooter className="text-sm text-muted-foreground"> Proactive emptying = below 80% fill level | Normal emptying = 80%+ </CardFooter> </Card> ) }
Leave a Comment