#dashboard {
font-family: sans-serif;
padding: 1.5em;
background: #ffffff;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
max-width: 400px;
margin: auto;
}
#dashboard h2, #dashboard h3 {
margin-top: 0.5em;
}
#weather {
font-size: 1.2em;
margin-bottom: 1em;
}
ul#departures {
padding-left: 1em;
list-style: none;
}
ul#departures li {
padding: 0.5em 0;
border-bottom: 1px solid #eee;
}
@media screen and (max-width: 480px) {
#dashboard {
font-size: 1em;
padding: 1em;
}
}
Stuvsta just nu
Nästa pendeltåg från Stuvsta
- Laddar avgångar…
const WEATHER_API_KEY = ”be599ad20e043a231aae8d76cdd8b0b9”;
const GTFS_CLIENT_NAME = ”Realtid_Stuvsta”; // tex: mittnamn-gtfs-v1
const STUVSTA_STOP_ID = ”stop-point:SL:Stuvsta”; // GTFS-ID för Stuvsta (kan behöva bekräftas)
// 1. Hämta väder
fetch(`https://api.openweathermap.org/data/2.5/weather?q=Stuvsta,SE&appid=${WEATHER_API_KEY}&units=metric&lang=sv`)
.then(res => res.json())
.then(data => {
const desc = data.weather[0].description;
const temp = Math.round(data.main.temp);
document.getElementById(‘weather’).innerText = `${desc}, ${temp}°C`;
});
// 2. Hämta pendeltågsavgångar via Entur GraphQL
const query = `
{
stopPlace(id: ”${STUVSTA_STOP_ID}”) {
name
estimatedCalls(timeRange: 3600, numberOfDepartures: 5) {
expectedDepartureTime
destinationDisplay {
frontText
}
serviceJourney {
journeyPattern {
line {
publicCode
}
}
}
}
}
}
`;
fetch(”https://api.entur.io/journey-planner/v3/graphql”, {
method: ”POST”,
headers: {
”Content-Type”: ”application/json”,
”ET-Client-Name”: GTFS_CLIENT_NAME
},
body: JSON.stringify({ query })
})
.then(res => res.json())
.then(data => {
const calls = data.data.stopPlace.estimatedCalls;
const list = document.getElementById(‘departures’);
list.innerHTML = ””;
calls.forEach(call => {
const line = call.serviceJourney.journeyPattern.line.publicCode;
const destination = call.destinationDisplay.frontText;
const depTime = new Date(call.expectedDepartureTime);
const now = new Date();
const minutes = Math.round((depTime – now) / 60000);
const li = document.createElement(”li”);
li.textContent = `${line} mot ${destination} – om ${minutes} min`;
list.appendChild(li);
});
})
.catch(err => {
document.getElementById(‘departures’).innerHTML = ”
”;
console.error(err);
});