diff --git a/.gitignore b/.gitignore index be9ac2d..3c3532a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ /obj /bin -wwwroot/ + diff --git a/Services/WeatherService.cs b/Services/WeatherService.cs index a77a964..8443037 100644 --- a/Services/WeatherService.cs +++ b/Services/WeatherService.cs @@ -20,7 +20,8 @@ public async Task GetWeatherForBergenAsync() try { // API request - string requestUri = "https://api.open-meteo.com/v1/forecast?latitude=60.393&longitude=5.3242&hourly=temperature_2m,precipitation,rain,showers,weather_code,wind_speed_10m"; + string requestUri = "https://api.open-meteo.com/v1/forecast?latitude=60.393&longitude=5.3242&hourly=temperature_2m,relative_humidity_2m,apparent_temperature,rain,showers,snowfall,snow_depth,weather_code,surface_pressure,cloud_cover,cloud_cover_low,cloud_cover_mid,cloud_cover_high,visibility,wind_speed_10m,uv_index,is_day,sunshine_duration&forecast_days=1"; + var response = await _httpClient.GetAsync(requestUri); if (response.IsSuccessStatusCode) @@ -31,16 +32,22 @@ public async Task GetWeatherForBergenAsync() if (weatherData?.Hourly != null) { - // Check if the first element in the lists exist and use them, otherwise return "undefined" + // Return only fields that are working float? temperature = weatherData.Hourly.Temperature2M?.Count > 0 ? weatherData.Hourly.Temperature2M[0] : (float?)null; float? windspeed = weatherData.Hourly.WindSpeed10M?.Count > 0 ? weatherData.Hourly.WindSpeed10M[0] : (float?)null; int? weatherCode = weatherData.Hourly.WeatherCode?.Count > 0 ? weatherData.Hourly.WeatherCode[0] : (int?)null; + float? visibility = weatherData.Hourly.Visibility?.Count > 0 ? weatherData.Hourly.Visibility[0] : (float?)null; + string humidity = weatherData.Hourly.RelativeHumidity2M?.Count > 0 ? $"{weatherData.Hourly.RelativeHumidity2M[0]}%" : "undefined"; + bool? isDay = weatherData.Hourly.IsDay?.Count > 0 ? (weatherData.Hourly.IsDay[0] == 1) : (bool?)null; return Ok(new { temperature = temperature.HasValue ? $"{temperature}°C" : "undefined", windspeed = windspeed.HasValue ? $"{windspeed} km/h" : "undefined", - condition = weatherCode.HasValue && weatherCode.Value == 3 ? "Cloudy" : "Clear" + condition = weatherCode.HasValue && weatherCode.Value == 3 ? "Cloudy" : "Clear", + visibility = visibility.HasValue ? $"{visibility} km" : "undefined", + humidity = humidity, + isDay = isDay.HasValue ? (isDay.Value ? "Day" : "Night") : "undefined" }); } else @@ -61,4 +68,3 @@ public async Task GetWeatherForBergenAsync() } } } - diff --git a/classes/WeatherData.cs b/classes/WeatherData.cs index 79eef43..42b5d0a 100644 --- a/classes/WeatherData.cs +++ b/classes/WeatherData.cs @@ -5,19 +5,61 @@ public class WeatherData { [JsonPropertyName("hourly")] - public HourlyData Hourly { get; set; } + public HourlyData? Hourly { get; set; } } public class HourlyData { [JsonPropertyName("temperature_2m")] - public List Temperature2M { get; set; } + public List? Temperature2M { get; set; } [JsonPropertyName("wind_speed_10m")] - public List WindSpeed10M { get; set; } + public List? WindSpeed10M { get; set; } [JsonPropertyName("weather_code")] - public List WeatherCode { get; set; } + public List? WeatherCode { get; set; } - // Add other fields like precipitation, rain, etc. if needed + [JsonPropertyName("uv_index")] + public List? UVIndex { get; set; } + + [JsonPropertyName("sunshine_duration")] + public List? SunshineDuration { get; set; } + + [JsonPropertyName("is_day")] + public List? IsDay { get; set; } + + [JsonPropertyName("visibility")] + public List? Visibility { get; set; } + + [JsonPropertyName("relative_humidity_2m")] + public List? RelativeHumidity2M { get; set; } + + [JsonPropertyName("apparent_temperature")] + public List? ApparentTemperature { get; set; } + + [JsonPropertyName("wind_gusts_10m")] + public List? WindGusts10M { get; set; } + + [JsonPropertyName("rain")] + public List? Rain { get; set; } + + [JsonPropertyName("showers")] + public List? Showers { get; set; } + + [JsonPropertyName("surface_pressure")] + public List? SurfacePressure { get; set; } + + [JsonPropertyName("cloud_cover")] + public List? CloudCover { get; set; } + + [JsonPropertyName("cloud_cover_low")] + public List? CloudCoverLow { get; set; } + + [JsonPropertyName("cloud_cover_mid")] + public List? CloudCoverMid { get; set; } + + [JsonPropertyName("cloud_cover_high")] + public List? CloudCoverHigh { get; set; } + + // Add other fields like snowfall, snow_depth if needed } diff --git a/documentation/WeatherApp.png b/documentation/WeatherApp.png new file mode 100644 index 0000000..0aea51e Binary files /dev/null and b/documentation/WeatherApp.png differ diff --git a/readme.md b/readme.md index 90dddb5..8af32cf 100644 --- a/readme.md +++ b/readme.md @@ -18,6 +18,6 @@ **Navigate to files** -|[HTML](/wwwroot/index.html)|[CSS](/wwwroot/styles.css)|[Figma](documentation/Figma-design.pdf) +|[HTML](/wwwroot/index.html)|[CSS](/wwwroot/styles.css)|[Figma](documentation/Figma-design.pdf)[Plan](documentation\WeatherApp.png) |[Program.cs](/Program.cs)|[WheatherData.cs](/classes/WeatherData.cs) -|[WeatherController.cs](/Controller/WeatherController.cs)|[WheatherService.cs](/Services/WeatherService.cs) +|[WeatherController.cs](/Controller/WeatherController.cs)|[WheatherService.cs](/Services/WeatherService.cs)| diff --git a/wwwroot/backround.jpg b/wwwroot/backround.jpg new file mode 100644 index 0000000..d1bd1c3 Binary files /dev/null and b/wwwroot/backround.jpg differ diff --git a/wwwroot/images/BaxAma.png b/wwwroot/images/BaxAma.png new file mode 100644 index 0000000..6b56eb2 Binary files /dev/null and b/wwwroot/images/BaxAma.png differ diff --git a/wwwroot/images/BaxAma2.png b/wwwroot/images/BaxAma2.png new file mode 100644 index 0000000..6a87d89 Binary files /dev/null and b/wwwroot/images/BaxAma2.png differ diff --git a/wwwroot/images/bergen.jpg b/wwwroot/images/bergen.jpg new file mode 100644 index 0000000..7ca7334 Binary files /dev/null and b/wwwroot/images/bergen.jpg differ diff --git a/wwwroot/index.html b/wwwroot/index.html index 6931d15..e4e7b0c 100644 --- a/wwwroot/index.html +++ b/wwwroot/index.html @@ -1,54 +1,54 @@ - - - - Bax Weather Network - - - -
-

Bax Weather Network

-

Local weather ONLY

-
+ + + + Bax Weather Network + + + -
-
+ + + +
+ +
+ +
+

Bergen

Current weather in Bergen, Norway.

+

_____________________________

+

Temperature: Loading...

-

Windspeed: Loading...

Condition: Loading...

-
-
- - - - \ No newline at end of file + + + + + +
+ + diff --git a/wwwroot/script.js b/wwwroot/script.js new file mode 100644 index 0000000..961a451 --- /dev/null +++ b/wwwroot/script.js @@ -0,0 +1,89 @@ +// Function to uncheck all checkboxes +function resetSelection() { + const checkboxes = document.querySelectorAll('.checkbox-list input[type="checkbox"]'); + + checkboxes.forEach(checkbox => { + checkbox.checked = false; + }); + + toggleElements(); +} + +document.getElementById("resetButton").addEventListener("click", resetSelection); + +window.onload = function () { + fetchWeather(); + toggleElements(); + document.getElementById("refreshButton").addEventListener("click", refreshWeather); // Add the event listener for the refresh button here +}; + +// Function to toggle visibility of weather elements based on checkbox states +function toggleElements() { + const temperatureEl = document.getElementById("temperature"); + const windspeedEl = document.getElementById("windspeed"); + const conditionEl = document.getElementById("condition"); + const isDayEl = document.getElementById("is-day"); + const visibilityEl = document.getElementById("visibility"); + const humidityEl = document.getElementById("humidity"); + + if (temperatureEl && windspeedEl && conditionEl && isDayEl && visibilityEl && humidityEl) { + temperatureEl.style.display = document.getElementById("toggle-temperature").checked ? "block" : "none"; + windspeedEl.style.display = document.getElementById("toggle-windspeed").checked ? "block" : "none"; + conditionEl.style.display = document.getElementById("toggle-condition").checked ? "block" : "none"; + isDayEl.style.display = document.getElementById("toggle-is-day").checked ? "block" : "none"; + visibilityEl.style.display = document.getElementById("toggle-visibility").checked ? "block" : "none"; + humidityEl.style.display = document.getElementById("toggle-humidity").checked ? "block" : "none"; + } +} + +document.querySelectorAll('input[type="checkbox"]').forEach((checkbox) => { + checkbox.addEventListener('change', toggleElements); +}); + +// Fetch weather data function +async function fetchWeather() { + try { + const response = await fetch("/api/weather"); + if (!response.ok) { + throw new Error("Failed to fetch weather data"); + } + + const weatherData = await response.json(); + console.log("Received Weather Data: ", weatherData); // Added to check that Api data is received + + // Ensure weatherData contains the required fields + if (weatherData) { + // Update the HTML elements with the fetched data + document.getElementById("temperature").innerText = `Temperature: ${weatherData.temperature || 'N/A'}`; + document.getElementById("windspeed").innerText = `Windspeed: ${weatherData.windspeed || 'N/A'}`; + document.getElementById("condition").innerText = `Condition: ${weatherData.condition || 'N/A'}`; + document.getElementById("is-day").innerText = `Day or Night: ${weatherData.isDay || 'N/A'}`; + document.getElementById("visibility").innerText = `Visibility: ${weatherData.visibility || 'N/A'}`; + document.getElementById("humidity").innerText = `Humidity: ${weatherData.humidity || 'N/A'}`; + } + } catch (error) { + console.error("Error fetching weather data: ", error.message); + + // Handle errors by showing "Error" in the text fields + document.getElementById("temperature").innerText = "Temperature: Error"; + document.getElementById("windspeed").innerText = "Windspeed: Error"; + document.getElementById("condition").innerText = "Condition: Error"; + document.getElementById("is-day").innerText = "Day or Night: Error"; + document.getElementById("visibility").innerText = "Visibility: Error"; + document.getElementById("humidity").innerText = "Humidity: Error"; + } +} + +// Function to refresh weather data +function refreshWeather() { + + document.getElementById("temperature").innerText = "Temperature: Loading..."; + document.getElementById("windspeed").innerText = "Windspeed: Loading..."; + document.getElementById("condition").innerText = "Condition: Loading..."; + document.getElementById("is-day").innerText = "Day or Night: Loading..."; + document.getElementById("visibility").innerText = "Visibility: Loading..."; + document.getElementById("humidity").innerText = "Humidity: Loading..."; + + + fetchWeather(); +} diff --git a/wwwroot/styles.css b/wwwroot/styles.css index 7396b72..7973034 100644 --- a/wwwroot/styles.css +++ b/wwwroot/styles.css @@ -2,85 +2,140 @@ box-sizing: border-box; margin: 0; padding: 0; - background-color: rgb(243, 243, 243); - font-family: Arial, Helvetica, sans-serif; + font-family: Arial, Helvetica, sans-serif, ; } -body { - min-height: 100vh; - min-width: 100vw; +html, body { + height: 100%; + margin: 0; + padding: 0; + font-family: Arial, sans-serif; + background-image: url("images/bergen.jpg"); + background-size: cover; + background-attachment: fixed; + background-position: center; + overflow: hidden; } -/* -----------HEADER---------- */ - header { min-height: 100px; + display: flex; + align-items: center; + justify-content: center; + background: none; + position: fixed; } -.logo { - font-weight: 700; - color: rgb(90, 90, 234); - letter-spacing: -3px; - text-decoration-line: overline; - padding-top: 10px; - padding-left: 10px; -} - -.local-only { - color: rgb(90, 90, 234); - padding-left: 10px; - font-size: 13px; -} - -/* -------------MAIN------------- */ - main { display: flex; justify-content: center; - text-align: center; - min-height: 400px; + align-items: center; + min-height: 100vh; } .weather-container { - align-items: center; - gap: 20px; display: flex; flex-direction: column; - justify-content: space-around; - min-width: 500px; + align-items: center; + background-color: rgba(90, 90, 234, 0.9); + border-radius: 5px; + padding: 20px; + width: 100%; + max-width: 500px; + color: whitesmoke; } -.bergen { - color: rgb(30, 29, 29); - justify-content: start; - padding-top: 100px; - text-align: center; +.weather-container p { + margin-bottom: 12px; + text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.7); + font-weight: bold; } -p { - color: rgb(30, 29, 29); +.bergen { + font-weight: bold; + text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.7); } -#getWeather { - background-color: rgb(90, 90, 234); - text-decoration: none; - color: whitesmoke; +#refreshButton { + height: 40px; + background: linear-gradient(135deg, #153677, #4e085f); + color: white; border: none; - border-radius: 2px; - width: 90px; + border-radius: 8px; + padding: 10px 20px; + cursor: pointer; + font-size: 16px; + transition: background-color 0.3s ease; +} + +.checkbox-list { + max-height: 20px; + overflow: hidden; + transition: max-height 0.4s ease; + padding: 0; +} + +.checkbox-container:hover .checkbox-list { + max-height: 350px; + padding: 5px; +} + +.checkbox-container { + background-color: rgba(90, 90, 234, 0.9); + padding: 10px 20px; + border-radius: 10px; + color: white; + margin-top: 10px; + text-align: center; +} + +.divider { + border: 0; + height: 1px; + background: white; + margin: 15px 0; +} + +#resetButton { height: 40px; - font-size: 17px; + background: linear-gradient(135deg, #153677, #4e085f); + color: white; + border: none; + border-radius: 8px; + padding: 10px 20px; + cursor: pointer; + font-size: 16px; + margin-top: 10px; + transition: background-color 0.3s ease; + text-align: center; + width: 100%; + display: block; } -#weatherInfo { - color: rgb(90, 90, 234); +.checkbox-container label { + display: block; + margin-bottom: 5px; } -main { - background-image: url('images/bryggen.jpg'); - background-size: cover; - background-position: center; - background-repeat: no-repeat; - min-height: 600px; - padding: 20px; -} \ No newline at end of file +.choose-condition { + text-decoration: underline; + font-weight: bold; + color: white; + margin-bottom: 10px; +} + + +@media (max-width: 768px) { + .weather-container { + width: 90%; + padding: 10px; + } + + .logo { + font-size: 20px; + } + + #refreshButton { + font-size: 14px; + } +}