From b4658bb9b9c08a4715897b0f72d5f516877e0d20 Mon Sep 17 00:00:00 2001 From: beenull Date: Sun, 26 Nov 2023 18:27:27 +0000 Subject: [PATCH] Upload files to "/" --- script.js | 92 +++++++++++++++++++++++ snow.svg | 1 + storm.svg | 1 + style.css | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 307 insertions(+) create mode 100644 script.js create mode 100644 snow.svg create mode 100644 storm.svg create mode 100644 style.css diff --git a/script.js b/script.js new file mode 100644 index 0000000..92b715a --- /dev/null +++ b/script.js @@ -0,0 +1,92 @@ +const wrapper = document.querySelector(".wrapper"), + inputPart = wrapper.querySelector(".input-part"), + infoTxt = inputPart.querySelector(".info-txt"), + inputField = inputPart.querySelector("input"), + locationBtn = inputPart.querySelector("button"), + wIcon = wrapper.querySelector(".weather-part img"), + arrowBack = wrapper.querySelector("header i"); + +const apiKey = "ADD_API_KEY"; +let api; + +inputField.addEventListener("keyup", (e) => { + if (e.key == "Enter" && inputField.value != "") { + requestApi(inputField.value); + } +}); + +locationBtn.addEventListener("click", () => { + if (navigator.geolocation) { + //if browser supports geolocation + navigator.geolocation.getCurrentPosition(onSuccess, onError); + } else { + alert("your browser does not support geolocation api"); + } +}); + +function onSuccess(position) { + const { latitude, longitude } = position.coords; //getting latitue and longitude of use device from coords obj + api = `https://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&units=metric&appid=${apiKey}`; + fecthData(); +} +function onError(error) { + infoTxt.innerText = error.message; + infoTxt.classList.add("error"); +} + +function requestApi(city) { + api = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${apiKey}`; + fecthData(); +} + +function fecthData() { + infoTxt.innerText = "Getting Weather details...."; + infoTxt.classList.add("pending"); + // getting api response and returning it with parsing into js obj and in another + // then function calling weatherDetails() with passing api result as an argument + fetch(api) + .then((response) => response.json()) + .then((result) => weatherDetails(result)); +} + +function weatherDetails(info) { + if (info.cod == "404") { + infoTxt.innerText = `${inputField.value} isn't a valid city name`; + infoTxt.classList.replace("pending", "error"); + } else { + // lets gets + const city = info.name; + const country = info.sys.country; + const { description, id } = info.weather[0]; + const { feels_like, humidity, temp } = info.main; + + if (id == 800) { + wIcon.src = "/clear.svg"; + } else if (id >= 200 && id <= 232) { + wIcon.src = "/storm.svg"; + } else if (id >= 600 && id <= 622) { + wIcon.src = "/snow.svg"; + } else if (id >= 701 && id <= 781) { + wIcon.src = "/haze.svg"; + } else if (id >= 801 && id <= 804) { + wIcon.src = "/cloud.svg"; + } else if ((id >= 500 && id <= 531) || (id >= 300 && id <= 321)) { + wIcon.src = "/rain.svg"; + } + + // lets pass thes values to partivular html element + wrapper.querySelector(".temp .numb").innerText = Math.floor(temp); + wrapper.querySelector(".weather").innerText = description; + wrapper.querySelector(".location span").innerText = `${city}, ${country}`; + wrapper.querySelector(".temp .numb-2").innerText = Math.floor(feels_like); + wrapper.querySelector(".humidity span").innerText = `${humidity}%`; + + infoTxt.classList.remove("pending", "error"); + wrapper.classList.add("active"); + console.log("info", info); + } +} + +arrowBack.addEventListener("click", () => { + wrapper.classList.remove("active"); +}); diff --git a/snow.svg b/snow.svg new file mode 100644 index 0000000..157e07e --- /dev/null +++ b/snow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/storm.svg b/storm.svg new file mode 100644 index 0000000..64c19ae --- /dev/null +++ b/storm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..91fe260 --- /dev/null +++ b/style.css @@ -0,0 +1,213 @@ +*{ + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: IBM Plex Mono,monospace; + color: inherit; + text-decoration: none; + color: #ccc; +} +body{ + display: flex; + align-items: center; + justify-content: center; + min-height: 100vh; + background: #1D1F21; +} +::selection{ + color: #fff; + background: #43AFFC; +} +.wrapper{ + width: 400px; + background: #1D1F21; + border: 1px solid transparent; + border-top-color: transparent; + border-right-color: transparent; + border-bottom-color: transparent; + border-left-color: transparent; + border-top-color: transparent; + border-right-color: transparent; + border-bottom-color: transparent; + border-left-color: transparent; + border-color: #ccc; +} +.wrapper header{ + font-size: 21px; + font-weight: 500; + color: #ccc; + padding: 16px 15px; + align-items: center; + border-bottom: 1px solid #ccc; +} +header i{ + font-size: 0em; + cursor: pointer; + margin-right: 8px; +} +.wrapper.active header i{ + margin-left: 5px; + font-size: 30px; + vertical-align: middle; +} +.wrapper .input-part{ + margin: 20px 25px 30px; +} +.wrapper.active .input-part{ + display: none; +} +.input-part .info-txt{ + display: none; + font-size: 17px; + text-align: center; + padding: 12px 10px; + margin-bottom: 15px; +} +.input-part .info-txt.error{ + color: #ccc; + display: block; + background: #721c24; + border: 1px solid #ccc; +} +.input-part .info-txt.pending{ + color: #ccc; + display: block; + background: #0c5460; + border: 1px solid #ccc; +} +.input-part :where(input, button){ + width: 100%; + height: 55px; + border: none; + outline: none; + font-size: 18px; + border: 1px solid #ccc; +} +.input-part input{ + text-align: center; + padding: 0 15px; + border: 1px solid #ccc; +} +.input-part input:is(:focus, :valid){ + border: 2px solid #000428; +} +.input-part input::placeholder{ + color: #bfbfbf; +} +.input-part .separator{ + height: 1px; + width: 100%; + margin: 25px 0; + background: #ccc; + position: relative; + display: flex; + align-items: center; + justify-content: center; +} +.separator::before{ + color: #b3b3b3; + font-size: 19px; + padding: 0 15px; + background: #fff; +} +.input-part button{ + color: #fff; + cursor: pointer; + background: #1D1F21; + transition: 0.3s ease; +} +.input-part button:hover{ + background: #1D1F21; +} + +.wrapper .weather-part{ + display: none; + margin: 30px 0 0; + align-items: center; + justify-content: center; + flex-direction: column; +} +.wrapper.active .weather-part{ + display: flex; +} +.weather-part img{ + max-width: 125px; +} +.weather-part .temp{ + display: flex; + font-weight: 500; + font-size: 72px; +} +.weather-part .temp .numb{ + font-weight: 600; +} +.weather-part .temp .deg{ + font-size: 40px; + display: block; + margin: 10px 5px 0 0; +} +.weather-part .weather{ + font-size: 15px; + text-align: center; + margin: -5px 20px 15px; +} +.weather-part .location{ + display: flex; + font-size: 19px; + padding: 0 20px; + text-align: center; + margin-bottom: 30px; + align-items: flex-start; +} +.location i{ + font-size: 22px; + margin: 4px 5px 0 0; +} +.weather-part .bottom-details{ + display: flex; + width: 100%; + justify-content: space-between; + border-top: 1px solid #ccc; +} +.bottom-details .column{ + display: flex; + width: 100%; + padding: 15px 0; + align-items: center; + justify-content: center; +} +.column i{ + color: #ccc; + font-size: 40px; +} +.column.humidity{ + border-left: 1px solid #ccc; +} +.column .details{ + margin-left: 3px; +} +.details .temp, .humidity span{ + font-size: 18px; + font-weight: 500; + margin-top: -3px; +} +.details .temp .deg{ + margin: 0; + font-size: 17px; + padding: 0 2px 0 1px; +} +.column .details p{ + font-size: 14px; + margin-top: -6px; +} +.humidity i{ + font-size: 37px; +} +.footer { + position: absolute; + bottom: 0; + width: 100%; + height: 50px; + text-align: center; + color: #999; +} \ No newline at end of file