280 lines
8.9 KiB
Svelte
280 lines
8.9 KiB
Svelte
<script lang="ts">
|
|
import { Button } from '$lib/components/ui/button';
|
|
import type { PageData } from './$types';
|
|
import PageContainer from '$lib/components/layout/PageContainer.svelte';
|
|
import DashboardHeader from '$lib/components/layout/DashboardHeader.svelte';
|
|
import WishlistSection from '$lib/components/dashboard/WishlistSection.svelte';
|
|
import LocalWishlistsSection from '$lib/components/dashboard/LocalWishlistsSection.svelte';
|
|
import { enhance } from '$app/forms';
|
|
import { Star } from '@lucide/svelte';
|
|
import { languageStore } from '$lib/stores/language.svelte';
|
|
|
|
let { data }: { data: PageData } = $props();
|
|
|
|
function getInitialTheme() {
|
|
if (data.isAuthenticated) {
|
|
return data.user?.dashboardTheme || 'none';
|
|
} else {
|
|
if (typeof window !== 'undefined') {
|
|
return localStorage.getItem('dashboardTheme') || 'none';
|
|
}
|
|
return 'none';
|
|
}
|
|
}
|
|
|
|
function getInitialColor() {
|
|
if (data.isAuthenticated) {
|
|
return data.user?.dashboardColor || null;
|
|
} else {
|
|
if (typeof window !== 'undefined') {
|
|
return localStorage.getItem('dashboardColor') || null;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
let currentTheme = $state(getInitialTheme());
|
|
let currentColor = $state(getInitialColor());
|
|
|
|
function handleThemeUpdate(theme: string | null) {
|
|
currentTheme = theme || 'none';
|
|
|
|
if (!data.isAuthenticated && typeof window !== 'undefined') {
|
|
localStorage.setItem('dashboardTheme', currentTheme);
|
|
}
|
|
}
|
|
|
|
function handleColorUpdate(color: string | null) {
|
|
currentColor = color;
|
|
|
|
if (!data.isAuthenticated && typeof window !== 'undefined') {
|
|
if (color) {
|
|
localStorage.setItem('dashboardColor', color);
|
|
} else {
|
|
localStorage.removeItem('dashboardColor');
|
|
}
|
|
}
|
|
}
|
|
|
|
const t = $derived(languageStore.t);
|
|
|
|
const myWishlists = $derived(() => data.wishlists || []);
|
|
|
|
const claimedWishlists = $derived(() => {
|
|
return (data.savedWishlists || [])
|
|
.filter((saved) => saved.wishlist?.ownerToken)
|
|
.map((saved) => ({
|
|
...saved.wishlist,
|
|
isFavorite: saved.isFavorite,
|
|
isClaimed: true,
|
|
savedId: saved.id
|
|
}));
|
|
});
|
|
|
|
const savedWishlists = $derived(() => {
|
|
return (data.savedWishlists || []).filter((saved) => !saved.wishlist?.ownerToken);
|
|
});
|
|
</script>
|
|
|
|
<PageContainer theme={currentTheme} themeColor={currentColor}>
|
|
<DashboardHeader
|
|
userName={data.user?.name}
|
|
userEmail={data.user?.email}
|
|
dashboardTheme={currentTheme}
|
|
dashboardColor={currentColor}
|
|
isAuthenticated={data.isAuthenticated}
|
|
onThemeUpdate={handleThemeUpdate}
|
|
onColorUpdate={handleColorUpdate}
|
|
/>
|
|
|
|
{#if data.isAuthenticated}
|
|
<WishlistSection
|
|
title={t.dashboard.myWishlists}
|
|
description={t.dashboard.myWishlistsDescription}
|
|
items={myWishlists()}
|
|
emptyMessage={t.dashboard.emptyWishlists}
|
|
emptyActionLabel={t.dashboard.emptyWishlistsAction}
|
|
emptyActionHref="/"
|
|
showCreateButton={true}
|
|
fallbackColor={currentColor}
|
|
fallbackTheme={currentTheme}
|
|
>
|
|
{#snippet actions(wishlist, unlocked)}
|
|
<div class="flex gap-2 flex-wrap">
|
|
<form
|
|
method="POST"
|
|
action="?/toggleFavorite"
|
|
use:enhance={() => {
|
|
return async ({ update }) => {
|
|
await update({ reset: false });
|
|
};
|
|
}}
|
|
>
|
|
<input type="hidden" name="wishlistId" value={wishlist.id} />
|
|
<input type="hidden" name="isFavorite" value={wishlist.isFavorite} />
|
|
<Button type="submit" size="sm" variant="outline">
|
|
<Star class={wishlist.isFavorite ? 'fill-yellow-500 text-yellow-500' : ''} />
|
|
</Button>
|
|
</form>
|
|
<Button
|
|
size="sm"
|
|
onclick={() => (window.location.href = `/wishlist/${wishlist.ownerToken}/edit`)}
|
|
>
|
|
{t.dashboard.manage}
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onclick={() => {
|
|
navigator.clipboard.writeText(
|
|
`${window.location.origin}/wishlist/${wishlist.publicToken}`
|
|
);
|
|
}}
|
|
>
|
|
{t.dashboard.copyLink}
|
|
</Button>
|
|
{#if unlocked}
|
|
<form
|
|
method="POST"
|
|
action="?/deleteWishlist"
|
|
use:enhance={() => {
|
|
return async ({ update }) => {
|
|
await update({ reset: false });
|
|
};
|
|
}}
|
|
>
|
|
<input type="hidden" name="wishlistId" value={wishlist.id} />
|
|
<Button type="submit" size="sm" variant="destructive">
|
|
{t.dashboard.delete}
|
|
</Button>
|
|
</form>
|
|
{/if}
|
|
</div>
|
|
{/snippet}
|
|
</WishlistSection>
|
|
|
|
<LocalWishlistsSection
|
|
isAuthenticated={data.isAuthenticated}
|
|
fallbackColor={currentColor}
|
|
fallbackTheme={currentTheme}
|
|
/>
|
|
|
|
<WishlistSection
|
|
title={t.dashboard.claimedWishlists}
|
|
description={t.dashboard.claimedWishlistsDescription}
|
|
items={claimedWishlists()}
|
|
emptyMessage={t.dashboard.emptyClaimedWishlists}
|
|
emptyDescription={t.dashboard.emptyClaimedWishlistsDescription}
|
|
hideIfEmpty={true}
|
|
fallbackColor={currentColor}
|
|
fallbackTheme={currentTheme}
|
|
>
|
|
{#snippet actions(wishlist, unlocked)}
|
|
<div class="flex gap-2 flex-wrap">
|
|
<form
|
|
method="POST"
|
|
action="?/toggleSavedFavorite"
|
|
use:enhance={() => {
|
|
return async ({ update }) => {
|
|
await update({ reset: false });
|
|
};
|
|
}}
|
|
>
|
|
<input type="hidden" name="savedWishlistId" value={wishlist.savedId} />
|
|
<input type="hidden" name="isFavorite" value={wishlist.isFavorite} />
|
|
<Button type="submit" size="sm" variant="outline">
|
|
<Star class={wishlist.isFavorite ? 'fill-yellow-500 text-yellow-500' : ''} />
|
|
</Button>
|
|
</form>
|
|
<Button
|
|
size="sm"
|
|
onclick={() => (window.location.href = `/wishlist/${wishlist.ownerToken}/edit`)}
|
|
>
|
|
{t.dashboard.manage}
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onclick={() => {
|
|
navigator.clipboard.writeText(
|
|
`${window.location.origin}/wishlist/${wishlist.publicToken}`
|
|
);
|
|
}}
|
|
>
|
|
{t.dashboard.copyLink}
|
|
</Button>
|
|
{#if unlocked}
|
|
<form
|
|
method="POST"
|
|
action="?/unsaveWishlist"
|
|
use:enhance={() => {
|
|
return async ({ update }) => {
|
|
await update({ reset: false });
|
|
};
|
|
}}
|
|
>
|
|
<input type="hidden" name="savedWishlistId" value={wishlist.savedId} />
|
|
<Button type="submit" size="sm" variant="destructive">
|
|
{t.dashboard.unclaim}
|
|
</Button>
|
|
</form>
|
|
{/if}
|
|
</div>
|
|
{/snippet}
|
|
</WishlistSection>
|
|
|
|
<WishlistSection
|
|
title={t.dashboard.savedWishlists}
|
|
description={t.dashboard.savedWishlistsDescription}
|
|
items={savedWishlists()}
|
|
emptyMessage={t.dashboard.emptySavedWishlists}
|
|
emptyDescription={t.dashboard.emptySavedWishlistsDescription}
|
|
fallbackColor={currentColor}
|
|
fallbackTheme={currentTheme}
|
|
hideIfEmpty={true}
|
|
>
|
|
{#snippet actions(saved, unlocked)}
|
|
<div class="flex gap-2 flex-wrap">
|
|
<form
|
|
method="POST"
|
|
action="?/toggleSavedFavorite"
|
|
use:enhance={() => {
|
|
return async ({ update }) => {
|
|
await update({ reset: false });
|
|
};
|
|
}}
|
|
>
|
|
<input type="hidden" name="savedWishlistId" value={saved.id} />
|
|
<input type="hidden" name="isFavorite" value={saved.isFavorite} />
|
|
<Button type="submit" size="sm" variant="outline">
|
|
<Star class={saved.isFavorite ? 'fill-yellow-500 text-yellow-500' : ''} />
|
|
</Button>
|
|
</form>
|
|
<Button
|
|
size="sm"
|
|
onclick={() => (window.location.href = `/wishlist/${saved.wishlist.publicToken}`)}
|
|
>
|
|
{t.dashboard.viewWishlist}
|
|
</Button>
|
|
{#if unlocked}
|
|
<form
|
|
method="POST"
|
|
action="?/unsaveWishlist"
|
|
use:enhance={() => {
|
|
return async ({ update }) => {
|
|
await update({ reset: false });
|
|
};
|
|
}}
|
|
>
|
|
<input type="hidden" name="savedWishlistId" value={saved.id} />
|
|
<Button type="submit" size="sm" variant="destructive">
|
|
{t.dashboard.unsave}
|
|
</Button>
|
|
</form>
|
|
{/if}
|
|
</div>
|
|
{/snippet}
|
|
</WishlistSection>
|
|
{/if}
|
|
</PageContainer>
|