From 833518cea77b6a4227c92cb576ad54d0b563be86 Mon Sep 17 00:00:00 2001 From: nicolinabl Date: Thu, 23 Oct 2025 10:22:26 +0200 Subject: [PATCH] added sunrise sunset api + displayed on page --- index.html | 16 ++-- index.js | 240 +++++++++++++++++++++++++++++++++-------------------- index.ts | 62 +++++++++++++- 3 files changed, 219 insertions(+), 99 deletions(-) diff --git a/index.html b/index.html index 804d2ea..e996574 100644 --- a/index.html +++ b/index.html @@ -39,14 +39,16 @@

23°

--> -
-

sunrise

-

06.00

-
+
+
diff --git a/index.js b/index.js index 657a142..5749ea1 100644 --- a/index.js +++ b/index.js @@ -1,88 +1,169 @@ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); }; //---------------------------------- // Dom selectors //---------------------------------- const topInfoContainer = document.getElementById("topInfoContainer"); -const weeklyTempContainer = document.getElementById("weeklyTemp"); /* added this: dom selector for bottom section */ +const weeklyTempContainer = document.getElementById("weeklyTemp"); const adviceContainer = document.getElementById("adviceSection"); +const sunTimesContainer = document.getElementById("sunTimesContainer"); //---------------------------------- // API link //---------------------------------- const weatherURL = `https://opendata-download-metfcst.smhi.se/api/category/snow1g/version/1/geotype/point/lon/16.158/lat/58.5812/data.json?parameters=air_temperature,symbol_code`; +const sunriseSunset = `https://api.sunrisesunset.io/json?lat=58.5812&lng=16.158`; /* Look into adjusting coordinates */ //---------------------------------- -// Fetch API function +// Fetch weather API function //---------------------------------- let data; /*Look into this */ let todayWeather; const fetchData = () => __awaiter(void 0, void 0, void 0, function* () { - try { - const response = yield fetch(weatherURL); - if (!response.ok) { - throw new Error(`HTTP error: ${response.status}`); + try { + const response = yield fetch(weatherURL); + if (!response.ok) { + throw new Error(`HTTP error: ${response.status}`); + } + data = yield response.json(); + console.log(data); + displayWeeklyTemps(); /* added this. Calling function for weekly forecast */ + todayForecast(); + } + catch (error) { + console.log("catch and error"); /* What do we mean here? */ + } +}); +//---------------------------------- +// Fetch sunrise/sunset API function +//---------------------------------- +let sunData; +const fetchSunriseSunsetData = () => __awaiter(void 0, void 0, void 0, function* () { + try { + const response = yield fetch(sunriseSunset); + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + sunData = yield response.json(); + console.log(sunData); + displaySunTimes(sunData); + } + catch (error) { + console.error("An error occured:", error); } - data = yield response.json(); - console.log(data); - displayWeeklyTemps(); /* added this. Calling function for weekly forecast */ - todayForecast(); - } - catch (error) { - console.log("catch and error"); - } }); //---------------------------------- +// Sunrise/sunset function +//---------------------------------- +// interface SunriseSunsetData { /* This not needed? */ +// sunrise: number +// sunset: number +// } +// let sunriseSunsetTimes: SunriseSunsetData +const displaySunTimes = (sunData) => { + const sunrise = sunData.results.sunrise; + const sunset = sunData.results.sunset; + sunTimesContainer.innerHTML = ` +
+

Sunrise

+

${sunrise}

+
+ +
+

sunset

+

${sunset}

+
+ `; +}; +fetchSunriseSunsetData(); +//Mapping codes and conditions: +const weatherSymbol = (code) => { + const mapping = { + 1: "Clear sky", + 2: "Nearly clear", + 3: "Variable clouds", + 4: "Halfclear sky", + 5: "Cloudy", + 6: "Overcast", + 7: "Fog", + 8: "Light rain", + 9: "Moderate rain", + 10: "Heavy showers", + 11: "Thunderstorm", + 12: "Light sleet", + 13: "Moderate sleet", + 14: "Heavy sleet", + 15: "Light snow", + 16: "Moderate snow", + 17: "Heavy snow", + 18: "Light rain", + 19: "Moderate rain", + 20: "Heavy rain", + 21: "Thunder", + 22: "Light sleet", + 23: "Moderate sleet", + 24: "Heavy sleet", + 25: "Light snow", + 26: "Moderate snow", + 27: "Heavy snow" + }; + return mapping[Math.round(code)] || "Unknown"; +}; +//---------------------------------- // Show todays forecast function //---------------------------------- -const todayForecast = () => { - // const timeNow = new Date() /* <-- gets current time. Next step: show data from the timeSeries closest to current time instead of always showing timeSeries[0]. Very hard..... */ - todayWeather = { - condition: data.timeSeries[0].data.symbol_code, - airTemp: data.timeSeries[0].data.air_temperature - }; - topInfoContainer.innerHTML = ` +const todayForecast = ( /*data: any*/) => { + // const timeNow = new Date() /* <-- gets current time. Next step: show data from the timeSeries closest to current time instead of always showing timeSeries[0]. Very hard..... */ + const current = data.timeSeries[0].data; + const airTemp = current.air_temperature; + const conditionCode = current.symbol_code; + const conditionLabel = weatherSymbol(conditionCode); + todayWeather = { + condition: weatherSymbol(data.timeSeries[0].data.symbol_code), + airTemp + }; + topInfoContainer.innerHTML = `

${todayWeather.condition}


${todayWeather.airTemp}°

`; - if (data.symbol_code === 6) { - } - showMessage(todayWeather, adviceContainer, weeklyTempContainer); + if (data.symbol_code === 6) { + } + showMessage(todayWeather, adviceContainer, weeklyTempContainer); }; const showMessage = (data, adviceContainer, weeklyTempContainer) => { - if (!weeklyTempContainer || !adviceContainer) - return; - adviceContainer.innerHTML = ``; - if ((data.condition >= 1 && data.condition <= 2) && data.airTemp >= 20) { - document.body.style.backgroundColor = "#F7E9B9"; - document.body.style.color = "#2A5510"; - adviceContainer.innerHTML = ` + if (!weeklyTempContainer || !adviceContainer) + return; + adviceContainer.innerHTML = ``; + if ((data.condition >= 1 && data.condition <= 2) && data.airTemp >= 20) { + document.body.style.backgroundColor = "#F7E9B9"; + document.body.style.color = "#2A5510"; + adviceContainer.innerHTML = ` outlined icon with weather-appropriate accessories

get your sunglasses on. Stockholm is amazing

`; - } - else if ((data.condition >= 3 && data.condition <= 6) && data.airTemp < 20) { - document.body.style.backgroundColor = "#FFFFFF"; - document.body.style.color = "#F47775"; - adviceContainer.innerHTML = ` + } + else if ((data.condition >= 3 && data.condition <= 6) && data.airTemp < 20) { + document.body.style.backgroundColor = "#FFFFFF"; + document.body.style.color = "#F47775"; + adviceContainer.innerHTML = ` outlined icon with weather-appropriate accessories

Light a fire and get cosy. Stockholm is looking grey today.

`; - } - else if (data.condition >= 8 && data.condition <= 20) { - document.body.style.backgroundColor = "#BDE8FA"; - document.body.style.color = "#164A68"; - adviceContainer.innerHTML = ` + } + else if (data.condition >= 8 && data.condition <= 20) { + document.body.style.backgroundColor = "#BDE8FA"; + document.body.style.color = "#164A68"; + adviceContainer.innerHTML = ` outlined icon with weather-appropriate accessories

Don’t forget your umbrella. It’s wet in Stockholm today.

`; - } + } }; fetchData(); //---------------------------------- @@ -91,28 +172,28 @@ fetchData(); const weekDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; /* Array of weekdays. To be used for displaying weekdays dynamically */ let weatherForecast; /* Defining weatherForecast object */ const displayWeeklyTemps = () => { - const rotateWeekdays = () => { - const today = new Date(); /* Gets today */ - const todayIndex = today.getDay(); /* Gets index of today. 0 = sunday */ - const rotated = weekDays.slice(todayIndex).concat(weekDays.slice(0, todayIndex)); - return rotated; - }; - const rotatedWeekdays = rotateWeekdays(); - weatherForecast = { - firstDay: data.timeSeries[0].data.air_temperature, - secondDay: data.timeSeries[25].data.air_temperature, - thirdDay: data.timeSeries[49].data.air_temperature, - fourthDay: data.timeSeries[59].data.air_temperature, - fifthDay: data.timeSeries[63].data.air_temperature, - sixthDay: data.timeSeries[67].data.air_temperature, - seventhDay: data.timeSeries[71].data.air_temperature - }; - const labels = rotatedWeekdays.map((day, i) => { - if (i === 0) - return "Today"; - return day; - }); - weeklyTempContainer.innerHTML = ` + const rotateWeekdays = () => { + const today = new Date(); /* Gets today */ + const todayIndex = today.getDay(); /* Gets index of today. 0 = sunday */ + const rotated = weekDays.slice(todayIndex).concat(weekDays.slice(0, todayIndex)); + return rotated; + }; + const rotatedWeekdays = rotateWeekdays(); + weatherForecast = { + firstDay: data.timeSeries[0].data.air_temperature, + secondDay: data.timeSeries[25].data.air_temperature, + thirdDay: data.timeSeries[49].data.air_temperature, + fourthDay: data.timeSeries[59].data.air_temperature, + fifthDay: data.timeSeries[63].data.air_temperature, + sixthDay: data.timeSeries[67].data.air_temperature, + seventhDay: data.timeSeries[71].data.air_temperature + }; + const labels = rotatedWeekdays.map((day, i) => { + if (i === 0) + return "Today"; + return day; + }); + weeklyTempContainer.innerHTML = `

${labels[0]}

${weatherForecast.firstDay}°

@@ -149,23 +230,6 @@ const displayWeeklyTemps = () => {
`; }; -//test to get swedish local time -const todaySwedishForecast = (data) => { - var _a; - const now = new Date(); - const currentHour = now.getHours(); - const entry = (_a = data.timeSeries.find((item) => { - const forecastDate = new Date(item.validTime); - return forecastDate.getHours() === currentHour; - })) !== null && _a !== void 0 ? _a : data.timeSeries[0]; - const forecastDate = new Date(entry.validTime); - console.log("forecast time (swedish local", forecastDate.toString); -}; -/* Next step figure out: -- which timeSeries to use for each day? -- Average temp or lowest and highest? How find? -- How to loop through days and show current day on top? -*/ /* const symbolMeanings: string[] = [ "", // index 0 (unused, just a placeholder) diff --git a/index.ts b/index.ts index c8db353..69f7c29 100644 --- a/index.ts +++ b/index.ts @@ -2,8 +2,9 @@ // Dom selectors //---------------------------------- const topInfoContainer = document.getElementById("topInfoContainer") as HTMLElement -const weeklyTempContainer = document.getElementById("weeklyTemp") as HTMLElement /* added this: dom selector for bottom section */ +const weeklyTempContainer = document.getElementById("weeklyTemp") as HTMLElement const adviceContainer = document.getElementById("adviceSection") as HTMLElement +const sunTimesContainer = document.getElementById("sunTimesContainer") as HTMLElement //---------------------------------- @@ -11,6 +12,8 @@ const adviceContainer = document.getElementById("adviceSection") as HTMLElement //---------------------------------- const weatherURL = `https://opendata-download-metfcst.smhi.se/api/category/snow1g/version/1/geotype/point/lon/16.158/lat/58.5812/data.json?parameters=air_temperature,symbol_code` +const sunriseSunset = `https://api.sunrisesunset.io/json?lat=58.5812&lng=16.158` /* Look into adjusting coordinates */ + //---------------------------------- // Suggestions of interfaces: @@ -27,7 +30,7 @@ interface TodayWeatherData { } //---------------------------------- -// Fetch API function +// Fetch weather API function //---------------------------------- let data: any /*Look into this */ let todayWeather: TodayWeatherData @@ -45,11 +48,63 @@ const fetchData = async () => { todayForecast() } catch (error) { - console.log("catch and error") + console.log("catch and error") /* What do we mean here? */ + } +} + + +//---------------------------------- +// Fetch sunrise/sunset API function +//---------------------------------- +let sunData: any + +const fetchSunriseSunsetData = async () => { + try { + const response = await fetch(sunriseSunset) + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`) + } + + sunData = await response.json() + console.log(sunData) + displaySunTimes(sunData) + + } catch (error) { + console.error("An error occured:", error) } } +//---------------------------------- +// Sunrise/sunset function +//---------------------------------- + +// interface SunriseSunsetData { /* This not needed? */ +// sunrise: number +// sunset: number +// } + +// let sunriseSunsetTimes: SunriseSunsetData + +const displaySunTimes = (sunData: any) => { + + const sunrise = sunData.results.sunrise + const sunset = sunData.results.sunset + + sunTimesContainer.innerHTML = ` +
+

Sunrise

+

${sunrise}

+
+ +
+

sunset

+

${sunset}

+
+ ` +} + +fetchSunriseSunsetData() //Mapping codes and conditions: @@ -148,7 +203,6 @@ const showMessage = (data: TodayWeatherData, adviceContainer: HTMLElement, weekl fetchData() - //---------------------------------- // Display weekly temps bottom part function //----------------------------------