Spaces:
Sleeping
Sleeping
Download frontend/src/components/Dashboard/SimulationLab.jsx from SeriousSam07/Ritu-AI: direct link, hf CLI and curl.
- Browser
- Download file 7.83 kB
-
https://huggingface.co/spaces/SeriousSam07/Ritu-AI/resolve/main/frontend/src/components/Dashboard/SimulationLab.jsx
- Command line
-
hf download hf://spaces/SeriousSam07/Ritu-AI/frontend/src/components/Dashboard/SimulationLab.jsx
-
curl -L -o SimulationLab.jsx https://huggingface.co/spaces/SeriousSam07/Ritu-AI/resolve/main/frontend/src/components/Dashboard/SimulationLab.jsx
7.83 kB
| 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> | |
| ); | |
| } | |