Spaces:
Sleeping
Sleeping
File size: 7,827 Bytes
0c02b78 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | import React, { useState } from 'react';
import { motion } from 'framer-motion';
export default function SimulationLab({ currentCity, onRunSimulation, isSimulating }) {
const [tempOffset, setTempOffset] = useState(0);
const [rainModifier, setRainModifier] = useState(0);
const [humidityModifier, setHumidityModifier] = useState(0);
const [aqiModifier, setAqiModifier] = useState(0);
const [uvModifier, setUvModifier] = useState(0);
const [pressureModifier, setPressureModifier] = useState(0);
const handleRun = () => {
onRunSimulation({
tempOffset,
rainModifier,
humidityModifier,
aqiModifier,
uvModifier,
pressureModifier,
});
};
return (
<div className="bg-white/80 backdrop-blur-xl border border-slate-200 rounded-3xl p-6 shadow-xl mb-8 relative overflow-hidden">
<div className="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-purple-500 to-indigo-500"></div>
<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-6">
<div>
<h2 className="text-2xl font-black text-slate-800 flex items-center gap-2">
<span className="text-purple-600">🧪</span> What-If Simulation Lab
</h2>
<p className="text-sm text-slate-500 mt-1 font-medium">Adjust climatic variables to simulate environmental impact on {currentCity?.name}.</p>
</div>
<button
onClick={handleRun}
disabled={isSimulating || !currentCity}
className={`mt-4 sm:mt-0 px-6 py-2.5 rounded-xl font-bold text-white shadow-md transition-all ${isSimulating ? 'bg-slate-400 cursor-not-allowed' : 'bg-gradient-to-r from-purple-600 to-indigo-600 hover:shadow-lg hover:scale-105'}`}
>
{isSimulating ? 'Running...' : 'Run Simulation'}
</button>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* Temperature Slider */}
<div className="bg-slate-50 p-4 rounded-2xl border border-slate-100">
<div className="flex justify-between items-center mb-2">
<label className="text-sm font-bold text-slate-700 flex items-center gap-1">🌡️ Temp Anomaly</label>
<span className={`text-sm font-black ${tempOffset > 0 ? 'text-red-500' : tempOffset < 0 ? 'text-blue-500' : 'text-slate-500'}`}>
{tempOffset > 0 ? '+' : ''}{tempOffset}°C
</span>
</div>
<input
type="range" min="-5" max="5" step="0.5" value={tempOffset} onChange={(e) => setTempOffset(parseFloat(e.target.value))}
className="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-purple-600"
/>
<div className="flex justify-between text-[10px] text-slate-400 mt-1 font-bold">-5°C (Cooler) <span className="text-right">+5°C (Hotter)</span></div>
</div>
{/* Rain Slider */}
<div className="bg-slate-50 p-4 rounded-2xl border border-slate-100">
<div className="flex justify-between items-center mb-2">
<label className="text-sm font-bold text-slate-700 flex items-center gap-1">💧 Rainfall Modifier</label>
<span className={`text-sm font-black ${rainModifier > 0 ? 'text-blue-500' : rainModifier < 0 ? 'text-orange-500' : 'text-slate-500'}`}>
{rainModifier > 0 ? '+' : ''}{rainModifier}%
</span>
</div>
<input
type="range" min="-50" max="100" step="5" value={rainModifier} onChange={(e) => setRainModifier(parseInt(e.target.value))}
className="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-blue-500"
/>
<div className="flex justify-between text-[10px] text-slate-400 mt-1 font-bold">-50% (Drought) <span className="text-right">+100% (Flood)</span></div>
</div>
{/* Humidity Slider */}
<div className="bg-slate-50 p-4 rounded-2xl border border-slate-100">
<div className="flex justify-between items-center mb-2">
<label className="text-sm font-bold text-slate-700 flex items-center gap-1">🌫️ Humidity</label>
<span className={`text-sm font-black ${humidityModifier > 0 ? 'text-teal-600' : humidityModifier < 0 ? 'text-orange-500' : 'text-slate-500'}`}>
{humidityModifier > 0 ? '+' : ''}{humidityModifier}%
</span>
</div>
<input
type="range" min="-30" max="30" step="5" value={humidityModifier} onChange={(e) => setHumidityModifier(parseInt(e.target.value))}
className="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-teal-500"
/>
<div className="flex justify-between text-[10px] text-slate-400 mt-1 font-bold">-30% (Drier) <span className="text-right">+30% (Muggy)</span></div>
</div>
{/* AQI Slider */}
<div className="bg-slate-50 p-4 rounded-2xl border border-slate-100">
<div className="flex justify-between items-center mb-2">
<label className="text-sm font-bold text-slate-700 flex items-center gap-1">💨 AQI Modifier</label>
<span className={`text-sm font-black ${aqiModifier > 0 ? 'text-red-500' : aqiModifier < 0 ? 'text-emerald-500' : 'text-slate-500'}`}>
{aqiModifier > 0 ? '+' : ''}{aqiModifier} pts
</span>
</div>
<input
type="range" min="-50" max="200" step="10" value={aqiModifier} onChange={(e) => setAqiModifier(parseInt(e.target.value))}
className="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-yellow-600"
/>
<div className="flex justify-between text-[10px] text-slate-400 mt-1 font-bold">Cleaner <span className="text-right">More Polluted</span></div>
</div>
{/* UV Index Slider */}
<div className="bg-slate-50 p-4 rounded-2xl border border-slate-100">
<div className="flex justify-between items-center mb-2">
<label className="text-sm font-bold text-slate-700 flex items-center gap-1">🌞 UV Index</label>
<span className={`text-sm font-black ${uvModifier > 0 ? 'text-orange-600' : uvModifier < 0 ? 'text-blue-500' : 'text-slate-500'}`}>
{uvModifier > 0 ? '+' : ''}{uvModifier}
</span>
</div>
<input
type="range" min="-3" max="5" step="1" value={uvModifier} onChange={(e) => setUvModifier(parseInt(e.target.value))}
className="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-orange-500"
/>
<div className="flex justify-between text-[10px] text-slate-400 mt-1 font-bold">Less UV <span className="text-right">Extreme UV</span></div>
</div>
{/* Pressure Slider */}
<div className="bg-slate-50 p-4 rounded-2xl border border-slate-100">
<div className="flex justify-between items-center mb-2">
<label className="text-sm font-bold text-slate-700 flex items-center gap-1">⏱️ Pressure</label>
<span className={`text-sm font-black ${pressureModifier !== 0 ? 'text-purple-600' : 'text-slate-500'}`}>
{pressureModifier > 0 ? '+' : ''}{pressureModifier} hPa
</span>
</div>
<input
type="range" min="-20" max="20" step="2" value={pressureModifier} onChange={(e) => setPressureModifier(parseInt(e.target.value))}
className="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-slate-600"
/>
<div className="flex justify-between text-[10px] text-slate-400 mt-1 font-bold">Low Pressure <span className="text-right">High Pressure</span></div>
</div>
</div>
</div>
);
}
|