Untitled
unknown
plain_text
9 months ago
8.3 kB
6
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>
);
}Editor is loading...
Leave a Comment