weatherwise-pro / script.js
QuentinCaron's picture
can you create a weather widget that mimic the one from perplexity fully interactive
aadabc6 verified
Raw
History Blame Contribute Delete
6.07 kB
// 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;