Untitled
import React, { useState } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Leaf, TreePine, Recycle, PlaneTakeoff, Car, LightbulbOff, Smartphone } from "lucide-react"; import { Pie, PieChart } from "recharts"; import { useMetrics } from '@/hooks/useMetrics'; import { AppSidebar } from "@/components/app-sidebar"; import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"; import { Separator } from "@/components/ui/separator"; import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, } from "@/components/ui/breadcrumb"; import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent, } from "@/components/ui/chart"; const timeOptions = [ { value: "day", label: "Last 24 Hours" }, { value: "week", label: "Last Week" }, { value: "month", label: "Last Month" }, { value: "year", label: "Last Year" }, ]; const materialChartConfig = { 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; export default function EnvironmentalImpact() { const [selectedPeriod, setSelectedPeriod] = useState("month"); const { metrics, loading, error } = useMetrics(); const getPeriodMultiplier = (period) => { switch (period) { case 'day': return 1/30; case 'week': return 1/4; case 'year': return 12; default: return 1; // month } }; const getAdjustedMetrics = (metrics, period) => { if (!metrics) return null; const multiplier = getPeriodMultiplier(period); const { environmental_impact: impact } = metrics; return { co2_saved: impact.co2_saved * multiplier, trees_saved: impact.trees_saved * multiplier, paper_weight_recycled: impact.paper_weight_recycled * multiplier, plastic_weight_recycled: impact.plastic_weight_recycled * multiplier, organic_weight_processed: impact.organic_weight_processed * multiplier, }; }; if (loading) return <div className="p-4">Loading...</div>; if (error) return <div className="p-4">Error: {error}</div>; if (!metrics) return null; const impact = getAdjustedMetrics(metrics, selectedPeriod); // Environmental equivalents calculations const carKmAvoided = impact.co2_saved * 4; // Approx 250g CO2 per km const flightsAvoided = Math.round(impact.co2_saved / 0.2); // Assuming 0.2kg CO2 per short flight const phoneCharges = Math.round(impact.co2_saved * 1000); // Rough estimate for phone charges const lightbulbHours = Math.round(impact.co2_saved * 100); // LED bulb hours equivalent // Tree equivalents const oxygenForPeople = Math.round(impact.trees_saved * 2); // People's oxygen needs per day const paperSheetsSaved = Math.round(impact.trees_saved * 8333); // Sheets per tree approximation const materialsData = [ { name: "paper", value: impact.paper_weight_recycled, fill: "var(--color-paper)" }, { name: "plastic", value: impact.plastic_weight_recycled, fill: "var(--color-plastic)" }, { name: "organic", value: impact.organic_weight_processed, fill: "var(--color-organic)" } ].filter(item => item.value > 0); return ( <SidebarProvider> <AppSidebar /> <SidebarInset> <header className="flex shrink-0 items-center gap-2 border-b px-4 py-6"> <SidebarTrigger className="-ml-1" /> <Separator orientation="vertical" className="mr-2 h-4" /> <Breadcrumb> <BreadcrumbList> <BreadcrumbItem> <BreadcrumbLink href="/">Home</BreadcrumbLink> </BreadcrumbItem> <BreadcrumbItem> <BreadcrumbLink href="/impact">Environmental Impact</BreadcrumbLink> </BreadcrumbItem> </BreadcrumbList> </Breadcrumb> </header> <main className="p-4 space-y-4"> <div className="flex justify-between items-center"> <h1 className="text-2xl font-bold">Environmental Impact</h1> <Select value={selectedPeriod} onValueChange={setSelectedPeriod}> <SelectTrigger className="w-[180px]"> <SelectValue placeholder="Select period" /> </SelectTrigger> <SelectContent> {timeOptions.map((option) => ( <SelectItem key={option.value} value={option.value}> {option.label} </SelectItem> ))} </SelectContent> </Select> </div> <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4"> {/* CO2 Saved Card */} <Card className="xl:col-span-2"> <CardHeader className="pb-2"> <CardTitle className="flex items-center gap-2 text-lg"> <Leaf className="h-5 w-5 text-green-500" /> CO₂ Impact </CardTitle> </CardHeader> <CardContent> <div className="mt-2 space-y-4"> <div className="text-3xl font-bold text-green-500"> {impact.co2_saved.toFixed(2)} kg CO₂ saved </div> <div className="grid grid-cols-2 gap-4"> <div className="flex items-center gap-2 text-sm"> <Car className="h-4 w-4 text-blue-500" /> <span>{carKmAvoided.toFixed(1)} km of driving avoided</span> </div> <div className="flex items-center gap-2 text-sm"> <PlaneTakeoff className="h-4 w-4 text-blue-500" /> <span>Equal to {flightsAvoided} short flights</span> </div> <div className="flex items-center gap-2 text-sm"> <Smartphone className="h-4 w-4 text-blue-500" /> <span>{phoneCharges} phone charges saved</span> </div> <div className="flex items-center gap-2 text-sm"> <LightbulbOff className="h-4 w-4 text-blue-500" /> <span>{lightbulbHours} hours of LED bulb usage</span> </div> </div> </div> </CardContent> </Card> {/* Trees Saved Card */} <Card> <CardHeader className="pb-2"> <CardTitle className="flex items-center gap-2 text-lg"> <TreePine className="h-5 w-5 text-green-700" /> Tree Impact </CardTitle> </CardHeader> <CardContent> <div className="mt-2 space-y-4"> <div className="text-3xl font-bold text-green-700"> {impact.trees_saved.toFixed(3)} trees preserved </div> <div className="space-y-2"> <div className="text-sm"> ⚡ Provides daily oxygen for {oxygenForPeople} people </div> <div className="text-sm"> 📄 Saved {paperSheetsSaved.toLocaleString()} sheets of paper </div> </div> </div> </CardContent> </Card> {/* Materials Recycled Card */} <Card className="xl:col-span-3"> <CardHeader className="pb-2"> <CardTitle className="flex items-center gap-2 text-lg"> <Recycle className="h-5 w-5 text-blue-500" /> Materials Recycled by Type </CardTitle> </CardHeader> <CardContent> <ChartContainer config={materialChartConfig} className="mx-auto h-[300px] w-full" > <PieChart> <ChartTooltip content={ <ChartTooltipContent formatter={(value: number) => `${value.toFixed(2)} kg`} /> } /> <Pie data={materialsData} dataKey="value" nameKey="name" cx="50%" cy="50%" innerRadius={60} outerRadius={120} label={(entry) => `${materialChartConfig[entry.name].label}: ${entry.value.toFixed(2)}kg`} labelLine={true} /> </PieChart> </ChartContainer> </CardContent> </Card> </div> </main> </SidebarInset> </SidebarProvider> ); }
Leave a Comment