Untitled
unknown
plain_text
10 months ago
10 kB
9
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 { useTranslation, type SupportedLanguages } from "@/utils/translations";
import { useSettings } from '@/hooks/useSettings';
import { AppSidebar } from "@/components/app-sidebar";
import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
import TreeVisualization from "@/components/tree-visualization";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";
import { Separator } from "@/components/ui/separator";
import {
ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
import { Alert, AlertDescription } from "@/components/ui/alert";
export default function EnvironmentalImpact() {
const { metrics, loading, error } = useMetrics();
const { settings } = useSettings();
const { t } = useTranslation(settings?.language as SupportedLanguages || 'EN');
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;
const materialChartConfig = {
materials: {
label: t('environmentalImpact.materialsRecycled'),
},
paper: {
label: t('bins.Papier'),
color: "#3B82F6",
},
plastic: {
label: t('bins.Gelber Sack'),
color: "#FACC15",
},
organic: {
label: t('bins.Biomüll'),
color: "#92400E",
},
} satisfies ChartConfig;
const carKmAvoided = impact.co2_saved * 4;
const flightsAvoided = Math.round((impact.co2_saved / 90) * 100) / 100;
const phoneCharges = Math.round(impact.co2_saved * 1000);
const lightbulbHours = Math.round(impact.co2_saved * 100);
const totalMaterials = impact.paper_weight_recycled + impact.plastic_weight_recycled + impact.organic_weight_processed;
const materialsData = [
{
browser: "paper",
label: materialChartConfig.paper.label,
visitors: Math.round(impact.paper_weight_recycled * 100) / 100,
fill: materialChartConfig.paper.color
},
{
browser: "plastic",
label: materialChartConfig.plastic.label,
visitors: Math.round(impact.plastic_weight_recycled * 100) / 100,
fill: materialChartConfig.plastic.color
},
{
browser: "organic",
label: materialChartConfig.organic.label,
visitors: Math.round(impact.organic_weight_processed * 100) / 100,
fill: materialChartConfig.organic.color
}
].filter(item => item.visitors > 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 className="hidden md:block">
<BreadcrumbLink href="/">{t('navigation.home')}</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator className="hidden md:block" />
<BreadcrumbItem>
<BreadcrumbPage>{t('navigation.impact')}</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</header>
<main className="p-4 space-y-4">
<Alert>
<AlertCircle className="h-4 w-4" />
<AlertDescription>
{t('environmentalImpact.customBinWarning')}
</AlertDescription>
</Alert>
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
<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" />
{t('environmentalImpact.co2Impact')}
</CardTitle>
</CardHeader>
<CardContent>
<div className="mt-2 space-y-4">
<div className="text-3xl font-bold text-green-500">
{impact.co2_saved.toFixed(2)} {t('environmentalImpact.co2Saved')}
</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)} {t('environmentalImpact.drivingAvoided')}</span>
</div>
<div className="flex items-center gap-2 text-sm">
<PlaneTakeoff className="h-4 w-4 text-blue-500" />
<span>{t('environmentalImpact.flightsAvoided').replace('{}', flightsAvoided.toString())}</span>
</div>
<div className="flex items-center gap-2 text-sm">
<Smartphone className="h-4 w-4 text-blue-500" />
<span>{t('environmentalImpact.phoneCharges').replace('{}', phoneCharges.toString())}</span>
</div>
<div className="flex items-center gap-2 text-sm">
<LightbulbOff className="h-4 w-4 text-blue-500" />
<span>{t('environmentalImpact.ledBulbUsage').replace('{}', lightbulbHours.toString())}</span>
</div>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-2">
<CardTitle className="flex items-center gap-2 text-lg">
<TreePine className="h-5 w-5 text-green-700" />
{t('environmentalImpact.treeImpact')}
</CardTitle>
</CardHeader>
<CardContent>
<div className="mt-2 space-y-4">
<div className="text-3xl font-bold text-green-700">
{impact.trees_saved.toFixed(3)} {t('environmentalImpact.treesPreserved')}
</div>
<div className="space-y-2">
<div className="text-sm">
{t('environmentalImpact.oxygenProvided').replace('{}', oxygenForPeople.toString())}
</div>
<div className="text-sm">
{t('environmentalImpact.paperSheetsSaved').replace('{}', paperSheetsSaved.toLocaleString())}
</div>
</div>
</div>
</CardContent>
</Card>
<Card className="flex flex-col">
<CardHeader className="items-center pb-0">
<CardTitle>{t('environmentalImpact.materialsRecycled')}</CardTitle>
<CardDescription>{t('common.currentFillLevels')}</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={({ active, payload }) => {
if (active && payload && payload.length) {
return (
<div className="rounded-lg border bg-background p-2 shadow-sm">
<div className="grid grid-cols-2 gap-2">
<div className="flex items-center gap-2">
<div
className="h-2 w-2 rounded"
style={{
background: payload[0].payload.fill,
}}
/>
<span className="font-medium">
{payload[0].payload.label}
</span>
</div>
<div>{payload[0].value.toFixed(2)} {t('environmentalImpact.kg')}</div>
</div>
</div>
)
}
return null
}}
/>
<Pie data={materialsData} dataKey="visitors">
<LabelList
dataKey="label"
className="fill-background"
stroke="none"
fontSize={12}
/>
</Pie>
</PieChart>
</ChartContainer>
</CardContent>
<CardFooter className="flex-col gap-2 text-sm">
<div className="leading-none text-muted-foreground">
{t('environmentalImpact.totalProcessed').replace('{}', totalMaterials.toFixed(2))}
</div>
</CardFooter>
</Card>
<Card className="xl:col-span-2">
<TreeVisualization impact={impact} />
</Card>
</div>
</main>
</SidebarInset>
</SidebarProvider>
);
}Editor is loading...
Leave a Comment