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

C22 - Sarah K Charday N #16

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
af31a9e
Added basic templates for index.html and index.css.
svankoch Dec 2, 2024
a742dcc
Implemented temperature control with dynamic color updates on page lo…
svankoch Dec 2, 2024
68a08fa
Refactored temperature control logic and landscape updates. Merged te…
svankoch Dec 3, 2024
f7056da
Added functionality to update city name header when user enters text …
svankoch Dec 3, 2024
62a4404
Added event listener for button click to get realtime temperature.
svankoch Dec 3, 2024
ffbfa2a
Created wave4 branch. Added placeholders (currently commented out) fo…
svankoch Dec 3, 2024
0ce9168
Removed placeholder in HTML file for tempValue. Added axios for proxy…
svankoch Dec 4, 2024
0188cfd
Meets Wave 4 Requirements. Refactored temperature handling, error log…
svankoch Dec 4, 2024
fdc638b
Added sky options to Index HTML file.
svankoch Dec 4, 2024
7a88bd9
Meets Wave 5 requirements. Added SKIES constant for sky visualization…
svankoch Dec 4, 2024
b4f09f6
Added reset button functionality to set city name and city name text …
svankoch Dec 4, 2024
65f5540
Refactored access on all DOM elements through the 'elements' object f…
svankoch Dec 4, 2024
778d76d
Extracted city name validation into a separate function isValidCityNa…
svankoch Dec 4, 2024
214f010
Removed unused variable headerCityName from event handler registration.
svankoch Dec 4, 2024
50bc70a
Removed axios installation, replaced local Axios script reference wi…
svankoch Dec 4, 2024
d8eb43e
Refactored reset button to reset UI, not just city name. Created defa…
svankoch Dec 4, 2024
3ff70d1
Merge pull request #1 from chardayneal/wave6
svankoch Dec 4, 2024
94cd506
Removed duplicate call to updateSky on page load. Reorganized functio…
svankoch Dec 4, 2024
56b9c2b
Merge pull request #2 from chardayneal/wave6
svankoch Dec 5, 2024
b530f1f
Refactored the weather application to manage state more efficiently b…
svankoch Dec 5, 2024
e997fe1
Update URL to make calls from rendered server instead of local server
chardayneal Dec 6, 2024
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
Prev Previous commit
Next Next commit
Meets Wave 5 requirements. Added SKIES constant for sky visualization…
… and updateSky function to dynamically display sky conditions. Refactored temperature category mapping with getTemperatureCategory to improve readability and maintainability. Improved error handling by introducing logError and displayErrorMessage functions for better user feedback and debugging. Modified updateTemp to ensure default handling of invalid temperature values. Introduced registerHandlers for cleaner event listener registration. Replaced repetitive DOM queries with getElement utility and centralized elements mapping. Enhanced initial state setup for default city and weather display on page load.
svankoch committed Dec 4, 2024
commit 7a88bd9819ac8d079106639660d66629475b5a47
5 changes: 4 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -25,7 +25,10 @@ <h2>Temperature</h2>
<span id="tempValue"></span>
<span id="decreaseTempControl">⬇️</span>
</div>
<button id="currentTempButton">Get Realtime Temperature</button>
<div class="button-and-error">
<button id="currentTempButton">Get Realtime Temperature</button>
<div id="errorMessage"></div>
</div>
</div>
</section>
<section class="sky__section">
128 changes: 92 additions & 36 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -7,28 +7,43 @@ const TEMPS_IN_F = {
hot: 80,
}

const SKIES = {
sunny: "☁️ ☁️ ☁️ ☀️ ☁️ ☁️",
cloudy: "☁️☁️ ☁️ ☁️☁️ ☁️ 🌤 ☁️ ☁️☁️",
rainy: "🌧🌈⛈🌧🌧💧⛈🌧🌦🌧💧🌧🌧",
snowy: "🌨❄️🌨🌨❄️❄️🌨❄️🌨❄️❄️🌨🌨"
};

const LANDSCAPES = {
hot: "🌵__🐍_🦂_🌵🌵__🐍_🏜_🦂",
warm: "🌸🌿🌼__🌷🌻🌿_☘️🌱_🌻🌷",
cool: "🌾🌾_🍃_🪨__🛤_🌾🌾🌾_🍃",
cold: "🌲🌲⛄️🌲⛄️🍂🌲🍁🌲🌲⛄️🍂🌲"
};

const getElement = (id) => document.getElementById(id);
const elements = {
tempValue: document.getElementById('tempValue'),
incrTempControl: document.getElementById('increaseTempControl'),
decrTempControl: document.getElementById('decreaseTempControl'),
landscape: document.getElementById('landscape'),
cityNameInput: document.getElementById('cityNameInput'),
headerCityName: document.getElementById('headerCityName'),
currentTempButton: document.getElementById('currentTempButton')
tempValue: getElement('tempValue'),
incrTempControl: getElement('increaseTempControl'),
decrTempControl: getElement('decreaseTempControl'),
landscape: getElement('landscape'),
cityNameInput: getElement('cityNameInput'),
headerCityName: getElement('headerCityName'),
currentTempButton: getElement('currentTempButton'),
skySelect: getElement('skySelect'),
sky: getElement('sky'),
};

const updateSky = (selectedSky) => {
const skyText = SKIES[selectedSky] || SKIES.sunny;
elements.sky.textContent = skyText;
};

const updateTemp = (incrementValue) => {
let tempInF = parseInt(elements.tempValue.textContent) || NaN;
if (isNaN(tempInF)) {
tempInF = 0;
console.error('Invalid temperature value detected, defaulting to 0');
logError('Invalid temperature value detected, defaulting to 0');
}
const newTempInF = tempInF + incrementValue;
elements.tempValue.textContent = newTempInF;
@@ -42,22 +57,41 @@ const convertTemp = (tempInK) => {
};

const updateTempColor = (tempInF) => {
const color = tempInF < TEMPS_IN_F.cold ? 'teal'
: tempInF < TEMPS_IN_F.cool ? 'green'
: tempInF < TEMPS_IN_F.warm ? 'yellow'
: tempInF < TEMPS_IN_F.hot ? 'orange'
: 'red';
elements.tempValue.style.color = color;
const category = getTemperatureCategory(tempInF);
const colorMap = {
cold: 'teal',
cool: 'green',
warm: 'yellow',
hot: 'orange',
veryHot: 'red',
};
elements.tempValue.style.color = colorMap[category];
};

const updateLandscape = (tempInF) => {
const landscape = tempInF < TEMPS_IN_F.cool ? LANDSCAPES.cold
: tempInF < TEMPS_IN_F.warm ? LANDSCAPES.cool
: tempInF < TEMPS_IN_F.hot ? LANDSCAPES.warm
: LANDSCAPES.hot;
elements.landscape.textContent = landscape;
const category = getTemperatureCategory(tempInF);
const landscapeMap = {
cold: LANDSCAPES.cold,
cool: LANDSCAPES.cool,
warm: LANDSCAPES.warm,
hot: LANDSCAPES.hot,
};
elements.landscape.textContent = landscapeMap[category] || LANDSCAPES.hot;
};

const getTemperatureCategory = (tempInF) => {
const thresholds = [
{ threshold: TEMPS_IN_F.cold, category: 'cold' },
{ threshold: TEMPS_IN_F.cool, category: 'cool' },
{ threshold: TEMPS_IN_F.warm, category: 'warm' },
{ threshold: TEMPS_IN_F.hot, category: 'hot' },
];

const category = thresholds.find(t => tempInF < t.threshold);
return category ? category.category : 'veryHot';
};


const getLocation = async (cityName) => {
try {
const response = await axios.get(`http://127.0.0.1:5000/location?q=${cityName}`);
@@ -86,7 +120,7 @@ const getWeather = async ({ lat, lon }) => {
}
};

const displayWeatherForCity = async (cityName) => {
const displayWeatherForCity = async (cityName = DEFAULT_CITY) => {
try {
const location = await getLocation(cityName);

@@ -96,42 +130,53 @@ const displayWeatherForCity = async (cityName) => {
if (weather) {
handleWeatherData(weather);
} else {
console.log('Could not fetch weather for', cityName);
logError('Could not fetch weather for', { cityName });
}
} else {
console.log('Could not fetch location for', cityName);
logError('Could not fetch location for', { cityName });
}
} catch (error) {
console.log('Error during weather retrieval:', error.message);
alert('An unexpected error occurred. Please try again.');
logError('Error during weather retrieval:', { message: error.message });
}
};

const handleWeatherData = (weather) => {
const tempInK = weather.main.temp;
const tempInF = convertTemp(tempInK);
elements.tempValue.textContent = tempInF;
updateTempColor(tempInF);
updateLandscape(tempInF);
if (weather.main && weather.main.temp) {
const tempInK = weather.main.temp;
const tempInF = convertTemp(tempInK);
elements.tempValue.textContent = tempInF;
updateTempColor(tempInF);
updateLandscape(tempInF);
} else {
logError('Invalid weather data received', weather);
}
};

const logError = (message, errorDetails) => {
console.error(message, errorDetails);
displayErrorMessage(message);
};

const displayErrorMessage = (message) => {
const errorMessageElement = getElement('errorMessage');
errorMessageElement.textContent = message;
errorMessageElement.style.display = 'block';
setTimeout(() => {
errorMessageElement.style.display = 'none';
}, 5000);
};


const registerHandlers = () => {
const {
incrTempControl,
decrTempControl,
cityNameInput,
headerCityName,
currentTempButton,
skySelect,
} = elements;

cityNameInput.value = DEFAULT_CITY;
headerCityName.textContent = DEFAULT_CITY;
displayWeatherForCity(DEFAULT_CITY);

incrTempControl.addEventListener('click', () => updateTemp(1));
decrTempControl.addEventListener('click', () => updateTemp(-1));

@@ -141,13 +186,24 @@ const registerHandlers = () => {

currentTempButton.addEventListener('click', () => {
const cityName = headerCityName.textContent.trim();

if (!cityName) {
alert('Please enter a city name.');
displayErrorMessage('Please enter a city name.');
// alert('Please enter a city name.');
return;
}
displayWeatherForCity(cityName);
});

skySelect.addEventListener('change', (event) => {
const selectedSky = event.target.value;
updateSky(selectedSky);
});
};

document.addEventListener('DOMContentLoaded', registerHandlers);
document.addEventListener('DOMContentLoaded', () => {
registerHandlers();
displayWeatherForCity();
cityNameInput.value = DEFAULT_CITY;
headerCityName.textContent = DEFAULT_CITY;
updateSky();
});
20 changes: 20 additions & 0 deletions styles/index.css
Original file line number Diff line number Diff line change
@@ -83,6 +83,26 @@ justify-content: space-around;
/* justify-content: center; */
}

.button-and-error {
display: flex;
flex-direction: column; /* Makes the button and error message stack vertically */
align-items: center; /* Centers the button and error message */
}

#currentTempButton {
margin-top: 32px;
}

#errorMessage {
display: none;
color: red;
font-weight: bold;
text-align: center;
margin-top: 14px;
width: 100%;
max-width: 300px;
}

#tempValue {
font-size: 3rem;
margin-left: 1.5rem;