add weather widget
This commit is contained in:
1 parent
dfe77a7ea1
commit
f5159100f7
1 file changed
+128
+128
@@ -80,6 +80,17 @@
|
||||
<a href="#food" class="text-gray-600 hover:text-brand-600 transition" data-i18n="nav_food">Ẩm thực</a>
|
||||
</nav>
|
||||
|
||||
<div class="hidden xl:flex items-center gap-2.5 border-l border-gray-200 pl-5" role="status" aria-live="polite" aria-label="Nha Trang weather">
|
||||
<i id="weather-icon" class="fa-solid fa-cloud-sun text-2xl text-amber-500" aria-hidden="true"></i>
|
||||
<div class="leading-tight">
|
||||
<div class="flex items-baseline gap-1.5">
|
||||
<span id="weather-temperature" class="text-lg font-bold text-gray-900">--°C</span>
|
||||
<span id="weather-location" class="text-xs font-semibold text-gray-500">Nha Trang</span>
|
||||
</div>
|
||||
<span id="weather-condition" class="text-xs text-gray-500" data-i18n="weather_loading">Đang tải thời tiết...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Action & Language Toggle -->
|
||||
<div class="flex items-center space-x-3">
|
||||
<!-- Language Switcher -->
|
||||
@@ -469,6 +480,18 @@
|
||||
attr_4_loc: "Vịnh Nha Trang, Khánh Hòa",
|
||||
weather_title: "Thời điểm lý tưởng du lịch",
|
||||
weather_desc: "Lên kế hoạch cho chuyến đi của bạn với thông tin thời tiết chính xác.",
|
||||
weather_loading: "Đang tải thời tiết...",
|
||||
weather_unavailable: "Không có dữ liệu",
|
||||
weather_clear: "Trời quang",
|
||||
weather_mainly_clear: "Ít mây",
|
||||
weather_partly_cloudy: "Có mây rải rác",
|
||||
weather_overcast: "Nhiều mây",
|
||||
weather_fog: "Sương mù",
|
||||
weather_drizzle: "Mưa phùn",
|
||||
weather_rain: "Mưa",
|
||||
weather_snow: "Tuyết",
|
||||
weather_showers: "Mưa rào",
|
||||
weather_thunderstorm: "Dông",
|
||||
season_dry_title: "Tháng 1 — Tháng 8 (Mùa khô)",
|
||||
season_dry_desc: "Thời kỳ hoàn hảo nhất cho du lịch biển. Trời nắng rực rỡ, biển êm, nước trong vắt, cực kỳ thích hợp cho các hoạt động lặn ngắm san hô, tắm biển và tham quan đảo.",
|
||||
season_dry_tag: "✨ Khuyên dùng cho nghỉ dưỡng",
|
||||
@@ -546,6 +569,18 @@
|
||||
attr_4_loc: "Залив Нячанг, Кханьхоа",
|
||||
weather_title: "Лучшее время для поездки",
|
||||
weather_desc: "Спланируйте свою поездку на основе точных метеорологических данных.",
|
||||
weather_loading: "Загрузка погоды...",
|
||||
weather_unavailable: "Нет данных",
|
||||
weather_clear: "Ясно",
|
||||
weather_mainly_clear: "Преимущественно ясно",
|
||||
weather_partly_cloudy: "Переменная облачность",
|
||||
weather_overcast: "Пасмурно",
|
||||
weather_fog: "Туман",
|
||||
weather_drizzle: "Морось",
|
||||
weather_rain: "Дождь",
|
||||
weather_snow: "Снег",
|
||||
weather_showers: "Ливень",
|
||||
weather_thunderstorm: "Гроза",
|
||||
season_dry_title: "Январь — Август (Сухой сезон)",
|
||||
season_dry_desc: "Идеальный период для пляжного отдыха. Ясное солнце, спокойное море, прозрачная вода — лучшее время для дайвинга и морских прогулок.",
|
||||
season_dry_tag: "✨ Рекомендуется для отдыха",
|
||||
@@ -623,6 +658,18 @@
|
||||
attr_4_loc: "Nha Trang Bay, Khanh Hoa",
|
||||
weather_title: "Best Time to Visit",
|
||||
weather_desc: "Plan your trip with accurate seasonal weather insights.",
|
||||
weather_loading: "Loading weather...",
|
||||
weather_unavailable: "Unavailable",
|
||||
weather_clear: "Clear",
|
||||
weather_mainly_clear: "Mainly clear",
|
||||
weather_partly_cloudy: "Partly cloudy",
|
||||
weather_overcast: "Overcast",
|
||||
weather_fog: "Fog",
|
||||
weather_drizzle: "Drizzle",
|
||||
weather_rain: "Rain",
|
||||
weather_snow: "Snow",
|
||||
weather_showers: "Showers",
|
||||
weather_thunderstorm: "Thunderstorm",
|
||||
season_dry_title: "January — August (Dry Season)",
|
||||
season_dry_desc: "The absolute best season for beach holidays. Bright sunshine, calm seas, and crystal-clear water, perfect for snorkeling and island hopping.",
|
||||
season_dry_tag: "✨ Recommended for Vacations",
|
||||
@@ -700,6 +747,18 @@
|
||||
attr_4_loc: "庆和省芽庄湾",
|
||||
weather_title: "最佳旅游季节",
|
||||
weather_desc: "根据精准气候指南,轻松规划您的完美行程。",
|
||||
weather_loading: "正在加载天气...",
|
||||
weather_unavailable: "暂无数据",
|
||||
weather_clear: "晴朗",
|
||||
weather_mainly_clear: "大致晴朗",
|
||||
weather_partly_cloudy: "局部多云",
|
||||
weather_overcast: "阴天",
|
||||
weather_fog: "有雾",
|
||||
weather_drizzle: "毛毛雨",
|
||||
weather_rain: "下雨",
|
||||
weather_snow: "下雪",
|
||||
weather_showers: "阵雨",
|
||||
weather_thunderstorm: "雷暴",
|
||||
season_dry_title: "1月 — 8月 (旱季)",
|
||||
season_dry_desc: "海滨旅游的黄金季节。阳光灿烂,风平浪静,海水清澈,极其适合潜水、游泳及跳岛游。",
|
||||
season_dry_tag: "✨ 度假强烈推荐",
|
||||
@@ -777,6 +836,18 @@
|
||||
attr_4_loc: "Bucht von Nha Trang, Khánh Hòa",
|
||||
weather_title: "Beste Reisezeit",
|
||||
weather_desc: "Planen Sie Ihre Reise mit verlässlichen Informationen zum saisonalen Wetter.",
|
||||
weather_loading: "Wetter wird geladen...",
|
||||
weather_unavailable: "Keine Daten",
|
||||
weather_clear: "Klar",
|
||||
weather_mainly_clear: "Überwiegend klar",
|
||||
weather_partly_cloudy: "Teilweise bewölkt",
|
||||
weather_overcast: "Bedeckt",
|
||||
weather_fog: "Nebel",
|
||||
weather_drizzle: "Nieselregen",
|
||||
weather_rain: "Regen",
|
||||
weather_snow: "Schnee",
|
||||
weather_showers: "Regenschauer",
|
||||
weather_thunderstorm: "Gewitter",
|
||||
season_dry_title: "Januar — August (Trockenzeit)",
|
||||
season_dry_desc: "Die beste Zeit für einen Strandurlaub: viel Sonne, ruhige See und klares Wasser. Ideal zum Schnorcheln, Baden und für Inselbesuche.",
|
||||
season_dry_tag: "✨ Ideal für einen Erholungsurlaub",
|
||||
@@ -854,6 +925,18 @@
|
||||
attr_4_loc: "Baie de Nha Trang, Khánh Hòa",
|
||||
weather_title: "Quand partir ?",
|
||||
weather_desc: "Planifiez votre séjour grâce à nos informations sur le climat selon les saisons.",
|
||||
weather_loading: "Chargement de la météo...",
|
||||
weather_unavailable: "Données indisponibles",
|
||||
weather_clear: "Ciel dégagé",
|
||||
weather_mainly_clear: "Globalement dégagé",
|
||||
weather_partly_cloudy: "Partiellement nuageux",
|
||||
weather_overcast: "Couvert",
|
||||
weather_fog: "Brouillard",
|
||||
weather_drizzle: "Bruine",
|
||||
weather_rain: "Pluie",
|
||||
weather_snow: "Neige",
|
||||
weather_showers: "Averses",
|
||||
weather_thunderstorm: "Orage",
|
||||
season_dry_title: "Janvier — août (saison sèche)",
|
||||
season_dry_desc: "La meilleure période pour profiter de la plage : soleil généreux, mer calme et eau limpide. Parfaite pour le snorkeling, la baignade et les excursions dans les îles.",
|
||||
season_dry_tag: "✨ Idéal pour des vacances détente",
|
||||
@@ -888,6 +971,48 @@
|
||||
};
|
||||
|
||||
let currentLang = 'vi';
|
||||
let currentWeatherCondition = 'weather_loading';
|
||||
|
||||
function getWeatherPresentation(code) {
|
||||
if (code === 0) return { key: 'weather_clear', icon: 'fa-sun', color: 'text-amber-500' };
|
||||
if (code === 1) return { key: 'weather_mainly_clear', icon: 'fa-cloud-sun', color: 'text-amber-500' };
|
||||
if (code === 2) return { key: 'weather_partly_cloudy', icon: 'fa-cloud-sun', color: 'text-amber-500' };
|
||||
if (code === 3) return { key: 'weather_overcast', icon: 'fa-cloud', color: 'text-gray-500' };
|
||||
if ([45, 48].includes(code)) return { key: 'weather_fog', icon: 'fa-smog', color: 'text-gray-500' };
|
||||
if ([51, 53, 55, 56, 57].includes(code)) return { key: 'weather_drizzle', icon: 'fa-cloud-rain', color: 'text-sky-500' };
|
||||
if ([61, 63, 65, 66, 67].includes(code)) return { key: 'weather_rain', icon: 'fa-cloud-rain', color: 'text-sky-600' };
|
||||
if ([71, 73, 75, 77].includes(code)) return { key: 'weather_snow', icon: 'fa-snowflake', color: 'text-sky-500' };
|
||||
if ([80, 81, 82, 85, 86].includes(code)) return { key: 'weather_showers', icon: 'fa-cloud-showers-heavy', color: 'text-sky-600' };
|
||||
if ([95, 96, 99].includes(code)) return { key: 'weather_thunderstorm', icon: 'fa-cloud-bolt', color: 'text-indigo-500' };
|
||||
return { key: 'weather_partly_cloudy', icon: 'fa-cloud-sun', color: 'text-amber-500' };
|
||||
}
|
||||
|
||||
function renderWeatherCondition() {
|
||||
const condition = document.getElementById('weather-condition');
|
||||
if (condition) condition.textContent = translations[currentLang][currentWeatherCondition] || translations.en[currentWeatherCondition];
|
||||
}
|
||||
|
||||
async function loadCurrentWeather() {
|
||||
const temperature = document.getElementById('weather-temperature');
|
||||
const icon = document.getElementById('weather-icon');
|
||||
|
||||
try {
|
||||
const response = await fetch('https://api.open-meteo.com/v1/forecast?latitude=12.2388&longitude=109.1967¤t=temperature_2m,weather_code&timezone=Asia%2FHo_Chi_Minh');
|
||||
if (!response.ok) throw new Error('Weather request failed');
|
||||
|
||||
const data = await response.json();
|
||||
const presentation = getWeatherPresentation(data.current.weather_code);
|
||||
temperature.textContent = `${Math.round(data.current.temperature_2m)}°C`;
|
||||
icon.className = `fa-solid ${presentation.icon} text-2xl ${presentation.color}`;
|
||||
currentWeatherCondition = presentation.key;
|
||||
} catch {
|
||||
temperature.textContent = '--°C';
|
||||
icon.className = 'fa-solid fa-cloud text-2xl text-gray-400';
|
||||
currentWeatherCondition = 'weather_unavailable';
|
||||
}
|
||||
|
||||
renderWeatherCondition();
|
||||
}
|
||||
|
||||
function getPreferredLanguage() {
|
||||
const supported = Object.keys(translations);
|
||||
@@ -926,6 +1051,7 @@
|
||||
});
|
||||
|
||||
document.documentElement.lang = lang;
|
||||
renderWeatherCondition();
|
||||
}
|
||||
|
||||
function toggleMobileMenu() {
|
||||
@@ -980,6 +1106,8 @@
|
||||
|
||||
// Initialize from browser language preferences
|
||||
setLanguage(getPreferredLanguage());
|
||||
loadCurrentWeather();
|
||||
setInterval(loadCurrentWeather, 30 * 60 * 1000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user