diff --git a/src/lib/quantity-format.ts b/src/lib/quantity-format.ts index 8215eb7..6346dab 100644 --- a/src/lib/quantity-format.ts +++ b/src/lib/quantity-format.ts @@ -1,7 +1,7 @@ export function formatQuantity(q: number | null): string { - if (q === null || q === undefined) return ''; - const rounded = Math.round(q); - if (Math.abs(q - rounded) < 0.01) return String(rounded); - // auf max. 2 Nachkommastellen, trailing Nullen raus - return q.toFixed(2).replace(/\.?0+$/, ''); + if (q === null || q === undefined) return ''; + const rounded = Math.round(q); + if (Math.abs(q - rounded) < 0.01) return String(rounded); + // auf max. 2 Nachkommastellen, trailing Nullen raus + return q.toFixed(2).replace(/\.?0+$/, ''); } diff --git a/src/routes/shopping-list/+page.svelte b/src/routes/shopping-list/+page.svelte index 8e86c7b..04813d7 100644 --- a/src/routes/shopping-list/+page.svelte +++ b/src/routes/shopping-list/+page.svelte @@ -7,6 +7,7 @@ import type { ShoppingListRow as Row } from '$lib/server/shopping/repository'; import { shoppingCartStore } from '$lib/client/shopping-cart.svelte'; import { confirmAction } from '$lib/client/confirm.svelte'; + import { requireOnline } from '$lib/client/require-online'; let snapshot = $state({ recipes: [], rows: [], uncheckedCount: 0 }); let loading = $state(true); @@ -23,6 +24,7 @@ } async function onToggleRow(row: Row, next: boolean) { + if (!requireOnline('Abhaken')) return; const method = next ? 'POST' : 'DELETE'; await fetch('/api/shopping-list/check', { method, @@ -34,6 +36,7 @@ } async function onServingsChange(recipeId: number, servings: number) { + if (!requireOnline('Portionen-Aenderung')) return; await fetch(`/api/shopping-list/recipe/${recipeId}`, { method: 'PATCH', headers: { 'content-type': 'application/json' }, @@ -44,18 +47,21 @@ } async function onRemoveRecipe(recipeId: number) { + if (!requireOnline('Rezept-Entfernung')) return; await fetch(`/api/shopping-list/recipe/${recipeId}`, { method: 'DELETE' }); await load(); void shoppingCartStore.refresh(); } async function clearChecked() { + if (!requireOnline('Erledigte entfernen')) return; await fetch('/api/shopping-list/checked', { method: 'DELETE' }); await load(); void shoppingCartStore.refresh(); } async function clearAll() { + if (!requireOnline('Liste leeren')) return; const ok = await confirmAction({ title: 'Einkaufsliste leeren?', message: 'Alle Rezepte und abgehakten Zutaten werden entfernt. Das lässt sich nicht rückgängig machen.', diff --git a/tests/unit/quantity-format.test.ts b/tests/unit/quantity-format.test.ts index f2ce542..a631b06 100644 --- a/tests/unit/quantity-format.test.ts +++ b/tests/unit/quantity-format.test.ts @@ -2,27 +2,27 @@ import { describe, it, expect } from 'vitest'; import { formatQuantity } from '../../src/lib/quantity-format'; describe('formatQuantity', () => { - it('renders null as empty string', () => { - expect(formatQuantity(null)).toBe(''); - }); + it('renders null as empty string', () => { + expect(formatQuantity(null)).toBe(''); + }); - it('renders whole numbers as integer', () => { - expect(formatQuantity(400)).toBe('400'); - }); + it('renders whole numbers as integer', () => { + expect(formatQuantity(400)).toBe('400'); + }); - it('renders near-integer as integer (epsilon 0.01)', () => { - expect(formatQuantity(400.001)).toBe('400'); - expect(formatQuantity(399.999)).toBe('400'); - }); + it('renders near-integer as integer (epsilon 0.01)', () => { + expect(formatQuantity(400.001)).toBe('400'); + expect(formatQuantity(399.999)).toBe('400'); + }); - it('renders fractional with up to 2 decimals, trailing zeros trimmed', () => { - expect(formatQuantity(0.5)).toBe('0.5'); - expect(formatQuantity(0.333333)).toBe('0.33'); - expect(formatQuantity(1.1)).toBe('1.1'); - expect(formatQuantity(1.1)).toBe('1.1'); - }); + it('renders fractional with up to 2 decimals, trailing zeros trimmed', () => { + expect(formatQuantity(0.5)).toBe('0.5'); + expect(formatQuantity(0.333333)).toBe('0.33'); + expect(formatQuantity(1.1)).toBe('1.1'); + expect(formatQuantity(1.1)).toBe('1.1'); + }); - it('handles zero', () => { - expect(formatQuantity(0)).toBe('0'); - }); + it('handles zero', () => { + expect(formatQuantity(0)).toBe('0'); + }); });