Untitled
unknown
plain_text
16 days ago
9.2 kB
4
Indexable
"use client" import React from 'react'; import { Card, CardContent, CardHeader, CardTitle, CardDescription, CardFooter } from "@/components/ui/card"; import { Leaf, TreePine, Recycle, PlaneTakeoff, Car, LightbulbOff, Smartphone, TrendingUp, AlertCircle } from "lucide-react"; import { Pie, PieChart, LabelList } 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"; import { Alert, AlertDescription } from "@/components/ui/alert"; const materialChartConfig = { materials: { label: "Materials", }, 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 { metrics, loading, error } = useMetrics(); if (loading) return <div className="p-4">Loading...</div>; if (error) return <div className="p-4">Error: {error}</div>; if (!metrics) return null; const { environmental_impact: impact } = metrics; // 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 totalMaterials = impact.paper_weight_recycled + impact.plastic_weight_recycled + impact.organic_weight_processed; const previousTotal = totalMaterials * 0.95; // Example: assuming 5% increase const trendPercentage = ((totalMaterials - previousTotal) / previousTotal * 100).toFixed(1); const materialsData = [ { type: "paper", name: "Paper", weight: Math.round(impact.paper_weight_recycled * 100) / 100, fill: "var(--color-paper)" }, { type: "plastic", name: "Plastic", weight: Math.round(impact.plastic_weight_recycled * 100) / 100, fill: "var(--color-plastic)" }, { type: "organic", name: "Organic", weight: Math.round(impact.organic_weight_processed * 100) / 100, fill: "var(--color-organic)" } ].filter(item => item.weight > 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> </div> <Alert> <AlertCircle className="h-4 w-4" /> <AlertDescription> These statistics are calculated based on default bin configurations. Custom bin settings may affect the accuracy of these measurements. </AlertDescription> </Alert> <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="flex flex-col"> <CardHeader className="items-center pb-0"> <CardTitle>Materials Recycled by Type</CardTitle> <CardDescription>Total Materials Processed</CardDescription> </CardHeader> <CardContent className="flex-1 pb-0"> <ChartContainer config={materialChartConfig} className="mx-auto aspect-square max-h-[250px] [&_.recharts-text]:fill-background" > <PieChart> <ChartTooltip content={ <ChartTooltipContent formatter={(value: number, name: string) => [`${value.toFixed(2)} kg`, name]} /> } /> <Pie data={materialsData} dataKey="weight" nameKey="name"> <LabelList dataKey="type" className="fill-background" stroke="none" fontSize={12} formatter={(value: keyof typeof materialChartConfig) => materialChartConfig[value]?.label } /> </Pie> </PieChart> </ChartContainer> </CardContent> <CardFooter className="flex-col gap-2 text-sm"> <div className="flex items-center gap-2 font-medium leading-none"> Trending up by {trendPercentage}% <TrendingUp className="h-4 w-4" /> </div> <div className="leading-none text-muted-foreground"> Total materials processed: {totalMaterials.toFixed(2)} kg </div> </CardFooter> </Card> </div> </main> </SidebarInset> </SidebarProvider> ); }
Editor is loading...
Leave a Comment