Untitled
import React, { useState } from 'react'; import { Area, AreaChart, CartesianGrid, XAxis, Pie, PieChart, LabelList } from "recharts"; import { TrendingUp } from "lucide-react"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "@/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent, } from "@/components/ui/chart"; import { useMetrics } from '@/hooks/useMetrics'; // Chart configurations const co2ChartConfig = { co2: { label: "CO2 Saved (kg)", color: "hsl(var(--chart-1))", }, } satisfies ChartConfig; const treeChartConfig = { trees: { label: "Trees Saved", color: "hsl(var(--chart-2))", }, } satisfies ChartConfig; const materialsChartConfig = { paper: { label: "Paper", color: "hsl(var(--chart-1))", }, plastic: { label: "Plastic", color: "hsl(var(--chart-2))", }, organic: { label: "Organic", color: "hsl(var(--chart-3))", }, } satisfies ChartConfig; const periods = { "1M": "Last Month", "3M": "Last 3 Months", "6M": "Last 6 Months", "1Y": "Last Year", "ALL": "All Time" }; export default function EnvironmentalImpact() { const { metrics, loading, error } = useMetrics(); const [selectedPeriod, setSelectedPeriod] = useState("ALL"); if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error}</div>; if (!metrics) return null; const { environmental_impact } = metrics; // Create data for materials pie chart const materialsData = [ { type: "paper", weight: environmental_impact.paper_weight_recycled, fill: "var(--color-paper)" }, { type: "plastic", weight: environmental_impact.plastic_weight_recycled, fill: "var(--color-plastic)" }, { type: "organic", weight: environmental_impact.organic_weight_processed, fill: "var(--color-organic)" } ].filter(item => item.weight > 0); // Mock time series data (you'll need to modify this based on your actual data structure) const timeSeriesData = [ { month: "Current", co2: environmental_impact.co2_saved, trees: environmental_impact.trees_saved } ]; return ( <div className="grid gap-4 md:grid-cols-2"> {/* CO2 Saved Chart */} <Card> <CardHeader> <div className="flex justify-between"> <div> <CardTitle>CO2 Saved</CardTitle> <CardDescription>Environmental impact tracking</CardDescription> </div> <Select value={selectedPeriod} onValueChange={setSelectedPeriod}> <SelectTrigger className="w-36"> <SelectValue placeholder="Select period" /> </SelectTrigger> <SelectContent> {Object.entries(periods).map(([value, label]) => ( <SelectItem key={value} value={value}>{label}</SelectItem> ))} </SelectContent> </Select> </div> </CardHeader> <CardContent> <ChartContainer config={co2ChartConfig}> <AreaChart accessibilityLayer data={timeSeriesData} margin={{ left: 12, right: 12 }} > <CartesianGrid vertical={false} /> <XAxis dataKey="month" tickLine={false} axisLine={false} tickMargin={8} /> <ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} /> <Area dataKey="co2" type="natural" fill="var(--color-co2)" fillOpacity={0.4} stroke="var(--color-co2)" /> </AreaChart> </ChartContainer> </CardContent> <CardFooter> <div className="flex w-full items-start gap-2 text-sm"> <div className="grid gap-2"> <div className="flex items-center gap-2 font-medium"> Total CO2 Saved: {environmental_impact.co2_saved.toFixed(2)} kg </div> </div> </div> </CardFooter> </Card> {/* Trees Saved Chart */} <Card> <CardHeader> <div className="flex justify-between"> <div> <CardTitle>Trees Saved</CardTitle> <CardDescription>Environmental impact tracking</CardDescription> </div> <Select value={selectedPeriod} onValueChange={setSelectedPeriod}> <SelectTrigger className="w-36"> <SelectValue placeholder="Select period" /> </SelectTrigger> <SelectContent> {Object.entries(periods).map(([value, label]) => ( <SelectItem key={value} value={value}>{label}</SelectItem> ))} </SelectContent> </Select> </div> </CardHeader> <CardContent> <ChartContainer config={treeChartConfig}> <AreaChart accessibilityLayer data={timeSeriesData} margin={{ left: 12, right: 12 }} > <CartesianGrid vertical={false} /> <XAxis dataKey="month" tickLine={false} axisLine={false} tickMargin={8} /> <ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} /> <Area dataKey="trees" type="natural" fill="var(--color-trees)" fillOpacity={0.4} stroke="var(--color-trees)" /> </AreaChart> </ChartContainer> </CardContent> <CardFooter> <div className="flex w-full items-start gap-2 text-sm"> <div className="grid gap-2"> <div className="flex items-center gap-2 font-medium"> Total Trees Saved: {environmental_impact.trees_saved.toFixed(3)} </div> </div> </div> </CardFooter> </Card> {/* Materials Recycled Pie Chart */} <Card className="md:col-span-2"> <CardHeader className="items-center"> <CardTitle>Materials Recycled by Type</CardTitle> <CardDescription>Distribution of recycled materials</CardDescription> </CardHeader> <CardContent> <ChartContainer config={materialsChartConfig} className="mx-auto aspect-square max-h-[300px] [&_.recharts-text]:fill-background" > <PieChart> <ChartTooltip content={<ChartTooltipContent nameKey="weight" hideLabel />} /> <Pie data={materialsData} dataKey="weight"> <LabelList dataKey="type" className="fill-background" stroke="none" fontSize={12} formatter={(value: keyof typeof materialsChartConfig) => `${materialsChartConfig[value]?.label}: ${materialsData.find(d => d.type === value)?.weight.toFixed(2)}kg` } /> </Pie> </PieChart> </ChartContainer> </CardContent> <CardFooter className="flex-col gap-2 text-sm"> <div className="leading-none text-muted-foreground"> Total materials processed: {( environmental_impact.paper_weight_recycled + environmental_impact.plastic_weight_recycled + environmental_impact.organic_weight_processed ).toFixed(2)} kg </div> </CardFooter> </Card> </div> ); }
Leave a Comment