1function carregarPrevisaoTempo() { 2 if (!navigator.geolocation) { 3 console.error("Geolocalização não suportada pelo navegador."); 4 return; 5 } 6 7 navigator.geolocation.getCurrentPosition( 8 (position) => { 9 const lat = position.coords.latitude; 10 const lon = position.coords.longitude; 11 12 // Obter nome da cidade 13 fetch( 14 `https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}` 15 ) 16 .then((res) => res.json()) 17 .then((localData) => { 18 const cidade = 19 localData.address.city || 20 localData.address.town || 21 localData.address.village || 22 localData.address.county || 23 "sua região"; 24 25 const titulo = document.getElementById("titulo-cidade-tempo"); 26 if (titulo) titulo.innerText = `Previsão do tempo para ${cidade}`; 27 }); 28 29 // Obter previsão do tempo 30 fetch(`/api/clima?lat=${lat}&lon=${lon}`) 31 .then((res) => res.json()) 32 .then((data) => { 33 const dias = data.daily.time; 34 const max = data.daily.temperature_2m_max; 35 const min = data.daily.temperature_2m_min; 36 const weather = data.daily.weathercode; 37 38 const icones = { 39 0: "âï¸", // Céu limpo 40 1: "ð¤ï¸", // Principalmente limpo 41 2: "â ", // Parcialmente nublado 42 3: "âï¸", // Nublado 43 45: "ð«ï¸", // Névoa 44 48: "ð«ï¸", // Névoa com gelo 45 51: "ð¦ï¸", // Garoa leve 46 53: "ð¦ï¸", // Garoa moderada 47 55: "ð¦ï¸", // Garoa densa 48 56: "ð§ï¸", // Garoa congelante leve 49 57: "ð§ï¸", // Garoa congelante densa 50 61: "ð§ï¸", // Chuva leve 51 63: "ð§ï¸", // Chuva moderada 52 65: "ð§ï¸", // Chuva forte 53 66: "ð¨ï¸", // Chuva congelante leve 54 67: "ð¨ï¸", // Chuva congelante forte 55 71: "ð¨ï¸", // Neve leve 56 73: "ð¨ï¸", // Neve moderada 57 75: "ð¨ï¸", // Neve intensa 58 77: "âï¸", // Cristais de gelo 59 80: "ð§ï¸", // Pancadas de chuva fracas 60 81: "ð§ï¸", // Pancadas de chuva moderadas 61 82: "ð§ï¸", // Pancadas de chuva fortes 62 85: "ð¨ï¸", // Pancadas de neve fracas 63 86: "ð¨ï¸", // Pancadas de neve fortes 64 95: "âï¸", // Tempestade leve ou moderada 65 96: "âï¸", // Tempestade com granizo leve 66 99: "âï¸", // Tempestade com granizo forte 67 68 // Extras personalizados 69 frio: "ð¡ï¸âï¸", 70 calor: "ð¡ï¸âï¸", 71 }; 72 73 // HTML Desktop 74 let htmlDesktop = `<div class="d-none d-md-flex justify-content-center flex-wrap" style="gap: 60px; padding: 30px 0;">`; 75 dias.forEach((dia, i) => { 76 const date = new Date(dia); 77 const diaSemana = date.toLocaleDateString("pt-BR", { 78 weekday: "short", 79 }); 80 const extra = 81 max[i] >= 30 ? icones.calor : min[i] <= 10 ? icones.frio : ""; 82 htmlDesktop += ` 83 <div class="text-center" style="min-width: 90px;"> 84 <div style="font-size: 1.8rem;">${ 85 icones[weather[i]] || "â" 86 } ${extra}</div> 87 <div class="f14">${diaSemana}</div> 88 <div class="f14">${min[i]}° / ${max[i]}°</div> 89 </div> 90 `; 91 }); 92 htmlDesktop += `</div>`; 93 94 // HTML Mobile 95 const grupos = [ 96 [0, 1], 97 [2, 3], 98 [4, 5, 6], 99 ]; 100 let htmlMobile = ` 101 <div class="swiper swiper-tempo d-md-none"> 102 <div class="swiper-wrapper"> 103 `; 104 grupos.forEach((indices) => { 105 htmlMobile += `<div class="swiper-slide d-flex justify-content-center gap-4">`; 106 indices.forEach((i) => { 107 const date = new Date(dias[i]); 108 const diaSemana = date.toLocaleDateString("pt-BR", { 109 weekday: "short", 110 }); 111 const extra = 112 max[i] >= 30 ? icones.calor : min[i] <= 10 ? icones.frio : ""; 113 htmlMobile += ` 114 <div class="text-center" style="min-width: 90px;"> 115 <div style="font-size: 1.8rem;">${ 116 icones[weather[i]] || "â" 117 } ${extra}</div> 118 <div class="f14">${diaSemana}</div> 119 <div class="f14">${min[i]}° / ${max[i]}°</div> 120 </div> 121 `; 122 }); 123 htmlMobile += `</div>`; 124 }); 125 htmlMobile += `</div></div>`; 126 127 const container = document.getElementById("previsao-tempo"); 128 if (container) { 129 container.innerHTML = htmlDesktop + htmlMobile; 130 131 // Inicializa o Swiper somente após injetar o HTML e garantir que ele exista 132 const isMobile = window.innerWidth <= 768; 133 if (isMobile) { 134 setTimeout(() => { 135 if (typeof Swiper !== "undefined") { 136 const swiperElement = document.querySelector( 137 ".swiper-tempo .swiper-wrapper" 138 ); 139 if (swiperElement && swiperElement.children.length > 0) { 140 new Swiper(".swiper-tempo", { 141 slidesPerView: 1, 142 spaceBetween: 20, 143 autoplay: { 144 delay: 5000, // 5 segundos 145 disableOnInteraction: false, // continua mesmo com swipe manual 146 }, 147 }); 148 } 149 } 150 }, 100); 151 } 152 } 153 }); 154 }, 155 (error) => { 156 console.error("Erro ao obter localização:", error); 157 } 158 ); 159} 160 161document.addEventListener("DOMContentLoaded", carregarPrevisaoTempo);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.