Untitled

 avatar
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