├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── src ├── img │ ├── back.jpg │ └── weather.gif ├── js │ ├── city-case.js │ ├── clear-input.js │ ├── convert-hour-date.js │ ├── convert-temp.js │ ├── faracast-fahrenheit.js │ ├── forecast-celsius.js │ ├── index.js │ ├── select-icon.js │ ├── show-hide.js │ ├── token.js │ └── weather-today.js ├── main.js ├── main.scss └── scss │ ├── abstracts │ ├── __abstracts-dir.scss │ ├── _fonts.scss │ ├── _mixins.scss │ └── _variables.scss │ ├── base │ ├── __base-dir.scss │ ├── _reset.scss │ └── _typography.scss │ ├── components │ ├── __components-dir.scss │ ├── _button.scss │ ├── _icons.scss │ └── _input.scss │ ├── layouts │ ├── __layouts-dir.scss │ ├── _footer.scss │ ├── _header.scss │ └── _main-navigation.scss │ └── vendor │ └── __vendors-dir.scss └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | src/js/token.js -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## 1.0.0 4 | 5 | * Initial release -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | 1. Fork it! 4 | 2. Create your feature branch: `git checkout -b my-new-feature` 5 | 3. Commit your changes: `git commit -m 'Add some feature'` 6 | 4. Push to the branch: `git push origin my-new-feature` 7 | 8 | **After your pull request is merged**, you can safely delete your branch. 9 | 10 | ### [<-- Back](https://github.com/mariorodeghiero/weather-fetch-api) 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Mário Antônio do Amaral Rodeghiero 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Weather App 2 | 3 | Repository created for study and creation app weather using ES6 - fetch API + webpack. 4 | 5 | ![Example running](src/img/weather.gif) 6 | 7 | ### Prerequisites 8 | 9 | What things you need to install the software and how to install them 10 | 11 | * node.js 12 | * NPM Package Manager 13 | * Create token in [openweather] 14 | 15 | ### Installing 16 | 17 | Clone this repository 18 | 19 | ``` 20 | git clone https://github.com/mariorodeghiero/weather-fetch-api 21 | ``` 22 | 23 | Installing the dependencies from the NPM Package Manager 24 | 25 | ``` 26 | npm install 27 | ``` 28 | 29 | To start the development environment, run the following command: 30 | 31 | ``` 32 | npm run dev 33 | ``` 34 | 35 | **Note:** This command also performs a clear in the **dist** folder and build again. 36 | 37 | ``` 38 | npm run server 39 | ``` 40 | 41 | After run, the browser open window automatically at http://localhost:8080 42 | 43 | ## Deployment 44 | 45 | Run the command below to deploy, minimizing All Files. 46 | 47 | ``` 48 | npm run prod 49 | ``` 50 | 51 | ## Contributing 52 | 53 | Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us. 54 | 55 | ## Author 56 | 57 | * [Mário Antônio do Amaral Rodeghiero](https://github.com/mariorodeghiero) 58 | 59 | ## License 60 | 61 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details 62 | 63 | [openweather]: https://openweathermap.org 64 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | webpack boiler-plate 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 | 17 | 18 |
19 | 20 |

Welcome to the 21 |
22 | Weather App 23 |

24 |
25 | 26 | 31 | 32 |
33 |
34 |
35 |
36 |
37 | 38 |
39 |
40 | 41 | 46 |
47 | 48 | 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-boilerplate-mr", 3 | "version": "1.0.0", 4 | "description": "Repository created for study and creation of a boilerplate using webpack ^ 3.x.x", 5 | "main": "app.js", 6 | "homepage": "https://github.com/mariorodeghiero/webpack-boilerplate/blob/master/README.md", 7 | "bugs": { 8 | "url": "https://github.com/mariorodeghiero/webpack-boilerplate/issues" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/mariorodeghiero/webpack-boilerplate.git" 13 | }, 14 | "scripts": { 15 | "server": "node_modules/.bin/webpack-dev-server --inline --open", 16 | "dev": "webpack --colors --progress", 17 | "prod": "NODE_ENV=production webpack" 18 | }, 19 | "keywords": [ 20 | "webpack", 21 | "webpack 3", 22 | "boiler-plate", 23 | "es6", 24 | "babel", 25 | "sass" 26 | ], 27 | "tags": [ 28 | "webpack", 29 | "boiler-plate" 30 | ], 31 | "author": { 32 | "name": "Mário Antônio do A. Rodeghiero", 33 | "email": "mario.rodeghiero@gmail.com", 34 | "homepage": "https://mariorodeghiero.com" 35 | }, 36 | "license": "MIT", 37 | "devDependencies": { 38 | "babel-preset-env": "^1.6.1", 39 | "babel-preset-es2015": "^6.24.1", 40 | "clean-webpack-plugin": "^0.1.19", 41 | "css-loader": "^0.28.11", 42 | "extract-text-webpack-plugin": "^3.0.2", 43 | "file-loader": "^1.1.11", 44 | "html-webpack-plugin": "^2.30.1", 45 | "img-loader": "^2.0.1", 46 | "node-sass": "^4.8.3", 47 | "purify-css": "^1.2.6", 48 | "purifycss-webpack": "^0.7.0", 49 | "raw-loader": "^0.5.1", 50 | "sass-loader": "^6.0.7", 51 | "style-loader": "^0.20.3", 52 | "uglifyjs-webpack-plugin": "^1.2.5", 53 | "webpack": "^3.11.0", 54 | "webpack-dev-server": "^2.11.2" 55 | }, 56 | "dependencies": { 57 | "babel-core": "^6.26.0", 58 | "babel-loader": "^7.1.4" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/img/back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mariorodeghiero/weather-fetch-api/a7f56eefceeda71b10eb5c32f6fd14082a7ee2ec/src/img/back.jpg -------------------------------------------------------------------------------- /src/img/weather.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mariorodeghiero/weather-fetch-api/a7f56eefceeda71b10eb5c32f6fd14082a7ee2ec/src/img/weather.gif -------------------------------------------------------------------------------- /src/js/city-case.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Convert the name of the city to Upercase 3 | */ 4 | 5 | function cityCase(str) { 6 | return str 7 | .split(" ") 8 | .map(word => word[0].toUpperCase() + word.substring(1)) 9 | .join(" "); 10 | } 11 | 12 | export { cityCase }; 13 | -------------------------------------------------------------------------------- /src/js/clear-input.js: -------------------------------------------------------------------------------- 1 | /** 2 | * function clear input 3 | */ 4 | 5 | function clearInput() { 6 | document.getElementById("searchForm").reset(); 7 | } 8 | 9 | export { clearInput }; 10 | -------------------------------------------------------------------------------- /src/js/convert-hour-date.js: -------------------------------------------------------------------------------- 1 | /** 2 | * function get hour and Date 3 | */ 4 | function getDateHour() { 5 | let now = new Date(); 6 | let dayName = new Array( 7 | "Sunday", 8 | "Monday", 9 | "Tuesday", 10 | "Wednesday", 11 | "Thursday", 12 | "Friday", 13 | "Saturday" 14 | ); 15 | return `${dayName[now.getDay()]} ${now.getHours()}:${getMinute(now)}`; 16 | } 17 | 18 | function getMinute(time) { 19 | let min = ("0" + time.getMinutes()).slice(-2); 20 | return min; 21 | } 22 | 23 | export { getMinute, getDateHour }; 24 | -------------------------------------------------------------------------------- /src/js/convert-temp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * convert temperature in kelvin 3 | */ 4 | function celsius(tempKelvin) { 5 | const celsius = Math.round(tempKelvin - 273.15); 6 | return celsius; 7 | } 8 | 9 | function fahrenheit(tempKelvin) { 10 | const fahrenheit = Math.round((tempKelvin - 273.15) * 1.8 + 32); 11 | return fahrenheit; 12 | } 13 | 14 | export { celsius, fahrenheit }; 15 | -------------------------------------------------------------------------------- /src/js/faracast-fahrenheit.js: -------------------------------------------------------------------------------- 1 | import { fahrenheit } from "./convert-temp"; 2 | 3 | function forecast(data) { 4 | let arrDate = []; 5 | const arrayForecast = [2, 10, 18, 26, 34]; 6 | 7 | arrayForecast.forEach(i => { 8 | let date = data.list[i].dt_txt 9 | .slice(5, 10) 10 | .split("-") 11 | .reverse() 12 | .join("/"); 13 | 14 | arrDate.push(date); 15 | }); 16 | 17 | document.querySelector("#outPutForecast").innerHTML = ` 18 |
19 |

Mim

20 |

Max

21 |
22 |
23 |

${arrDate[0]}

24 |

${fahrenheit(data.list[1].main.temp_max)}°F

25 |

${fahrenheit(data.list[1].main.temp_min)}°F

26 |
27 |
28 |

${arrDate[1]}

29 |

${fahrenheit(data.list[2].main.temp_max)}°F

30 |

${fahrenheit(data.list[2].main.temp_min)}°F

31 |
32 |
33 |

${arrDate[2]}

34 |

${fahrenheit(data.list[10].main.temp_max)}°F

35 |

${fahrenheit(data.list[10].main.temp_min)}°F

36 |
37 |
38 |

${arrDate[3]}

39 |

${fahrenheit(data.list[18].main.temp_max)}°F

40 |

${fahrenheit(data.list[18].main.temp_min)}°F

41 |
42 |
43 |

${arrDate[4]}

44 |

${fahrenheit(data.list[26].main.temp_max)}°F

45 |

${fahrenheit(data.list[26].main.temp_min)}°F

46 |
47 | `; 48 | } 49 | 50 | export { forecast }; 51 | -------------------------------------------------------------------------------- /src/js/forecast-celsius.js: -------------------------------------------------------------------------------- 1 | import { celsius } from "./convert-temp"; 2 | 3 | function forecastCelsius(data) { 4 | let arrDate = []; 5 | const arrayForecast = [2, 10, 18, 26, 34]; 6 | 7 | arrayForecast.forEach(i => { 8 | let date = data.list[i].dt_txt 9 | .slice(5, 10) 10 | .split("-") 11 | .reverse() 12 | .join("/"); 13 | 14 | arrDate.push(date); 15 | }); 16 | 17 | document.querySelector("#outPutForecast").innerHTML = ` 18 |
19 |

Mim

20 |

Max

21 |
22 |
23 |

${arrDate[0]}

24 |

${celsius(data.list[1].main.temp_max)}°C

25 |

${celsius(data.list[1].main.temp_min)}°C

26 |
27 |
28 |

${arrDate[1]}

29 |

${celsius(data.list[2].main.temp_max)}°C

30 |

${celsius(data.list[2].main.temp_min)}°C

31 |
32 |
33 |

${arrDate[2]}

34 |

${celsius(data.list[10].main.temp_max)}°C

35 |

${celsius(data.list[10].main.temp_min)}°C

36 |
37 |
38 |

${arrDate[3]}

39 |

${celsius(data.list[18].main.temp_max)}°C

40 |

${celsius(data.list[18].main.temp_min)}°C

41 |
42 |
43 |

${arrDate[4]}

44 |

${celsius(data.list[26].main.temp_max)}°C

45 |

${celsius(data.list[26].main.temp_min)}°C

46 |
47 | `; 48 | } 49 | 50 | export { forecastCelsius }; 51 | -------------------------------------------------------------------------------- /src/js/index.js: -------------------------------------------------------------------------------- 1 | import { getWeatherToday } from "./weather-today"; 2 | import { forecast } from "./faracast-fahrenheit"; 3 | import { forecastCelsius } from "./forecast-celsius"; 4 | import { clearInput } from "./clear-input"; 5 | import { appKey } from "./token"; 6 | import { showOutPut, hideOutPut } from "./show-hide"; 7 | 8 | let setTemp = document.getElementById("set-temp"); 9 | document.querySelector("#searchForm").addEventListener("submit", getWeather); 10 | 11 | function getWeather(e) { 12 | const city = document.querySelector("#cityInput").value; 13 | const url = `http://api.openweathermap.org/data/2.5/weather?q=${city}&APPID=${appKey}`; 14 | hideOutPut(); 15 | 16 | fetch(url) 17 | .then(response => response.json()) 18 | .then(data => { 19 | getWeatherToday(data); 20 | getWeatherWeek(data.name); 21 | }) 22 | .catch(err => console.log(err)); 23 | clearInput(); 24 | e.preventDefault(); 25 | } 26 | 27 | function getWeatherWeek(city) { 28 | const urlForecast = `http://api.openweathermap.org/data/2.5/forecast?q=${city}&APPID=${appKey}`; 29 | 30 | fetch(urlForecast) 31 | .then(response => response.json()) 32 | .then( 33 | data => 34 | setTemp.checked == false ? forecast(data) : forecastCelsius(data) 35 | ); 36 | setInterval(function() { 37 | showOutPut(); 38 | }, 500); 39 | } 40 | -------------------------------------------------------------------------------- /src/js/select-icon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * function select icon 3 | */ 4 | 5 | function selectIcon(code) { 6 | const N = code.replace(/\D/g, ""); 7 | const iconMap = { 8 | "01": "wi wi-day-sunny", 9 | "02": "wi wi-night-cloudy", 10 | "03": "wi wi-cloud", 11 | "04": "wi wi-cloudy", 12 | "09": "wi wi-showers", 13 | "10": "wi wi-rain", 14 | "11": "wi wi-thunderstorm", 15 | "13": "wi wi-snow-wind", 16 | "50": "wi wi-fog" 17 | }; 18 | return iconMap[N] ? iconMap[N] : "wi wi-day-sunny"; 19 | } 20 | 21 | export { selectIcon }; 22 | -------------------------------------------------------------------------------- /src/js/show-hide.js: -------------------------------------------------------------------------------- 1 | function showOutPut() { 2 | document.querySelector("#outPut").classList.remove("zoomOut"); 3 | document.querySelector("#outPut").classList.add("zoomIn"); 4 | document.getElementById("outPut").style.display = "block"; 5 | } 6 | function hideOutPut() { 7 | document.querySelector("#outPut").classList.toggle("zoomIn"); 8 | document.querySelector("#outPut").classList.add("zoomOut"); 9 | } 10 | 11 | export { showOutPut, hideOutPut }; 12 | -------------------------------------------------------------------------------- /src/js/token.js: -------------------------------------------------------------------------------- 1 | /** 2 | * token of API http://api.openweathermap.org/data/2.5 3 | */ 4 | const appKey = ""; 5 | 6 | export { appKey }; 7 | -------------------------------------------------------------------------------- /src/js/weather-today.js: -------------------------------------------------------------------------------- 1 | import { celsius, fahrenheit } from "./convert-temp"; 2 | import { getMinute, getDateHour } from "./convert-hour-date"; 3 | import { selectIcon } from "./select-icon"; 4 | import { cityCase } from "./city-case"; 5 | 6 | let icon = document.querySelector("#icon-div"); 7 | let details = document.querySelector("#details-div"); 8 | 9 | function getWeatherToday(data) { 10 | icon.innerHTML = ` 11 | 12 |

13 | ${fahrenheit(data.main.temp)}°F | 14 | ${celsius(data.main.temp)}°C 15 |

16 |
17 |

18 | Wind: ${data.wind.speed} mph 19 |
20 | Humidity: ${data.main.humidity}% 21 |

22 |
23 | `; 24 | 25 | details.innerHTML = ` 26 |

${data.name}, ${data.sys.country}

27 |
28 |
29 |

${getDateHour()}

30 |

${cityCase(data.weather[0].description)}

31 |
32 | `; 33 | } 34 | 35 | export { getWeatherToday }; 36 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import "./js/index"; 2 | import "./main.scss"; 3 | -------------------------------------------------------------------------------- /src/main.scss: -------------------------------------------------------------------------------- 1 | @import './scss/abstracts/__abstracts-dir.scss'; 2 | @import './scss/layouts/__layouts-dir.scss'; 3 | @import './scss/base/__base-dir.scss'; 4 | @import './scss/components/__components-dir.scss'; -------------------------------------------------------------------------------- /src/scss/abstracts/__abstracts-dir.scss: -------------------------------------------------------------------------------- 1 | @import "fonts"; 2 | @import "mixins"; 3 | @import "variables"; -------------------------------------------------------------------------------- /src/scss/abstracts/_fonts.scss: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Roboto:400,300,100"); 2 | -------------------------------------------------------------------------------- /src/scss/abstracts/_mixins.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mariorodeghiero/weather-fetch-api/a7f56eefceeda71b10eb5c32f6fd14082a7ee2ec/src/scss/abstracts/_mixins.scss -------------------------------------------------------------------------------- /src/scss/abstracts/_variables.scss: -------------------------------------------------------------------------------- 1 | $color-white: rgba(255, 255, 255, 1); 2 | $bck-color: rgb(21, 96, 119); 3 | $color-green: rgb(2, 218, 146); 4 | $color-blue: rgb(5, 175, 187); 5 | $bck-opacity: rgba(0, 0, 0, 0.2); 6 | $color-gray: #7b848f; 7 | $font-stack: 12px/26px Arial, sans-serif; 8 | -------------------------------------------------------------------------------- /src/scss/base/__base-dir.scss: -------------------------------------------------------------------------------- 1 | @import "reset"; 2 | @import "typography"; -------------------------------------------------------------------------------- /src/scss/base/_reset.scss: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body, 7 | html { 8 | font-size: 100%; 9 | } 10 | 11 | ol, 12 | ul { 13 | list-style: none; 14 | } 15 | 16 | blockquote, 17 | q { 18 | quotes: none; 19 | } 20 | 21 | blockquote:before, 22 | blockquote:after, 23 | q:before, 24 | q:after { 25 | content: ""; 26 | content: none; 27 | } 28 | 29 | table { 30 | border-collapse: collapse; 31 | border-spacing: 0; 32 | } 33 | 34 | h1, 35 | h2, 36 | h3, 37 | h4, 38 | p, 39 | span { 40 | font-family: "Roboto"; 41 | font-weight: 100; 42 | line-height: 1.1; 43 | letter-spacing: 0.025em; 44 | } 45 | -------------------------------------------------------------------------------- /src/scss/base/_typography.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mariorodeghiero/weather-fetch-api/a7f56eefceeda71b10eb5c32f6fd14082a7ee2ec/src/scss/base/_typography.scss -------------------------------------------------------------------------------- /src/scss/components/__components-dir.scss: -------------------------------------------------------------------------------- 1 | @import "button"; 2 | @import "input"; 3 | @import "icons"; 4 | -------------------------------------------------------------------------------- /src/scss/components/_button.scss: -------------------------------------------------------------------------------- 1 | .set-temp { 2 | width: 80px; 3 | height: 26px; 4 | background: $color-gray; 5 | margin: 20px; 6 | position: relative; 7 | float: right; 8 | border-radius: 50px; 9 | &:after { 10 | content: "°C"; 11 | color: $color-white; 12 | position: absolute; 13 | right: 20px; 14 | z-index: 0; 15 | font: $font-stack; 16 | font-weight: bold; 17 | text-shadow: 1px 1px 0px rgba(255, 255, 255, 0.15); 18 | } 19 | &:before { 20 | content: "°F "; 21 | color: $color-white; 22 | position: absolute; 23 | left: 20px; 24 | z-index: 0; 25 | font: $font-stack; 26 | font-weight: bold; 27 | } 28 | label { 29 | display: block; 30 | width: 34px; 31 | height: 20px; 32 | cursor: pointer; 33 | position: absolute; 34 | top: 3px; 35 | left: 3px; 36 | z-index: 1; 37 | background: $color-white; 38 | border-radius: 50px; 39 | transition: all 0.4s ease; 40 | box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.3); 41 | } 42 | input[type="checkbox"] { 43 | visibility: hidden; 44 | &:checked + label { 45 | left: 43px; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/scss/components/_icons.scss: -------------------------------------------------------------------------------- 1 | @import url(https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/css/weather-icons.min.css); 2 | -------------------------------------------------------------------------------- /src/scss/components/_input.scss: -------------------------------------------------------------------------------- 1 | .container-search { 2 | text-align: center; 3 | margin-bottom: 50px; 4 | input[type="text"] { 5 | border: none; 6 | width: 180px; 7 | padding: 10px; 8 | outline: 0; 9 | background-color: $bck-opacity; 10 | border-radius: 4px; 11 | color: $color-white; 12 | font-size: 0.8rem; 13 | &::-webkit-input-placeholder { 14 | color: $color-white; 15 | text-align: center; 16 | } 17 | } 18 | } 19 | 20 | .weather-info { 21 | padding: 10px; 22 | margin: 0 auto; 23 | width: 500px; 24 | height: 300px; 25 | border-radius: 5px; 26 | background-color: $bck-opacity; 27 | color: $color-white; 28 | animation-duration: 2s; 29 | display: none; 30 | .div-info { 31 | display: grid; 32 | grid-template-columns: repeat(2, 1fr); 33 | grid-auto-rows: minmax(100px, 170px); 34 | grid-gap: 10px; 35 | .icon-div { 36 | .icon { 37 | padding: 10px 10px; 38 | font-size: 4.3rem; 39 | } 40 | h2 { 41 | padding-top: 30px; 42 | font-size: 1.7rem; 43 | float: right; 44 | } 45 | h3 { 46 | margin-top: 35px; 47 | font-size: 1.2rem; 48 | text-align: right; 49 | } 50 | } 51 | .details { 52 | text-align: right; 53 | h2 { 54 | font-weight: 400; 55 | font-size: 1.7rem; 56 | padding-right: 15px; 57 | padding-top: 10px; 58 | padding-bottom: 60px; 59 | } 60 | h3 { 61 | padding-right: 15px; 62 | } 63 | } 64 | } 65 | .fore-cast { 66 | text-align: center; 67 | display: grid; 68 | grid-template-columns: repeat(6, 1fr); 69 | grid-auto-rows: minmax(100px, auto); 70 | h3 { 71 | font-weight: 300; 72 | padding-top: 60px; 73 | + h3 { 74 | padding-top: 22px; 75 | } 76 | } 77 | h4 { 78 | font-weight: 300; 79 | padding-top: 25px; 80 | } 81 | p { 82 | padding-top: 20px; 83 | + p { 84 | padding-top: 25px; 85 | } 86 | } 87 | .box { 88 | border-right: 1px solid rgb(195, 228, 228); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/scss/layouts/__layouts-dir.scss: -------------------------------------------------------------------------------- 1 | @import "header"; 2 | @import "footer"; 3 | @import "main-navigation"; -------------------------------------------------------------------------------- /src/scss/layouts/_footer.scss: -------------------------------------------------------------------------------- 1 | .footer { 2 | position: absolute; 3 | bottom: 0; 4 | width: 100%; 5 | p { 6 | color: $color-white; 7 | padding: 10px; 8 | text-align: center; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/scss/layouts/_header.scss: -------------------------------------------------------------------------------- 1 | h1 { 2 | color: $color-white; 3 | padding-top: 70px; 4 | padding-bottom: 20px; 5 | line-height: 1.6em; 6 | span { 7 | font-weight: 300; 8 | color: $color-blue; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/scss/layouts/_main-navigation.scss: -------------------------------------------------------------------------------- 1 | .main { 2 | background: url("/src/img/back.jpg") no-repeat bottom center scroll; 3 | background-size: cover; 4 | width: 100%; 5 | height: 100vh; 6 | position: absolute; 7 | } 8 | 9 | .welcome { 10 | text-align: center; 11 | } 12 | -------------------------------------------------------------------------------- /src/scss/vendor/__vendors-dir.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mariorodeghiero/weather-fetch-api/a7f56eefceeda71b10eb5c32f6fd14082a7ee2ec/src/scss/vendor/__vendors-dir.scss -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var ExtractTextPlugin = require("extract-text-webpack-plugin"); 3 | var path = require("path"); 4 | var UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 5 | var glob = require('glob'); 6 | let PurifyCSSPlugin = require('purifycss-webpack'); 7 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 8 | var CleanWebpackPlugin = require('clean-webpack-plugin') 9 | 10 | 11 | var inProduction = (process.env.NODE_ENV === 'production'); 12 | 13 | var HWPConfig = new HtmlWebpackPlugin({ 14 | template: __dirname + "/index.html", 15 | file: "index.html", 16 | inject: "body" 17 | }); 18 | 19 | module.exports = { 20 | entry: { 21 | app: [ 22 | './src/main.js', 23 | './src/main.scss' 24 | ] 25 | }, 26 | output: { 27 | path: path.resolve(__dirname, './dist'), 28 | filename: '[name].[chunkhash].js' 29 | }, 30 | module: { 31 | rules: [{ 32 | test: /\.s[ac]ss$/, 33 | use: ExtractTextPlugin.extract({ 34 | use: ['css-loader', 'sass-loader'], 35 | fallback: 'style-loader' 36 | }) 37 | }, 38 | { 39 | test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/, 40 | loader: 'file-loader', 41 | options: { 42 | name: 'img/[name].[hash].[ext]' 43 | } 44 | }, 45 | { 46 | test: /\.js$/, 47 | exclude: /node_modules/, 48 | loader: "babel-loader", 49 | query: { 50 | presets: [ 51 | ["es2015", { 52 | modules: false 53 | }] 54 | ] 55 | } 56 | }, 57 | ] 58 | }, 59 | plugins: [ 60 | HWPConfig, 61 | new CleanWebpackPlugin(['dist'], { 62 | root: __dirname, 63 | verbose: true, 64 | dry: false 65 | }), 66 | new ExtractTextPlugin('[name].css'), 67 | new PurifyCSSPlugin({ 68 | paths: glob.sync(path.join(__dirname, 'index.html')), 69 | minimize: inProduction 70 | }), 71 | 72 | new webpack.LoaderOptionsPlugin({ 73 | minimize: inProduction 74 | }), 75 | ] 76 | }; 77 | 78 | if (inProduction) { 79 | module.exports.plugins.push( 80 | new UglifyJsPlugin({ 81 | uglifyOptions: { 82 | compress: { 83 | warnings: false 84 | }, 85 | output: { 86 | comments: false 87 | }, 88 | sourceMap: true 89 | } 90 | }) 91 | ) 92 | } --------------------------------------------------------------------------------