Untitled

 avatar
unknown
plain_text
6 days ago
12 kB
3
Indexable
'use client';

import { useState } from 'react';
import { Card, CardContent, CardHeader, CardTitle, CardDescription, CardFooter } from '@/components/ui/card';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Area, AreaChart, CartesianGrid, XAxis, YAxis, Tooltip, ResponsiveContainer, PieChart, Pie, Cell } from 'recharts';
import { Leaf, TreePine, Recycle, Plane, TrendingUp } from 'lucide-react';
import { cn } from '@/lib/utils';
import { useMetrics } from '@/hooks/useMetrics';

const timeRanges = ['Last Week', 'Last Month', 'Last 3 Months', 'Last Year', 'All Time'];

function StatCard({ title, value, icon: Icon, className }: { title: string; value: string; icon: any; className?: string }) {
  return (
    <Card className={cn("relative overflow-hidden", className)}>
      <CardHeader className="flex flex-row items-center justify-between pb-2">
        <CardTitle className="text-sm font-medium text-muted-foreground">{title}</CardTitle>
        <Icon className="h-4 w-4 text-muted-foreground" />
      </CardHeader>
      <CardContent>
        <div className="text-2xl font-bold">{value}</div>
      </CardContent>
    </Card>
  );
}

function App() {
  const [timeRange, setTimeRange] = useState('Last Month');
  const { metrics, loading, error } = useMetrics();

  if (loading) return <div className="flex items-center justify-center min-h-screen">Loading...</div>;
  if (error) return <div className="flex items-center justify-center min-h-screen">Error: {error}</div>;
  if (!metrics) return <div className="flex items-center justify-center min-h-screen">No data available</div>;

  // Mock time series data - replace with actual time series data from your API
  const timeSeriesData = [
    { date: 'Jan', co2: 0.5 },
    { date: 'Feb', co2: 1.2 },
    { date: 'Mar', co2: metrics.environmental_impact.co2_saved },
  ];

  const treeSeriesData = [
    { date: 'Jan', trees: 0.01 },
    { date: 'Feb', trees: 0.02 },
    { date: 'Mar', trees: metrics.environmental_impact.trees_saved },
  ];

  const materialsData = [
    { name: 'Paper', value: metrics.environmental_impact.paper_weight_recycled },
    { name: 'Plastic', value: metrics.environmental_impact.plastic_weight_recycled },
    { name: 'Organic', value: metrics.environmental_impact.organic_weight_processed },
  ];

  const COLORS = ['hsl(var(--chart-1))', 'hsl(var(--chart-2))', 'hsl(var(--chart-3))'];

  return (
    <div className="min-h-screen bg-background p-8">
      <div className="mx-auto max-w-7xl">
        <h1 className="text-4xl font-bold mb-8">Environmental Impact</h1>

        <div className="grid gap-6">
          <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
            <StatCard
              title="CO₂ Saved"
              value={`${metrics.environmental_impact.co2_saved.toFixed(2)} kg`}
              icon={Leaf}
            />
            <StatCard
              title="Trees Saved"
              value={metrics.environmental_impact.trees_saved.toFixed(3)}
              icon={TreePine}
            />
            <StatCard
              title="Materials Recycled"
              value={`${(metrics.environmental_impact.paper_weight_recycled + 
                metrics.environmental_impact.plastic_weight_recycled + 
                metrics.environmental_impact.organic_weight_processed).toFixed(2)} kg`}
              icon={Recycle}
            />
            <StatCard
              title="Flights Equivalent"
              value={`${(metrics.environmental_impact.co2_saved / 200).toFixed(3)}`}
              icon={Plane}
            />
          </div>

          <div className="grid gap-4 md:grid-cols-2">
            <Card>
              <CardHeader>
                <div className="flex items-center justify-between mb-2">
                  <div>
                    <CardTitle>CO₂ Savings Trend</CardTitle>
                    <CardDescription>
                      Tracking the reduction in carbon emissions over time
                    </CardDescription>
                  </div>
                  <Select value={timeRange} onValueChange={setTimeRange}>
                    <SelectTrigger className="w-[180px]">
                      <SelectValue placeholder="Select time range" />
                    </SelectTrigger>
                    <SelectContent>
                      {timeRanges.map((range) => (
                        <SelectItem key={range} value={range}>{range}</SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </CardHeader>
              <CardContent>
                <div className="h-[300px]">
                  <ResponsiveContainer width="100%" height="100%">
                    <AreaChart data={timeSeriesData} margin={{ left: 12, right: 12 }}>
                      <CartesianGrid vertical={false} />
                      <XAxis dataKey="date" tickLine={false} axisLine={false} tickMargin={8} />
                      <YAxis tickLine={false} axisLine={false} tickMargin={8} />
                      <Tooltip />
                      <Area
                        type="monotone"
                        dataKey="co2"
                        stroke="hsl(var(--chart-1))"
                        fill="hsl(var(--chart-1))"
                        fillOpacity={0.2}
                        name="CO₂ Saved (kg)"
                      />
                    </AreaChart>
                  </ResponsiveContainer>
                </div>
              </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 leading-none">
                      Total CO₂ saved: {metrics.environmental_impact.co2_saved.toFixed(2)} kg
                      <TrendingUp className="h-4 w-4" />
                    </div>
                    <div className="flex items-center gap-2 leading-none text-muted-foreground">
                      January - March 2024
                    </div>
                  </div>
                </div>
              </CardFooter>
            </Card>

            <Card>
              <CardHeader>
                <div className="flex items-center justify-between mb-2">
                  <div>
                    <CardTitle>Trees Saved Trend</CardTitle>
                    <CardDescription>
                      Equivalent number of trees preserved through recycling
                    </CardDescription>
                  </div>
                  <Select value={timeRange} onValueChange={setTimeRange}>
                    <SelectTrigger className="w-[180px]">
                      <SelectValue placeholder="Select time range" />
                    </SelectTrigger>
                    <SelectContent>
                      {timeRanges.map((range) => (
                        <SelectItem key={range} value={range}>{range}</SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </CardHeader>
              <CardContent>
                <div className="h-[300px]">
                  <ResponsiveContainer width="100%" height="100%">
                    <AreaChart data={treeSeriesData} margin={{ left: 12, right: 12 }}>
                      <CartesianGrid vertical={false} />
                      <XAxis dataKey="date" tickLine={false} axisLine={false} tickMargin={8} />
                      <YAxis tickLine={false} axisLine={false} tickMargin={8} />
                      <Tooltip />
                      <Area
                        type="monotone"
                        dataKey="trees"
                        stroke="hsl(var(--chart-2))"
                        fill="hsl(var(--chart-2))"
                        fillOpacity={0.2}
                        name="Trees Saved"
                      />
                    </AreaChart>
                  </ResponsiveContainer>
                </div>
              </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 leading-none">
                      Total trees saved: {metrics.environmental_impact.trees_saved.toFixed(3)}
                      <TrendingUp className="h-4 w-4" />
                    </div>
                    <div className="flex items-center gap-2 leading-none text-muted-foreground">
                      January - March 2024
                    </div>
                  </div>
                </div>
              </CardFooter>
            </Card>

            <Card className="md:col-span-2">
              <CardHeader>
                <div className="flex items-center justify-between mb-2">
                  <div>
                    <CardTitle>Materials Recycled by Type</CardTitle>
                    <CardDescription>
                      Distribution of recycled materials by category
                    </CardDescription>
                  </div>
                  <Select value={timeRange} onValueChange={setTimeRange}>
                    <SelectTrigger className="w-[180px]">
                      <SelectValue placeholder="Select time range" />
                    </SelectTrigger>
                    <SelectContent>
                      {timeRanges.map((range) => (
                        <SelectItem key={range} value={range}>{range}</SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </CardHeader>
              <CardContent>
                <div className="h-[300px]">
                  <ResponsiveContainer width="100%" height="100%">
                    <PieChart>
                      <Pie
                        data={materialsData}
                        cx="50%"
                        cy="50%"
                        innerRadius={60}
                        outerRadius={80}
                        fill="#8884d8"
                        paddingAngle={5}
                        dataKey="value"
                        label={({ name, value }) => `${name}: ${value.toFixed(2)}kg`}
                      >
                        {materialsData.map((entry, index) => (
                          <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
                        ))}
                      </Pie>
                      <Tooltip />
                    </PieChart>
                  </ResponsiveContainer>
                </div>
              </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 leading-none">
                      Total materials recycled: {(
                        metrics.environmental_impact.paper_weight_recycled +
                        metrics.environmental_impact.plastic_weight_recycled +
                        metrics.environmental_impact.organic_weight_processed
                      ).toFixed(2)} kg
                    </div>
                  </div>
                </div>
              </CardFooter>
            </Card>
          </div>
        </div>
      </div>
    </div>
  );
}

export default App;
Leave a Comment