add: internationalization translation to danish

This commit is contained in:
2025-11-25 21:59:53 +01:00
parent 0c8dc087ca
commit 3b7b54b4bf
14 changed files with 311 additions and 227 deletions

View File

@@ -1,18 +1,23 @@
<script lang="ts"> <script lang="ts">
import { Button } from '$lib/components/ui/button'; import { Button } from '$lib/components/ui/button';
import { ThemeToggle } from '$lib/components/ui/theme-toggle'; import { ThemeToggle } from '$lib/components/ui/theme-toggle';
import { LanguageToggle } from '$lib/components/ui/language-toggle';
import { signOut } from '@auth/sveltekit/client'; import { signOut } from '@auth/sveltekit/client';
import { languageStore } from '$lib/stores/language.svelte';
let { userName, userEmail }: { userName?: string | null; userEmail?: string | null } = $props(); let { userName, userEmail }: { userName?: string | null; userEmail?: string | null } = $props();
const t = $derived(languageStore.t);
</script> </script>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<h1 class="text-3xl font-bold">Dashboard</h1> <h1 class="text-3xl font-bold">{t.nav.dashboard}</h1>
<p class="text-muted-foreground">Welcome back, {userName || userEmail}</p> <p class="text-muted-foreground">{t.dashboard.welcomeBack}, {userName || userEmail}</p>
</div> </div>
<div class="flex items-center gap-2"> <div class="flex items-center gap-1 sm:gap-2">
<LanguageToggle />
<ThemeToggle /> <ThemeToggle />
<Button variant="outline" onclick={() => signOut({ callbackUrl: '/' })}>Sign Out</Button> <Button variant="outline" onclick={() => signOut({ callbackUrl: '/' })}>{t.auth.signOut}</Button>
</div> </div>
</div> </div>

View File

@@ -7,6 +7,7 @@
import ImageSelector from './ImageSelector.svelte'; import ImageSelector from './ImageSelector.svelte';
import ColorPicker from '$lib/components/ui/ColorPicker.svelte'; import ColorPicker from '$lib/components/ui/ColorPicker.svelte';
import { enhance } from '$app/forms'; import { enhance } from '$app/forms';
import { languageStore } from '$lib/stores/language.svelte';
interface Props { interface Props {
onSuccess?: () => void; onSuccess?: () => void;
@@ -14,6 +15,8 @@
let { onSuccess }: Props = $props(); let { onSuccess }: Props = $props();
const t = $derived(languageStore.t);
const currencies = ['DKK', 'EUR', 'USD', 'SEK', 'NOK', 'GBP']; const currencies = ['DKK', 'EUR', 'USD', 'SEK', 'NOK', 'GBP'];
let linkUrl = $state(''); let linkUrl = $state('');
@@ -52,7 +55,7 @@
<Card> <Card>
<CardHeader> <CardHeader>
<CardTitle>Add New Item</CardTitle> <CardTitle>{t.form.addNewItem}</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<form <form
@@ -68,12 +71,12 @@
> >
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="space-y-2 md:col-span-2"> <div class="space-y-2 md:col-span-2">
<Label for="title">Item Name *</Label> <Label for="title">{t.form.itemName} *</Label>
<Input id="title" name="title" required placeholder="e.g., Blue Headphones" /> <Input id="title" name="title" required placeholder="e.g., Blue Headphones" />
</div> </div>
<div class="space-y-2 md:col-span-2"> <div class="space-y-2 md:col-span-2">
<Label for="description">Description</Label> <Label for="description">{t.form.description}</Label>
<Textarea <Textarea
id="description" id="description"
name="description" name="description"
@@ -83,7 +86,7 @@
</div> </div>
<div class="space-y-2 md:col-span-2"> <div class="space-y-2 md:col-span-2">
<Label for="link">Link (URL)</Label> <Label for="link">{t.form.link}</Label>
<Input <Input
id="link" id="link"
name="link" name="link"
@@ -95,7 +98,7 @@
</div> </div>
<div class="space-y-2 md:col-span-2"> <div class="space-y-2 md:col-span-2">
<Label for="imageUrl">Image URL</Label> <Label for="imageUrl">{t.form.imageUrl}</Label>
<Input <Input
id="imageUrl" id="imageUrl"
name="imageUrl" name="imageUrl"
@@ -108,12 +111,12 @@
</div> </div>
<div class="space-y-2"> <div class="space-y-2">
<Label for="price">Price</Label> <Label for="price">{t.form.price}</Label>
<Input id="price" name="price" type="number" step="0.01" placeholder="0.00" /> <Input id="price" name="price" type="number" step="0.01" placeholder="0.00" />
</div> </div>
<div class="space-y-2 md:col-span-2"> <div class="space-y-2 md:col-span-2">
<Label for="currency">Currency</Label> <Label for="currency">{t.form.currency}</Label>
<select <select
id="currency" id="currency"
name="currency" name="currency"
@@ -127,14 +130,14 @@
<div class="md:col-span-2"> <div class="md:col-span-2">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<Label for="color">Card Color (optional)</Label> <Label for="color">{t.form.cardColor}</Label>
<ColorPicker bind:color={color} /> <ColorPicker bind:color={color} />
</div> </div>
<input type="hidden" name="color" value={color || ''} /> <input type="hidden" name="color" value={color || ''} />
</div> </div>
</div> </div>
<Button type="submit" class="w-full md:w-auto">Add Item</Button> <Button type="submit" class="w-full md:w-auto">{t.wishlist.addItem}</Button>
</form> </form>
</CardContent> </CardContent>
</Card> </Card>

View File

@@ -8,6 +8,7 @@
import ColorPicker from '$lib/components/ui/ColorPicker.svelte'; import ColorPicker from '$lib/components/ui/ColorPicker.svelte';
import { enhance } from '$app/forms'; import { enhance } from '$app/forms';
import type { Item } from '$lib/server/schema'; import type { Item } from '$lib/server/schema';
import { languageStore } from '$lib/stores/language.svelte';
interface Props { interface Props {
item: Item; item: Item;
@@ -21,6 +22,8 @@
let { item, onSuccess, onCancel, onColorChange, currentPosition = 1, totalItems = 1, onPositionChange }: Props = $props(); let { item, onSuccess, onCancel, onColorChange, currentPosition = 1, totalItems = 1, onPositionChange }: Props = $props();
const t = $derived(languageStore.t);
const currencies = ['DKK', 'EUR', 'USD', 'SEK', 'NOK', 'GBP']; const currencies = ['DKK', 'EUR', 'USD', 'SEK', 'NOK', 'GBP'];
let linkUrl = $state(item.link || ''); let linkUrl = $state(item.link || '');
@@ -59,7 +62,7 @@
<Card> <Card>
<CardHeader> <CardHeader>
<CardTitle>Edit Item</CardTitle> <CardTitle>{t.wishlist.editItem}</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<form <form
@@ -77,12 +80,12 @@
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="space-y-2 md:col-span-2"> <div class="space-y-2 md:col-span-2">
<Label for="title">Item Name *</Label> <Label for="title">{t.form.itemName} *</Label>
<Input id="title" name="title" required value={item.title} placeholder="e.g., Blue Headphones" /> <Input id="title" name="title" required value={item.title} placeholder="e.g., Blue Headphones" />
</div> </div>
<div class="space-y-2 md:col-span-2"> <div class="space-y-2 md:col-span-2">
<Label for="description">Description</Label> <Label for="description">{t.form.description}</Label>
<Textarea <Textarea
id="description" id="description"
name="description" name="description"
@@ -93,7 +96,7 @@
</div> </div>
<div class="space-y-2 md:col-span-2"> <div class="space-y-2 md:col-span-2">
<Label for="link">Link (URL)</Label> <Label for="link">{t.form.link}</Label>
<Input <Input
id="link" id="link"
name="link" name="link"
@@ -105,7 +108,7 @@
</div> </div>
<div class="space-y-2 md:col-span-2"> <div class="space-y-2 md:col-span-2">
<Label for="imageUrl">Image URL</Label> <Label for="imageUrl">{t.form.imageUrl}</Label>
<Input <Input
id="imageUrl" id="imageUrl"
name="imageUrl" name="imageUrl"
@@ -118,12 +121,12 @@
</div> </div>
<div class="space-y-2"> <div class="space-y-2">
<Label for="price">Price</Label> <Label for="price">{t.form.price}</Label>
<Input id="price" name="price" type="number" step="0.01" value={item.price || ''} placeholder="0.00" /> <Input id="price" name="price" type="number" step="0.01" value={item.price || ''} placeholder="0.00" />
</div> </div>
<div class="space-y-2 md:col-span-2"> <div class="space-y-2 md:col-span-2">
<Label for="currency">Currency</Label> <Label for="currency">{t.form.currency}</Label>
<select <select
id="currency" id="currency"
name="currency" name="currency"
@@ -137,14 +140,14 @@
<div class="md:col-span-2"> <div class="md:col-span-2">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<Label for="color">Card Color (optional)</Label> <Label for="color">{t.form.cardColor}</Label>
<ColorPicker bind:color={color} onchange={() => onColorChange?.(item.id, color || '')} /> <ColorPicker bind:color={color} onchange={() => onColorChange?.(item.id, color || '')} />
</div> </div>
<input type="hidden" name="color" value={color || ''} /> <input type="hidden" name="color" value={color || ''} />
</div> </div>
<div class="space-y-2 md:col-span-2"> <div class="space-y-2 md:col-span-2">
<Label for="position">Position in List</Label> <Label for="position">{t.form.position}</Label>
<Input <Input
id="position" id="position"
type="number" type="number"
@@ -166,9 +169,9 @@
</div> </div>
<div class="flex gap-2"> <div class="flex gap-2">
<Button type="submit" class="flex-1 md:flex-none">Save Changes</Button> <Button type="submit" class="flex-1 md:flex-none">{t.form.saveChanges}</Button>
{#if onCancel} {#if onCancel}
<Button type="button" variant="outline" class="flex-1 md:flex-none" onclick={onCancel}>Cancel</Button> <Button type="button" variant="outline" class="flex-1 md:flex-none" onclick={onCancel}>{t.form.cancel}</Button>
{/if} {/if}
</div> </div>
</form> </form>

View File

@@ -6,6 +6,7 @@
import type { Item } from "$lib/server/schema"; import type { Item } from "$lib/server/schema";
import { enhance } from "$app/forms"; import { enhance } from "$app/forms";
import { flip } from "svelte/animate"; import { flip } from "svelte/animate";
import { languageStore } from '$lib/stores/language.svelte';
let { let {
items = $bindable([]), items = $bindable([]),
@@ -18,6 +19,8 @@
onStartEditing: (item: Item) => void; onStartEditing: (item: Item) => void;
onReorder: (items: Item[]) => Promise<void>; onReorder: (items: Item[]) => Promise<void>;
} = $props(); } = $props();
const t = $derived(languageStore.t);
</script> </script>
<div class="space-y-4"> <div class="space-y-4">
@@ -33,7 +36,7 @@
size="sm" size="sm"
onclick={() => onStartEditing(item)} onclick={() => onStartEditing(item)}
> >
Edit {t.wishlist.edit}
</Button> </Button>
{#if rearranging} {#if rearranging}
<form <form
@@ -51,7 +54,7 @@
variant="destructive" variant="destructive"
size="sm" size="sm"
> >
Delete {t.form.delete}
</Button> </Button>
</form> </form>
{/if} {/if}
@@ -64,7 +67,7 @@
<Card> <Card>
<CardContent class="p-12"> <CardContent class="p-12">
<EmptyState <EmptyState
message="No items yet. Click 'Add Item' to get started!" message={t.wishlist.noItems + ". " + t.wishlist.addFirstItem + "!"}
/> />
</CardContent> </CardContent>
</Card> </Card>

View File

@@ -3,6 +3,7 @@
import { Input } from '$lib/components/ui/input'; import { Input } from '$lib/components/ui/input';
import { Label } from '$lib/components/ui/label'; import { Label } from '$lib/components/ui/label';
import { Card, CardContent } from '$lib/components/ui/card'; import { Card, CardContent } from '$lib/components/ui/card';
import { languageStore } from '$lib/stores/language.svelte';
interface Props { interface Props {
publicUrl: string; publicUrl: string;
@@ -11,6 +12,8 @@
let { publicUrl, ownerUrl }: Props = $props(); let { publicUrl, ownerUrl }: Props = $props();
const t = $derived(languageStore.t);
let copiedPublic = $state(false); let copiedPublic = $state(false);
let copiedOwner = $state(false); let copiedOwner = $state(false);
@@ -34,22 +37,22 @@
<Card> <Card>
<CardContent class="space-y-4 pt-6"> <CardContent class="space-y-4 pt-6">
<div class="space-y-2"> <div class="space-y-2">
<Label>Share with friends (view only)</Label> <Label>{t.wishlist.shareViewOnly}</Label>
<div class="flex gap-2"> <div class="flex gap-2">
<Input readonly value={publicLink} class="font-mono text-sm" /> <Input readonly value={publicLink} class="font-mono text-sm" />
<Button variant="outline" onclick={() => copyToClipboard(publicLink, 'public')}> <Button variant="outline" onclick={() => copyToClipboard(publicLink, 'public')}>
{copiedPublic ? 'Copied!' : 'Copy'} {copiedPublic ? t.wishlist.copied : t.wishlist.copy}
</Button> </Button>
</div> </div>
</div> </div>
{#if ownerLink} {#if ownerLink}
<div class="space-y-2"> <div class="space-y-2">
<Label>Your edit link (keep this private!)</Label> <Label>{t.wishlist.shareEditLink}</Label>
<div class="flex gap-2"> <div class="flex gap-2">
<Input readonly value={ownerLink} class="font-mono text-sm" /> <Input readonly value={ownerLink} class="font-mono text-sm" />
<Button variant="outline" onclick={() => copyToClipboard(ownerLink, 'owner')}> <Button variant="outline" onclick={() => copyToClipboard(ownerLink, 'owner')}>
{copiedOwner ? 'Copied!' : 'Copy'} {copiedOwner ? t.wishlist.copied : t.wishlist.copy}
</Button> </Button>
</div> </div>
</div> </div>

View File

@@ -1,7 +1,6 @@
<script lang="ts"> <script lang="ts">
import { Button } from "$lib/components/ui/button"; import { Button } from "$lib/components/ui/button";
import { Lock, LockOpen } from "lucide-svelte"; import { languageStore } from '$lib/stores/language.svelte';
import { enhance } from "$app/forms";
let { let {
rearranging = $bindable(false), rearranging = $bindable(false),
@@ -13,9 +12,7 @@
onToggleAddForm: () => void; onToggleAddForm: () => void;
} = $props(); } = $props();
function toggleRearranging() { const t = $derived(languageStore.t);
rearranging = !rearranging;
}
</script> </script>
<div class="flex flex-col md:flex-row gap-4"> <div class="flex flex-col md:flex-row gap-4">
@@ -23,6 +20,6 @@
onclick={onToggleAddForm} onclick={onToggleAddForm}
class="w-full md:w-auto" class="w-full md:w-auto"
> >
{showAddForm ? "Cancel" : "+ Add Item"} {showAddForm ? t.form.cancel : t.wishlist.addWish}
</Button> </Button>
</div> </div>

View File

@@ -6,6 +6,7 @@
import { Pencil, Check, X } from "lucide-svelte"; import { Pencil, Check, X } from "lucide-svelte";
import ColorPicker from "$lib/components/ui/ColorPicker.svelte"; import ColorPicker from "$lib/components/ui/ColorPicker.svelte";
import type { Wishlist } from "$lib/server/schema"; import type { Wishlist } from "$lib/server/schema";
import { languageStore } from '$lib/stores/language.svelte';
let { let {
wishlist, wishlist,
@@ -21,6 +22,8 @@
onEndDateUpdate: (endDate: string | null) => void; onEndDateUpdate: (endDate: string | null) => void;
} = $props(); } = $props();
const t = $derived(languageStore.t);
let editingTitle = $state(false); let editingTitle = $state(false);
let editingDescription = $state(false); let editingDescription = $state(false);
let wishlistTitle = $state(wishlist.title); let wishlistTitle = $state(wishlist.title);
@@ -123,7 +126,7 @@
<!-- Description --> <!-- Description -->
<div class="space-y-2"> <div class="space-y-2">
<div class="flex items-center justify-between gap-2"> <div class="flex items-center justify-between gap-2">
<Label for="wishlist-description">Description (optional)</Label> <Label for="wishlist-description">{t.form.descriptionOptional}</Label>
<button <button
type="button" type="button"
onclick={() => { onclick={() => {
@@ -159,14 +162,14 @@
/> />
{:else} {:else}
<div class="w-full py-2 px-3 rounded-md border border-input bg-transparent text-sm min-h-[80px]"> <div class="w-full py-2 px-3 rounded-md border border-input bg-transparent text-sm min-h-[80px]">
{wishlistDescription || "No description"} {wishlistDescription || t.form.noDescription}
</div> </div>
{/if} {/if}
</div> </div>
<!-- End Date --> <!-- End Date -->
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 sm:gap-4"> <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 sm:gap-4">
<Label for="wishlist-end-date">End Date (optional)</Label> <Label for="wishlist-end-date">{t.form.endDateOptional}</Label>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
{#if wishlistEndDate} {#if wishlistEndDate}
<button <button

View File

@@ -4,6 +4,7 @@
import { GripVertical, ExternalLink } from "lucide-svelte"; import { GripVertical, ExternalLink } from "lucide-svelte";
import { getCardStyle } from '$lib/utils/colors'; import { getCardStyle } from '$lib/utils/colors';
import { Button } from "$lib/components/ui/button"; import { Button } from "$lib/components/ui/button";
import { languageStore } from '$lib/stores/language.svelte';
interface Props { interface Props {
item: Item; item: Item;
@@ -19,6 +20,8 @@
showDragHandle = false, showDragHandle = false,
}: Props = $props(); }: Props = $props();
const t = $derived(languageStore.t);
const currencySymbols: Record<string, string> = { const currencySymbols: Record<string, string> = {
DKK: "kr", DKK: "kr",
EUR: "€", EUR: "€",
@@ -101,7 +104,7 @@
class="gap-1.5" class="gap-1.5"
> >
<ExternalLink class="w-4 h-4" /> <ExternalLink class="w-4 h-4" />
View Product {t.wishlist.viewProduct}
</Button> </Button>
{/if} {/if}

View File

@@ -1,86 +1,148 @@
import type { Translation } from './en'; import type { Translation } from './en';
// Danish translations - ADD YOUR TRANSLATIONS HERE // Danish translations
export const da: Translation = { export const da: Translation = {
// Navigation // Navigation
nav: { nav: {
dashboard: 'Dashboard' // TODO: Add Danish translation dashboard: 'Dashboard'
}, },
// Dashboard // Dashboard
dashboard: { dashboard: {
myWishlists: 'My Wishlists', // TODO: Add Danish translation myWishlists: 'Mine Ønskelister',
myWishlistsDescription: 'Wishlists you own and manage', // TODO: Add Danish translation myWishlistsDescription: 'Ønskelister du ejer og administrerer',
savedWishlists: 'Saved Wishlists', // TODO: Add Danish translation savedWishlists: 'Gemte Ønskelister',
savedWishlistsDescription: "Wishlists you're following", // TODO: Add Danish translation savedWishlistsDescription: 'Ønskelister du følger',
createNew: '+ Create New', // TODO: Add Danish translation createNew: '+ Opret Ny',
manage: 'Manage', // TODO: Add Danish translation manage: 'Administrer',
copyLink: 'Copy Link', // TODO: Add Danish translation copyLink: 'Kopiér Link',
viewWishlist: 'View Wishlist', // TODO: Add Danish translation viewWishlist: 'Se Ønskeliste',
unsave: 'Unsave', // TODO: Add Danish translation unsave: 'Fjern',
emptyWishlists: "You haven't created any wishlists yet.", // TODO: Add Danish translation emptyWishlists: 'Du har ikke oprettet nogen ønskelister endnu.',
emptyWishlistsAction: 'Create Your First Wishlist', // TODO: Add Danish translation emptyWishlistsAction: 'Opret Din Første Ønskeliste',
emptySavedWishlists: "You haven't saved any wishlists yet.", // TODO: Add Danish translation emptySavedWishlists: 'Du har ikke gemt nogen ønskelister endnu.',
emptySavedWishlistsDescription: "When viewing someone's wishlist, you can save it to easily find it later.", // TODO: Add Danish translation emptySavedWishlistsDescription: 'Når du ser en andens ønskeliste, kan du gemme den for nemt at finde den senere.',
by: 'by', // TODO: Add Danish translation by: 'af',
ends: 'Ends' // TODO: Add Danish translation ends: 'Slutter',
welcomeBack: 'Velkommen tilbage',
searchPlaceholder: 'Søg ønsker...'
}, },
// Wishlist // Wishlist
wishlist: { wishlist: {
title: 'Wishlist', // TODO: Add Danish translation title: 'Ønskeliste',
addItem: 'Add Item', // TODO: Add Danish translation createTitle: 'Opret Din Ønskeliste',
editItem: 'Edit Item', // TODO: Add Danish translation createDescription: 'Opret en ønskeliste og del den med venner og familie',
deleteItem: 'Delete Item', // TODO: Add Danish translation addWish: '+ Tilføj Ønske',
reserve: 'Reserve', // TODO: Add Danish translation editWish: 'Rediger Ønske',
unreserve: 'Unreserve', // TODO: Add Danish translation deleteWish: 'Slet Ønske',
reserved: 'Reserved', // TODO: Add Danish translation reserve: 'Reservér',
save: 'Save', // TODO: Add Danish translation unreserve: 'Fjern Reservation',
saveWishlist: 'Save Wishlist', // TODO: Add Danish translation reserved: 'Reserveret',
share: 'Share', // TODO: Add Danish translation reservedBy: 'af',
edit: 'Edit', // TODO: Add Danish translation save: 'Gem',
back: 'Back', // TODO: Add Danish translation saveWishlist: 'Gem Ønskeliste',
noItems: 'No items yet', // TODO: Add Danish translation unsaveWishlist: 'Fjern',
addFirstItem: 'Add your first item' // TODO: Add Danish translation share: 'Del',
edit: 'Rediger',
back: 'Tilbage',
noWishes: 'Ingen ønsker endnu',
addFirstWish: 'Tilføj dit første ønske',
emptyWishes: 'Denne ønskeliste har ingen ønsker endnu.',
viewProduct: 'Se Produkt',
claimWishlist: 'Tag Ejerskab Af Ønskeliste',
unclaimWishlist: 'Fjern Ejerskab Af Ønskeliste',
youOwnThis: 'Du Ejer Denne Ønskeliste',
alreadyInDashboard: 'Denne ønskeliste er allerede it dit dashboard.',
claimDescription: 'Tag ejerskab af denne ønskeliste for at tilføje den til dit dashboard',
claimedDescription: 'Du har taget ejerskab af denne ønskeliste og kan tilgå den fra dit dashboard',
deleteWishlist: 'Slet Ønskeliste',
deleteConfirm: 'Er du sikker på, at du vil slette denne ønskeliste? Denne handling kan ikke fortrydes.',
lockEditing: 'Lås Redigering',
unlockEditing: 'Lås Op for Sletning',
shareViewOnly: 'Del med venner (afslører reservationer)',
shareEditLink: 'Dit redigeringslink (giver redigeringsadgang)',
copy: 'Kopiér',
copied: 'Kopieret!',
signInToSave: 'Log ind for at gemme',
saveThisWishlist: 'Gem Denne Ønskeliste',
saveDescription: 'Gem denne ønskeliste for nemt at finde den senere i dit dashboard',
creating: 'Opretter...',
createWishlist: 'Opret Ønskeliste'
}, },
// Forms // Forms
form: { form: {
title: 'Title', // TODO: Add Danish translation title: 'Titel',
description: 'Description', // TODO: Add Danish translation wishlistTitle: 'Ønskeliste Titel',
price: 'Price', // TODO: Add Danish translation wishlistTitlePlaceholder: 'Min Fødselsdagsønskeliste',
url: 'URL', // TODO: Add Danish translation description: 'Beskrivelse',
image: 'Image', // TODO: Add Danish translation descriptionPlaceholder: 'Tilføj kontekst til din ønskeliset',
submit: 'Submit', // TODO: Add Danish translation descriptionOptional: 'Beskrivelse (valgfri)',
cancel: 'Cancel', // TODO: Add Danish translation noDescription: 'Ingen beskrivelse',
save: 'Save', // TODO: Add Danish translation price: 'Pris',
delete: 'Delete', // TODO: Add Danish translation currency: 'Valuta',
email: 'Email', // TODO: Add Danish translation url: 'URL',
password: 'Password', // TODO: Add Danish translation link: 'Link (URL)',
name: 'Name', // TODO: Add Danish translation image: 'Billede',
username: 'Username' // TODO: Add Danish translation imageUrl: 'Billede URL',
submit: 'Indsend',
cancel: 'Annuller',
save: 'Gem',
saveChanges: 'Gem Ændringer',
delete: 'Slet',
email: 'E-mail',
password: 'Adgangskode',
confirmPassword: 'Bekræft Adgangskode',
name: 'Navn',
username: 'Brugernavn',
wishName: 'Ønskenavn',
yourName: 'Dit navn',
optional: 'valgfri',
required: 'påkrævet',
color: 'Farve',
wishlistColor: 'Ønskeliste Farve (valgfri)',
cardColor: 'Kortfarve (valgfri)',
endDate: 'Slutdato',
endDateOptional: 'Slutdato (valgfri)',
position: 'Position i Listen',
addNewWish: 'Tilføj Nyt Ønske'
}, },
// Auth // Auth
auth: { auth: {
signIn: 'Sign In', // TODO: Add Danish translation signIn: 'Log Ind',
signUp: 'Sign Up', // TODO: Add Danish translation signUp: 'Tilmeld',
signOut: 'Sign Out', // TODO: Add Danish translation signOut: 'Log Ud',
welcome: 'Welcome', // TODO: Add Danish translation signingIn: 'Logger ind...',
createAccount: 'Create Account', // TODO: Add Danish translation welcome: 'Velkommen',
alreadyHaveAccount: 'Already have an account?', // TODO: Add Danish translation welcomeBack: 'Velkommen Tilbage',
dontHaveAccount: "Don't have an account?" // TODO: Add Danish translation signInPrompt: 'Log ind på din konto',
signUpPrompt: 'Tilmeld dig for at administrere dine ønskelister',
createAccount: 'Opret en Konto',
alreadyHaveAccount: 'Har du allerede en konto?',
dontHaveAccount: 'Har du ikke en konto?',
continueWith: 'Eller fortsæt med'
}, },
// Common // Common
common: { common: {
loading: 'Loading...', // TODO: Add Danish translation loading: 'Indlæser...',
error: 'Error', // TODO: Add Danish translation error: 'Fejl',
success: 'Success', // TODO: Add Danish translation success: 'Succes',
confirm: 'Confirm', // TODO: Add Danish translation confirm: 'Bekræft',
close: 'Close', // TODO: Add Danish translation close: 'Luk',
or: 'or', // TODO: Add Danish translation or: 'eller',
and: 'and' // TODO: Add Danish translation and: 'og'
},
// Reservation
reservation: {
reserveThis: 'Reservér Denne',
cancelReservation: 'Annuller Reservation',
yourNameOptional: 'Dit navn (valgfri)',
confirm: 'Bekræft',
cancel: 'Annuller'
}, },
// Date formatting // Date formatting

View File

@@ -20,42 +20,90 @@ export const en = {
emptySavedWishlists: "You haven't saved any wishlists yet.", emptySavedWishlists: "You haven't saved any wishlists yet.",
emptySavedWishlistsDescription: "When viewing someone's wishlist, you can save it to easily find it later.", emptySavedWishlistsDescription: "When viewing someone's wishlist, you can save it to easily find it later.",
by: 'by', by: 'by',
ends: 'Ends' ends: 'Ends',
welcomeBack: 'Welcome back',
searchPlaceholder: 'Search wishes...'
}, },
// Wishlist // Wishlist
wishlist: { wishlist: {
title: 'Wishlist', title: 'Wishlist',
addItem: 'Add Item', createTitle: 'Create Your Wishlist',
editItem: 'Edit Item', createDescription: 'Create a wishlist and share it with friends and family',
deleteItem: 'Delete Item', addWish: '+ Add Wish',
editWish: 'Edit Wish',
deleteWish: 'Delete Wish',
reserve: 'Reserve', reserve: 'Reserve',
unreserve: 'Unreserve', unreserve: 'Unreserve',
reserved: 'Reserved', reserved: 'Reserved',
reservedBy: 'by',
save: 'Save', save: 'Save',
saveWishlist: 'Save Wishlist', saveWishlist: 'Save Wishlist',
unsaveWishlist: 'Unsave',
share: 'Share', share: 'Share',
edit: 'Edit', edit: 'Edit',
back: 'Back', back: 'Back',
noItems: 'No items yet', noWishes: 'No wishes yet',
addFirstItem: 'Add your first item' addFirstWish: 'Add your first wish',
emptyWishes: "This wishlist doesn't have any wishes yet.",
viewProduct: 'View Product',
claimWishlist: 'Claim Wishlist',
unclaimWishlist: 'Unclaim Wishlist',
youOwnThis: 'You Own This Wishlist',
alreadyInDashboard: 'This wishlist is already in your dashboard as the owner.',
claimDescription: 'Claim this wishlist to add it to your dashboard',
claimedDescription: 'You have claimed this wishlist and can access it from your dashboard',
deleteWishlist: 'Delete Wishlist',
deleteConfirm: 'Are you sure you want to delete this wishlist? This action cannot be undone.',
lockEditing: 'Lock Editing',
unlockEditing: 'Unlock for Deletion',
shareViewOnly: 'Share with friends (view only)',
shareEditLink: 'Your edit link (keep this private!)',
copy: 'Copy',
copied: 'Copied!',
signInToSave: 'Sign in to Save',
saveThisWishlist: 'Save This Wishlist',
saveDescription: 'Save this wishlist to easily find it later in your dashboard',
creating: 'Creating...',
createWishlist: 'Create Wishlist'
}, },
// Forms // Forms
form: { form: {
title: 'Title', title: 'Title',
wishlistTitle: 'Wishlist Title',
wishlistTitlePlaceholder: 'My Birthday Wishlist',
description: 'Description', description: 'Description',
descriptionPlaceholder: 'Add some context for your wishlist...',
descriptionOptional: 'Description (optional)',
noDescription: 'No description',
price: 'Price', price: 'Price',
currency: 'Currency',
url: 'URL', url: 'URL',
link: 'Link (URL)',
image: 'Image', image: 'Image',
imageUrl: 'Image URL',
submit: 'Submit', submit: 'Submit',
cancel: 'Cancel', cancel: 'Cancel',
save: 'Save', save: 'Save',
saveChanges: 'Save Changes',
delete: 'Delete', delete: 'Delete',
email: 'Email', email: 'Email',
password: 'Password', password: 'Password',
confirmPassword: 'Confirm Password',
name: 'Name', name: 'Name',
username: 'Username' username: 'Username',
wishName: 'Wish Name',
yourName: 'Your name',
optional: 'optional',
required: 'required',
color: 'Color',
wishlistColor: 'Wishlist Color (optional)',
cardColor: 'Card Color (optional)',
endDate: 'End Date',
endDateOptional: 'End Date (optional)',
position: 'Position in List',
addNewWish: 'Add New Wish'
}, },
// Auth // Auth
@@ -63,10 +111,15 @@ export const en = {
signIn: 'Sign In', signIn: 'Sign In',
signUp: 'Sign Up', signUp: 'Sign Up',
signOut: 'Sign Out', signOut: 'Sign Out',
signingIn: 'Signing in...',
welcome: 'Welcome', welcome: 'Welcome',
createAccount: 'Create Account', welcomeBack: 'Welcome Back',
signInPrompt: 'Sign in to your account',
signUpPrompt: 'Sign up to manage your wishlists',
createAccount: 'Create an Account',
alreadyHaveAccount: 'Already have an account?', alreadyHaveAccount: 'Already have an account?',
dontHaveAccount: "Don't have an account?" dontHaveAccount: "Don't have an account?",
continueWith: 'Or continue with'
}, },
// Common // Common
@@ -80,6 +133,15 @@ export const en = {
and: 'and' and: 'and'
}, },
// Reservation
reservation: {
reserveThis: 'Reserve This',
cancelReservation: 'Cancel Reservation',
yourNameOptional: 'Your name (optional)',
confirm: 'Confirm',
cancel: 'Cancel'
},
// Date formatting // Date formatting
date: { date: {
format: { format: {
@@ -89,80 +151,4 @@ export const en = {
} }
}; };
export type Translation = { export type Translation = typeof en;
nav: {
dashboard: string;
};
dashboard: {
myWishlists: string;
myWishlistsDescription: string;
savedWishlists: string;
savedWishlistsDescription: string;
createNew: string;
manage: string;
copyLink: string;
viewWishlist: string;
unsave: string;
emptyWishlists: string;
emptyWishlistsAction: string;
emptySavedWishlists: string;
emptySavedWishlistsDescription: string;
by: string;
ends: string;
};
wishlist: {
title: string;
addItem: string;
editItem: string;
deleteItem: string;
reserve: string;
unreserve: string;
reserved: string;
save: string;
saveWishlist: string;
share: string;
edit: string;
back: string;
noItems: string;
addFirstItem: string;
};
form: {
title: string;
description: string;
price: string;
url: string;
image: string;
submit: string;
cancel: string;
save: string;
delete: string;
email: string;
password: string;
name: string;
username: string;
};
auth: {
signIn: string;
signUp: string;
signOut: string;
welcome: string;
createAccount: string;
alreadyHaveAccount: string;
dontHaveAccount: string;
};
common: {
loading: string;
error: string;
success: string;
confirm: string;
close: string;
or: string;
and: string;
};
date: {
format: {
short: string;
long: string;
};
};
};

View File

@@ -5,12 +5,16 @@
import { Textarea } from '$lib/components/ui/textarea'; import { Textarea } from '$lib/components/ui/textarea';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '$lib/components/ui/card'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '$lib/components/ui/card';
import { ThemeToggle } from '$lib/components/ui/theme-toggle'; import { ThemeToggle } from '$lib/components/ui/theme-toggle';
import { LanguageToggle } from '$lib/components/ui/language-toggle';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import ColorPicker from '$lib/components/ui/ColorPicker.svelte'; import ColorPicker from '$lib/components/ui/ColorPicker.svelte';
import type { PageData } from './$types'; import type { PageData } from './$types';
import { languageStore } from '$lib/stores/language.svelte';
let { data }: { data: PageData } = $props(); let { data }: { data: PageData } = $props();
const t = $derived(languageStore.t);
let title = $state(''); let title = $state('');
let description = $state(''); let description = $state('');
let color = $state<string | null>(null); let color = $state<string | null>(null);
@@ -44,17 +48,18 @@
<CardHeader> <CardHeader>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<CardTitle class="text-3xl">Create Your Wishlist</CardTitle> <CardTitle class="text-3xl">{t.wishlist.createTitle}</CardTitle>
<CardDescription> <CardDescription>
Create a wishlist and share it with friends and family {t.wishlist.createDescription}
</CardDescription> </CardDescription>
</div> </div>
<div class="flex items-center gap-2"> <div class="flex items-center gap-1 sm:gap-2">
<LanguageToggle />
<ThemeToggle /> <ThemeToggle />
{#if data.session?.user} {#if data.session?.user}
<Button variant="outline" onclick={() => goto('/dashboard')}>Dashboard</Button> <Button variant="outline" onclick={() => goto('/dashboard')}>{t.nav.dashboard}</Button>
{:else} {:else}
<Button variant="outline" onclick={() => goto('/signin')}>Sign In</Button> <Button variant="outline" onclick={() => goto('/signin')}>{t.auth.signIn}</Button>
{/if} {/if}
</div> </div>
</div> </div>
@@ -62,31 +67,31 @@
<CardContent> <CardContent>
<form onsubmit={(e) => { e.preventDefault(); createWishlist(); }} class="space-y-4"> <form onsubmit={(e) => { e.preventDefault(); createWishlist(); }} class="space-y-4">
<div class="space-y-2"> <div class="space-y-2">
<Label for="title">Wishlist Title</Label> <Label for="title">{t.form.wishlistTitle}</Label>
<Input <Input
id="title" id="title"
bind:value={title} bind:value={title}
placeholder="My Birthday Wishlist" placeholder={t.form.wishlistTitlePlaceholder}
required required
/> />
</div> </div>
<div class="space-y-2"> <div class="space-y-2">
<Label for="description">Description (optional)</Label> <Label for="description">{t.form.descriptionOptional}</Label>
<Textarea <Textarea
id="description" id="description"
bind:value={description} bind:value={description}
placeholder="Add some context for your wishlist..." placeholder={t.form.descriptionPlaceholder}
rows={3} rows={3}
/> />
</div> </div>
<div class="space-y-2"> <div class="space-y-2">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<Label for="color">Wishlist Color (optional)</Label> <Label for="color">{t.form.wishlistColor}</Label>
<ColorPicker bind:color={color} size="sm" /> <ColorPicker bind:color={color} size="sm" />
</div> </div>
</div> </div>
<Button type="submit" class="w-full" disabled={isCreating || !title.trim()}> <Button type="submit" class="w-full" disabled={isCreating || !title.trim()}>
{isCreating ? 'Creating...' : 'Create Wishlist'} {isCreating ? t.wishlist.creating : t.wishlist.createWishlist}
</Button> </Button>
</form> </form>
</CardContent> </CardContent>

View File

@@ -4,11 +4,15 @@
import { Input } from '$lib/components/ui/input'; import { Input } from '$lib/components/ui/input';
import { Label } from '$lib/components/ui/label'; import { Label } from '$lib/components/ui/label';
import { ThemeToggle } from '$lib/components/ui/theme-toggle'; import { ThemeToggle } from '$lib/components/ui/theme-toggle';
import { LanguageToggle } from '$lib/components/ui/language-toggle';
import type { PageData } from './$types'; import type { PageData } from './$types';
import { signIn } from '@auth/sveltekit/client'; import { signIn } from '@auth/sveltekit/client';
import { languageStore } from '$lib/stores/language.svelte';
let { data }: { data: PageData } = $props(); let { data }: { data: PageData } = $props();
const t = $derived(languageStore.t);
let isSubmitting = $state(false); let isSubmitting = $state(false);
async function handleSubmit(e: SubmitEvent) { async function handleSubmit(e: SubmitEvent) {
@@ -34,13 +38,14 @@
</script> </script>
<div class="min-h-screen flex items-center justify-center p-4"> <div class="min-h-screen flex items-center justify-center p-4">
<div class="absolute top-4 right-4"> <div class="absolute top-4 right-4 flex items-center gap-1 sm:gap-2">
<LanguageToggle />
<ThemeToggle /> <ThemeToggle />
</div> </div>
<Card class="w-full max-w-md"> <Card class="w-full max-w-md">
<CardHeader> <CardHeader>
<CardTitle class="text-2xl">Welcome Back</CardTitle> <CardTitle class="text-2xl">{t.auth.welcomeBack}</CardTitle>
<CardDescription>Sign in to your account</CardDescription> <CardDescription>{t.auth.signInPrompt}</CardDescription>
</CardHeader> </CardHeader>
<CardContent class="space-y-4"> <CardContent class="space-y-4">
{#if data.registered} {#if data.registered}
@@ -57,17 +62,17 @@
<form onsubmit={handleSubmit} class="space-y-4"> <form onsubmit={handleSubmit} class="space-y-4">
<div class="space-y-2"> <div class="space-y-2">
<Label for="username">Username</Label> <Label for="username">{t.form.username}</Label>
<Input id="username" name="username" type="text" required /> <Input id="username" name="username" type="text" required />
</div> </div>
<div class="space-y-2"> <div class="space-y-2">
<Label for="password">Password</Label> <Label for="password">{t.form.password}</Label>
<Input id="password" name="password" type="password" required /> <Input id="password" name="password" type="password" required />
</div> </div>
<Button type="submit" class="w-full" disabled={isSubmitting}> <Button type="submit" class="w-full" disabled={isSubmitting}>
{isSubmitting ? 'Signing in...' : 'Sign In'} {isSubmitting ? t.auth.signingIn : t.auth.signIn}
</Button> </Button>
</form> </form>
@@ -77,7 +82,7 @@
<span class="w-full border-t"></span> <span class="w-full border-t"></span>
</div> </div>
<div class="relative flex justify-center text-xs uppercase"> <div class="relative flex justify-center text-xs uppercase">
<span class="bg-card px-2 text-muted-foreground">Or continue with</span> <span class="bg-card px-2 text-muted-foreground">{t.auth.continueWith}</span>
</div> </div>
</div> </div>
@@ -88,14 +93,14 @@
class="w-full" class="w-full"
onclick={() => signIn(provider.id, { callbackUrl: '/dashboard' })} onclick={() => signIn(provider.id, { callbackUrl: '/dashboard' })}
> >
Sign in with {provider.name} {t.auth.signIn} with {provider.name}
</Button> </Button>
{/each} {/each}
{/if} {/if}
<div class="text-center text-sm text-muted-foreground"> <div class="text-center text-sm text-muted-foreground">
Don't have an account? {t.auth.dontHaveAccount}
<a href="/signup" class="text-primary hover:underline">Sign up</a> <a href="/signup" class="text-primary hover:underline">{t.auth.signUp}</a>
</div> </div>
</CardContent> </CardContent>
</Card> </Card>

View File

@@ -4,20 +4,25 @@
import { Input } from '$lib/components/ui/input'; import { Input } from '$lib/components/ui/input';
import { Label } from '$lib/components/ui/label'; import { Label } from '$lib/components/ui/label';
import { ThemeToggle } from '$lib/components/ui/theme-toggle'; import { ThemeToggle } from '$lib/components/ui/theme-toggle';
import { LanguageToggle } from '$lib/components/ui/language-toggle';
import type { ActionData, PageData } from './$types'; import type { ActionData, PageData } from './$types';
import { signIn } from '@auth/sveltekit/client'; import { signIn } from '@auth/sveltekit/client';
import { languageStore } from '$lib/stores/language.svelte';
let { form, data }: { form: ActionData; data: PageData } = $props(); let { form, data }: { form: ActionData; data: PageData } = $props();
const t = $derived(languageStore.t);
</script> </script>
<div class="min-h-screen flex items-center justify-center p-4"> <div class="min-h-screen flex items-center justify-center p-4">
<div class="absolute top-4 right-4"> <div class="absolute top-4 right-4 flex items-center gap-1 sm:gap-2">
<LanguageToggle />
<ThemeToggle /> <ThemeToggle />
</div> </div>
<Card class="w-full max-w-md"> <Card class="w-full max-w-md">
<CardHeader> <CardHeader>
<CardTitle class="text-2xl">Create an Account</CardTitle> <CardTitle class="text-2xl">{t.auth.createAccount}</CardTitle>
<CardDescription>Sign up to manage your wishlists</CardDescription> <CardDescription>{t.auth.signUpPrompt}</CardDescription>
</CardHeader> </CardHeader>
<CardContent class="space-y-4"> <CardContent class="space-y-4">
{#if form?.error} {#if form?.error}
@@ -28,26 +33,26 @@
<form method="POST" class="space-y-4"> <form method="POST" class="space-y-4">
<div class="space-y-2"> <div class="space-y-2">
<Label for="name">Name</Label> <Label for="name">{t.form.name}</Label>
<Input id="name" name="name" type="text" required value={form?.name || ''} /> <Input id="name" name="name" type="text" required value={form?.name || ''} />
</div> </div>
<div class="space-y-2"> <div class="space-y-2">
<Label for="username">Username</Label> <Label for="username">{t.form.username}</Label>
<Input id="username" name="username" type="text" required value={form?.username || ''} /> <Input id="username" name="username" type="text" required value={form?.username || ''} />
</div> </div>
<div class="space-y-2"> <div class="space-y-2">
<Label for="password">Password</Label> <Label for="password">{t.form.password}</Label>
<Input id="password" name="password" type="password" required minlength={8} /> <Input id="password" name="password" type="password" required minlength={8} />
</div> </div>
<div class="space-y-2"> <div class="space-y-2">
<Label for="confirmPassword">Confirm Password</Label> <Label for="confirmPassword">{t.form.confirmPassword}</Label>
<Input id="confirmPassword" name="confirmPassword" type="password" required minlength={8} /> <Input id="confirmPassword" name="confirmPassword" type="password" required minlength={8} />
</div> </div>
<Button type="submit" class="w-full">Sign Up</Button> <Button type="submit" class="w-full">{t.auth.signUp}</Button>
</form> </form>
{#if data.oauthProviders.length > 0} {#if data.oauthProviders.length > 0}
@@ -56,7 +61,7 @@
<span class="w-full border-t"></span> <span class="w-full border-t"></span>
</div> </div>
<div class="relative flex justify-center text-xs uppercase"> <div class="relative flex justify-center text-xs uppercase">
<span class="bg-card px-2 text-muted-foreground">Or continue with</span> <span class="bg-card px-2 text-muted-foreground">{t.auth.continueWith}</span>
</div> </div>
</div> </div>
@@ -67,14 +72,14 @@
class="w-full" class="w-full"
onclick={() => signIn(provider.id, { callbackUrl: '/dashboard' })} onclick={() => signIn(provider.id, { callbackUrl: '/dashboard' })}
> >
Sign up with {provider.name} {t.auth.signUp} with {provider.name}
</Button> </Button>
{/each} {/each}
{/if} {/if}
<div class="text-center text-sm text-muted-foreground"> <div class="text-center text-sm text-muted-foreground">
Already have an account? {t.auth.alreadyHaveAccount}
<a href="/signin" class="text-primary hover:underline">Sign in</a> <a href="/signin" class="text-primary hover:underline">{t.auth.signIn}</a>
</div> </div>
</CardContent> </CardContent>
</Card> </Card>

View File

@@ -13,9 +13,12 @@
import { Button } from "$lib/components/ui/button"; import { Button } from "$lib/components/ui/button";
import { Search, Lock, LockOpen } from "lucide-svelte"; import { Search, Lock, LockOpen } from "lucide-svelte";
import { enhance } from "$app/forms"; import { enhance } from "$app/forms";
import { languageStore } from '$lib/stores/language.svelte';
let { data }: { data: PageData } = $props(); let { data }: { data: PageData } = $props();
const t = $derived(languageStore.t);
let showAddForm = $state(false); let showAddForm = $state(false);
let rearranging = $state(false); let rearranging = $state(false);
let editingItem = $state<Item | null>(null); let editingItem = $state<Item | null>(null);
@@ -214,10 +217,10 @@
variant="outline" variant="outline"
class="w-full md:w-auto opacity-60 cursor-not-allowed" class="w-full md:w-auto opacity-60 cursor-not-allowed"
> >
You Own This Wishlist {t.wishlist.youOwnThis}
</Button> </Button>
<p class="text-sm text-muted-foreground mt-2"> <p class="text-sm text-muted-foreground mt-2">
This wishlist is already in your dashboard as the owner. {t.wishlist.alreadyInDashboard}
</p> </p>
{:else} {:else}
<form <form
@@ -275,7 +278,7 @@
<Search class="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" /> <Search class="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
<Input <Input
type="search" type="search"
placeholder="Search items..." placeholder={t.dashboard.searchPlaceholder}
bind:value={searchQuery} bind:value={searchQuery}
class="pl-9" class="pl-9"
/> />
@@ -298,10 +301,10 @@
> >
{#if rearranging} {#if rearranging}
<Lock class="mr-2 h-4 w-4" /> <Lock class="mr-2 h-4 w-4" />
Lock Editing {t.wishlist.lockEditing}
{:else} {:else}
<LockOpen class="mr-2 h-4 w-4" /> <LockOpen class="mr-2 h-4 w-4" />
Unlock for Reordering & Deletion {t.wishlist.unlockEditing}
{/if} {/if}
</Button> </Button>
@@ -311,9 +314,7 @@
action="?/deleteWishlist" action="?/deleteWishlist"
use:enhance={({ cancel }) => { use:enhance={({ cancel }) => {
if ( if (
!confirm( !confirm(t.wishlist.deleteConfirm)
"Are you sure you want to delete this wishlist? This action cannot be undone.",
)
) { ) {
cancel(); cancel();
return; return;
@@ -330,7 +331,7 @@
variant="destructive" variant="destructive"
class="w-full md:w-auto" class="w-full md:w-auto"
> >
Delete Wishlist {t.wishlist.deleteWishlist}
</Button> </Button>
</form> </form>
{/if} {/if}