// Weather API configuration const WEATHER_API_KEY = 'demo_key'; // Replace with actual API key const WEATHER_API_URL = 'https://api.openweathermap.org/data/2.5'; // Mock weather data for demonstration const mockWeatherData = { current: { temp: 22, feels_like: 24, humidity: 65, pressure: 1013, wind_speed: 3.5, weather: [{ main: 'Clear', description: 'clear sky', icon: '01d' }] }, daily: [ { dt: Date.now()/1000 + 86400, temp: { day: 23 }, weather: [{ main: 'Clouds', icon: '02d' }] }, { dt: Date.now()/1000 + 172800, temp: { day: 21 }, weather: [{ main: 'Rain', icon: '10d' }] }, { dt: Date.now()/1000 + 259200, temp: { day: 25 }, weather: [{ main: 'Clear', icon: '01d' }] }, { dt: Date.now()/1000 + 345600, temp: { day: 20 }, weather: [{ main: 'Clouds', icon: '03d' }] }, { dt: Date.now()/1000 + 432000, temp: { day: 19 }, weather: [{ main: 'Rain', icon: '09d' }] } ] }; // Utility functions class WeatherUtils { static kelvinToCelsius(kelvin) { return Math.round(kelvin - 273.15); } static getWeatherIcon(iconCode) { const iconMap = { '01d': 'sun', '01n': 'moon', '02d': 'cloud', '02n': 'cloud', '03d': 'cloud', '03n': 'cloud', '04d': 'cloud', '04n': 'cloud', '09d': 'cloud-rain', '09n': 'cloud-rain', '10d': 'cloud-drizzle', '10n': 'cloud-drizzle', '11d': 'cloud-lightning', '11n': 'cloud-lightning', '13d': 'cloud-snow', '13n': 'cloud-snow', '50d': 'wind', '50n': 'wind' }; return iconMap[iconCode] || 'cloud'; } static formatDate(timestamp) { const date = new Date(timestamp * 1000); return date.toLocaleDateString('en-US', { weekday: 'short' }); } static getWindDirection(degrees) { const directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']; return directions[Math.round(degrees / 45) % 8]; } } // Weather API service class WeatherService { static async getWeatherData(lat, lon) { try { // For demo purposes, return mock data // In production, uncomment the API call below /* const response = await fetch( `${WEATHER_API_URL}/onecall?lat=${lat}&lon=${lon}&exclude=minutely,hourly,alerts&appid=${WEATHER_API_KEY}` ); if (!response.ok) throw new Error('Weather data fetch failed'); return await response.json(); */ // Simulate API delay await new Promise(resolve => setTimeout(resolve, 1000)); return mockWeatherData; } catch (error) { console.error('Error fetching weather data:', error); throw error; } } static async getLocationWeather(city) { try { // For demo, return mock data with city name const data = { ...mockWeatherData, city: city || 'Current Location' }; await new Promise(resolve => setTimeout(resolve, 800)); return data; } catch (error) { console.error('Error fetching location weather:', error); throw error; } } } // Global state management class WeatherState { constructor() { this.currentLocation = 'Current Location'; this.weatherData = null; this.loading = false; this.error = null; } setLoading(loading) { this.loading = loading; this.notifyListeners(); } setWeatherData(data, location) { this.weatherData = data; this.currentLocation = location; this.error = null; this.notifyListeners(); } setError(error) { this.error = error; this.weatherData = null; this.notifyListeners(); } addListener(listener) { this.listeners = this.listeners || []; this.listeners.push(listener); } notifyListeners() { if (this.listeners) { this.listeners.forEach(listener => listener(this)); } } } // Initialize global state const weatherState = new WeatherState(); // Event handlers document.addEventListener('DOMContentLoaded', function() { // Initialize with current location weather loadCurrentLocationWeather(); }); async function loadCurrentLocationWeather() { weatherState.setLoading(true); try { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( async (position) => { const { latitude, longitude } = position.coords; const data = await WeatherService.getWeatherData(latitude, longitude); weatherState.setWeatherData(data, 'Current Location'); }, async (error) => { // Fallback to default location const data = await WeatherService.getLocationWeather('New York'); weatherState.setWeatherData(data, 'New York'); } ); } else { // Fallback to default location const data = await WeatherService.getLocationWeather('New York'); weatherState.setWeatherData(data, 'New York'); } } catch (error) { weatherState.setError('Failed to load weather data'); } } async function searchLocation(city) { if (!city.trim()) return; weatherState.setLoading(true); try { const data = await WeatherService.getLocationWeather(city); weatherState.setWeatherData(data, city); } catch (error) { weatherState.setError('Location not found'); } } // Export for use in components window.WeatherState = weatherState; window.WeatherUtils = WeatherUtils; window.searchLocation = searchLocation; window.loadCurrentLocationWeather = loadCurrentLocationWeather;