refactor: $app/stores → $app/state, legacy stores → runes
Codemod-driven migration of 55 .svelte files from the deprecated $app/stores module to the rune-based $app/state ($page.x → page.x, no auto-subscription wrapper). Two custom writable() stores converted to .svelte.ts factory functions matching the existing theme store pattern, with consumers updated to use .value getters and the explicit .set() method. UserHeader.svelte's login link now guards page.url.search behind the browser flag — search-param access throws during prerender, and this defensive change unblocks future prerender adoption on any page that includes the header.
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "homepage",
|
"name": "homepage",
|
||||||
"version": "1.51.0",
|
"version": "1.52.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* Migrate `$app/stores` (deprecated) to `$app/state` (rune-based).
|
||||||
|
*
|
||||||
|
* For each .svelte file:
|
||||||
|
* - Rewrite `from '$app/stores'` → `from '$app/state'`
|
||||||
|
* - For each named import, drop the `$` prefix from auto-subscriptions:
|
||||||
|
* `$page.url.pathname` → `page.url.pathname`
|
||||||
|
* `$navigating` → `navigating`
|
||||||
|
* `$updated` → `updated`
|
||||||
|
* Aliased imports (`page as appPage`) are tracked, so `$appPage` becomes `appPage`.
|
||||||
|
*
|
||||||
|
* Skips:
|
||||||
|
* - Non-.svelte files (server-only code uses getRequestEvent instead).
|
||||||
|
* - Files importing other things from $app/stores that don't have a state equivalent
|
||||||
|
* (none observed in this repo).
|
||||||
|
*
|
||||||
|
* Run: pnpm exec vite-node scripts/codemod-app-stores-to-state.ts [--dry]
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { readFileSync, writeFileSync, readdirSync, statSync } from 'node:fs';
|
||||||
|
import { join, extname } from 'node:path';
|
||||||
|
|
||||||
|
const SRC = 'src';
|
||||||
|
const DRY = process.argv.includes('--dry');
|
||||||
|
|
||||||
|
const STORES_IMPORT_RE =
|
||||||
|
/import\s*\{([^}]+)\}\s*from\s*['"]\$app\/stores['"]\s*;?/;
|
||||||
|
|
||||||
|
function walk(dir: string, out: string[] = []): string[] {
|
||||||
|
for (const name of readdirSync(dir)) {
|
||||||
|
const p = join(dir, name);
|
||||||
|
const s = statSync(p);
|
||||||
|
if (s.isDirectory()) walk(p, out);
|
||||||
|
else if (extname(p) === '.svelte') out.push(p);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseImports(inner: string): Array<{ orig: string; local: string }> {
|
||||||
|
return inner
|
||||||
|
.split(',')
|
||||||
|
.map((s) => s.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
.map((spec) => {
|
||||||
|
const m = spec.match(/^(\w+)(?:\s+as\s+(\w+))?$/);
|
||||||
|
if (!m) return null;
|
||||||
|
return { orig: m[1], local: m[2] ?? m[1] };
|
||||||
|
})
|
||||||
|
.filter((x): x is { orig: string; local: string } => x !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rewriteFile(src: string): { code: string; changed: boolean } {
|
||||||
|
const m = STORES_IMPORT_RE.exec(src);
|
||||||
|
if (!m) return { code: src, changed: false };
|
||||||
|
|
||||||
|
const imports = parseImports(m[1]);
|
||||||
|
if (imports.length === 0) return { code: src, changed: false };
|
||||||
|
|
||||||
|
// Replace the import path; preserve the same import shape.
|
||||||
|
let out = src.replace(STORES_IMPORT_RE, (full) =>
|
||||||
|
full.replace(/['"]\$app\/stores['"]/, "'$app/state'")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Drop `$` prefix from each local name where it appears as a store
|
||||||
|
// auto-subscription (i.e. $name followed by a non-word boundary).
|
||||||
|
for (const { local } of imports) {
|
||||||
|
const re = new RegExp(`\\$${local}\\b`, 'g');
|
||||||
|
out = out.replace(re, local);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { code: out, changed: out !== src };
|
||||||
|
}
|
||||||
|
|
||||||
|
const files = walk(SRC);
|
||||||
|
let changed = 0;
|
||||||
|
for (const f of files) {
|
||||||
|
const orig = readFileSync(f, 'utf8');
|
||||||
|
const { code, changed: didChange } = rewriteFile(orig);
|
||||||
|
if (!didChange) continue;
|
||||||
|
if (!DRY) writeFileSync(f, code);
|
||||||
|
changed++;
|
||||||
|
console.log(` ${f}`);
|
||||||
|
}
|
||||||
|
console.log(`\n${DRY ? '[dry] ' : ''}${changed} files migrated`);
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { enhance } from '$app/forms';
|
import { enhance } from '$app/forms';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import Heart from '@lucide/svelte/icons/heart';
|
import Heart from '@lucide/svelte/icons/heart';
|
||||||
|
|
||||||
let { recipeId, isFavorite = $bindable(false), isLoggedIn = false } = $props<{ recipeId: string, isFavorite?: boolean, isLoggedIn?: boolean }>();
|
let { recipeId, isFavorite = $bindable(false), isLoggedIn = false } = $props<{ recipeId: string, isFavorite?: boolean, isLoggedIn?: boolean }>();
|
||||||
|
|
||||||
const recipeLang = $derived($page.url.pathname.split('/')[1] || 'rezepte');
|
const recipeLang = $derived(page.url.pathname.split('/')[1] || 'rezepte');
|
||||||
|
|
||||||
let isLoading = $state(false);
|
let isLoading = $state(false);
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { recipeTranslationStore } from '$lib/stores/recipeTranslation';
|
import { recipeTranslationStore } from '$lib/stores/recipeTranslation.svelte';
|
||||||
import { languageStore } from '$lib/stores/language';
|
import { languageStore } from '$lib/stores/language.svelte';
|
||||||
import { convertFitnessPath } from '$lib/js/fitnessI18n';
|
import { convertFitnessPath } from '$lib/js/fitnessI18n';
|
||||||
import { convertCospendPath } from '$lib/js/cospendI18n';
|
import { convertCospendPath } from '$lib/js/cospendI18n';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
let { lang = undefined }: { lang?: 'de' | 'en' | 'la' } = $props();
|
let { lang = undefined }: { lang?: 'de' | 'en' | 'la' } = $props();
|
||||||
|
|
||||||
// Use prop for display if provided (SSR-safe), otherwise fall back to store
|
// Use prop for display if provided (SSR-safe), otherwise fall back to store
|
||||||
const displayLang = $derived(lang ?? $languageStore);
|
const displayLang = $derived(lang ?? languageStore.value);
|
||||||
|
|
||||||
let currentPath = $state('');
|
let currentPath = $state('');
|
||||||
let langButton: HTMLButtonElement;
|
let langButton: HTMLButtonElement;
|
||||||
@@ -33,14 +33,14 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Whether the current page is a faith route (show LA option)
|
// Whether the current page is a faith route (show LA option)
|
||||||
const faithPath = $derived(currentPath || $page.url.pathname);
|
const faithPath = $derived(currentPath || page.url.pathname);
|
||||||
const isFaithRoute = $derived(
|
const isFaithRoute = $derived(
|
||||||
faithPath.startsWith('/glaube') || faithPath.startsWith('/faith') || faithPath.startsWith('/fides')
|
faithPath.startsWith('/glaube') || faithPath.startsWith('/faith') || faithPath.startsWith('/fides')
|
||||||
);
|
);
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
// Update current language and path when page changes (reactive to browser navigation)
|
// Update current language and path when page changes (reactive to browser navigation)
|
||||||
const path = $page.url.pathname;
|
const path = page.url.pathname;
|
||||||
currentPath = path;
|
currentPath = path;
|
||||||
|
|
||||||
if (path.startsWith('/recipes') || path.startsWith('/faith')) {
|
if (path.startsWith('/recipes') || path.startsWith('/faith')) {
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
|
|
||||||
// Compute target paths for each language (used as href for no-JS)
|
// Compute target paths for each language (used as href for no-JS)
|
||||||
function computeTargetPath(targetLang: 'de' | 'en' | 'la'): string {
|
function computeTargetPath(targetLang: 'de' | 'en' | 'la'): string {
|
||||||
const path = currentPath || $page.url.pathname;
|
const path = currentPath || page.url.pathname;
|
||||||
|
|
||||||
if (path.startsWith('/glaube') || path.startsWith('/faith') || path.startsWith('/fides')) {
|
if (path.startsWith('/glaube') || path.startsWith('/faith') || path.startsWith('/fides')) {
|
||||||
return convertFaithPath(path, targetLang);
|
return convertFaithPath(path, targetLang);
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use translated recipe slugs from page data when available (works during SSR)
|
// Use translated recipe slugs from page data when available (works during SSR)
|
||||||
const pageData = $page.data;
|
const pageData = page.data;
|
||||||
if (targetLang === 'en' && path.startsWith('/rezepte')) {
|
if (targetLang === 'en' && path.startsWith('/rezepte')) {
|
||||||
if (pageData?.englishShortName) {
|
if (pageData?.englishShortName) {
|
||||||
return `/recipes/${pageData.englishShortName}`;
|
return `/recipes/${pageData.englishShortName}`;
|
||||||
@@ -171,7 +171,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we have recipe translation data from store, use the correct short names
|
// If we have recipe translation data from store, use the correct short names
|
||||||
const recipeData = $recipeTranslationStore;
|
const recipeData = recipeTranslationStore.value;
|
||||||
if (recipeData) {
|
if (recipeData) {
|
||||||
if (lang === 'en' && recipeData.englishShortName) {
|
if (lang === 'en' && recipeData.englishShortName) {
|
||||||
await goto(`/recipes/${recipeData.englishShortName}`);
|
await goto(`/recipes/${recipeData.englishShortName}`);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import ErrorView from './ErrorView.svelte';
|
import ErrorView from './ErrorView.svelte';
|
||||||
import { getErrorTitle, getErrorDescription, errorLabels, pick } from '$lib/js/errorStrings';
|
import { getErrorTitle, getErrorDescription, errorLabels, pick } from '$lib/js/errorStrings';
|
||||||
@@ -18,8 +18,8 @@
|
|||||||
|
|
||||||
let { sectionHref, sectionLabel, isEnglish: isEnglishProp, extraActions }: Props = $props();
|
let { sectionHref, sectionLabel, isEnglish: isEnglishProp, extraActions }: Props = $props();
|
||||||
|
|
||||||
let status = $derived($page.status);
|
let status = $derived(page.status);
|
||||||
let error = $derived($page.error as any);
|
let error = $derived(page.error as any);
|
||||||
let bibleQuote = $derived(error?.bibleQuote);
|
let bibleQuote = $derived(error?.bibleQuote);
|
||||||
let detectedEnglish = $derived(error?.lang === 'en');
|
let detectedEnglish = $derived(error?.lang === 'en');
|
||||||
let isEnglish = $derived(isEnglishProp ?? detectedEnglish);
|
let isEnglish = $derived(isEnglishProp ?? detectedEnglish);
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
|
import { browser } from '$app/environment';
|
||||||
import LogIn from '@lucide/svelte/icons/log-in';
|
import LogIn from '@lucide/svelte/icons/log-in';
|
||||||
|
|
||||||
let { user, recipeLang = 'rezepte', lang = 'de' } = $props();
|
let { user, recipeLang = 'rezepte', lang = 'de' } = $props();
|
||||||
@@ -157,7 +158,7 @@
|
|||||||
<li><a href={resolve('/[recipeLang=recipeLang]/administration', { recipeLang })}>Administration</a></li>
|
<li><a href={resolve('/[recipeLang=recipeLang]/administration', { recipeLang })}>Administration</a></li>
|
||||||
{/if}
|
{/if}
|
||||||
<li><a href="https://sso.bocken.org/if/user/#/settings" >Einstellungen</a></li>
|
<li><a href="https://sso.bocken.org/if/user/#/settings" >Einstellungen</a></li>
|
||||||
<li><a href={`${resolve('/logout')}?callbackUrl=${encodeURIComponent(getLogoutCallbackUrl($page.url.pathname))}`}>Log Out</a></li>
|
<li><a href={`${resolve('/logout')}?callbackUrl=${encodeURIComponent(getLogoutCallbackUrl(page.url.pathname))}`}>Log Out</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -165,7 +166,7 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<a
|
<a
|
||||||
class="entry login-link"
|
class="entry login-link"
|
||||||
href={`${resolve('/login')}?callbackUrl=${encodeURIComponent($page.url.pathname + $page.url.search)}`}
|
href={`${resolve('/login')}?callbackUrl=${encodeURIComponent(page.url.pathname + (browser ? page.url.search : ''))}`}
|
||||||
aria-label={lang === 'de' ? 'Anmelden' : 'Login'}
|
aria-label={lang === 'de' ? 'Anmelden' : 'Login'}
|
||||||
title={lang === 'de' ? 'Anmelden' : 'Login'}
|
title={lang === 'de' ? 'Anmelden' : 'Login'}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import ProfilePicture from './ProfilePicture.svelte';
|
import ProfilePicture from './ProfilePicture.svelte';
|
||||||
import { formatCurrency } from '$lib/utils/formatters';
|
import { formatCurrency } from '$lib/utils/formatters';
|
||||||
import { detectCospendLang, locale, t } from '$lib/js/cospendI18n';
|
import { detectCospendLang, locale, t } from '$lib/js/cospendI18n';
|
||||||
|
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
const loc = $derived(locale(lang));
|
const loc = $derived(locale(lang));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import ProfilePicture from './ProfilePicture.svelte';
|
import ProfilePicture from './ProfilePicture.svelte';
|
||||||
import { formatCurrency as formatCurrencyUtil } from '$lib/utils/formatters';
|
import { formatCurrency as formatCurrencyUtil } from '$lib/utils/formatters';
|
||||||
import { detectCospendLang, locale, t } from '$lib/js/cospendI18n';
|
import { detectCospendLang, locale, t } from '$lib/js/cospendI18n';
|
||||||
|
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
const loc = $derived(locale(lang));
|
const loc = $derived(locale(lang));
|
||||||
|
|
||||||
let { initialBalance = null, initialDebtData = null } = $props<{ initialBalance?: any, initialDebtData?: any }>();
|
let { initialBalance = null, initialDebtData = null } = $props<{ initialBalance?: any, initialDebtData?: any }>();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import ProfilePicture from './ProfilePicture.svelte';
|
import ProfilePicture from './ProfilePicture.svelte';
|
||||||
import EditButton from '$lib/components/EditButton.svelte';
|
import EditButton from '$lib/components/EditButton.svelte';
|
||||||
import { getCategoryEmoji } from '$lib/utils/categories';
|
import { getCategoryEmoji } from '$lib/utils/categories';
|
||||||
@@ -13,9 +13,9 @@
|
|||||||
let { paymentId, onclose, onpaymentDeleted } = $props();
|
let { paymentId, onclose, onpaymentDeleted } = $props();
|
||||||
|
|
||||||
// Get session from page store
|
// Get session from page store
|
||||||
let session = $derived($page.data?.session);
|
let session = $derived(page.data?.session);
|
||||||
|
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
const root = $derived(cospendRoot(lang));
|
const root = $derived(cospendRoot(lang));
|
||||||
const loc = $derived(locale(lang));
|
const loc = $derived(locale(lang));
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<script>
|
<script>
|
||||||
import ProfilePicture from './ProfilePicture.svelte';
|
import ProfilePicture from './ProfilePicture.svelte';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { detectCospendLang, t } from '$lib/js/cospendI18n';
|
import { detectCospendLang, t } from '$lib/js/cospendI18n';
|
||||||
|
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
|
|
||||||
let {
|
let {
|
||||||
splitMethod = $bindable('equal'),
|
splitMethod = $bindable('equal'),
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { getEnrichedExerciseById } from '$lib/data/exercisedb';
|
import { getEnrichedExerciseById } from '$lib/data/exercisedb';
|
||||||
import { detectFitnessLang, fitnessSlugs } from '$lib/js/fitnessI18n';
|
import { detectFitnessLang, fitnessSlugs } from '$lib/js/fitnessI18n';
|
||||||
|
|
||||||
let { exerciseId, plain = false } = $props();
|
let { exerciseId, plain = false } = $props();
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const exercise = $derived(getEnrichedExerciseById(exerciseId, lang));
|
const exercise = $derived(getEnrichedExerciseById(exerciseId, lang));
|
||||||
const sl = $derived(fitnessSlugs(lang));
|
const sl = $derived(fitnessSlugs(lang));
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
import PersonStanding from '@lucide/svelte/icons/person-standing';
|
import PersonStanding from '@lucide/svelte/icons/person-standing';
|
||||||
import Shapes from '@lucide/svelte/icons/shapes';
|
import Shapes from '@lucide/svelte/icons/shapes';
|
||||||
import Weight from '@lucide/svelte/icons/weight';
|
import Weight from '@lucide/svelte/icons/weight';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
|
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const isEn = $derived(lang === 'en');
|
const isEn = $derived(lang === 'en');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { untrack } from 'svelte';
|
import { untrack } from 'svelte';
|
||||||
import Heart from '@lucide/svelte/icons/heart';
|
import Heart from '@lucide/svelte/icons/heart';
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
initialResults = undefined,
|
initialResults = undefined,
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const s = $derived(fitnessSlugs(lang));
|
const s = $derived(fitnessSlugs(lang));
|
||||||
const isEn = $derived(lang === 'en');
|
const isEn = $derived(lang === 'en');
|
||||||
const btnLabel = $derived(confirmLabel ?? t('log_food', lang));
|
const btnLabel = $derived(confirmLabel ?? t('log_food', lang));
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { detectFitnessLang } from '$lib/js/fitnessI18n';
|
import { detectFitnessLang } from '$lib/js/fitnessI18n';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import Beef from '@lucide/svelte/icons/beef';
|
import Beef from '@lucide/svelte/icons/beef';
|
||||||
import Droplet from '@lucide/svelte/icons/droplet';
|
import Droplet from '@lucide/svelte/icons/droplet';
|
||||||
import Wheat from '@lucide/svelte/icons/wheat';
|
import Wheat from '@lucide/svelte/icons/wheat';
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
showDetailRows = true,
|
showDetailRows = true,
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const isEn = $derived(lang === 'en');
|
const isEn = $derived(lang === 'en');
|
||||||
|
|
||||||
const macroPercent = $derived.by(() => {
|
const macroPercent = $derived.by(() => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { detectFitnessLang } from '$lib/js/fitnessI18n';
|
import { detectFitnessLang } from '$lib/js/fitnessI18n';
|
||||||
import frontSvgRaw from '$lib/assets/muscle-front.svg?raw';
|
import frontSvgRaw from '$lib/assets/muscle-front.svg?raw';
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
/** @type {{ data?: { totals?: Record<string, MuscleTotals> } | null }} */
|
/** @type {{ data?: { totals?: Record<string, MuscleTotals> } | null }} */
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const isEn = $derived(lang === 'en');
|
const isEn = $derived(lang === 'en');
|
||||||
/** @type {Record<string, MuscleTotals>} */
|
/** @type {Record<string, MuscleTotals>} */
|
||||||
const totals = $derived(data?.totals ?? {});
|
const totals = $derived(data?.totals ?? {});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { getExerciseById, getExerciseMetrics } from '$lib/data/exercises';
|
import { getExerciseById, getExerciseMetrics } from '$lib/data/exercises';
|
||||||
import Clock from '@lucide/svelte/icons/clock';
|
import Clock from '@lucide/svelte/icons/clock';
|
||||||
import Weight from '@lucide/svelte/icons/weight';
|
import Weight from '@lucide/svelte/icons/weight';
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
import Flame from '@lucide/svelte/icons/flame';
|
import Flame from '@lucide/svelte/icons/flame';
|
||||||
import { detectFitnessLang, fitnessSlugs } from '$lib/js/fitnessI18n';
|
import { detectFitnessLang, fitnessSlugs } from '$lib/js/fitnessI18n';
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const sl = $derived(fitnessSlugs(lang));
|
const sl = $derived(fitnessSlugs(lang));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
import Square from '@lucide/svelte/icons/square';
|
import Square from '@lucide/svelte/icons/square';
|
||||||
import { METRIC_LABELS } from '$lib/data/exercises';
|
import { METRIC_LABELS } from '$lib/data/exercises';
|
||||||
import RestTimer from './RestTimer.svelte';
|
import RestTimer from './RestTimer.svelte';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
|
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {{
|
* @type {{
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
import { getExerciseById } from '$lib/data/exercises';
|
import { getExerciseById } from '$lib/data/exercises';
|
||||||
import EllipsisVertical from '@lucide/svelte/icons/ellipsis-vertical';
|
import EllipsisVertical from '@lucide/svelte/icons/ellipsis-vertical';
|
||||||
import MapPin from '@lucide/svelte/icons/map-pin';
|
import MapPin from '@lucide/svelte/icons/map-pin';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
|
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {{
|
* @type {{
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import Play from '@lucide/svelte/icons/play';
|
|||||||
import Pause from '@lucide/svelte/icons/pause';
|
import Pause from '@lucide/svelte/icons/pause';
|
||||||
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
||||||
import SyncIndicator from '$lib/components/fitness/SyncIndicator.svelte';
|
import SyncIndicator from '$lib/components/fitness/SyncIndicator.svelte';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
|
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
|
|
||||||
let { href, elapsed = '0:00', paused = false, syncStatus = 'idle', onPauseToggle,
|
let { href, elapsed = '0:00', paused = false, syncStatus = 'idle', onPauseToggle,
|
||||||
restSeconds = 0, restTotal = 0, onRestAdjust = null, onRestSkip = null } = $props();
|
restSeconds = 0, restTotal = 0, onRestAdjust = null, onRestSkip = null } = $props();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { enhance } from '$app/forms';
|
import { enhance } from '$app/forms';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
|
|
||||||
let { item, multiplier = 1, yeastId = 0, lang = 'de' } = $props();
|
let { item, multiplier = 1, yeastId = 0, lang = 'de' } = $props();
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
: 'Zwischen Frischhefe und Trockenhefe wechseln');
|
: 'Zwischen Frischhefe und Trockenhefe wechseln');
|
||||||
|
|
||||||
// Get all current URL parameters to preserve state
|
// Get all current URL parameters to preserve state
|
||||||
const currentParams = $derived(browser ? new URLSearchParams(window.location.search) : $page.url.searchParams);
|
const currentParams = $derived(browser ? new URLSearchParams(window.location.search) : page.url.searchParams);
|
||||||
|
|
||||||
/** @param {Event} event */
|
/** @param {Event} event */
|
||||||
function toggleHefe(event) {
|
function toggleHefe(event) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { onNavigate } from "$app/navigation";
|
import { onNavigate } from "$app/navigation";
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import HefeSwapper from './HefeSwapper.svelte';
|
import HefeSwapper from './HefeSwapper.svelte';
|
||||||
import NutritionSummary from './NutritionSummary.svelte';
|
import NutritionSummary from './NutritionSummary.svelte';
|
||||||
import AddToFoodLogButton from './AddToFoodLogButton.svelte';
|
import AddToFoodLogButton from './AddToFoodLogButton.svelte';
|
||||||
@@ -272,7 +272,7 @@ const yeastIds = $derived.by(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Get all current URL parameters to preserve state in multiplier forms
|
// Get all current URL parameters to preserve state in multiplier forms
|
||||||
const currentParams = $derived(browser ? new URLSearchParams(window.location.search) : $page.url.searchParams);
|
const currentParams = $derived(browser ? new URLSearchParams(window.location.search) : page.url.searchParams);
|
||||||
|
|
||||||
// Progressive enhancement - use JS if available
|
// Progressive enhancement - use JS if available
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
export type Language = 'de' | 'en';
|
||||||
|
|
||||||
|
function createLanguage() {
|
||||||
|
let value = $state<Language>('de');
|
||||||
|
|
||||||
|
return {
|
||||||
|
get value() { return value; },
|
||||||
|
set: (v: Language) => { value = v; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const languageStore = createLanguage();
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
import { writable } from 'svelte/store';
|
|
||||||
|
|
||||||
type Language = 'de' | 'en';
|
|
||||||
|
|
||||||
function createLanguageStore() {
|
|
||||||
const { subscribe, set } = writable<Language>('de');
|
|
||||||
|
|
||||||
return {
|
|
||||||
subscribe,
|
|
||||||
set,
|
|
||||||
init: () => {
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
const path = window.location.pathname;
|
|
||||||
if (path.startsWith('/recipes') || path.startsWith('/faith')) {
|
|
||||||
set('en');
|
|
||||||
} else if (path.startsWith('/rezepte') || path.startsWith('/glaube')) {
|
|
||||||
set('de');
|
|
||||||
} else {
|
|
||||||
const preferredLanguage = localStorage.getItem('preferredLanguage');
|
|
||||||
set(preferredLanguage === 'en' ? 'en' : 'de');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export const languageStore = createLanguageStore();
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
export interface RecipeTranslationData {
|
||||||
|
germanShortName: string;
|
||||||
|
englishShortName?: string;
|
||||||
|
hasEnglishTranslation: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createRecipeTranslation() {
|
||||||
|
let value = $state<RecipeTranslationData | null>(null);
|
||||||
|
|
||||||
|
return {
|
||||||
|
get value() { return value; },
|
||||||
|
set: (v: RecipeTranslationData | null) => { value = v; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const recipeTranslationStore = createRecipeTranslation();
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import { writable } from 'svelte/store';
|
|
||||||
|
|
||||||
interface RecipeTranslationData {
|
|
||||||
germanShortName: string;
|
|
||||||
englishShortName?: string;
|
|
||||||
hasEnglishTranslation: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const recipeTranslationStore = writable<RecipeTranslationData | null>(null);
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import Header from '$lib/components/Header.svelte';
|
import Header from '$lib/components/Header.svelte';
|
||||||
import ErrorView from '$lib/components/ErrorView.svelte';
|
import ErrorView from '$lib/components/ErrorView.svelte';
|
||||||
import { getErrorTitle, getErrorDescription, errorLabels, pick } from '$lib/js/errorStrings';
|
import { getErrorTitle, getErrorDescription, errorLabels, pick } from '$lib/js/errorStrings';
|
||||||
|
|
||||||
let status = $derived($page.status);
|
let status = $derived(page.status);
|
||||||
let error = $derived($page.error as any);
|
let error = $derived(page.error as any);
|
||||||
|
|
||||||
let bibleQuote = $derived(error?.bibleQuote);
|
let bibleQuote = $derived(error?.bibleQuote);
|
||||||
let isEnglish = $derived(error?.lang === 'en');
|
let isEnglish = $derived(error?.lang === 'en');
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import SectionError from '$lib/components/SectionError.svelte';
|
import SectionError from '$lib/components/SectionError.svelte';
|
||||||
import { detectCospendLang, cospendRoot } from '$lib/js/cospendI18n';
|
import { detectCospendLang, cospendRoot } from '$lib/js/cospendI18n';
|
||||||
|
|
||||||
let lang = $derived(detectCospendLang($page.url.pathname));
|
let lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
let isEnglish = $derived(lang === 'en');
|
let isEnglish = $derived(lang === 'en');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { fly } from 'svelte/transition';
|
import { fly } from 'svelte/transition';
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
let { data, children } = $props();
|
let { data, children } = $props();
|
||||||
|
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
const root = $derived(cospendRoot(lang));
|
const root = $derived(cospendRoot(lang));
|
||||||
const labels = $derived(cospendLabels(lang));
|
const labels = $derived(cospendLabels(lang));
|
||||||
|
|
||||||
@@ -29,9 +29,9 @@
|
|||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
// Check if URL contains payment view route OR if we have paymentId in state
|
// Check if URL contains payment view route OR if we have paymentId in state
|
||||||
const match = $page.url.pathname.match(/\/(cospend|expenses)\/payments\/view\/([^\/]+)/);
|
const match = page.url.pathname.match(/\/(cospend|expenses)\/payments\/view\/([^\/]+)/);
|
||||||
const statePaymentId = $page.state?.paymentId;
|
const statePaymentId = page.state?.paymentId;
|
||||||
const isOnDashboard = $page.route.id === '/[cospendRoot=cospendRoot]/dash';
|
const isOnDashboard = page.route.id === '/[cospendRoot=cospendRoot]/dash';
|
||||||
|
|
||||||
// Only show modal if we're on the dashboard AND have a payment to show
|
// Only show modal if we're on the dashboard AND have a payment to show
|
||||||
if (isOnDashboard && (match || statePaymentId)) {
|
if (isOnDashboard && (match || statePaymentId)) {
|
||||||
@@ -49,14 +49,14 @@
|
|||||||
paymentId = null;
|
paymentId = null;
|
||||||
|
|
||||||
// Dispatch a custom event to trigger dashboard refresh
|
// Dispatch a custom event to trigger dashboard refresh
|
||||||
if ($page.route.id === '/[cospendRoot=cospendRoot]/dash') {
|
if (page.route.id === '/[cospendRoot=cospendRoot]/dash') {
|
||||||
window.dispatchEvent(new CustomEvent('dashboardRefresh'));
|
window.dispatchEvent(new CustomEvent('dashboardRefresh'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {string} path */
|
/** @param {string} path */
|
||||||
function isActive(path) {
|
function isActive(path) {
|
||||||
const currentPath = $page.url.pathname;
|
const currentPath = page.url.pathname;
|
||||||
// Exact match for dash
|
// Exact match for dash
|
||||||
if (path.endsWith('/dash')) {
|
if (path.endsWith('/dash')) {
|
||||||
return currentPath === path || currentPath === path + '/';
|
return currentPath === path || currentPath === path + '/';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { invalidateAll } from '$app/navigation';
|
import { invalidateAll } from '$app/navigation';
|
||||||
import { pushState } from '$app/navigation';
|
import { pushState } from '$app/navigation';
|
||||||
import ProfilePicture from '$lib/components/cospend/ProfilePicture.svelte';
|
import ProfilePicture from '$lib/components/cospend/ProfilePicture.svelte';
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
import { detectCospendLang, cospendRoot, t, locale, paymentCategoryName } from '$lib/js/cospendI18n';
|
import { detectCospendLang, cospendRoot, t, locale, paymentCategoryName } from '$lib/js/cospendI18n';
|
||||||
|
|
||||||
let { data } = $props(); // Contains session data and balance from server
|
let { data } = $props(); // Contains session data and balance from server
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
const root = $derived(cospendRoot(lang));
|
const root = $derived(cospendRoot(lang));
|
||||||
const loc = $derived(locale(lang));
|
const loc = $derived(locale(lang));
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
import Copy from '@lucide/svelte/icons/copy';
|
import Copy from '@lucide/svelte/icons/copy';
|
||||||
|
|
||||||
import Check from '@lucide/svelte/icons/check';
|
import Check from '@lucide/svelte/icons/check';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { detectCospendLang, t, locale, categoryName, formatTTL as formatTTLi18n, ttlOptions } from '$lib/js/cospendI18n';
|
import { detectCospendLang, t, locale, categoryName, formatTTL as formatTTLi18n, ttlOptions } from '$lib/js/cospendI18n';
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
const loc = $derived(locale(lang));
|
const loc = $derived(locale(lang));
|
||||||
|
|
||||||
/** @type {Record<string, { icon: typeof Plus, color: string }>} */
|
/** @type {Record<string, { icon: typeof Plus, color: string }>} */
|
||||||
@@ -355,7 +355,7 @@
|
|||||||
|
|
||||||
/** @param {{ id: string, token: string }} tok */
|
/** @param {{ id: string, token: string }} tok */
|
||||||
async function copyTokenLink(tok) {
|
async function copyTokenLink(tok) {
|
||||||
const root = $page.url.pathname.split('/')[1];
|
const root = page.url.pathname.split('/')[1];
|
||||||
const url = new URL(`/${root}/list`, window.location.origin);
|
const url = new URL(`/${root}/list`, window.location.origin);
|
||||||
url.searchParams.set('token', tok.token);
|
url.searchParams.set('token', tok.token);
|
||||||
await navigator.clipboard.writeText(url.toString());
|
await navigator.clipboard.writeText(url.toString());
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import ProfilePicture from '$lib/components/cospend/ProfilePicture.svelte';
|
import ProfilePicture from '$lib/components/cospend/ProfilePicture.svelte';
|
||||||
import { getCategoryEmoji } from '$lib/utils/categories';
|
import { getCategoryEmoji } from '$lib/utils/categories';
|
||||||
import { toast } from '$lib/js/toast.svelte';
|
import { toast } from '$lib/js/toast.svelte';
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
import { formatCurrency } from '$lib/utils/formatters';
|
import { formatCurrency } from '$lib/utils/formatters';
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
const root = $derived(cospendRoot(lang));
|
const root = $derived(cospendRoot(lang));
|
||||||
const loc = $derived(locale(lang));
|
const loc = $derived(locale(lang));
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { enhance } from '$app/forms';
|
import { enhance } from '$app/forms';
|
||||||
import { detectCospendLang, cospendRoot, locale, t, getCategoryOptionsI18n, frequencyDescription } from '$lib/js/cospendI18n';
|
import { detectCospendLang, cospendRoot, locale, t, getCategoryOptionsI18n, frequencyDescription } from '$lib/js/cospendI18n';
|
||||||
import { PREDEFINED_USERS, isPredefinedUsersMode } from '$lib/config/users';
|
import { PREDEFINED_USERS, isPredefinedUsersMode } from '$lib/config/users';
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
let { data, form } = $props();
|
let { data, form } = $props();
|
||||||
|
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
const root = $derived(cospendRoot(lang));
|
const root = $derived(cospendRoot(lang));
|
||||||
const loc = $derived(locale(lang));
|
const loc = $derived(locale(lang));
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { detectCospendLang, cospendRoot, locale, t, getCategoryOptionsI18n } from '$lib/js/cospendI18n';
|
import { detectCospendLang, cospendRoot, locale, t, getCategoryOptionsI18n } from '$lib/js/cospendI18n';
|
||||||
import { confirm } from '$lib/js/confirmDialog.svelte';
|
import { confirm } from '$lib/js/confirmDialog.svelte';
|
||||||
import FormSection from '$lib/components/FormSection.svelte';
|
import FormSection from '$lib/components/FormSection.svelte';
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
const root = $derived(cospendRoot(lang));
|
const root = $derived(cospendRoot(lang));
|
||||||
const loc = $derived(locale(lang));
|
const loc = $derived(locale(lang));
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { goto, invalidateAll } from '$app/navigation';
|
import { goto, invalidateAll } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import ProfilePicture from '$lib/components/cospend/ProfilePicture.svelte';
|
import ProfilePicture from '$lib/components/cospend/ProfilePicture.svelte';
|
||||||
import { getCategoryEmoji } from '$lib/utils/categories';
|
import { getCategoryEmoji } from '$lib/utils/categories';
|
||||||
import EditButton from '$lib/components/EditButton.svelte';
|
import EditButton from '$lib/components/EditButton.svelte';
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
const root = $derived(cospendRoot(lang));
|
const root = $derived(cospendRoot(lang));
|
||||||
const loc = $derived(locale(lang));
|
const loc = $derived(locale(lang));
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
import AddButton from '$lib/components/AddButton.svelte';
|
import AddButton from '$lib/components/AddButton.svelte';
|
||||||
import { formatCurrency } from '$lib/utils/formatters';
|
import { formatCurrency } from '$lib/utils/formatters';
|
||||||
import Toggle from '$lib/components/Toggle.svelte';
|
import Toggle from '$lib/components/Toggle.svelte';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { detectCospendLang, cospendRoot, t, locale, paymentCategoryName, frequencyDescription, formatNextExecutionI18n } from '$lib/js/cospendI18n';
|
import { detectCospendLang, cospendRoot, t, locale, paymentCategoryName, frequencyDescription, formatNextExecutionI18n } from '$lib/js/cospendI18n';
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
const root = $derived(cospendRoot(lang));
|
const root = $derived(cospendRoot(lang));
|
||||||
const loc = $derived(locale(lang));
|
const loc = $derived(locale(lang));
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { detectCospendLang, cospendRoot, locale, t, getCategoryOptionsI18n, frequencyDescription } from '$lib/js/cospendI18n';
|
import { detectCospendLang, cospendRoot, locale, t, getCategoryOptionsI18n, frequencyDescription } from '$lib/js/cospendI18n';
|
||||||
import { PREDEFINED_USERS, isPredefinedUsersMode } from '$lib/config/users';
|
import { PREDEFINED_USERS, isPredefinedUsersMode } from '$lib/config/users';
|
||||||
import { validateCronExpression, calculateNextExecutionDate } from '$lib/utils/recurring';
|
import { validateCronExpression, calculateNextExecutionDate } from '$lib/utils/recurring';
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
const root = $derived(cospendRoot(lang));
|
const root = $derived(cospendRoot(lang));
|
||||||
const loc = $derived(locale(lang));
|
const loc = $derived(locale(lang));
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { enhance } from '$app/forms';
|
import { enhance } from '$app/forms';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import ProfilePicture from '$lib/components/cospend/ProfilePicture.svelte';
|
import ProfilePicture from '$lib/components/cospend/ProfilePicture.svelte';
|
||||||
import { PREDEFINED_USERS, isPredefinedUsersMode } from '$lib/config/users';
|
import { PREDEFINED_USERS, isPredefinedUsersMode } from '$lib/config/users';
|
||||||
import { detectCospendLang, cospendRoot, t, locale } from '$lib/js/cospendI18n';
|
import { detectCospendLang, cospendRoot, t, locale } from '$lib/js/cospendI18n';
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
let { data, form } = $props();
|
let { data, form } = $props();
|
||||||
|
|
||||||
const lang = $derived(detectCospendLang($page.url.pathname));
|
const lang = $derived(detectCospendLang(page.url.pathname));
|
||||||
const root = $derived(cospendRoot(lang));
|
const root = $derived(cospendRoot(lang));
|
||||||
const loc = $derived(locale(lang));
|
const loc = $derived(locale(lang));
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import SectionError from '$lib/components/SectionError.svelte';
|
import SectionError from '$lib/components/SectionError.svelte';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
|
|
||||||
let faithLang = $derived($page.params.faithLang!);
|
let faithLang = $derived(page.params.faithLang!);
|
||||||
let isEnglish = $derived(faithLang === 'faith');
|
let isEnglish = $derived(faithLang === 'faith');
|
||||||
let sectionLabel = $derived(
|
let sectionLabel = $derived(
|
||||||
faithLang === 'fides'
|
faithLang === 'fides'
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { asset, resolve } from '$app/paths';
|
import { asset, resolve } from '$app/paths';
|
||||||
import '$lib/css/christ.css';
|
import '$lib/css/christ.css';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import Header from '$lib/components/Header.svelte'
|
import Header from '$lib/components/Header.svelte'
|
||||||
import UserHeader from '$lib/components/UserHeader.svelte';
|
import UserHeader from '$lib/components/UserHeader.svelte';
|
||||||
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
|
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
|
||||||
@@ -39,7 +39,7 @@ const typedLang = $derived(/** @type {'de' | 'en'} */ (data.lang));
|
|||||||
|
|
||||||
/** @param {string} path */
|
/** @param {string} path */
|
||||||
function isActive(path) {
|
function isActive(path) {
|
||||||
const currentPath = $page.url.pathname;
|
const currentPath = page.url.pathname;
|
||||||
return currentPath.startsWith(path);
|
return currentPath.startsWith(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import ArrowDown from '@lucide/svelte/icons/arrow-down';
|
import ArrowDown from '@lucide/svelte/icons/arrow-down';
|
||||||
import ArrowLeft from '@lucide/svelte/icons/arrow-left';
|
import ArrowLeft from '@lucide/svelte/icons/arrow-left';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import ApologetikToc from '$lib/components/faith/ApologetikToc.svelte';
|
import ApologetikToc from '$lib/components/faith/ApologetikToc.svelte';
|
||||||
/** @type {number | string | null} */
|
/** @type {number | string | null} */
|
||||||
let expanded = $state(null);
|
let expanded = $state(null);
|
||||||
const isGerman = $derived($page.url.pathname.startsWith('/glaube'));
|
const isGerman = $derived(page.url.pathname.startsWith('/glaube'));
|
||||||
const isLatin = $derived($page.url.pathname.startsWith('/fides'));
|
const isLatin = $derived(page.url.pathname.startsWith('/fides'));
|
||||||
|
|
||||||
/** @param {number | string} id */
|
/** @param {number | string} id */
|
||||||
function toggle(id) {
|
function toggle(id) {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import SectionError from '$lib/components/SectionError.svelte';
|
import SectionError from '$lib/components/SectionError.svelte';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
|
|
||||||
let recipeLang = $derived($page.params.recipeLang!);
|
let recipeLang = $derived(page.params.recipeLang!);
|
||||||
let isEnglish = $derived(recipeLang === 'recipes');
|
let isEnglish = $derived(recipeLang === 'recipes');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import '$lib/css/recipe-links.css';
|
import '$lib/css/recipe-links.css';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { onNavigate } from '$app/navigation';
|
import { onNavigate } from '$app/navigation';
|
||||||
import Header from '$lib/components/Header.svelte'
|
import Header from '$lib/components/Header.svelte'
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ const labels = $derived({
|
|||||||
|
|
||||||
/** @param {string} path */
|
/** @param {string} path */
|
||||||
function isActive(path) {
|
function isActive(path) {
|
||||||
const currentPath = $page.url.pathname;
|
const currentPath = page.url.pathname;
|
||||||
// Exact match for recipe lang root
|
// Exact match for recipe lang root
|
||||||
if (path === `/${data.recipeLang}`) {
|
if (path === `/${data.recipeLang}`) {
|
||||||
return currentPath === `/${data.recipeLang}` || currentPath === `/${data.recipeLang}/`;
|
return currentPath === `/${data.recipeLang}` || currentPath === `/${data.recipeLang}/`;
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import ErrorView from '$lib/components/ErrorView.svelte';
|
import ErrorView from '$lib/components/ErrorView.svelte';
|
||||||
import { getErrorTitle, getErrorDescription, errorLabels, pick } from '$lib/js/errorStrings';
|
import { getErrorTitle, getErrorDescription, errorLabels, pick } from '$lib/js/errorStrings';
|
||||||
|
|
||||||
let status = $derived($page.status);
|
let status = $derived(page.status);
|
||||||
let error = $derived($page.error as any);
|
let error = $derived(page.error as any);
|
||||||
let recipeLang = $derived($page.params.recipeLang);
|
let recipeLang = $derived(page.params.recipeLang);
|
||||||
let recipeName = $derived($page.params.name);
|
let recipeName = $derived(page.params.name);
|
||||||
let user = $derived($page.data?.session?.user);
|
let user = $derived(page.data?.session?.user);
|
||||||
|
|
||||||
let isEnglishRoute = $derived(recipeLang === 'recipes');
|
let isEnglishRoute = $derived(recipeLang === 'recipes');
|
||||||
let isEnglish = $derived(error?.lang === 'en' || isEnglishRoute);
|
let isEnglish = $derived(error?.lang === 'en' || isEnglishRoute);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
import RecipeNote from '$lib/components/recipes/RecipeNote.svelte';
|
import RecipeNote from '$lib/components/recipes/RecipeNote.svelte';
|
||||||
import FavoriteButton from '$lib/components/FavoriteButton.svelte';
|
import FavoriteButton from '$lib/components/FavoriteButton.svelte';
|
||||||
import { onDestroy } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
import { recipeTranslationStore } from '$lib/stores/recipeTranslation';
|
import { recipeTranslationStore } from '$lib/stores/recipeTranslation.svelte';
|
||||||
|
|
||||||
let { data } = $props<{ data: PageData }>();
|
let { data } = $props<{ data: PageData }>();
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount, tick } from 'svelte';
|
import { onMount, tick } from 'svelte';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ let { data } = $props();
|
|||||||
onMount(() => {
|
onMount(() => {
|
||||||
// Only proceed if we're actually offline or have a redirect target
|
// Only proceed if we're actually offline or have a redirect target
|
||||||
// This prevents issues if someone navigates here directly while online
|
// This prevents issues if someone navigates here directly while online
|
||||||
const targetUrl = $page.url.searchParams.get('redirect');
|
const targetUrl = page.url.searchParams.get('redirect');
|
||||||
|
|
||||||
if (!targetUrl) {
|
if (!targetUrl) {
|
||||||
// No redirect target - just go to main recipe list
|
// No redirect target - just go to main recipe list
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import SectionError from '$lib/components/SectionError.svelte';
|
import SectionError from '$lib/components/SectionError.svelte';
|
||||||
import { detectFitnessLang } from '$lib/js/fitnessI18n';
|
import { detectFitnessLang } from '$lib/js/fitnessI18n';
|
||||||
|
|
||||||
let lang = $derived(detectFitnessLang($page.url.pathname));
|
let lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
let isEnglish = $derived(lang === 'en');
|
let isEnglish = $derived(lang === 'en');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { onMount, onDestroy } from 'svelte';
|
import { onMount, onDestroy } from 'svelte';
|
||||||
import Header from '$lib/components/Header.svelte';
|
import Header from '$lib/components/Header.svelte';
|
||||||
import UserHeader from '$lib/components/UserHeader.svelte';
|
import UserHeader from '$lib/components/UserHeader.svelte';
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
const workout = getWorkout();
|
const workout = getWorkout();
|
||||||
const sync = getWorkoutSync();
|
const sync = getWorkoutSync();
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const s = $derived(fitnessSlugs(lang));
|
const s = $derived(fitnessSlugs(lang));
|
||||||
const labels = $derived(fitnessLabels(lang));
|
const labels = $derived(fitnessLabels(lang));
|
||||||
|
|
||||||
@@ -63,22 +63,22 @@
|
|||||||
|
|
||||||
/** @param {string} path */
|
/** @param {string} path */
|
||||||
function isActive(path) {
|
function isActive(path) {
|
||||||
const currentPath = $page.url.pathname;
|
const currentPath = page.url.pathname;
|
||||||
return currentPath.startsWith(path);
|
return currentPath.startsWith(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
const activePath = $derived(`/fitness/${s.workout}/${s.active}`);
|
const activePath = $derived(`/fitness/${s.workout}/${s.active}`);
|
||||||
const isOnActivePage = $derived($page.url.pathname === activePath);
|
const isOnActivePage = $derived(page.url.pathname === activePath);
|
||||||
const isNutritionPage = $derived(
|
const isNutritionPage = $derived(
|
||||||
$page.url.pathname.startsWith(`/fitness/${s.nutrition}`) &&
|
page.url.pathname.startsWith(`/fitness/${s.nutrition}`) &&
|
||||||
!$page.url.pathname.startsWith(`/fitness/${s.nutrition}/food`) &&
|
!page.url.pathname.startsWith(`/fitness/${s.nutrition}/food`) &&
|
||||||
!$page.url.pathname.startsWith(`/fitness/${s.nutrition}/meals`)
|
!page.url.pathname.startsWith(`/fitness/${s.nutrition}/meals`)
|
||||||
);
|
);
|
||||||
const isMeasureIndex = $derived(
|
const isMeasureIndex = $derived(
|
||||||
/^\/fitness\/(check-in|erfassung)\/?$/.test($page.url.pathname)
|
/^\/fitness\/(check-in|erfassung)\/?$/.test(page.url.pathname)
|
||||||
);
|
);
|
||||||
const isExercisesIndex = $derived(
|
const isExercisesIndex = $derived(
|
||||||
/^\/fitness\/(exercises|uebungen)\/?$/.test($page.url.pathname)
|
/^\/fitness\/(exercises|uebungen)\/?$/.test(page.url.pathname)
|
||||||
);
|
);
|
||||||
/** @param {number} secs */
|
/** @param {number} secs */
|
||||||
function formatElapsed(secs) {
|
function formatElapsed(secs) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import Pencil from '@lucide/svelte/icons/pencil';
|
import Pencil from '@lucide/svelte/icons/pencil';
|
||||||
import Trash2 from '@lucide/svelte/icons/trash-2';
|
import Trash2 from '@lucide/svelte/icons/trash-2';
|
||||||
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
`viewBox="0 ${BP_VIEW_TOP} 660.46 ${BP_VIEW_H}"`
|
`viewBox="0 ${BP_VIEW_TOP} 660.46 ${BP_VIEW_H}"`
|
||||||
);
|
);
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const checkinSlug = $derived(lang === 'en' ? 'check-in' : 'erfassung');
|
const checkinSlug = $derived(lang === 'en' ? 'check-in' : 'erfassung');
|
||||||
import { getWorkout } from '$lib/js/workout.svelte';
|
import { getWorkout } from '$lib/js/workout.svelte';
|
||||||
import PeriodTracker from '$lib/components/fitness/PeriodTracker.svelte';
|
import PeriodTracker from '$lib/components/fitness/PeriodTracker.svelte';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import Minus from '@lucide/svelte/icons/minus';
|
import Minus from '@lucide/svelte/icons/minus';
|
||||||
import Plus from '@lucide/svelte/icons/plus';
|
import Plus from '@lucide/svelte/icons/plus';
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const checkinSlug = $derived(lang === 'en' ? 'check-in' : 'erfassung');
|
const checkinSlug = $derived(lang === 'en' ? 'check-in' : 'erfassung');
|
||||||
|
|
||||||
/** @typedef {{ key: string, labelKey: string, img: string | null, paired: boolean, tipKey: string, dbSingle?: string, dbLeft?: string, dbRight?: string }} Step */
|
/** @typedef {{ key: string, labelKey: string, img: string | null, paired: boolean, tipKey: string, dbSingle?: string, dbLeft?: string, dbRight?: string }} Step */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
|
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
|
||||||
import { toast } from '$lib/js/toast.svelte';
|
import { toast } from '$lib/js/toast.svelte';
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
import SaveFab from '$lib/components/SaveFab.svelte';
|
import SaveFab from '$lib/components/SaveFab.svelte';
|
||||||
import DatePicker from '$lib/components/DatePicker.svelte';
|
import DatePicker from '$lib/components/DatePicker.svelte';
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const checkinSlug = $derived(lang === 'en' ? 'check-in' : 'erfassung');
|
const checkinSlug = $derived(lang === 'en' ? 'check-in' : 'erfassung');
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import Search from '@lucide/svelte/icons/search';
|
import Search from '@lucide/svelte/icons/search';
|
||||||
import Cable from '@lucide/svelte/icons/cable';
|
import Cable from '@lucide/svelte/icons/cable';
|
||||||
import Cog from '@lucide/svelte/icons/cog';
|
import Cog from '@lucide/svelte/icons/cog';
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
import { MUSCLE_GROUPS, MUSCLE_GROUP_DE } from '$lib/data/muscleMap';
|
import { MUSCLE_GROUPS, MUSCLE_GROUP_DE } from '$lib/data/muscleMap';
|
||||||
import MuscleFilter from '$lib/components/fitness/MuscleFilter.svelte';
|
import MuscleFilter from '$lib/components/fitness/MuscleFilter.svelte';
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const isEn = $derived(lang === 'en');
|
const isEn = $derived(lang === 'en');
|
||||||
const sl = $derived(fitnessSlugs(lang));
|
const sl = $derived(fitnessSlugs(lang));
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
|
|
||||||
/** @param {string | undefined | null} type @param {'en'|'de'} lang */
|
/** @param {string | undefined | null} type @param {'en'|'de'} lang */
|
||||||
function exerciseTypeInfo(type, lang) {
|
function exerciseTypeInfo(type, lang) {
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
}
|
}
|
||||||
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
|
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
|
||||||
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const s = $derived(fitnessSlugs(lang));
|
const s = $derived(fitnessSlugs(lang));
|
||||||
import FitnessChart from '$lib/components/fitness/FitnessChart.svelte';
|
import FitnessChart from '$lib/components/fitness/FitnessChart.svelte';
|
||||||
import MuscleMap from '$lib/components/fitness/MuscleMap.svelte';
|
import MuscleMap from '$lib/components/fitness/MuscleMap.svelte';
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page as appPage } from '$app/stores';
|
import { page as appPage } from '$app/state';
|
||||||
import ChevronLeft from '@lucide/svelte/icons/chevron-left';
|
import ChevronLeft from '@lucide/svelte/icons/chevron-left';
|
||||||
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
||||||
import SessionCard from '$lib/components/fitness/SessionCard.svelte';
|
import SessionCard from '$lib/components/fitness/SessionCard.svelte';
|
||||||
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
|
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($appPage.url.pathname));
|
const lang = $derived(detectFitnessLang(appPage.url.pathname));
|
||||||
const s = $derived(fitnessSlugs(lang));
|
const s = $derived(fitnessSlugs(lang));
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { goto, invalidateAll } from '$app/navigation';
|
import { goto, invalidateAll } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import Clock from '@lucide/svelte/icons/clock';
|
import Clock from '@lucide/svelte/icons/clock';
|
||||||
import Weight from '@lucide/svelte/icons/weight';
|
import Weight from '@lucide/svelte/icons/weight';
|
||||||
import Trophy from '@lucide/svelte/icons/trophy';
|
import Trophy from '@lucide/svelte/icons/trophy';
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
import { confirm } from '$lib/js/confirmDialog.svelte';
|
import { confirm } from '$lib/js/confirmDialog.svelte';
|
||||||
import { toast } from '$lib/js/toast.svelte';
|
import { toast } from '$lib/js/toast.svelte';
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const sl = $derived(fitnessSlugs(lang));
|
const sl = $derived(fitnessSlugs(lang));
|
||||||
import { getExerciseById, getExerciseMetrics, METRIC_LABELS } from '$lib/data/exercises';
|
import { getExerciseById, getExerciseMetrics, METRIC_LABELS } from '$lib/data/exercises';
|
||||||
import { formatPaceRangeLabel, formatPaceValue } from '$lib/data/cardioPrRanges';
|
import { formatPaceRangeLabel, formatPaceValue } from '$lib/data/cardioPrRanges';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { goto, invalidateAll } from '$app/navigation';
|
import { goto, invalidateAll } from '$app/navigation';
|
||||||
import ChevronLeft from '@lucide/svelte/icons/chevron-left';
|
import ChevronLeft from '@lucide/svelte/icons/chevron-left';
|
||||||
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
* }} FoodSelection
|
* }} FoodSelection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const s = $derived(fitnessSlugs(lang));
|
const s = $derived(fitnessSlugs(lang));
|
||||||
const isEn = $derived(lang === 'en');
|
const isEn = $derived(lang === 'en');
|
||||||
|
|
||||||
@@ -641,7 +641,7 @@
|
|||||||
let inlineTab = $state('search'); // 'search' | 'favorites' | 'meals'
|
let inlineTab = $state('search'); // 'search' | 'favorites' | 'meals'
|
||||||
|
|
||||||
// --- FAB modal (route-based via ?add param) ---
|
// --- FAB modal (route-based via ?add param) ---
|
||||||
const showFabModal = $derived($page.url.searchParams.has('add'));
|
const showFabModal = $derived(page.url.searchParams.has('add'));
|
||||||
let fabMealType = $state('lunch');
|
let fabMealType = $state('lunch');
|
||||||
|
|
||||||
const fabHref = $derived(`${resolve('/fitness/[nutrition=fitnessNutrition]', { nutrition: s.nutrition })}?add`);
|
const fabHref = $derived(`${resolve('/fitness/[nutrition=fitnessNutrition]', { nutrition: s.nutrition })}?add`);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import ChevronDown from '@lucide/svelte/icons/chevron-down';
|
import ChevronDown from '@lucide/svelte/icons/chevron-down';
|
||||||
import ExternalLink from '@lucide/svelte/icons/external-link';
|
import ExternalLink from '@lucide/svelte/icons/external-link';
|
||||||
import Heart from '@lucide/svelte/icons/heart';
|
import Heart from '@lucide/svelte/icons/heart';
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const s = $derived(fitnessSlugs(lang));
|
const s = $derived(fitnessSlugs(lang));
|
||||||
const isEn = $derived(lang === 'en');
|
const isEn = $derived(lang === 'en');
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { untrack } from 'svelte';
|
import { untrack } from 'svelte';
|
||||||
import Plus from '@lucide/svelte/icons/plus';
|
import Plus from '@lucide/svelte/icons/plus';
|
||||||
import Trash2 from '@lucide/svelte/icons/trash-2';
|
import Trash2 from '@lucide/svelte/icons/trash-2';
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
/** @typedef {import('$models/CustomMeal').ICustomMeal & { _id?: string }} Meal */
|
/** @typedef {import('$models/CustomMeal').ICustomMeal & { _id?: string }} Meal */
|
||||||
/** @typedef {import('$models/CustomMeal').ICustomMealIngredient} MealIngredient */
|
/** @typedef {import('$models/CustomMeal').ICustomMealIngredient} MealIngredient */
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const s = $derived(fitnessSlugs(lang));
|
const s = $derived(fitnessSlugs(lang));
|
||||||
const isEn = $derived(lang === 'en');
|
const isEn = $derived(lang === 'en');
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { invalidateAll } from '$app/navigation';
|
import { invalidateAll } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import FitnessChart from '$lib/components/fitness/FitnessChart.svelte';
|
import FitnessChart from '$lib/components/fitness/FitnessChart.svelte';
|
||||||
import MuscleHeatmap from '$lib/components/fitness/MuscleHeatmap.svelte';
|
import MuscleHeatmap from '$lib/components/fitness/MuscleHeatmap.svelte';
|
||||||
import Dumbbell from '@lucide/svelte/icons/dumbbell';
|
import Dumbbell from '@lucide/svelte/icons/dumbbell';
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
import StatsRingGraph from '$lib/components/fitness/StatsRingGraph.svelte';
|
import StatsRingGraph from '$lib/components/fitness/StatsRingGraph.svelte';
|
||||||
import { BODY_PART_CARDS, bodyPartSlug, bodyPartAccent } from '$lib/js/fitnessBodyParts';
|
import { BODY_PART_CARDS, bodyPartSlug, bodyPartAccent } from '$lib/js/fitnessBodyParts';
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const statsSlug = $derived(lang === 'en' ? 'stats' : 'statistik');
|
const statsSlug = $derived(lang === 'en' ? 'stats' : 'statistik');
|
||||||
const historySlug = $derived(lang === 'en' ? 'history' : 'verlauf');
|
const historySlug = $derived(lang === 'en' ? 'history' : 'verlauf');
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import ArrowLeft from '@lucide/svelte/icons/arrow-left';
|
import ArrowLeft from '@lucide/svelte/icons/arrow-left';
|
||||||
import Ruler from '@lucide/svelte/icons/ruler';
|
import Ruler from '@lucide/svelte/icons/ruler';
|
||||||
import TrendingUp from '@lucide/svelte/icons/trending-up';
|
import TrendingUp from '@lucide/svelte/icons/trending-up';
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const statsSlug = $derived(lang === 'en' ? 'stats' : 'statistik');
|
const statsSlug = $derived(lang === 'en' ? 'stats' : 'statistik');
|
||||||
const checkinSlug = $derived(lang === 'en' ? 'check-in' : 'erfassung');
|
const checkinSlug = $derived(lang === 'en' ? 'check-in' : 'erfassung');
|
||||||
const card = $derived(data.card);
|
const card = $derived(data.card);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import Plus from '@lucide/svelte/icons/plus';
|
import Plus from '@lucide/svelte/icons/plus';
|
||||||
import Trash2 from '@lucide/svelte/icons/trash-2';
|
import Trash2 from '@lucide/svelte/icons/trash-2';
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
|
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
|
||||||
import { toast } from '$lib/js/toast.svelte';
|
import { toast } from '$lib/js/toast.svelte';
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const sl = $derived(fitnessSlugs(lang));
|
const sl = $derived(fitnessSlugs(lang));
|
||||||
import { getExerciseById, getExerciseMetrics, METRIC_LABELS } from '$lib/data/exercises';
|
import { getExerciseById, getExerciseMetrics, METRIC_LABELS } from '$lib/data/exercises';
|
||||||
import TemplateCard from '$lib/components/fitness/TemplateCard.svelte';
|
import TemplateCard from '$lib/components/fitness/TemplateCard.svelte';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import Trash2 from '@lucide/svelte/icons/trash-2';
|
import Trash2 from '@lucide/svelte/icons/trash-2';
|
||||||
import Play from '@lucide/svelte/icons/play';
|
import Play from '@lucide/svelte/icons/play';
|
||||||
import Pause from '@lucide/svelte/icons/pause';
|
import Pause from '@lucide/svelte/icons/pause';
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
import { confirm } from '$lib/js/confirmDialog.svelte';
|
import { confirm } from '$lib/js/confirmDialog.svelte';
|
||||||
import { toast } from '$lib/js/toast.svelte';
|
import { toast } from '$lib/js/toast.svelte';
|
||||||
|
|
||||||
const lang = $derived(detectFitnessLang($page.url.pathname));
|
const lang = $derived(detectFitnessLang(page.url.pathname));
|
||||||
const isEn = $derived(lang === 'en');
|
const isEn = $derived(lang === 'en');
|
||||||
const sl = $derived(fitnessSlugs(lang));
|
const sl = $derived(fitnessSlugs(lang));
|
||||||
import { getWorkout } from '$lib/js/workout.svelte';
|
import { getWorkout } from '$lib/js/workout.svelte';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import Header from '$lib/components/Header.svelte';
|
import Header from '$lib/components/Header.svelte';
|
||||||
import UserHeader from '$lib/components/UserHeader.svelte';
|
import UserHeader from '$lib/components/UserHeader.svelte';
|
||||||
import ClipboardList from '@lucide/svelte/icons/clipboard-list';
|
import ClipboardList from '@lucide/svelte/icons/clipboard-list';
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
/** @param {string} path */
|
/** @param {string} path */
|
||||||
function isActive(path) {
|
function isActive(path) {
|
||||||
const currentPath = $page.url.pathname;
|
const currentPath = page.url.pathname;
|
||||||
if (path === '/tasks') {
|
if (path === '/tasks') {
|
||||||
return currentPath === '/tasks' || currentPath === '/tasks/';
|
return currentPath === '/tasks' || currentPath === '/tasks/';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user