Spaces:
Running
Running
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; |