diff --git a/.gitea/workflows/build-push.yaml b/.gitea/workflows/build-push.yaml
index ec6d5d6..65ef29f 100644
--- a/.gitea/workflows/build-push.yaml
+++ b/.gitea/workflows/build-push.yaml
@@ -3,7 +3,7 @@ run-name: ${{ gitea.actor }} is building and pushing
on:
create:
- tags: "*"
+ tags: '*'
env:
GITEA_DOMAIN: git.fjla.uk
@@ -36,4 +36,4 @@ jobs:
push: true
tags: |
${{ env.GITEA_DOMAIN }}/${{ env.RESULT_IMAGE_NAME }}:${{ gitea.ref_name }}
- ${{ env.GITEA_DOMAIN }}/${{ env.RESULT_IMAGE_NAME }}:latest
\ No newline at end of file
+ ${{ env.GITEA_DOMAIN }}/${{ env.RESULT_IMAGE_NAME }}:latest
diff --git a/.gitignore b/.gitignore
index 4615b07..875ef67 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@ node_modules
# Transpiled JSON
/static/mapFiles/json/
+/static/map-index.json
# Output
.output
diff --git a/scripts/parse-maps.js b/scripts/parse-maps.js
index 3f5d580..eea8161 100644
--- a/scripts/parse-maps.js
+++ b/scripts/parse-maps.js
@@ -4,13 +4,30 @@ import path from 'path';
const inputDir = './static/mapFiles/yaml';
const outputDir = './static/mapFiles/json';
+const indexFile = './static/map-index.json';
if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });
+const mapList = [];
+
fs.readdirSync(inputDir).forEach((file) => {
if (file.endsWith('.yaml')) {
- const content = yaml.load(fs.readFileSync(path.join(inputDir, file), 'utf8'));
+ const fullPath = path.join(inputDir, file);
+ const content = yaml.load(fs.readFileSync(fullPath, 'utf8'));
+
const fileName = file.replace('.yaml', '.json');
fs.writeFileSync(path.join(outputDir, fileName), JSON.stringify(content));
+
+ mapList.push({
+ routeId: content.routeId || null,
+ routeStart: content.routeStart || null,
+ routeEnd: content.routeEnd || null,
+ created: content.created || null,
+ checked: content.checked || null,
+ });
}
});
+
+fs.writeFileSync(indexFile, JSON.stringify(mapList));
+
+console.log(`Generated ${mapList.length} map files and index.`)
diff --git a/src/lib/components/mapIcons/Bridge.svelte b/src/lib/components/mapIcons/Bridge.svelte
index 5d741ba..a20b0ff 100644
--- a/src/lib/components/mapIcons/Bridge.svelte
+++ b/src/lib/components/mapIcons/Bridge.svelte
@@ -1,80 +1,194 @@
diff --git a/src/lib/components/mapIcons/ElectrificationChange.svelte b/src/lib/components/mapIcons/ElectrificationChange.svelte
index 21e3978..84d4969 100644
--- a/src/lib/components/mapIcons/ElectrificationChange.svelte
+++ b/src/lib/components/mapIcons/ElectrificationChange.svelte
@@ -1,13 +1,14 @@
diff --git a/src/lib/components/mapIcons/RouteEndLink.svelte b/src/lib/components/mapIcons/RouteEndLink.svelte
index e9f808a..e4f6d69 100644
--- a/src/lib/components/mapIcons/RouteEndLink.svelte
+++ b/src/lib/components/mapIcons/RouteEndLink.svelte
@@ -1,93 +1,121 @@
+
-
- {#each dummyFeatures as feature}
-
- {/each}
+
+ /* Mobile-First Base Styles */
+ :global(body) {
+ margin: 0;
+ background-color: #f8fafc;
+ color: #0f172a;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
+ }
+
+ .page-wrapper {
+ padding: 1rem;
+ max-width: 800px;
+ margin: 0 auto;
+ }
+
+ .main-header {
+ margin-bottom: 1.5rem;
+ }
+
+ h1 {
+ font-size: 1.5rem;
+ font-weight: 900;
+ letter-spacing: -0.05em;
+ margin: 0 0 1rem 0;
+ font-style: italic;
+ }
+
+ .search-input {
+ width: 100%;
+ padding: 0.8rem 1rem;
+ border: 2px solid #e2e8f0;
+ border-radius: 12px;
+ font-size: 1rem;
+ box-sizing: border-box; /* Ensures padding doesn't break width */
+ outline: none;
+ }
+
+ .search-input:focus {
+ border-color: #3b82f6;
+ }
+
+ /* Card Layout (Mobile) */
+ .list-container {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ }
+
+ .card {
+ display: block;
+ background: white;
+ padding: 1.25rem;
+ border-radius: 16px;
+ text-decoration: none;
+ color: inherit;
+ border: 1px solid #e2e8f0;
+ box-shadow: 0 1px 3px rgba(0,0,0,0.05);
+ transition: transform 0.1s ease;
+ }
+
+ .card:active {
+ transform: scale(0.98); /* Tactile feedback for mobile */
+ }
+
+ .card-top {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 0.75rem;
+ }
+
+ .route-id {
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
+ font-weight: 800;
+ color: #3b82f6;
+ background: #eff6ff;
+ padding: 0.2rem 0.5rem;
+ border-radius: 6px;
+ }
+
+ .card-body {
+ margin-bottom: 1rem;
+ }
+
+ .location {
+ font-size: 1.125rem;
+ font-weight: 700;
+ letter-spacing: -0.02em;
+ }
+
+ .path-arrow {
+ color: #cbd5e1;
+ font-size: 0.9rem;
+ margin: 0.2rem 0;
+ }
+
+ .card-footer {
+ font-size: 0.7rem;
+ color: #64748b;
+ text-transform: uppercase;
+ font-weight: 600;
+ letter-spacing: 0.05em;
+ border-top: 1px solid #f1f5f9;
+ padding-top: 0.75rem;
+ }
+
+/* Update your existing badge styles */
+.status-badge {
+ font-size: 0.65rem;
+ font-weight: 800;
+ text-transform: uppercase;
+ padding: 0.3rem 0.6rem;
+ border-radius: 999px;
+ white-space: nowrap; /* Prevents label snapping on small screens */
+}
+
+.verified {
+ background: #dcfce7;
+ color: #166534;
+}
+
+.stale {
+ background: #fef3c7; /* Amber/Yellow background */
+ color: #92400e; /* Dark brown/gold text */
+ border: 1px solid #fcd34d;
+}
+
+.draft {
+ background: #f1f5f9;
+ color: #475569;
+}
+
+ /* Desktop Adjustments */
+ @media (min-width: 640px) {
+ .page-wrapper {
+ padding: 3rem 1.5rem;
+ }
+
+ .main-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ .search-input {
+ width: 300px;
+ }
+
+ .path-arrow {
+ display: inline-block;
+ margin: 0 0.5rem;
+ transform: rotate(-90deg); /* Turn down arrow into right arrow */
+ }
+
+ .card-body {
+ display: flex;
+ align-items: center;
+ }
+ }
+
\ No newline at end of file
diff --git a/src/routes/+page.ts b/src/routes/+page.ts
new file mode 100644
index 0000000..2816f68
--- /dev/null
+++ b/src/routes/+page.ts
@@ -0,0 +1,17 @@
+import type { PageLoad } from "./$types";
+
+export const load: PageLoad = async ({ fetch }) => {
+ const response = await fetch('map-index.json');
+
+ if (!response.ok) {
+ return { maps: [] };
+ }
+
+ const maps = await response.json();
+
+ return {
+ maps: maps.sort((a: any, b: any) => {
+ return Number(a.routeId) - Number(b.routeId);
+ })
+ };
+};
\ No newline at end of file
diff --git a/src/routes/healthz/+server.ts b/src/routes/healthz/+server.ts
index f0df974..120c728 100644
--- a/src/routes/healthz/+server.ts
+++ b/src/routes/healthz/+server.ts
@@ -2,7 +2,10 @@ import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
export const GET: RequestHandler = () => {
- return json({ status: 'ok', uptime: process.uptime() }, {
- status: 200
- });
-};
\ No newline at end of file
+ return json(
+ { status: 'ok', uptime: process.uptime() },
+ {
+ status: 200
+ }
+ );
+};
diff --git a/src/routes/map/[slug]/+page.svelte b/src/routes/map/[slug]/+page.svelte
index 429d058..c2dc869 100644
--- a/src/routes/map/[slug]/+page.svelte
+++ b/src/routes/map/[slug]/+page.svelte
@@ -1,9 +1,9 @@
-
+
{#if showFilters}
(showFilters = false)}>
@@ -108,53 +123,130 @@
{#each filteredFeatures as f, i (`${f.type}-${f.miles}-${f.chains}-${i}`)}
- {#if (f.type === 'continues')}
-
- {:else}
-
- {/if}
+ {#if f.type === 'continues'}
+
+ {:else}
+
+ {/if}
{/each}
+
diff --git a/static/mapFiles/yaml/0001.yaml b/static/mapFiles/yaml/0001.yaml
index 24b5859..95f1bfe 100644
--- a/static/mapFiles/yaml/0001.yaml
+++ b/static/mapFiles/yaml/0001.yaml
@@ -1,5 +1,8 @@
-routeName: Paddington - Reading West Jn
+routeStart: Paddington
+routeEnd: Reading West Jn
routeId: 0001
+created: 2026-02-04
+checked: 2026-02-06
signallerStart: TVSC Paddington WS
signallerEnd: TVSC Reading WS
elecStart:
@@ -437,7 +440,7 @@ routeDetail:
- type: bridge
name: Yeading Brook
position: under
- category: waterway
+ category: stream
miles: 10
chains: 29
@@ -579,7 +582,7 @@ routeDetail:
- type: bridge
name: Stream
position: under
- category: waterway
+ category: stream
miles: 14
chains: 10
@@ -627,7 +630,7 @@ routeDetail:
- type: bridge
name: Stream
position: under
- category: waterway
+ category: stream
miles: 15
chains: 61
@@ -861,7 +864,7 @@ routeDetail:
- type: bridge
name: Stream
position: under
- category: waterway
+ category: stream
miles: 23
chains: 66
@@ -1042,6 +1045,7 @@ routeDetail:
diverges: left
direction: down
description: Henley-on-Thames from Platform 4 only
+ elecBranch: none
miles: 31
chains: 4
diff --git a/static/mapFiles/yaml/0002.yaml b/static/mapFiles/yaml/0002.yaml
new file mode 100644
index 0000000..a0d74d0
--- /dev/null
+++ b/static/mapFiles/yaml/0002.yaml
@@ -0,0 +1,18 @@
+routeStart: Reading West Jn
+routeEnd: Bristol TM
+routeId: 0002
+created: 2026-02-04
+checked:
+signallerStart: TVSC Reading WS
+signallerEnd: TVSC Temple Meads WS
+elecStart:
+ elec: 25kvac
+ eco: Didcot (TVSC)
+elecEnd:
+ elec: none
+routeDetail:
+- type: crossovers
+ name: Scours Lane Junction
+ description: Line diverges
+ miles: 38
+ chains: 90
\ No newline at end of file