Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panthers--Maggie T #92

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
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
38 changes: 35 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,41 @@
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Weather Report</title>
<link rel="stylesheet" href = "styles/index.css">
<script src="node_modules/axios/dist/axios.min.js"></script>
<script defer src="src/index.js"></script>

</head>
<body>

</body>
</html>
<div class="card">
<h1>Weather for <span id="city"></span></h1>
<div>
<input id="cityInput" type="text" size="30" placeholder="Enter city" />
<button id="citySearch">Search</button>
<button id="cityReset">Reset</button>
</div>

<h4>Temperature is <span id="temperature"></span>º F</h4>
<div>
<button id="decreaseTemp">-</button>
<button id="increaseTemp">+</button>
</div>
</div>

<div class = "landscapeSky">
<h4>Landscape is <span id="landscape"></span></h4>

<h4>Sky is <span id="sky"></span></h4>
<div>
<select id="skyInput">
<option value="sunny">Sunny</option>
<option value="cloudy">Cloudy</option>
<option value="rainy">Rainy</option>
<option value="snowy">Snowy</option>
</select>
Comment on lines +15 to +40

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Markup looks great!

</div>
</div>
</body>
</html>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"dependencies": {
"axios": "^0.27.2"
"axios": "^1.2.1"
}
}
175 changes: 175 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
//application states
const state = {
sky: 'sunny',
temperature: 0,
city: '',
};
Comment on lines +2 to +6

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having a hard coded default sky state, how might you refactor this so the logic is more data driven? The sky should really be displayed based on the call to the api

const temperatureChangeStep = 1;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer += temp or -= temp here 😁


//references to all elements on the page
const elTemperature = document.querySelector('#temperature');
const elIncreaseTemp = document.querySelector('#increaseTemp');
const elDecreaseTemp = document.querySelector('#decreaseTemp');
const elLandscape = document.querySelector('#landscape');
const elCity = document.querySelector('#city');
const elCityInput = document.querySelector('#cityInput');
const elCityReset = document.querySelector('#cityReset');
const elCitySearch = document.querySelector('#citySearch');
const elSky = document.querySelector('#sky');
const elSkyInput = document.querySelector('#skyInput');

//event handlers to intercept user interactions
elSkyInput.addEventListener('change', (event) => {
setSky(event.target.value);
});

elCityInput.addEventListener('input', (event) => {
setCity(event.target.value);
});

elCityReset.addEventListener('click', (event) => {
setCity('');
elCityInput.focus();
});
Comment on lines +30 to +33
Copy link

@ameerrah9 ameerrah9 Jan 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an issue with wave 06 (resetting the city name), the requirements specify that you must include a button that resets the city name & when a user clicks on this button, the city name will be set to a default name along with the temperature for that city. Currently your code is not displaying the city name when you reset the city.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you reset the city it should be updated to a selected city instead of an empty string like so:

cityNameInput.value = 'Seattle';


elCitySearch.addEventListener('click', (event) => {
searchCityWeather(state.city);
});

elIncreaseTemp.addEventListener('click', (event) => {
increaseTemp(event.target.value);
});

elDecreaseTemp.addEventListener('click', (event) => {
decreaseTemp(event.target.value);
});

//functions to render state to the screen
const renderSky = () => {
const sky = state.sky;
let skyScape = 'unknown';

if (sky === 'sunny') skyScape = '☀️';
else if (sky === 'cloudy') skyScape = '☁️';
else if (sky === 'rainy') skyScape = '🌧';
else if (sky === 'snowy') skyScape = '🌨';

elSky.innerText = skyScape;
};

const renderTemperature = () => {
elTemperature.innerText = state.temperature;

const temp = state.temperature;
let color = 'teal';
let landscape = '❄️❄️❄️❄️❄️';

if (temp >= 80) {
color = 'red';
landscape = '🔥🔥🔥🔥🔥';
} else if (temp >= 70) {
color = 'orange';
landscape = '😊😊😊😊😊';
} else if (temp >= 60) {
color = 'yellow';
landscape = '🌷🌷🌷🌷🌷';
} else if (temp >= 50) {
color = 'green';
landscape = '🐿🐿🐿🐿🐿';
}

elTemperature.style.color = color;
elLandscape.innerText = landscape;
};

const renderCity = () => {
elCity.innerText = state.city;
elCityInput.value = state.city;
};

//setters for changing state and calling respective render functions
const setSky = (value) => {
state.sky = value;
renderSky();
};

const setTemperature = (value) => {
state.temperature = value;
renderTemperature();
};

const setCity = (value) => {
state.city = value;
renderCity();
};

//functions to run user actions
const increaseTemp = () => {
setTemperature(state.temperature + temperatureChangeStep);
};

const decreaseTemp = () => {
setTemperature(state.temperature - temperatureChangeStep);
};

const kelvinToFarenheit = (k) => 1.8 * (k - 273) + 32;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏾


const searchCityWeather = (city) => {
console.log('searchCityWeather()', city);

//disable buttons to prevent multiple requests
elCitySearch.disabled = true;
elCityReset.disabled = true;

return fetchCityLatLong(city)
.then(fetchLatLongTemperature)
.then((temperature) => setTemperature(temperature))
.catch(console.error)
.finally(() => {
elCitySearch.disabled = false;
elCityReset.disabled = false;
});
};

//use the city to get lat/long
const fetchCityLatLong = (city) => {
console.log('fetchCityLatLong()', city);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remember to remove debugging log statements

const url = `http://127.0.0.1:5000/location?q=${city}`;

return axios.get(url).then((response) => {
const { data } = response;
const firstResult = data[0];
return {
lat: firstResult.lat,
lon: firstResult.lon,
};
});
};

// use lat/lon coordinates to get temperature
const fetchLatLongTemperature = (latLong) => {
const { lat, lon } = latLong;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

console.log('fetchLatLongTemperature()', lat, lon);

const url = `http://127.0.0.1:5000/weather?lat=${lat}&lon=${lon}`;
return axios.get(url).then((response) => {
const { data } = response;
const tempK = data.main.temp;
const tempF = kelvinToFarenheit(tempK);
const tempRounded = Math.round(tempF);
console.log({ tempRounded, tempK, tempF });

return tempRounded;
});
};

//initialization - render all state first
renderCity();
renderTemperature();
renderSky();

//run initial search and show a temperature
setCity('Denver');
searchCityWeather('Denver');

Comment on lines +166 to +174

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since your script file is included at the end of the HTML file, it's probably fine to invoke this directly. But prefer to register it to be called in response to the DOMContentLoaded event. In the similar live code we did, we did call our onLoaded function directly, since codesandbox got in the way of our code being able to see the DOMContentLoaded event.

// setTemperature(60)
123 changes: 123 additions & 0 deletions styles/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@

body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 30px;
background-color: rgb(136, 55, 211);
font-size: 120%;
flex-direction: column;
}
Comment on lines +2 to +11

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest adding media queries to account for all types of screen sizes


.card {
background-color: gray;
padding: 2em;
border-radius: 30px;
width: 100%;
height: 80%;
max-width: 420px;
margin: .5em;
font-family: 'Roboto Mono', monospace;
margin-top: 4em;
border: 1px solid purple;
}

button {
border-radius: 50%;
margin: .5em 1em;
height: 56px;
width: 55px;
border: 1px solid purple;
transition: 0.2s ease-in-out;
cursor: pointer;
font-size: 12px;
font-weight: 800;
}

button:hover {
background:rgb(214, 208, 202);
}

#cityInput {
border: 1px solid purple;
border-radius: 24px;
background-color: rgb(214, 208, 202);
color: black;
font-size: 105%;
font-family: inherit;
padding: 0.4em 1em;
width: 180px;
height: 24px;
}

#skyInput {
margin: 0;
width: calc(100% - 200px);
font-size: 105%;
border: 1px solid purple;
background-color: antiquewhite;
color: black;
font-family: inherit;
padding: 1.5em 1em;
float: left;

}

#decreaseTemp{
font-size: 36px;
font-weight: 600;
}
#increaseTemp {
font-size: 28px;
font-weight: 600;
}

Comment on lines +54 to +75

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing work with styling 👍🏾


.landscapeSky{
background-color: gray;
padding: 2em;
border-radius: 30px;
width: 100%;
max-width: 420px;
margin: .5em;
margin-bottom: 4em;
font-family: 'Roboto Mono', monospace;
font-size: 24px;
border: 1px solid purple;

}

h4 {
font-size: 30px;
font-family: 'Roboto Mono', monospace;
}

h1 {
font-size: 48px;
font-family: 'Roboto Mono', monospace;
}

.red {
color: red;
}

.orange {
color: orange;
}

.yellow {
color: gold;
}

.yellow-green {
color: yellowgreen;
}

.green {
color: green;
}

.teal {
color: teal;
}
24 changes: 15 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ asynckit@^0.4.0:
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==

axios@^0.27.2:
version "0.27.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
axios@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.2.1.tgz#44cf04a3c9f0c2252ebd85975361c026cb9f864a"
integrity sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==
dependencies:
follow-redirects "^1.14.9"
follow-redirects "^1.15.0"
form-data "^4.0.0"
proxy-from-env "^1.1.0"

combined-stream@^1.0.8:
version "1.0.8"
Expand All @@ -27,10 +28,10 @@ delayed-stream@~1.0.0:
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=

follow-redirects@^1.14.9:
version "1.15.0"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.0.tgz#06441868281c86d0dda4ad8bdaead2d02dca89d4"
integrity sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==
follow-redirects@^1.15.0:
version "1.15.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==

form-data@^4.0.0:
version "4.0.0"
Expand All @@ -52,3 +53,8 @@ mime-types@^2.1.12:
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"

proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==