Untitled

 avatar
unknown
plain_text
15 days ago
9.4 kB
4
Indexable
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