Add station modal logic and station data for part of route 0210

This commit is contained in:
2026-03-12 00:54:42 +00:00
parent 06861f4037
commit 0fc2c0177b
33 changed files with 2394 additions and 2045 deletions

View File

@@ -57,7 +57,12 @@
<div class="list-container">
<a href="https://owlboard.info" class="button-link">Go to OwlBoard Live Departures & PIS</a>
<input type="text" bind:value={searchTerm} placeholder="Search Station/Jn" class="search-input" />
<input
type="text"
bind:value={searchTerm}
placeholder="Search Station/Jn"
class="search-input"
/>
{#each filteredMaps as map (map.routeId)}
<a
href={resolve(`/map/${map.routeId.toString().padStart(4, '0')}`)}

View File

@@ -1,18 +1,30 @@
<script lang="ts">
import RouteRow from '$lib/components/RouteRow.svelte';
import RouteEndLink from '$lib/components/mapIcons/RouteEndLink.svelte';
import StationInfo from '$lib/components/StationInfo.svelte';
import { slide } from 'svelte/transition';
import { resolve } from '$app/paths';
import logo from '$lib/assets/round-logo.svg';
import { IconArrowsExchange, IconSettings } from '@tabler/icons-svelte';
import { IconArrowsExchange, IconSettings } from '@tabler/icons-svelte';
// data.route contains: routeStart, routeEnd, routeId, elecStart, elecEnd, routeDetail[]
export let data;
let { data } = $props();
let reversed = false; // Reverses Array, and passes value down to children
let activeCrs = $state<string | null>(null);
let isModalOpen = $derived(activeCrs !== null);
let visibleTypes = {
function openStationModal(crs: string) {
activeCrs = crs;
}
function closeStationModal() {
activeCrs = null;
}
let reversed = $state(false); // Reverses Array, and passes value down to children
let visibleTypes = $state({
station: true,
minorBridge: false,
bridge: true,
@@ -23,10 +35,10 @@
siteof: true,
junction: true,
tunnel: true,
crossing: true,
};
crossing: true
});
let showFilters = false;
let showFilters = $state(false);
// Toggle feature types
const toggleFilter = (type: string) => {
@@ -38,31 +50,29 @@
const formatLabel = (str: string) =>
str.replace(/([A-Z])/g, ' $1').replace(/^./, (s) => s.toUpperCase());
$: processedFeatures = (() => {
const processedFeatures = $derived.by(() => {
const list = reversed ? [...data.route.routeDetail].reverse() : [...data.route.routeDetail];
// Seed currentElec from the YAML header boundary
let currentElec = reversed ? data.route.elecEnd.elec : data.route.elecStart.elec;
return list.map((f) => {
if (f.type === 'electrificationChange') {
// Transition state: this tile and everything after it
// adopts the new electrification.
currentElec = reversed ? f.from.elec : f.to.elec;
}
return {
...f,
activeElec: currentElec
};
});
})();
$: filteredFeatures = processedFeatures.filter((f) => {
return visibleTypes[f.type] ?? true;
});
const filteredFeatures = $derived(processedFeatures.filter((f) => visibleTypes[f.type] ?? true));
</script>
{#if isModalOpen && activeCrs}
<StationInfo crs={activeCrs} onclose={closeStationModal} />
{/if}
<div class="map-layout">
<header class="top-nav">
<div class="nav-cluster">
@@ -76,8 +86,8 @@
{reversed ? data.route.routeEnd : data.route.routeStart}
</h1>
<span class="secondary-station">
<span class="route-stack-to">
to</span> {reversed ? data.route.routeStart : data.route.routeEnd}
<span class="route-stack-to"> to</span>
{reversed ? data.route.routeStart : data.route.routeEnd}
</span>
{/if}
</div>
@@ -87,7 +97,9 @@
<button class="icon-btn" onclick={() => (reversed = !reversed)}>
<IconArrowsExchange />
</button>
<button class="icon-btn" onclick={() => (showFilters = !showFilters)}> <IconSettings /> </button>
<button class="icon-btn" onclick={() => (showFilters = !showFilters)}>
<IconSettings />
</button>
</div>
</header>
@@ -139,7 +151,12 @@
{#if f.type === 'continues'}
<RouteEndLink feature={f} />
{:else}
<RouteRow feature={f} activeElec={f.activeElec} {reversed} />
<RouteRow
feature={f}
activeElec={f.activeElec}
{reversed}
onShowInfo={openStationModal}
/>
{/if}
{/each}
</div>
@@ -212,7 +229,7 @@
.route-stack {
display: flex;
font-family: "urwgothic";
font-family: 'urwgothic';
flex-direction: column;
min-width: 0;
margin-left: 0;
@@ -250,7 +267,7 @@
}
@media (min-width: 536px) {
.primary-station {
.primary-station {
font-size: 1.5rem;
}
.secondary-station {

View File

@@ -20,9 +20,8 @@ export const load: PageLoad = async ({ params }) => {
return {
route: rawData,
slug: slug,
slug: slug
};
} catch (err) {
console.error(`Error loading map ${slug}: `, err);
throw error(500, {