Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"liveServer.settings.port": 5501
}
11 changes: 0 additions & 11 deletions index.html

This file was deleted.

152 changes: 152 additions & 0 deletions weather.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
@import url('https://fonts.googleapis.com/css?family=Google+Sans&display=swap');
body {
font-family: 'Google Sans', arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
text-align: center;
}
img {
width: 50px;
height: 50px;
}
#weather-data {
display: grid;
grid-template-areas:
"location . . . . . degree-div"
"week week week week week week week";
}
#location {
grid-area: location;
color: #b5b5b5;
}
#degree-div,
.degree-div {
grid-area: degree-div;
color: black;
display: grid;
grid-template-areas:
"degree degree-type"
"degree .";
width: 90px;
}
#week {
grid-area: week;
display: grid;
grid-template-areas: "day1 day2 day3 day4 day5 day6 day7";
}
#degree,
.degree {
grid-area: degree
}
#degree-type,
.degree-type {
grid-area: degree-type;
}
.min {
color: #b5b5b5;
}
.day-name {
grid-area: day-name;
}
.icon {
grid-area: icon;
}
.minmax {
display: flex;
grid-area: minmax;
justify-content: center;
}
#day1 {
grid-area: day1;
grid-template-areas:
"day-name"
"icon"
"minmax";
}
#day2 {
grid-area: day2;
grid-template-areas:
"day-name"
"icon"
"minmax";
}
#day3 {
grid-area: day3;
grid-template-areas:
"day-name"
"icon"
"minmax";
}
#day4 {
grid-area: day4;
grid-template-areas:
"day-name"
"icon"
"minmax";
}
#day5 {
grid-area: day5;
grid-template-areas:
"day-name"
"icon"
"minmax";
}
#day6 {
grid-area: day6;
grid-template-areas:
"day-name"
"icon"
"minmax";
}
#day7 {
grid-area: day7;
grid-template-areas:
"day-name"
"icon"
"minmax";
}
@media (max-width: 675px) {
#weather-data {
display: grid;
grid-template-areas:
"location . degree-div"
"week week";
}
#week {
grid-area: week;
display: grid;
grid-template-areas:
"day1 day2 day3 day4"
"day5 day6 day7 .";
}
}
@media (max-width: 450px) {
#week {
grid-area: week;
display: grid;
grid-template-areas:
"day1 day2"
"day3 day4"
"day5 day6"
"day7 .";
}
}
@media (max-width: 250px) {
#weather-data {
display: grid;
grid-template-areas:
"location"
"degree-div"
"week";
}
#week {
grid-area: week;
display: grid;
grid-template-areas:
"day1"
"day2"
"day3"
"day4"
"day5"
"day6"
"day7";
}
}
15 changes: 15 additions & 0 deletions weather.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather</title>
<link rel="stylesheet" href="weather.css">
</head>
<body>
<h1 id="title"></h1>
<div id="weather-data"></div>
<script src='config.js'></script>
<script src="weather.js"></script>
</body>
</html>
97 changes: 97 additions & 0 deletions weather.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// gets user coordinates from navigator.geolocation
// uses coordinates to get weather for that location
// if user does not share location, asks user for zipcode
// uses zipcode data to get coordinates
// uses coordinates to get weather for that location

const div = document.getElementById('weather-data');
const title = document.getElementById('title');
let longitude = 0.0;
let latitude = 0.0;
function getZip() {
const zipcode = prompt("What's your zipcode? ");
const zipData = new XMLHttpRequest();
zipData.onreadystatechange = () => {
if (zipData.readyState === 4 && zipData.status === 200) {
const locationData = JSON.parse(zipData.responseText);
const city = locationData.places[0][ 'place name' ];
const state = locationData.places[0][ 'state abbreviation' ];
div.innerHTML = `<h3 id="location">${city}, ${state}</h3>`;
title.textContent = `Weather for ${city}`;
longitude = parseFloat(locationData.places[0].longitude);
latitude = parseFloat(locationData.places[0].latitude);
getWeather(latitude, longitude);
}
}
zipData.open('GET', `https://api.zippopotam.us/us/${zipcode}`);
zipData.send();
}
function success(pos){
const latitude = pos.coords.latitude;
const longitude = pos.coords.longitude;
const key = config.geo_key;
fetch(`https://api.opencagedata.com/geocode/v1/json?q=${latitude}+${longitude}&key=${geo_key}`)
.then(response => response.json())
.then(data => {
title.textContent = `Weather for ${data.results[0].components.city}`;
div.innerHTML = `<h3 id="location">${data.results[0].components.city}, ${data.results[0].components.state_code}</h3>`;
});
getWeather(latitude, longitude);
}
function getWeather(latitude, longitude) {
weatherDataLong.open('GET', `http://www.7timer.info/bin/api.pl?lon=${longitude}&lat=${latitude}&product=civil&output=json`);
weatherDataLong.send();
weatherDataSimple.open('GET', `http://www.7timer.info/bin/api.pl?lon=${longitude}&lat=${latitude}&product=civillight&output=json`);
weatherDataSimple.send();
}

navigator.geolocation.getCurrentPosition(success, getZip);

const weatherDataSimple = new XMLHttpRequest();
weatherDataSimple.onreadystatechange = () => {
if (weatherDataSimple.readyState === 4 && weatherDataSimple.status === 200) {
const meteoData = JSON.parse(weatherDataSimple.responseText);
const min = meteoData[ 'dataseries' ][0][ 'temp2m' ][ 'min' ] * 9 / 5 + 32;
const max = meteoData[ 'dataseries' ][0][ 'temp2m' ][ 'max' ] * 9 / 5 + 32;
let forecast = ``;
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
for (let i=0; i<meteoData[ 'dataseries' ].length; i++) { //need a way to determine name of the day
let date = `${meteoData[ 'dataseries' ][i][ 'date' ]}`;
let day = date.replace(/(\d{4})(\d{2})(\d{2})/g, '$1-$2-$3');
day = new Date(day); //for some reason the date obj is giving the day before
day = day.getDay();
if (day < 6) day = days[day+1]; //this is to fix the issue w/ the date obj
else day = days[0]; // but if the date obj works as it shoudl, will be wrong

let icon = meteoData[ 'dataseries' ][i][ 'weather' ];
icon == 'clear' ? icon = `<img src="https://ssl.gstatic.com/onebox/weather/64/sunny.png">`
: icon == 'lightsnow' ? icon = `<img src="https://ssl.gstatic.com/onebox/weather/48/snow_light.png">`
: icon == 'snow' ? icon = `<img src="https://ssl.gstatic.com/onebox/weather/48/snow.png">`
: icon == 'rain' ? icon = `<img src="https://ssl.gstatic.com/onebox/weather/48/rain.png">`
: icon == 'lightrain' ? icon = `<img src="https://ssl.gstatic.com/onebox/weather/48/rain_light.png">`
: icon == 'thunderstorm' ? icon = `<img src="https://ssl.gstatic.com/onebox/weather/48/thunderstorms.png">`
: icon == 'foggy' ? icon = `<img src="https://ssl.gstatic.com/onebox/weather/48/fog.png">`
: icon == 'windy' ? icon = `<img src="https://ssl.gstatic.com/onebox/weather/48/windy.png">`
: icon == 'partlycloudy' ? icon = `<img src="https://ssl.gstatic.com/onebox/weather/48/partly_cloudy.png">`
: icon = `<img src="https://ssl.gstatic.com/onebox/weather/48/cloudy.png">`; //else cloudy
console.log(`http://www.7timer.info/bin/api.pl?lon=${longitude}&lat=${latitude}&product=civillight&output=json`);
forecast += `<div id="day${i+1}" class="day">
<div class="day-name">${day}</div>
<div class="icon">${icon}</div>
<div class="minmax">
<h4 class="max">${parseFloat(max.toFixed(2))}°</h4> <h4 class="min">${parseFloat(min.toFixed(2))}°</h4>
</div></div>`;
}
div.innerHTML += `<div id="week">${forecast}</div>`;
}
}

const weatherDataLong = new XMLHttpRequest();
weatherDataLong.onreadystatechange = () => {
if (weatherDataLong.readyState === 4 && weatherDataLong.status === 200) {
const meteoData = JSON.parse(weatherDataLong.responseText);
const current = meteoData[ 'dataseries' ][0][ 'temp2m' ] * 9 / 5 + 32; //current temp -- temp2m is not the surface temp, cannot find surface temp in data
div.innerHTML += `<div class="degree-div"><h1 class="degree">${current}</h1><h4 class="degree-type">°F</h4></div>`;
}
}