File size: 6,068 Bytes
aadabc6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// 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;