({ activeField, selectedFields, allFields }: WeatherViewProps)
| 130 | |
| 131 | |
| 132 | const WeatherView = ({ activeField, selectedFields, allFields }: WeatherViewProps) => { |
| 133 | const isMobile = useIsMobile(); |
| 134 | const [compareField, setCompareField] = useState<Field | null>(null); |
| 135 | const [showCompareSelector, setShowCompareSelector] = useState(false); |
| 136 | const [endDate, setEndDate] = useState<Date>(new Date()); |
| 137 | const [startDate, setStartDate] = useState<Date>(() => { |
| 138 | const d = new Date(); |
| 139 | d.setFullYear(d.getFullYear() - 1); |
| 140 | return d; |
| 141 | }); |
| 142 | const [monthlyData, setMonthlyData] = useState<any[]>([]); |
| 143 | const [dailyData, setDailyData] = useState<any[]>([]); |
| 144 | const [soilMoistureData, setSoilMoistureData] = useState<any[]>([]); |
| 145 | const [loading, setLoading] = useState(false); |
| 146 | const [liveWeather, setLiveWeather] = useState<LiveWeather | null>(null); |
| 147 | const [liveLoading, setLiveLoading] = useState(false); |
| 148 | |
| 149 | // AQI state |
| 150 | const [aqiData, setAqiData] = useState<AqiData | null>(null); |
| 151 | const [aqiLoading, setAqiLoading] = useState(false); |
| 152 | |
| 153 | // GEE analytics state |
| 154 | const [geeData, setGeeData] = useState<any>(null); |
| 155 | const [geeLoading, setGeeLoading] = useState(false); |
| 156 | |
| 157 | // NDVI time-series state |
| 158 | const [ndviTimeSeries, setNdviTimeSeries] = useState<any>(null); |
| 159 | const [ndviTsLoading, setNdviTsLoading] = useState(false); |
| 160 | // Map token for crop planning |
| 161 | const [mapToken, setMapToken] = useState(""); |
| 162 | // Soil data for crop planning |
| 163 | const [soilData, setSoilData] = useState<any>(null); |
| 164 | |
| 165 | const effectiveField = activeField || selectedFields[0]; |
| 166 | |
| 167 | const urban = isUrbanRegion(geeData?.land_use); |
| 168 | |
| 169 | // Fetch GEE analytics |
| 170 | useEffect(() => { |
| 171 | if (!effectiveField) { setGeeData(null); return; } |
| 172 | const cached = getFreshLocalCacheValue<any>(GEE_ANALYTICS_CACHE_KEY, effectiveField.id, QUERY_CACHE_TTL_MS); |
| 173 | if (cached) { |
| 174 | setGeeData(cached); |
| 175 | return; |
| 176 | } |
| 177 | const fetchGee = async () => { |
| 178 | setGeeLoading(true); |
| 179 | try { |
| 180 | const polygon = effectiveField.coordinates[0]; |
| 181 | const data = await invokeWithRetry<any>( |
| 182 | "gee-analytics", |
| 183 | { polygon, analyses: ["land_use", "vegetation", "suitability"] }, |
| 184 | { retries: 4, isEmpty: (d) => !hasGeeAnalyticsPayload(d) } |
| 185 | ); |
| 186 | if (hasGeeAnalyticsPayload(data)) { |
| 187 | setGeeData(data); |
| 188 | setLocalCache(GEE_ANALYTICS_CACHE_KEY, effectiveField.id, data); |
| 189 | } else { |
nothing calls this directly
no test coverage detected