diff --git a/package.json b/package.json
index df1b5f6..21e25ea 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,7 @@
"@sveltejs/adapter-auto": "^3.3.1",
"@sveltejs/adapter-netlify": "^4.4.0",
"@sveltejs/kit": "^2.15.1",
- "@sveltejs/vite-plugin-svelte": "^3.1.2",
+ "@sveltejs/vite-plugin-svelte": "^4.0.0",
"@types/leaflet": "^1.9.15",
"@types/sanitize-html": "^2.13.0",
"@typescript-eslint/eslint-plugin": "^5.62.0",
@@ -27,9 +27,9 @@
"prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.2",
"sass": "^1.83.1",
- "svelte": "^4.2.19",
- "svelte-check": "^3.8.6",
- "svelte-preprocess": "^5.1.4",
+ "svelte": "^5.0.0",
+ "svelte-check": "^4.0.0",
+ "svelte-preprocess": "^6.0.0",
"tslib": "^2.8.1",
"typescript": "^5.7.2",
"vite": "^5.4.11",
diff --git a/src/components/SummerHours2024.svelte b/src/components/SummerHours2024.svelte
index 4bd4b97..bde23d5 100644
--- a/src/components/SummerHours2024.svelte
+++ b/src/components/SummerHours2024.svelte
@@ -1,5 +1,9 @@
diff --git a/src/components/games/ApiPasswordForm.svelte b/src/components/games/ApiPasswordForm.svelte
deleted file mode 100644
index 12bcc1a..0000000
--- a/src/components/games/ApiPasswordForm.svelte
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
- {#if apiPassword.length === 0}
-
- To save things to the ledger you need to enter the password. Right now you
- haven't set one.
-
- {/if}
- {#if state === "view"}
- Edit Password
- {:else}
-
- {/if}
-
diff --git a/src/components/games/FloriferousPlayerForm.svelte b/src/components/games/FloriferousPlayerForm.svelte
deleted file mode 100644
index 679f861..0000000
--- a/src/components/games/FloriferousPlayerForm.svelte
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
-
diff --git a/src/components/games/index.ts b/src/components/games/index.ts
deleted file mode 100644
index 2806140..0000000
--- a/src/components/games/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import FloriferousPlayerForm from './FloriferousPlayerForm.svelte';
-
-export { FloriferousPlayerForm, PreviousGameScores };
diff --git a/src/components/games/types.ts b/src/components/games/types.ts
deleted file mode 100644
index e69de29..0000000
diff --git a/src/components/salary-calculator/employee.svelte b/src/components/salary-calculator/employee.svelte
index 2f75a11..20414a9 100644
--- a/src/components/salary-calculator/employee.svelte
+++ b/src/components/salary-calculator/employee.svelte
@@ -1,10 +1,19 @@
diff --git a/src/routes/api/games/floriferous.json/+server.ts b/src/routes/api/games/floriferous.json/+server.ts
deleted file mode 100644
index e1a534e..0000000
--- a/src/routes/api/games/floriferous.json/+server.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { MONGO_URL, MONGO_DB_NAME, API_PASSWORD } from '$env/static/private';
-import type { error } from '@sveltejs/kit';
-import type { RequestHandler } from './$types';
-
-import { MongodbFloriferousGameRepository } from '$lib/floriferous/mongodb-floriferous-game-repository';
-import { FloriferousApiController } from '$lib/floriferous/floriferous-api-controller';
-import { SimplePasswordAuthenticator } from '$lib/simple-password-authenticator';
-import {
- FloriferousGameApiPort,
- type FloriferousGameJson
-} from '$lib/floriferous/floriferous-game-api-port';
-
-export const GET: RequestHandler = async () => {
- const controller = new FloriferousApiController(
- new MongodbFloriferousGameRepository(MONGO_URL, MONGO_DB_NAME),
- new SimplePasswordAuthenticator(API_PASSWORD)
- );
-
- const response = await controller.getRecentGames(10);
-
- return new Response(JSON.stringify(response), { status: 200 });
-};
-
-export const POST = async ({ request }) => {
- const controller = new FloriferousApiController(
- new MongodbFloriferousGameRepository(MONGO_URL, MONGO_DB_NAME),
- new SimplePasswordAuthenticator(API_PASSWORD)
- );
-
- const isAuthenticated = controller.isRequestAuthenticated(request);
-
- if (!isAuthenticated) {
- return {
- status: 401,
- body: 'Unauthorized'
- };
- }
-
- try {
- const requestBody = await request.json();
- const response = await controller.createNewGame(requestBody);
-
- return new Response(JSON.stringify(response), {
- status: 200
- });
- } catch (e) {
- return new Response(JSON.stringify(e), {
- status: 500
- });
- }
-};
diff --git a/src/routes/blog/+page.svelte b/src/routes/blog/+page.svelte
index 5c25dae..7df7d7a 100644
--- a/src/routes/blog/+page.svelte
+++ b/src/routes/blog/+page.svelte
@@ -3,16 +3,20 @@
import Navbar from "$lib/components/Navbar.svelte";
import BlogPostListItem from "./BlogPostListItem.svelte";
- export let data: PageData;
+ interface Props {
+ data: PageData;
+ }
- $: ({
+ let { data }: Props = $props();
+
+ let {
posts,
numberOfPosts,
daysSinceLastPublish,
daysSinceFirstPost,
averageDaysBetweenPosts,
numberOfBlogPostsThisYear,
- } = data);
+ } = $derived(data);
diff --git a/src/routes/blog/BlogPostListItem.svelte b/src/routes/blog/BlogPostListItem.svelte
index f5c8d3b..a614a74 100644
--- a/src/routes/blog/BlogPostListItem.svelte
+++ b/src/routes/blog/BlogPostListItem.svelte
@@ -1,16 +1,29 @@
+
-
\ No newline at end of file
+{@render children?.()}
\ No newline at end of file
diff --git a/src/routes/blog/[slug]/+page.svelte b/src/routes/blog/[slug]/+page.svelte
index 02ce341..0e0e567 100644
--- a/src/routes/blog/[slug]/+page.svelte
+++ b/src/routes/blog/[slug]/+page.svelte
@@ -4,8 +4,12 @@
import Navbar from "$lib/components/Navbar.svelte";
import { onMount } from "svelte";
- export let data: PageData;
- $: ({ date, post } = data);
+ interface Props {
+ data: PageData;
+ }
+
+ let { data }: Props = $props();
+ let { date, post } = $derived(data);
onMount(() => {
console.log({ date, post });
diff --git a/src/routes/blog/new/+page.svelte b/src/routes/blog/new/+page.svelte
index 1715678..de856ec 100644
--- a/src/routes/blog/new/+page.svelte
+++ b/src/routes/blog/new/+page.svelte
@@ -1,12 +1,14 @@
-
-
-
-
- Board Game Scoring & Ledgers
-
- I like to play board games, but tallying up scores for some of them is a nightmare. I'm
- building some tools to help me keep score.
-
-
-
-
-
diff --git a/src/routes/games/PreviousGameScores.svelte b/src/routes/games/PreviousGameScores.svelte
deleted file mode 100644
index 694e588..0000000
--- a/src/routes/games/PreviousGameScores.svelte
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
- {#if isVisible}
-
(isVisible = false)}>Hide Previous Scores
-
- {#each gameSummaries as summary}
-
- {summary}
-
- {/each}
-
- {:else}
-
(isVisible = true)}
- >Show {gameSummaries.length} Previous {gameSummaries.length === 1 ? 'Game' : 'Games'}
- {/if}
-
-
-
diff --git a/src/routes/games/floriferous/+page.svelte b/src/routes/games/floriferous/+page.svelte
deleted file mode 100644
index 4ec28d7..0000000
--- a/src/routes/games/floriferous/+page.svelte
+++ /dev/null
@@ -1,199 +0,0 @@
-
-
-
-
- Floriferous Scoring
-
- Floriferous is a board game published by Pencil First games, in which you find find joy in the
- abundance of nature.
-
-
-
-
-
-
-
- {#if isPlayersVisible}
- {#if players.length > 0}
-
- {#each players as player}
-
- {player.name} ({player.score} points, finished on row {player.rowAtEndOfGame}) ( onRemovePlayer(player)}>Remove )
-
- {/each}
-
-
- {#if players.length > 1}
- {#if isWinnerVisible}
- And the winner is:{game.winner}
- Add to Ledger
-
- (apiPassword = event.detail)} />
-
- {#if apiPassword.length > 0}
- You can save this game in the Ledger
- Save Game
- {/if}
- {:else}
- Show me the winner
- {/if}
- {/if}
- {:else}
- Add at least one player to get started
- {/if}
-
- {#if !isWinnerVisible}
- Add a New Player
-
- {/if}
- {/if}
-
-
- {#if previousGames.length > 0}
-
- {/if}
-
-
-
diff --git a/src/routes/games/floriferous/+page.ts b/src/routes/games/floriferous/+page.ts
deleted file mode 100644
index 3b89851..0000000
--- a/src/routes/games/floriferous/+page.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import {
- FloriferousGameApiPort,
- type FloriferousGameJson
-} from '$lib/floriferous/floriferous-game-api-port';
-import type { Load } from '@sveltejs/kit';
-
-export const load: Load = async ({ fetch }): Promise<{ previousGames: FloriferousGameJson[] }> => {
- const previousGames = await fetch('/api/games/floriferous.json').then((res) => res.json());
- return {
- previousGames: previousGames.map(FloriferousGameApiPort.jsonToGame)
- };
-};
diff --git a/src/routes/games/floriferous/FloriferousScoreCalculator.svelte b/src/routes/games/floriferous/FloriferousScoreCalculator.svelte
deleted file mode 100644
index 5bc58e3..0000000
--- a/src/routes/games/floriferous/FloriferousScoreCalculator.svelte
+++ /dev/null
@@ -1,188 +0,0 @@
-
-
-{#if isVisible}
-
-
-
Your score is {currentScore}
-
-
- {#each actions as action}
-
- +{action.score}
- {#if action.name.length > 0} ({action.name}) {/if}
-
- {/each}
-
-
-
-
-
-{/if}
-
-
diff --git a/src/routes/games/types.ts b/src/routes/games/types.ts
deleted file mode 100644
index 4e4897b..0000000
--- a/src/routes/games/types.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export interface PreviousGame {
- prettyString: string;
-}
diff --git a/src/routes/home/HomepageHeader.svelte b/src/routes/home/HomepageHeader.svelte
index a45421f..fbc9a42 100644
--- a/src/routes/home/HomepageHeader.svelte
+++ b/src/routes/home/HomepageHeader.svelte
@@ -7,7 +7,11 @@
date: string;
}
- export let latestBlogPosts: BlogPost[] = [];
+ interface Props {
+ latestBlogPosts?: BlogPost[];
+ }
+
+ let { latestBlogPosts = [] }: Props = $props();
-
- Projected Costs
- {#if salaryCalculationMethod === 'average'}
-
- With {totalNumberOfEmployees ?? 0}
- {totalNumberOfEmployees === 1 ? 'Attendee' : 'Attendees'}, each costing aprox. {formatCurrency(
- salaryCostPerMinute,
- currency
- )}
- per minute, this meeting will cost £{totalCostPerMinute} per minute.
-
- {:else}
- With the following attendees:
-
- {#each employees as employee}
- {employee.count} x {employee.name} @ {employee.salary}/year
- {/each}
-
- This meeting will cost £{totalCostPerMinute}/minute
- {/if}
+
+ Projected Costs
+ {#if salaryCalculationMethod === "average"}
+
+ With {totalNumberOfEmployees ?? 0}
+ {totalNumberOfEmployees === 1 ? "Attendee" : "Attendees"}, each costing
+ aprox. {formatCurrency(salaryCostPerMinute, currency)}
+ per minute, this meeting will cost £{totalCostPerMinute} per minute.
+
+ {:else}
+ With the following attendees:
+
+ {#each employees as employee}
+ {employee.count} x {employee.name} @ {employee.salary}/year
+ {/each}
+
+ This meeting will cost £{totalCostPerMinute}/minute
+ {/if}
- This meeting will cost:
+ This meeting will cost:
-
-
- {formatCurrency(salaryCostPerMinute * totalNumberOfEmployees * 30, currency)} for 30 minutes
-
-
- {formatCurrency(salaryCostPerMinute * totalNumberOfEmployees * 45, currency)} for 45 minutes
-
-
- {formatCurrency(salaryCostPerMinute * totalNumberOfEmployees * 60, currency)} for 60 minutes
-
-
-
+
+
+ {formatCurrency(
+ salaryCostPerMinute * totalNumberOfEmployees * 30,
+ currency
+ )} for 30 minutes
+
+
+ {formatCurrency(
+ salaryCostPerMinute * totalNumberOfEmployees * 45,
+ currency
+ )} for 45 minutes
+
+
+ {formatCurrency(
+ salaryCostPerMinute * totalNumberOfEmployees * 60,
+ currency
+ )} for 60 minutes
+
+
+
-
- Timed Costs
+
+ Timed Costs
-
- 0}
- >
- {#if secondsElapsed === 0}
- Start the Meeting
- {:else}
- Reset
- {/if}
-
- {intervalRef ? 'Pause' : 'Start'}
-
-
- Total cost so far: {formatCurrency(totalCost, currency)} over {formatSecondsToMinutes(
- secondsElapsed
- )}
-
-
+
+ 0}
+ >
+ {#if secondsElapsed === 0}
+ Start the Meeting
+ {:else}
+ Reset
+ {/if}
+
+ {intervalRef ? "Pause" : "Start"}
+
+
+ Total cost so far: {formatCurrency(totalCost, currency)} over {formatSecondsToMinutes(
+ secondsElapsed
+ )}
+
+
-
+
diff --git a/src/routes/payday/+page.svelte b/src/routes/payday/+page.svelte
index 097c6e6..4690160 100644
--- a/src/routes/payday/+page.svelte
+++ b/src/routes/payday/+page.svelte
@@ -7,14 +7,14 @@
differenceInCalendarDays
} from "date-fns";
- let lastDayOfMonth = new Date();
- let daysUntilPayDay = 0;
+ let lastDayOfMonth = $state(new Date());
+ let daysUntilPayDay = $state(0);
function prettyPrintDays(numberOfDays: number): string {
return `${numberOfDays} ${numberOfDays === 1 ? "day" : "days"}`;
}
- $: pluralisedDays = prettyPrintDays(Math.abs(daysUntilPayDay));
+ let pluralisedDays = $derived(prettyPrintDays(Math.abs(daysUntilPayDay)));
onMount(() => {
lastDayOfMonth = endOfMonth(new Date());
diff --git a/src/routes/snout-street-studios/[slug]/+layout.svelte b/src/routes/snout-street-studios/[slug]/+layout.svelte
index da2f715..37da23c 100644
--- a/src/routes/snout-street-studios/[slug]/+layout.svelte
+++ b/src/routes/snout-street-studios/[slug]/+layout.svelte
@@ -1,3 +1,11 @@
+
+
Snout St. Studios
-
+{@render children?.()}
diff --git a/src/routes/sunrise-sunset/+page.svelte b/src/routes/sunrise-sunset/+page.svelte
index 1bd198a..d2ac2c3 100644
--- a/src/routes/sunrise-sunset/+page.svelte
+++ b/src/routes/sunrise-sunset/+page.svelte
@@ -12,7 +12,7 @@
import { SunriseSunsetStreakCalculator } from "./SunriseSunsetStreakCalculator.js";
import type { ISunriseSunsetGuessingHistory } from "./ISunriseSunsetGuessingHistory.js";
- let hasGuessingHistoryBeenLoaded = false;
+ let hasGuessingHistoryBeenLoaded = $state(false);
let debug = false;
let visibleNotification: Writable<"none" | "success" | "failure"> =
writable("none");
@@ -25,15 +25,19 @@
incorrectDays: []
});
- export let data: PageData;
+ interface Props {
+ data: PageData;
+ }
+
+ let { data }: Props = $props();
const now = new Date();
const todaysDateString = formatDate(now, "yyyy-MM-dd");
const localStorageKey = "sunrise-sunset-guessing-history";
- let currentStreakLength = 0;
+ let currentStreakLength = $state(0);
const streakCalculator = new SunriseSunsetStreakCalculator(todaysDateString);
- $: picture = data.body.photo;
+ let picture = $derived(data.body.photo);
function debugRemoveLocalStorage() {
localStorage.removeItem(localStorageKey);
@@ -119,7 +123,7 @@
{#if debug}
- Remove Local Storage
+ Remove Local Storage
{/if}
diff --git a/src/routes/sunrise-sunset/NotificationSection.svelte b/src/routes/sunrise-sunset/NotificationSection.svelte
index b60999a..bb3eb9d 100644
--- a/src/routes/sunrise-sunset/NotificationSection.svelte
+++ b/src/routes/sunrise-sunset/NotificationSection.svelte
@@ -3,7 +3,11 @@
import { fade } from "svelte/transition";
import type { Writable } from "svelte/store";
- export let visibleNotification: Writable<"none" | "success" | "failure">;
+ interface Props {
+ visibleNotification: Writable<"none" | "success" | "failure">;
+ }
+
+ let { visibleNotification }: Props = $props();
let hasAnimationTriggered = false;
const revealResultDelayDurationMs = 550;
diff --git a/src/routes/sunrise-sunset/OptionsSection.svelte b/src/routes/sunrise-sunset/OptionsSection.svelte
index ce874e0..edba5f4 100644
--- a/src/routes/sunrise-sunset/OptionsSection.svelte
+++ b/src/routes/sunrise-sunset/OptionsSection.svelte
@@ -1,8 +1,12 @@
+
-
+{@render children?.()}
diff --git a/src/routes/wainwrights/+page.svelte b/src/routes/wainwrights/+page.svelte
index 9316923..e03cf47 100644
--- a/src/routes/wainwrights/+page.svelte
+++ b/src/routes/wainwrights/+page.svelte
@@ -5,9 +5,13 @@
import type { Wainwright } from './Wainwright.js';
import { browser } from '$app/environment';
- export let data: PageData;
+ interface Props {
+ data: PageData;
+ }
- $: ({ wainwrights } = data);
+ let { data }: Props = $props();
+
+ let { wainwrights } = $derived(data);
onMount(async () => {
const L = await import('leaflet');
@@ -58,7 +62,7 @@
and forteen fells (including four mountains). These have become known as the Wainwrights.
-
+