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

Huma H./Sharks/C17 #86

Open
wants to merge 5 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
Binary file added assets/autumn.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/desert.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/summer.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/winter.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 45 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,52 @@
<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">
</head>
<body>


<header>
<h1>WEATHER REPORT</h1>
<section>
<div id="skyscape">☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️</div>
<div id="landscape">🌸🌿🌼__🌷🌻🌿_☘️🌱_🌻🌷</div>
</section>
<section>
<div>
<label>Sky</label>
<select id="skyDropdown">
<option value="sunny">Sunny</option>
<option value="cloudy">Cloudy</option>
<option value="rainy">Rainy</option>
<option value="snowy">Snowy</option>
</select>
</div>
<div>
<h2>City</h2>
<input type="text" id="inputCity" value="Orlando">
<button type= "reset" value="Reset" id="cityReset" class="cityNameResetBtn">Reset</button>
</div>
</section>
</header>

<main class="weather-container">
<section>
<h1>For the lovely city of</h1>
</section>
<section>
<h1 id="outputCity">Orlando</h1>
<button id="realTimeTemp">Get Real Temp</button>
</section>
<section>
<button id="upTemp">⬆</button>
<h1><span id="tempValue">75</span>°</h1>
<button id="downTemp">⬇</button>
</section>

<section>
</section>
</main>
<script src="src/index.js"></script>
<script src="./node_modules/axios/dist/axios.min.js"></script>

Choose a reason for hiding this comment

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

Clearly written, semantic HTML 👍

</body>
</html>
237 changes: 237 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
'use strict';

const state = {
tempValue: 75,
color: 'orange',
landscape: '🌸🌿🌼__🌷🌻🌿_☘️🌱_🌻🌷',
skyscape: '',
background: "url('../assets/summer.jpg')",
city: 'Orlando',
lat: '',
lon: '',
Comment on lines +10 to +11

Choose a reason for hiding this comment

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

You could also hard code the lat/lon for Orlando here instead of setting them to empty strings

};

// API calls
const getLatLon = () => {
const inputCityElement = document.getElementById('inputCity').value;
axios
.get('http://127.0.0.1:5000/location', { params: { q: state.city } })

Choose a reason for hiding this comment

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

Consider using a constant variable like LOCATION_URL instead of string literal here.

"Constants free the programmer from having to remember what each literal should be. Often values that stay constant throughout the program have a business meaning. If there are several such values, the programmer can define them all in the beginning of the program and then work with the easier-to-remember constant names." From: https://www.diffen.com/difference/Constant_vs_Literal

.then((response) => {
state.lat = response.data[0].lat;
state.lon = response.data[0].lon;
console.log(state.lat);
console.log(state.lon);
Comment on lines +22 to +23

Choose a reason for hiding this comment

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

Remove debugging print statements when you're done with them

getRealTemp();
})
.catch((error) => {
console.log('Error!', error);
});
};

const getRealTemp = () => {
console.log(state.lat);
console.log(state.lon);
Comment on lines +32 to +33

Choose a reason for hiding this comment

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

Can remove these

axios
.get('http://127.0.0.1:5000/weather', {
params: {
lat: state.lat,
lon: state.lon,
},
})
.then((response) => {
console.log(response);
// const tempValueK = response.data.current.temp;

Choose a reason for hiding this comment

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

Remove unused commented out code

const tempValueK = response.data.current.temp;
const tempValueF = ((tempValueK - 273.15) * 9) / 5 + 32;

Choose a reason for hiding this comment

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

Even though this is a pretty short piece of code, it would be nice if it was in a helper method so which would help with readability.

You could even put lines 44-50 into a helper method, something like formatRealTemp and that helper method would call your other hypothetical helper called convertKelvinToFarenheit

const tempF = Math.floor(tempValueF);
state.tempF = tempF;
displayRealTemp(tempF);
landscapeChangeAction();
tempValueColorAction();
})
.catch((error) => {
console.log('Error!', error);
});
};

const displayRealTemp = (tempF) => {
const tempValueElement = document.getElementById('tempValue');
// tempValueElement.textContent = state.tempF;

Choose a reason for hiding this comment

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

Remove unused commented out code to avoid introducing bugs if it accidentally gets uncommented

tempValueElement.textContent = tempF;
};

// Function to increase temp Value by clicking up arrow
const incTempAction = () => {
state.tempValue += 1;
const tempDigit = document.getElementById('tempValue');
tempDigit.textContent = state.tempValue;
tempValueColorAction();
landscapeChangeAction();
};

// Function to decrease temp Value by clicking up arrow
const decTempAction = () => {
state.tempValue -= 1;
const tempDigit = document.getElementById('tempValue');
tempDigit.textContent = state.tempValue;
tempValueColorAction();
landscapeChangeAction();
Comment on lines +75 to +78

Choose a reason for hiding this comment

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

Notice how lines 75-78 are the same as lines 66-69. You can put this logic into a helper method and call it in inc/decTempAction methods

};

// Function to change color of temp value according to temp range
const tempValueColorAction = () => {
console.log('tempValueColor being called');
// document.getElementById('tempValue').style.color = 'orange';
// state.color = 'orange';
const tempColorElement = document.getElementById('tempValue');
// tempColorElement.style.color = 'orange';
// tempColorElement.className = color;
Comment on lines +84 to +88

Choose a reason for hiding this comment

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

Remove unused code

if (state.tempValue <= 49) {
tempColorElement.style.color = 'teal';
} else if (50 <= state.tempValue && state.tempValue <= 59) {
tempColorElement.style.color = 'green';
} else if (60 <= state.tempValue && state.tempValue <= 69) {
tempColorElement.style.color = 'yellow';
} else if (70 <= state.tempValue && state.tempValue <= 79) {
tempColorElement.style.color = 'orange';
} else {
tempColorElement.style.color = 'red';
}
};

// Function to change landscape of temp value according to temp range
const landscapeChangeAction = () => {

Choose a reason for hiding this comment

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

Very minor callout - You've been following convention where you name a method with verb+noun like updateSkyAction. Here you could do the same to indicate what the method does changeLandscapeAction

const landscapeElement = document.getElementById('landscape');
landscapeElement.textContent = state.landscape;

if (state.tempValue <= 59) {
landscapeElement.textContent = '🌲🌲⛄️🌲⛄️🍂🌲🍁🌲🌲⛄️🍂🌲';
state.background = "url('../assets/winter.jpg')";
document.querySelector('html').style.backgroundImage =

Choose a reason for hiding this comment

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

Instead of accessing document.querySelector('html').style.backgroundImage in each if/elif block, you could create a variable on line 106:

const htmlElement = document.querySelector('html').style.backgroundImage;

Then you could use htmlElement in each block instead of the long statement

"url('../assets/winter.jpg')";
} else if (60 <= state.tempValue && state.tempValue <= 69) {
landscapeElement.textContent = '🌾🌾_🍃_🪨__🛤_🌾🌾🌾_🍃';
state.background = "url('../assets/autumn.jpg')";
document.querySelector('html').style.backgroundImage =
"url('../assets/autumn.jpg')";
} else if (70 <= state.tempValue && state.tempValue <= 79) {
landscapeElement.textContent = '🌸🌿🌼__🌷🌻🌿_☘️🌱_🌻🌷';
state.background = "url('../assets/summer.jpg')";
document.querySelector('html').style.backgroundImage =
"url('../assets/summer.jpg')";
} else if (80 <= state.tempValue) {
landscapeElement.textContent = '🌵__🐍_🦂_🌵🌵__🐍_🏜_🦂';
// state.background = url('../assets/desert.jpg');
document.querySelector('html').style.backgroundImage =
"url('../assets/desert.jpg')";
// document.html.style.backgroundImage = "url('../assets/desert.jpg')";
}
Comment on lines +107 to +128

Choose a reason for hiding this comment

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

Check out the logic here, see how similar the branches are of the conditional statement. We look for whether the temperature is within a range, and pick a color accordingly. What if we had a list of objects that we could iterate through to find the values. We could set up something like

const TEMP_LANDSCAPE = [ 
  { upperBound: 59, landscape: '🌲🌲⛄️🌲⛄️🍂🌲🍁🌲🌲⛄️🍂🌲', background: 'url('../assets/winter.jpg')'}, 
  { upperBound: 69, landscape: '🌾🌾_🍃_🪨__🛤_🌾🌾🌾_🍃', background: 'url('../assets/autumn.jpg')'} 
];

Then your method would iterate through TEMP_LANDSCAPE and find the first record that has an upper bound higher than our temperature, then use it as the source of picking the landscape which would help make the function a bit more concise.

This could accommodate a scenario where you might have even more landscapes in the future, which would prevent your conditional statement from being a really long block of if/elif/elif and so on

};

const updateSkyAction = () => {
const skyscapeElement = document.getElementById('skyscape');
const skyDropdownElement = document.getElementById('skyDropdown');
if (skyDropdownElement.value === 'sunny') {
state.skyscape = '☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️';
skyscapeElement.textContent = state.skyscape;
} else if (skyDropdownElement.value === 'cloudy') {
state.skyscape = '☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️🌦☁️☁️☁️☁️☁️☁️☁️☁️☁️';
skyscapeElement.textContent = state.skyscape;
} else if (skyDropdownElement.value === 'rainy') {
state.skyscape = '🌧🌈⛈🌧💧🌧🌦🌧💧🌧⛈🌈🌧';
skyscapeElement.textContent = state.skyscape;
} else {
state.skyscape = '🌨❄️🌨🌨❄️❄️🌨❄️❄️🌨❄️❄️🌨🌨❄️🌨';
skyscapeElement.textContent = state.skyscape;
Comment on lines +134 to +145

Choose a reason for hiding this comment

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

Similar to my comment in landscapeChangeAction you could create a constant list of objects SKYSCAPE and iterate over it to select the right emojis for the sky.

SKYSCAPE = [
{sky: 'sunny', skyscape: '☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️'}
]

}
// skyscapeElement.textContent = state.skyscape;
// skyscapeElement === state.skyscape.textContent;
};

// result.textContent = `${updateSkyAction.target.value}`;
// state.skyscape = `${updateSkyAction.target.value}`;
// `string interpolation
// ${} this will get value
// Function to display city letter by letter as inputting
Comment on lines +147 to +155

Choose a reason for hiding this comment

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

Remove


function updateOutputCity(event) {
const outputCityElement = document.getElementById('outputCity');
// state.city = event.target.value;
state.city = document.getElementById('inputCity').value;
outputCityElement.textContent = state.city;
}

// Function to reset the output city by clicking reset button
// const resetCityAction = () => {
// // const cityResetElement = document.getElementById('cityReset');
// const inputCityElement = document.getElementById('inputCity');
// inputCityElement.value = 'Orlando';

// const outputCityElement = document.getElementById('outputCity');
// outputCityElement.textContent = 'Orlando';
// state.city = 'Orlando';
// };

const resetCityAction = () => {
state.city = 'Orlando';
const inputCityElement = document.getElementById('inputCity');
inputCityElement.value = state.city;
updateOutputCity();
getLatLon();
};

const registerEventHandler = () => {
// event listener for clicking up arrow
const upTempElement = document.getElementById('upTemp');
upTempElement.addEventListener('click', incTempAction);

// event listener for clicking down arrow
const downTempElement = document.getElementById('downTemp');
downTempElement.addEventListener('click', decTempAction);

// event listener for dropdown so sky can change
const skyDropdownElement = document.getElementById('skyDropdown');
skyDropdownElement.addEventListener('change', updateSkyAction);

// event listener for inputting city so can display city
const inputCityElement = document.querySelector('input');
const outputCityElement = document.getElementById('outputCity');
inputCityElement.addEventListener('input', updateOutputCity);
inputCityElement.addEventListener('change', getLatLon);

// event listener for clicking city reset button
const cityResetElement = document.getElementById('cityReset');
cityResetElement.addEventListener('click', resetCityAction);

const realTimeTempElement = document.getElementById('realTimeTemp');
realTimeTempElement.addEventListener('click', getRealTemp);
};

document.addEventListener('DOMContentLoaded', registerEventHandler);

/* <label>Choose an ice cream flavor:
<select class="ice-cream" name="ice-cream">
<option value="">Select One …</option>
<option value="chocolate">Chocolate</option>
<option value="sardine">Sardine</option>
<option value="vanilla">Vanilla</option>
</select>
</label>

<div class="result"></div>

JavaScript
const selectElement = document.querySelector('.ice-cream');

selectElement.addEventListener('change', (event) => {
const result = document.querySelector('.result');
result.textContent = `You like ${event.target.value}`;
}); */

// const arrowEx = () => {
// // state.arrow += "⬆"
// const upTempElement = document.getElementById('upTemp');
// upTempElement.textContent += '⬆';
// };

// upTempElement.addEventListener('click', arrowEx);
Comment on lines +212 to +237

Choose a reason for hiding this comment

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

Be sure to clean up your code to remove comments/print statements, which makes your code more readable.

51 changes: 51 additions & 0 deletions styles/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
html {
font-family: Palatino, Verdana;
background-image: url('../assets/summer.jpg');
/* background-position: center; */
background-repeat: no-repeat;
background-size: cover;
}

header {
display: grid;
height: 10vh;
grid-template-columns: 1fr 1fr 1fr;
align-items: center;
justify-items: center;
color: #040110;
background-color: rgba(191, 191, 191, 0.217);
}

main {
/* grid-column: 1/3; */
/* grid-column-start: 2;
grid-column-end: 3; */
text-align: center;
position: absolute;
left: 30%;
border-radius: 5%;
padding: 2% 2% 2% 2%;
width: 40%;
align-self: center;
background-color: rgba(191, 191, 191, 0.476);
/* border-radius: 5px; */
box-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px;
}

/* .teal {
color: teal;
}
.green {
color: green;
}
.yellow {
color: yellow;
}

.red {
color: red;
} */

#tempValue {
color: orange;
}