Untitled
unknown
plain_text
a year ago
4.4 kB
13
Indexable
"use client"
import React, { useEffect, useState } from 'react';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { TreePine, Leaf } from "lucide-react";
import { Progress } from "@/components/ui/progress";
interface TreeVisualizationProps {
impact: {
co2_saved: number;
trees_saved: number;
};
}
const TreeVisualization: React.FC<TreeVisualizationProps> = ({ impact }) => {
const [scale, setScale] = useState(0);
const maxImpact = 10; // kg of CO2 for full size
// This useEffect now properly updates when impact changes
useEffect(() => {
const calculatedScale = Math.min((impact.co2_saved / maxImpact) * 100, 100);
// Force a re-render by creating a new state value
setScale(prevScale => {
if (prevScale !== calculatedScale) {
return calculatedScale;
}
return prevScale;
});
}, [impact.co2_saved]); // Explicitly depend on co2_saved
return (
<CardContent className="flex flex-col items-center space-y-4">
<div className="relative w-64 h-64 flex items-center justify-center">
<svg
viewBox="0 0 100 100"
className="w-full h-full transform transition-all duration-1000"
style={{ transform: `scale(${0.5 + (scale * 0.5) / 100})` }}
>
{/* Tree trunk */}
<path
d="M45 90 L55 90 L53 60 L47 60 Z"
fill="#8B4513"
className="transition-all duration-1000"
style={{
transform: `scaleY(${0.8 + (scale * 0.2) / 100})`,
transformOrigin: 'center bottom'
}}
/>
{/* Tree foliage layers */}
<g className="transition-all duration-1000">
{/* Bottom layer */}
<path
d="M20 60 L80 60 L50 30 Z"
fill="#2F855A"
opacity={scale >= 20 ? "1" : "0"}
className="transition-all duration-500"
/>
{/* Middle layer */}
<path
d="M25 45 L75 45 L50 20 Z"
fill="#276749"
opacity={scale >= 50 ? "1" : "0"}
className="transition-all duration-500"
/>
{/* Top layer */}
<path
d="M30 30 L70 30 L50 10 Z"
fill="#22543D"
opacity={scale >= 80 ? "1" : "0"}
className="transition-all duration-500"
/>
{/* Decorative elements that appear at full growth */}
{scale >= 95 && (
<>
{/* Small leaves */}
<circle cx="35" cy="50" r="2" fill="#48BB78" />
<circle cx="65" cy="50" r="2" fill="#48BB78" />
<circle cx="50" cy="25" r="2" fill="#48BB78" />
{/* Birds */}
<path
d="M30 35 Q35 32 40 35"
stroke="#4A5568"
fill="none"
strokeWidth="1"
/>
<path
d="M60 40 Q65 37 70 40"
stroke="#4A5568"
fill="none"
strokeWidth="1"
/>
</>
)}
</g>
</svg>
</div>
<div className="w-full space-y-2">
<div className="flex justify-between text-sm">
<span>Growth Progress</span>
<span>{Math.round(scale)}%</span>
</div>
<Progress value={scale} className="h-2" />
</div>
<div className="grid grid-cols-2 gap-4 text-sm text-muted-foreground">
<div className="flex items-center gap-2">
<Leaf className="h-4 w-4 text-green-500" />
<span>{impact.co2_saved.toFixed(2)} kg COâ‚‚ saved</span>
</div>
<div className="flex items-center gap-2">
<TreePine className="h-4 w-4 text-green-700" />
<span>{impact.trees_saved.toFixed(3)} trees preserved</span>
</div>
</div>
{scale >= 100 && (
<div className="text-sm font-medium text-green-600">
🎉 Maximum impact reached! Keep up the great work!
</div>
)}
</CardContent>
);
};
export default TreeVisualization;Editor is loading...
Leave a Comment