Untitled

 avatar
unknown
plain_text
6 days ago
8.3 kB
3
Indexable
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