This commit is contained in:
Vincent van der Wal
2026-07-19 16:13:51 +02:00
parent e031716ce6
commit baa4840b38
26 changed files with 1077 additions and 702 deletions
+73 -6
View File
@@ -5,7 +5,7 @@
import { resolve } from '$app/paths';
import { page } from '$app/stores';
import { type GeoLocation, storedLocation } from '$lib/stores/settings';
import { type GeoLocation, type Theme, storedLocation, storedTheme } from '$lib/stores/settings';
import { buildLocationRoute } from '$lib/utils/location';
@@ -23,6 +23,19 @@
location = value;
});
const themeCycle: Theme[] = ['system', 'light', 'dark'];
const themeTitles: Record<Theme, string> = {
system: 'Theme: follow system',
light: 'Theme: light',
dark: 'Theme: dark'
};
function cycleTheme() {
storedTheme.update(
(current) => themeCycle[(themeCycle.indexOf(current) + 1) % themeCycle.length]
);
}
function navigateToLocation(newLocation: GeoLocation) {
storedLocation.set(newLocation);
const locationRoute = buildLocationRoute(newLocation);
@@ -54,17 +67,19 @@
<!-- Current location display -->
{#if location}
<div class="hidden items-center gap-2 sm:flex">
<div
class="hidden items-center gap-2 rounded-full border border-border/70 bg-muted/40 py-1 ps-1 pe-3 sm:flex"
>
<img
class="h-5 w-5 rounded-full"
class="h-6 w-6 rounded-full ring-1 ring-border"
src="/images/country-flags/{(location.country_code || 'united_nations').toLowerCase()}.svg"
alt={location.country}
/>
<span class="text-sm font-medium text-foreground">
<span class="text-sm font-semibold text-foreground">
{location.name}
</span>
{#if location.admin1 || location.country}
<span class="text-xs text-muted-foreground">
<span class="hidden text-xs text-muted-foreground lg:inline">
{#if location.admin1}{location.admin1},{/if}
{location.country}
</span>
@@ -75,7 +90,7 @@
<!-- Spacer -->
<div class="flex-1"></div>
<!-- Location search -->
<!-- Location search: primary way to switch places, so keep it loud -->
<div class="w-full max-w-sm md:max-w-md">
<LocationSearch
label="Search location..."
@@ -84,6 +99,58 @@
}}
/>
</div>
<!-- Theme toggle: system → light → dark -->
<button
class="flex h-9 w-9 shrink-0 cursor-pointer items-center justify-center rounded-full border border-border/70 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
onclick={cycleTheme}
title={themeTitles[$storedTheme]}
aria-label={themeTitles[$storedTheme]}
>
{#if $storedTheme === 'light'}
<!-- sun -->
<svg
class="h-4.5 w-4.5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
stroke-width="1.75"
>
<circle cx="12" cy="12" r="4" />
<path
stroke-linecap="round"
d="M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32 1.41 1.41M2 12h2m16 0h2M4.93 19.07l1.41-1.41m11.32-11.32 1.41-1.41"
/>
</svg>
{:else if $storedTheme === 'dark'}
<!-- moon -->
<svg
class="h-4.5 w-4.5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
stroke-width="1.75"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z"
/>
</svg>
{:else}
<!-- monitor (system) -->
<svg
class="h-4.5 w-4.5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
stroke-width="1.75"
>
<rect x="3" y="4" width="18" height="13" rx="2" />
<path stroke-linecap="round" d="M8 21h8m-4-4v4" />
</svg>
{/if}
</button>
</header>
<style>