diff --git a/Weather Forecast Webapp/css/style.css b/Weather Forecast Webapp/css/style.css index bbb96a3d..3e08acd8 100644 --- a/Weather Forecast Webapp/css/style.css +++ b/Weather Forecast Webapp/css/style.css @@ -1,95 +1,224 @@ +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap'); *{ - margin: 0; - padding: 0; - } - - body { - background:linear-gradient(90deg,#614385, #516395); - line-height: 1.5; - font-size: 125%; - display: flex; - } - - /*--------------------------------------- CARD ------------------------------------------*/ - - .container { - position: relative; - background: rgba( 255, 255, 255, 0.25 ); -box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); -backdrop-filter: blur( 4px ); --webkit-backdrop-filter: blur( 4px ); -border-radius: 10px; -border: 1px solid rgba( 255, 255, 255, 0.18 ); - padding: 0 1em 1em; - margin: 150px 500px 400px auto; - -webkit-filter: drop-shadow(0 1em 1em rgba(226, 91, 91, 0.1)); - filter: drop-shadow(0 1em 1em rgba(226, 91, 91, 0.1)); - border-radius: 10px; - -webkit-border-radius: 10px; - -moz-border-radius: 10px; - -ms-border-radius: 10px; - -o-border-radius: 10px; - overflow: hidden; + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: 'Poppins', sans-serif; } +body{ + display: flex; + align-items: center; + justify-content: center; + min-height: 100vh; + background:linear-gradient(90deg,#614385, #516395); +} +::selection{ + background: rgba( 255, 255, 255, 0.25 ); + box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); + backdrop-filter: blur( 4px ); + -webkit-backdrop-filter: blur( 4px ); +} +.wrapper{ + width: 400px; + background: rgba( 255, 255, 255, 0.25 ); + box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); + backdrop-filter: blur( 4px ); + -webkit-backdrop-filter: blur( 4px ); + border: 1px solid rgba( 255, 255, 255, 0.18 ); + -webkit-filter: drop-shadow(0 1em 1em rgba(226, 91, 91, 0.1)); + filter: drop-shadow(0 1em 1em rgba(226, 91, 91, 0.1)); +} +.wrapper header{ + display: flex; + font-size: 21px; + font-weight: 500; - /*-------------------------------- FOR THE TILTED CARD------------------------------------ */ - - - - /* ------------------------------------------------------------------------------------------*/ - - .content { - position: relative; - margin: 0 60px auto; - padding: 0 1em; - } + padding: 16px 15px; + align-items: center; + background: rgba( 255, 255, 255, 0.25 ); + box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); + backdrop-filter: blur( 4px ); + -webkit-backdrop-filter: blur( 4px ); +} +header i{ + font-size: 0em; + cursor: pointer; + margin-right: 8px; +} +.wrapper.active header i{ + margin-left: 5px; + font-size: 30px; +} +.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; + border-radius: 7px; + margin-bottom: 15px; +} +.input-part .info-txt.error{ + background: rgba( 255, 255, 255, 0.25 ); + box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); + backdrop-filter: blur( 4px ); + -webkit-backdrop-filter: blur( 4px ); +} +.input-part .info-txt.pending{ + background: rgba( 255, 255, 255, 0.25 ); + box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); + backdrop-filter: blur( 4px ); + -webkit-backdrop-filter: blur( 4px ); +} +.input-part :where(input, button){ + width: 100%; + height: 55px; + border: none; + outline: none; + font-size: 18px; + border-radius: 7px; +} +.input-part input{ + text-align: center; + padding: 0 15px; + background: rgba( 255, 255, 255, 0.25 ); + box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); + backdrop-filter: blur( 4px ); + -webkit-backdrop-filter: blur( 4px ); +} +.input-part input:is(:focus, :valid){ + background: rgba( 255, 255, 255, 0.25 ); + box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); + backdrop-filter: blur( 4px ); + -webkit-backdrop-filter: blur( 4px ); +} +.input-part input::placeholder{ + background: rgba( 255, 255, 255, 0.25 ); + box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); + backdrop-filter: blur( 4px ); + -webkit-backdrop-filter: blur( 4px ); +} +.input-part .separator{ + height: 1px; + width: 100%; + margin: 25px 0; + background: rgba( 255, 255, 255, 0.25 ); + box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); + backdrop-filter: blur( 4px ); + -webkit-backdrop-filter: blur( 4px ); + position: relative; + display: flex; + align-items: center; + justify-content: center; +} +.separator::before{ + content: "or"; + border: 1px solid rgba( 255, 255, 255, 0.18 ); + font-size: 19px; + padding: 0 15px; + background: rgba( 255, 255, 255, 0.25 ); + box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); + backdrop-filter: blur( 4px ); + -webkit-backdrop-filter: blur( 4px ); +} +.input-part button{ - h1 { - border-bottom: 4px solid rebeccapurple; - padding-bottom: 0.25em; - margin-bottom: 0.25em; - text-align: center; - font-family: Verdana, Geneva, Tahoma, sans-serif; + cursor: pointer; + background: rgba( 255, 255, 255, 0.25 ); + box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); + backdrop-filter: blur( 4px ); + -webkit-backdrop-filter: blur( 4px ); + transition: 0.3s ease; +} +.input-part button:hover{ + background: rgba(98, 80, 149, 0.25); +} - } - - /*----------------------------------- INPUT BOX---------------------------------------*/ - - .input { - width: 100%; - border: none; - outline: none; - font-size: 1.4rem; - height: 50px; - padding: 10px 10px; - text-align: center; - font-weight: bold; - background: rgba( 255, 255, 255, 0.25 ); -box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); -backdrop-filter: blur( 4px ); --webkit-backdrop-filter: blur( 4px ); -border-radius: 10px; -border: 1px solid rgba( 255, 255, 255, 0.18 ); - } - - /*------------------------------------DETAILS----------------------------------------- */ - - .main-weather { - display: none; - padding: 20px; - line-height: 2.2rem; - border-radius: 10px; - height: 30vh; - text-align: center; - color: #23313E; - font-weight: bold; - } - - .temp { - - margin: 25px ; - font-size:40pt; - font-weight: 700; - } - - /*---------------------------------------------------------------------------------------*/ \ No newline at end of file +.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: 21px; + 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: #5449a7; + font-size: 40px; +} +.column.humidity{ + border-left: 1px solid rgb(145, 139, 185); +} +.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; +} \ No newline at end of file diff --git a/Weather Forecast Webapp/index.html b/Weather Forecast Webapp/index.html index f6553fd1..664487e5 100644 --- a/Weather Forecast Webapp/index.html +++ b/Weather Forecast Webapp/index.html @@ -1,38 +1,59 @@ - + + - - - - - - Weather + + Weather App + + + + - - -
-
-

WEATHER APP

- -
- -
-

Date

-
City
-
Temp
-
Min and Max Temp
-
Sunny
-
+
+
Weather App
+
+

+
+ +
+ +
+
+
+ Weather Icon +
+ _ + °C +
+
_ _
+
+ + _, _ +
+
+
+ +
+
+ _ + °C +
+

Feels like

+
+
+
+ +
+ _ +

Humidity

+
+
+
+
+ + - \ No newline at end of file diff --git a/Weather Forecast Webapp/js/icons/clear.svg b/Weather Forecast Webapp/js/icons/clear.svg new file mode 100644 index 00000000..371d7c38 --- /dev/null +++ b/Weather Forecast Webapp/js/icons/clear.svg @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Weather Forecast Webapp/js/icons/cloud.svg b/Weather Forecast Webapp/js/icons/cloud.svg new file mode 100644 index 00000000..39616667 --- /dev/null +++ b/Weather Forecast Webapp/js/icons/cloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Weather Forecast Webapp/js/icons/haze.svg b/Weather Forecast Webapp/js/icons/haze.svg new file mode 100644 index 00000000..8f41e2c0 --- /dev/null +++ b/Weather Forecast Webapp/js/icons/haze.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Weather Forecast Webapp/js/icons/rain.svg b/Weather Forecast Webapp/js/icons/rain.svg new file mode 100644 index 00000000..b843ef96 --- /dev/null +++ b/Weather Forecast Webapp/js/icons/rain.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Weather Forecast Webapp/js/icons/snow.svg b/Weather Forecast Webapp/js/icons/snow.svg new file mode 100644 index 00000000..157e07eb --- /dev/null +++ b/Weather Forecast Webapp/js/icons/snow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Weather Forecast Webapp/js/icons/storm.svg b/Weather Forecast Webapp/js/icons/storm.svg new file mode 100644 index 00000000..64c19aef --- /dev/null +++ b/Weather Forecast Webapp/js/icons/storm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Weather Forecast Webapp/js/script.js b/Weather Forecast Webapp/js/script.js index 9cfc9612..a60848d6 100644 --- a/Weather Forecast Webapp/js/script.js +++ b/Weather Forecast Webapp/js/script.js @@ -1,59 +1,89 @@ -/*---------------------------------------API--------------------------------------------*/ - -const api = { - key: "", /* <=== ENTER YOU API KEY WITHIN THE QUOTES*/ - base: "https://api.openweathermap.org/data/2.5/weather?", -} - -/*-------------------FUNCTION TO DISPLAY DATE AND TIME USING MOMENT.JS-------------------*/ - -const date = moment(); -document.getElementById("date").innerHTML = date.format("Mo MMM YYYY dddd, h:mm:ss"); - - -/*-----------------------FUNCTION TO TAKE THE VALUES WHEN ENTERED------------------------*/ - - const Input = document.getElementById('input'); - - Input.addEventListener('keypress', (event) => { - - if(event.keyCode == 13) { - getWeather(Input.value); //passing the input value to getWeather function - document.querySelector('.main-weather').style.display = "block"; //used to show the details as intially the display is set as none +const wrapper = document.querySelector(".wrapper"), +inputPart = document.querySelector(".input-part"), +infoTxt = inputPart.querySelector(".info-txt"), +inputField = inputPart.querySelector("input"), +locationBtn = inputPart.querySelector("button"), +weatherPart = wrapper.querySelector(".weather-part"), +wIcon = weatherPart.querySelector("img"), +arrowBack = wrapper.querySelector("header i"); + +let api; + +inputField.addEventListener("keyup", e =>{ + if(e.key == "Enter" && inputField.value != ""){ + requestApi(inputField.value); } }); -/*-------------------------------FUNCTION TO GET WEATHER--------------------------------*/ - - -function getWeather(city) { - fetch(`${api.base}q=${city}&appid=${api.key}&units=metric`) // format for calling api is given on the web docs - // units=metric used for celcius, if you remove it the temperature would be in Fahrenheit - .then(details => { - return details.json(); // Sending all details to showWeather function in form of json +locationBtn.addEventListener("click", () =>{ + if(navigator.geolocation){ + navigator.geolocation.getCurrentPosition(onSuccess, onError); + }else{ + alert("Your browser not support geolocation api"); + } +}); - }).then(showWeather); +function requestApi(city){ + api = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${'de1400a8c4500ee4e0ebe2e706f9d077'}`; + fetchData(); } -/*-------------------------------FUNCTION TO SHOW WEATHER--------------------------------*/ - - -function showWeather(details){ //Taking the received values from API into this function - - // console.log(details); - - let city = document.getElementById('city'); - city.innerHTML = `${details.name}, ${details.sys.country}`; - - let temperature = document.getElementById('temp'); - temperature.innerHTML = `${Math.round(details.main.temp)}°C`; //Rounding off the temp using math function +function onSuccess(position){ + const {latitude, longitude} = position.coords; + api = `https://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&units=metric&appid=${'de1400a8c4500ee4e0ebe2e706f9d077'}`; + fetchData(); +} - let minMax = document.getElementById('min-max'); - minMax.innerHTML = `${Math.round(details.main.temp_min)}°C (Min) and ${Math.round(details.main.temp_max)}°C (Max) `; //Rounding off the temp using math function +function onError(error){ + infoTxt.innerText = error.message; + infoTxt.classList.add("error"); +} - let weatherType = document.getElementById('weather-type'); - weatherType.innerHTML = `${details.weather[0].main}`; +function fetchData(){ + infoTxt.innerText = "Getting weather details..."; + infoTxt.classList.add("pending"); + fetch(api).then(res => res.json()).then(result => weatherDetails(result)).catch(() =>{ + infoTxt.innerText = "Something went wrong"; + infoTxt.classList.replace("pending", "error"); + }); } -/*----------------------------------------------------------------------------------------*/ +function weatherDetails(info){ + if(info.cod == "404"){ + infoTxt.classList.replace("pending", "error"); + infoTxt.innerText = `${inputField.value} isn't a valid city name`; + }else{ + const city = info.name; + const country = info.sys.country; + const {description, id} = info.weather[0]; + const {temp, feels_like, humidity} = info.main; + + if(id == 800){ + wIcon.src = "icons/clear.svg"; + }else if(id >= 200 && id <= 232){ + wIcon.src = "icons/storm.svg"; + }else if(id >= 600 && id <= 622){ + wIcon.src = "icons/snow.svg"; + }else if(id >= 701 && id <= 781){ + wIcon.src = "icons/haze.svg"; + }else if(id >= 801 && id <= 804){ + wIcon.src = "icons/cloud.svg"; + }else if((id >= 500 && id <= 531) || (id >= 300 && id <= 321)){ + wIcon.src = "icons/rain.svg"; + } + + weatherPart.querySelector(".temp .numb").innerText = Math.floor(temp); + weatherPart.querySelector(".weather").innerText = description; + weatherPart.querySelector(".location span").innerText = `${city}, ${country}`; + weatherPart.querySelector(".temp .numb-2").innerText = Math.floor(feels_like); + weatherPart.querySelector(".humidity span").innerText = `${humidity}%`; + infoTxt.classList.remove("pending", "error"); + infoTxt.innerText = ""; + inputField.value = ""; + wrapper.classList.add("active"); + } +} +arrowBack.addEventListener("click", ()=>{ + wrapper.classList.remove("active"); +}); \ No newline at end of file