190 lines
5.9 KiB
Svelte
190 lines
5.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 WishlistGrid from '$lib/components/dashboard/WishlistGrid.svelte';
|
|
import WishlistCard from '$lib/components/dashboard/WishlistCard.svelte';
|
|
import { enhance } from '$app/forms';
|
|
import { Star } from 'lucide-svelte';
|
|
import { languageStore } from '$lib/stores/language.svelte';
|
|
|
|
let { data }: { data: PageData } = $props();
|
|
|
|
const t = $derived(languageStore.t);
|
|
|
|
const sortedWishlists = $derived(
|
|
[...data.wishlists].sort((a, b) => {
|
|
if (a.isFavorite && !b.isFavorite) return -1;
|
|
if (!a.isFavorite && b.isFavorite) return 1;
|
|
|
|
const aHasEndDate = !!a.endDate;
|
|
const bHasEndDate = !!b.endDate;
|
|
|
|
if (aHasEndDate && !bHasEndDate) return -1;
|
|
if (!aHasEndDate && bHasEndDate) return 1;
|
|
|
|
if (aHasEndDate && bHasEndDate) {
|
|
return new Date(a.endDate!).getTime() - new Date(b.endDate!).getTime();
|
|
}
|
|
|
|
return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
|
|
})
|
|
);
|
|
|
|
const sortedSavedWishlists = $derived(
|
|
[...data.savedWishlists].sort((a, b) => {
|
|
if (a.isFavorite && !b.isFavorite) return -1;
|
|
if (!a.isFavorite && b.isFavorite) return 1;
|
|
|
|
const aHasEndDate = !!a.wishlist?.endDate;
|
|
const bHasEndDate = !!b.wishlist?.endDate;
|
|
|
|
if (aHasEndDate && !bHasEndDate) return -1;
|
|
if (!aHasEndDate && bHasEndDate) return 1;
|
|
|
|
if (aHasEndDate && bHasEndDate) {
|
|
return new Date(a.wishlist.endDate!).getTime() - new Date(b.wishlist.endDate!).getTime();
|
|
}
|
|
|
|
return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
|
|
})
|
|
);
|
|
|
|
function formatEndDate(date: Date | string | null): string | null {
|
|
if (!date) return null;
|
|
const d = new Date(date);
|
|
return d.toLocaleDateString(languageStore.t.date.format.short, { year: 'numeric', month: 'short', day: 'numeric' });
|
|
}
|
|
|
|
function getWishlistDescription(wishlist: any): string | null {
|
|
if (!wishlist) return null;
|
|
|
|
const lines: string[] = [];
|
|
|
|
const topItems = wishlist.items?.slice(0, 3).map((item: any) => item.title) || [];
|
|
if (topItems.length > 0) {
|
|
lines.push(topItems.join(', '));
|
|
}
|
|
|
|
if (wishlist.user?.name || wishlist.user?.username) {
|
|
const ownerName = wishlist.user.name || wishlist.user.username;
|
|
lines.push(`${t.dashboard.by} ${ownerName}`);
|
|
}
|
|
|
|
if (wishlist.endDate) {
|
|
lines.push(`${t.dashboard.ends}: ${formatEndDate(wishlist.endDate)}`);
|
|
}
|
|
|
|
return lines.length > 0 ? lines.join('\n') : null;
|
|
}
|
|
|
|
function getSavedWishlistDescription(saved: any): string | null {
|
|
return getWishlistDescription(saved.wishlist);
|
|
}
|
|
</script>
|
|
|
|
<PageContainer>
|
|
<DashboardHeader userName={data.user?.name} userEmail={data.user?.email} />
|
|
|
|
<WishlistGrid
|
|
title={t.dashboard.myWishlists}
|
|
description={t.dashboard.myWishlistsDescription}
|
|
items={sortedWishlists || []}
|
|
emptyMessage={t.dashboard.emptyWishlists}
|
|
emptyActionLabel={t.dashboard.emptyWishlistsAction}
|
|
emptyActionHref="/"
|
|
>
|
|
{#snippet headerAction()}
|
|
<Button onclick={() => (window.location.href = '/')}>{t.dashboard.createNew}</Button>
|
|
{/snippet}
|
|
|
|
{#snippet children(wishlist)}
|
|
<WishlistCard
|
|
title={wishlist.title}
|
|
description={getWishlistDescription(wishlist)}
|
|
itemCount={wishlist.items?.length || 0}
|
|
color={wishlist.color}
|
|
>
|
|
<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>
|
|
</div>
|
|
</WishlistCard>
|
|
{/snippet}
|
|
</WishlistGrid>
|
|
|
|
<WishlistGrid
|
|
title={t.dashboard.savedWishlists}
|
|
description={t.dashboard.savedWishlistsDescription}
|
|
items={sortedSavedWishlists || []}
|
|
emptyMessage={t.dashboard.emptySavedWishlists}
|
|
emptyDescription={t.dashboard.emptySavedWishlistsDescription}
|
|
>
|
|
{#snippet children(saved)}
|
|
<WishlistCard
|
|
title={saved.wishlist?.title}
|
|
description={getSavedWishlistDescription(saved)}
|
|
itemCount={saved.wishlist?.items?.length || 0}
|
|
color={saved.wishlist?.color}
|
|
>
|
|
<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>
|
|
<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>
|
|
</div>
|
|
</WishlistCard>
|
|
{/snippet}
|
|
</WishlistGrid>
|
|
</PageContainer>
|