import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter/foundation.dart'; import '../config/api_config.dart'; import '../models/weather_info.dart'; import '../services/weather_service.dart'; class WeatherWidget extends StatefulWidget { const WeatherWidget({super.key}); @override State createState() => _WeatherWidgetState(); } class _WeatherWidgetState extends State { Timer? _refreshTimer; @override void initState() { super.initState(); // Refresh weather every 1 hour _refreshTimer = Timer.periodic(const Duration(hours: 1), (timer) { if (mounted) { setState(() {}); // Rebuild to trigger FutureBuilder } }); } @override void dispose() { _refreshTimer?.cancel(); super.dispose(); } Widget _buildAqiIcon(int aqi) { Color color; IconData icon; String label; switch (aqi) { case 1: // Good color = Colors.blue; icon = Icons.sentiment_very_satisfied; label = "좋음"; break; case 2: // Fair color = Colors.green; icon = Icons.sentiment_satisfied; label = "보통"; break; case 3: // Moderate color = Colors.yellow[700]!; icon = Icons.sentiment_neutral; label = "주의"; break; case 4: // Poor color = Colors.orange; icon = Icons.sentiment_dissatisfied; label = "나쁨"; break; case 5: // Very Poor color = Colors.red; icon = Icons.sentiment_very_dissatisfied; label = "매우 나쁨"; break; default: return const SizedBox.shrink(); } return Column( children: [ Container( padding: const EdgeInsets.all(4), decoration: BoxDecoration( color: color.withOpacity(0.2), shape: BoxShape.circle, border: Border.all(color: color, width: 2), ), child: Icon(icon, color: color, size: 20), ), const SizedBox(height: 2), Text( label, style: TextStyle( color: color, fontSize: 10, fontWeight: FontWeight.bold, ), ), ], ); } @override Widget build(BuildContext context) { return FutureBuilder( future: Provider.of( context, listen: false, ).fetchWeather(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center( child: SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ), ); } if (snapshot.hasError) { debugPrint('Weather Error: ${snapshot.error}'); return const Text( 'Weather Unavailable', style: TextStyle(color: Colors.white54), ); } if (!snapshot.hasData) { return const SizedBox.shrink(); } final weather = snapshot.data!; // Assuming OpenWeatherMap icon format final iconUrl = (ApiConfig.useMockData || kIsWeb) ? null : (weather.icon.isNotEmpty ? "https://openweathermap.org/img/wn/${weather.icon}@2x.png" : null); return Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ // Weather Icon if (iconUrl != null) Image.network( iconUrl, width: 72, height: 72, errorBuilder: (_, __, ___) => const Icon(Icons.wb_sunny, color: Colors.amber), ) else const Icon(Icons.wb_sunny, color: Colors.amber, size: 60), const SizedBox(width: 16), // Temperature & City info Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Row( crossAxisAlignment: CrossAxisAlignment.baseline, textBaseline: TextBaseline.alphabetic, children: [ Text( '${weather.temperature.round()}°', style: Theme.of(context).textTheme.displaySmall?.copyWith( fontSize: 42, // Slightly larger to stand out color: Colors.yellowAccent, fontWeight: FontWeight.bold, height: 1.0, ), ), const SizedBox(width: 12), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '${weather.city} · ${weather.description}', style: Theme.of(context).textTheme.titleLarge?.copyWith( color: Colors.white70, fontWeight: FontWeight.w500, fontSize: 20 ), ), const SizedBox(height: 4), Text( '최고:${weather.tempMax.round()}° 최저:${weather.tempMin.round()}°', style: Theme.of(context).textTheme.titleLarge?.copyWith( color: Colors.white, fontSize: 22, fontWeight: FontWeight.bold ), ), ], ), ], ), ], ), // AQI Indicator (Right side) if (weather.aqi > 0) ...[ const SizedBox(width: 24), Container( height: 50, width: 2, color: Colors.white24, ), const SizedBox(width: 24), // Scaled up AQI Transform.scale( scale: 1.2, child: _buildAqiIcon(weather.aqi), ), ], ], ); }, ); } }