Compare commits
2 Commits
v3.0.0-dev
...
v3.0.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
| 91cb119b7d | |||
| 26e40c5bf6 |
1806
package-lock.json
generated
1806
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,7 @@
|
||||
"vitest-browser-svelte": "^2.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@owlboard/owlboard-ts": "^3.0.0-dev.20260428T2753",
|
||||
"@owlboard/owlboard-ts": "^3.0.0-dev.20260503T0051",
|
||||
"@tabler/icons-svelte": "^3.40.0"
|
||||
}
|
||||
}
|
||||
|
||||
59
src/lib/components/ui/Loading.svelte
Normal file
59
src/lib/components/ui/Loading.svelte
Normal file
@@ -0,0 +1,59 @@
|
||||
<script lang="ts">
|
||||
let {
|
||||
message = "Loading..."
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<div class="loading-state">
|
||||
<div class="track">
|
||||
<div class="shuttle"></div>
|
||||
</div>
|
||||
<p>{message}</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.loading-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 4rem 2rem;
|
||||
width: 75%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.track {
|
||||
width: 160px;
|
||||
height: 3px;
|
||||
background-color: var(--color-title);
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.shuttle {
|
||||
position: absolute;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
border-radius: 4px;
|
||||
background: linear-gradient(90deg, #1abc9c 0%, #3498db 100%);
|
||||
animation: data-travel 1.6s infinite ease-in-out;
|
||||
}
|
||||
|
||||
p {
|
||||
font-family: 'URW Gothic', sans-serif;
|
||||
letter-spacing: 0.15em;
|
||||
color: var(--color-title);
|
||||
animation: pulse 2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes data-travel {
|
||||
0% { left: -50%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% {opacity: 1;}
|
||||
50% {opacity: 0.4;}
|
||||
}
|
||||
</style>
|
||||
@@ -22,8 +22,22 @@
|
||||
justify-content: center;
|
||||
padding: 2px 8px;
|
||||
font-weight: 800;
|
||||
font-size: 1.1rem;
|
||||
background-color: #333;
|
||||
color: #fff;
|
||||
font-family:'Courier New', Courier, monospace;
|
||||
}
|
||||
|
||||
.AW {
|
||||
/* Transport for Wales */
|
||||
background: red;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.LM {
|
||||
/* West Midlands Trains */
|
||||
background: rgb(176, 115, 1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.GW {
|
||||
@@ -44,6 +58,12 @@
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.GN {
|
||||
/* Great Northern */
|
||||
background-color: fuchsia;
|
||||
color: rgb(229, 229, 229);
|
||||
}
|
||||
|
||||
.SW {
|
||||
/* South Western Railway */
|
||||
background-color: #2a3389;
|
||||
|
||||
@@ -1,15 +1,51 @@
|
||||
<script lang="ts">
|
||||
import type { ApiTrainsTrainByHeadcode } from '@owlboard/owlboard-ts';
|
||||
import { slide } from 'svelte/transition';
|
||||
import { OwlClient, ApiError, ValidationError } from '$lib/owlClient';
|
||||
import { slide } from 'svelte/transition';
|
||||
import { quintOut} from 'svelte/easing';
|
||||
import { formatUkTime } from '$lib/utils/time';
|
||||
import TocStyle from '$lib/components/ui/TocStyle.svelte';
|
||||
|
||||
let { service }: { service: ApiTrainsTrainByHeadcode.TrainByHeadcodeResponse} = $props();
|
||||
let isExpanded = $state(false);
|
||||
let loadingDetails = $state(false)
|
||||
let details = $state(null);
|
||||
|
||||
const toggleExpand = async (rid: string) => {
|
||||
if (isExpanded) {
|
||||
isExpanded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (details) {
|
||||
isExpanded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
loadingDetails = true;
|
||||
try {
|
||||
const result = await OwlClient.trains.getByRid(service.r)
|
||||
details = result.data;
|
||||
isExpanded = true;
|
||||
} catch (e) {
|
||||
console.Error("Failde to load train details")
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const toggleExpand = () => isExpanded = !isExpanded;
|
||||
|
||||
let OriginDepartureSummary = $derived(formatUkTime(service.od));
|
||||
|
||||
async function loadDetails(rid: string) {
|
||||
if (details) return;
|
||||
loadingDetails = true;
|
||||
|
||||
const result = await OwlClient.trains.getByRid(service.r)
|
||||
details = result.data;
|
||||
loadingDetails = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="train-service">
|
||||
@@ -30,8 +66,16 @@ import { formatUkTime } from '$lib/utils/time';
|
||||
<div class="location-summary">
|
||||
{service.dt}
|
||||
</div>
|
||||
<!-- Add arrow icon to signify drop-down -->
|
||||
<!-- ADD LOADING STATE -->
|
||||
</div>
|
||||
</button>
|
||||
{#if isExpanded && details}
|
||||
<div transition:slide={{duration: 800, easing: quintOut}} class="detauls-content">
|
||||
<!-- Here goes the data formatting! -->
|
||||
{JSON.stringify(details)}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@@ -42,6 +86,12 @@ import { formatUkTime } from '$lib/utils/time';
|
||||
box-shadow: var(--shadow-std);
|
||||
overflow: hidden;
|
||||
font-family: 'URW Gothic', sans-serif;
|
||||
transition: 0.2s all;
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
.train-service:hover {
|
||||
filter:brightness(1.5);
|
||||
}
|
||||
|
||||
.summary {
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
import { page } from '$app/state';
|
||||
import { slide, fade } from 'svelte/transition';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import { navigating } from '$app/state';
|
||||
import { LOCATIONS } from '$lib/locations-object.svelte';
|
||||
import { nearestStationsState } from '$lib/geohash.svelte';
|
||||
|
||||
import Loading from '$lib/components/ui/Loading.svelte';
|
||||
import TimezoneWarning from '$lib/components/ui/TimezoneWarning.svelte';
|
||||
|
||||
import '$lib/global.css';
|
||||
@@ -81,7 +82,12 @@
|
||||
|
||||
<main>
|
||||
<TimezoneWarning />
|
||||
{@render children()}
|
||||
|
||||
{#if navigating && navigating.to}
|
||||
<Loading />
|
||||
{:else}
|
||||
{@render children()}
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
<nav bind:clientWidth={navWidth}>
|
||||
|
||||
@@ -2,8 +2,11 @@
|
||||
import NoResults from '$lib/components/ui/NoResults.svelte';
|
||||
import TrainService from '$lib/components/ui/TrainService.svelte';
|
||||
let { data } = $props();
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
{#if data.results.length === 0}
|
||||
<NoResults
|
||||
message={"No trains found on this date with this headcode."}
|
||||
@@ -21,6 +24,7 @@
|
||||
width: 95%;
|
||||
margin: auto;
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
Reference in New Issue
Block a user