import 'package:flutter/material.dart'; class WeatherCard extends StatelessWidget { final Map? weather; const WeatherCard({super.key, required this.weather}); @override Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; if (weather == null) { return Container( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), decoration: BoxDecoration( color: scheme.surfaceContainerHighest, borderRadius: BorderRadius.circular(12), border: Border.all(color: scheme.outlineVariant), ), child: Text( 'Weather data unavailable — will retry at next slot.', style: TextStyle( color: scheme.onSurfaceVariant, fontStyle: FontStyle.italic, fontSize: 13, ), ), ); } final w = weather!; final location = w['location'] as String? ?? ''; final currentTemp = w['current_temp']; final condition = w['condition'] as String? ?? ''; final todayHigh = w['today_high']; final todayLow = w['today_low']; final yesterdayHigh = w['yesterday_high']; final fetchedAt = w['fetched_at'] as String?; final forecast = (w['forecast'] as List? ?? []) .cast>(); String? tempDelta; if (todayHigh != null && yesterdayHigh != null) { final diff = (todayHigh as num) - (yesterdayHigh as num); if (diff.abs() < 1) { tempDelta = 'Same as yesterday'; } else { final dir = diff > 0 ? 'warmer' : 'cooler'; tempDelta = '${diff.abs().round()}° $dir than yesterday'; } } String? fetchedLabel; if (fetchedAt != null) { try { final dt = DateTime.parse(fetchedAt).toLocal(); final h = dt.hour % 12 == 0 ? 12 : dt.hour % 12; final m = dt.minute.toString().padLeft(2, '0'); final period = dt.hour < 12 ? 'AM' : 'PM'; fetchedLabel = '$h:$m $period'; } catch (_) {} } return Container( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: scheme.surfaceContainerHighest, borderRadius: BorderRadius.circular(12), border: Border.all(color: scheme.outlineVariant), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header: location + fetched time Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( location, style: TextStyle( fontWeight: FontWeight.w600, fontSize: 14, color: scheme.onSurface, ), ), if (fetchedLabel != null) Text( 'as of $fetchedLabel', style: TextStyle( fontSize: 12, color: scheme.onSurfaceVariant, ), ), ], ), const SizedBox(height: 8), // Current temp + condition Row( crossAxisAlignment: CrossAxisAlignment.baseline, textBaseline: TextBaseline.alphabetic, children: [ Text( '$currentTemp°', style: TextStyle( fontSize: 36, fontWeight: FontWeight.w700, color: scheme.onSurface, height: 1, ), ), const SizedBox(width: 10), Text( condition, style: TextStyle( fontSize: 14, color: scheme.onSurfaceVariant, ), ), ], ), // Today high/low + delta if (todayHigh != null) ...[ const SizedBox(height: 8), Text( 'Today: $todayHigh° / $todayLow°' '${tempDelta != null ? ' · $tempDelta' : ''}', style: TextStyle(fontSize: 13, color: scheme.onSurfaceVariant), ), ], // Forecast strip if (forecast.isNotEmpty) ...[ const SizedBox(height: 12), const Divider(height: 1), const SizedBox(height: 12), SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( spacing: 8, children: forecast.map((day) { return SizedBox( width: 64, child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( day['day'] as String? ?? '', style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: scheme.onSurface, ), ), const SizedBox(height: 3), Text( day['condition'] as String? ?? '', style: TextStyle( fontSize: 11, color: scheme.onSurfaceVariant, ), textAlign: TextAlign.center, maxLines: 2, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 3), Text( '${day['high']}° / ${day['low']}°', style: TextStyle( fontSize: 12, color: scheme.onSurface, ), ), ], ), ); }).toList(), ), ), ], ], ), ); } }