add: better search and better delete locking mechanism
This commit is contained in:
@@ -8,11 +8,18 @@
|
||||
import { enhance } from '$app/forms';
|
||||
import { Star } from 'lucide-svelte';
|
||||
import { languageStore } from '$lib/stores/language.svelte';
|
||||
import SearchBar from '$lib/components/ui/SearchBar.svelte';
|
||||
import UnlockButton from '$lib/components/ui/UnlockButton.svelte';
|
||||
|
||||
let { data }: { data: PageData } = $props();
|
||||
|
||||
const t = $derived(languageStore.t);
|
||||
|
||||
let myWishlistsUnlocked = $state(false);
|
||||
let savedWishlistsUnlocked = $state(false);
|
||||
let myWishlistsSearch = $state('');
|
||||
let savedWishlistsSearch = $state('');
|
||||
|
||||
// Combine owned and claimed wishlists for "My Wishlists"
|
||||
const allMyWishlists = $derived(() => {
|
||||
const owned = data.wishlists || [];
|
||||
@@ -28,8 +35,15 @@
|
||||
return [...owned, ...claimed];
|
||||
});
|
||||
|
||||
const sortedWishlists = $derived(
|
||||
[...allMyWishlists()].sort((a, b) => {
|
||||
const sortedWishlists = $derived(() => {
|
||||
const filtered = myWishlistsSearch.trim()
|
||||
? allMyWishlists().filter(w =>
|
||||
w.title.toLowerCase().includes(myWishlistsSearch.toLowerCase()) ||
|
||||
w.description?.toLowerCase().includes(myWishlistsSearch.toLowerCase())
|
||||
)
|
||||
: allMyWishlists();
|
||||
|
||||
return [...filtered].sort((a, b) => {
|
||||
if (a.isFavorite && !b.isFavorite) return -1;
|
||||
if (!a.isFavorite && b.isFavorite) return 1;
|
||||
|
||||
@@ -44,30 +58,37 @@
|
||||
}
|
||||
|
||||
return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Saved wishlists are those WITHOUT ownerToken (saved from public view only)
|
||||
const sortedSavedWishlists = $derived(
|
||||
[...(data.savedWishlists || [])]
|
||||
.filter(saved => !saved.wishlist?.ownerToken) // No edit access
|
||||
.sort((a, b) => {
|
||||
if (a.isFavorite && !b.isFavorite) return -1;
|
||||
if (!a.isFavorite && b.isFavorite) return 1;
|
||||
const sortedSavedWishlists = $derived(() => {
|
||||
const filtered = savedWishlistsSearch.trim()
|
||||
? (data.savedWishlists || [])
|
||||
.filter(saved => !saved.wishlist?.ownerToken) // No edit access
|
||||
.filter(saved =>
|
||||
saved.wishlist?.title.toLowerCase().includes(savedWishlistsSearch.toLowerCase()) ||
|
||||
saved.wishlist?.description?.toLowerCase().includes(savedWishlistsSearch.toLowerCase())
|
||||
)
|
||||
: (data.savedWishlists || []).filter(saved => !saved.wishlist?.ownerToken);
|
||||
|
||||
const aHasEndDate = !!a.wishlist?.endDate;
|
||||
const bHasEndDate = !!b.wishlist?.endDate;
|
||||
return [...filtered].sort((a, b) => {
|
||||
if (a.isFavorite && !b.isFavorite) return -1;
|
||||
if (!a.isFavorite && b.isFavorite) return 1;
|
||||
|
||||
if (aHasEndDate && !bHasEndDate) return -1;
|
||||
if (!aHasEndDate && bHasEndDate) return 1;
|
||||
const aHasEndDate = !!a.wishlist?.endDate;
|
||||
const bHasEndDate = !!b.wishlist?.endDate;
|
||||
|
||||
if (aHasEndDate && bHasEndDate) {
|
||||
return new Date(a.wishlist.endDate!).getTime() - new Date(b.wishlist.endDate!).getTime();
|
||||
}
|
||||
if (aHasEndDate && !bHasEndDate) return -1;
|
||||
if (!aHasEndDate && bHasEndDate) return 1;
|
||||
|
||||
return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
|
||||
})
|
||||
);
|
||||
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;
|
||||
@@ -108,13 +129,22 @@
|
||||
<WishlistGrid
|
||||
title={t.dashboard.myWishlists}
|
||||
description={t.dashboard.myWishlistsDescription}
|
||||
items={sortedWishlists || []}
|
||||
items={sortedWishlists() || []}
|
||||
emptyMessage={t.dashboard.emptyWishlists}
|
||||
emptyActionLabel={t.dashboard.emptyWishlistsAction}
|
||||
emptyActionHref="/"
|
||||
>
|
||||
{#snippet headerAction()}
|
||||
<Button onclick={() => (window.location.href = '/')}>{t.dashboard.createNew}</Button>
|
||||
<div class="flex gap-2 flex-wrap">
|
||||
<Button onclick={() => (window.location.href = '/')}>{t.dashboard.createNew}</Button>
|
||||
<UnlockButton bind:unlocked={myWishlistsUnlocked} />
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
{#snippet searchBar()}
|
||||
{#if allMyWishlists().length > 0}
|
||||
<SearchBar bind:value={myWishlistsSearch} />
|
||||
{/if}
|
||||
{/snippet}
|
||||
|
||||
{#snippet children(wishlist)}
|
||||
@@ -169,7 +199,7 @@
|
||||
>
|
||||
{t.dashboard.copyLink}
|
||||
</Button>
|
||||
{#if wishlist.isClaimed}
|
||||
{#if wishlist.isClaimed && myWishlistsUnlocked}
|
||||
<!-- Add unclaim button for claimed wishlists -->
|
||||
<form method="POST" action="?/unsaveWishlist" use:enhance={() => {
|
||||
return async ({ update }) => {
|
||||
@@ -190,10 +220,20 @@
|
||||
<WishlistGrid
|
||||
title={t.dashboard.savedWishlists}
|
||||
description={t.dashboard.savedWishlistsDescription}
|
||||
items={sortedSavedWishlists || []}
|
||||
items={sortedSavedWishlists() || []}
|
||||
emptyMessage={t.dashboard.emptySavedWishlists}
|
||||
emptyDescription={t.dashboard.emptySavedWishlistsDescription}
|
||||
>
|
||||
{#snippet headerAction()}
|
||||
<UnlockButton bind:unlocked={savedWishlistsUnlocked} />
|
||||
{/snippet}
|
||||
|
||||
{#snippet searchBar()}
|
||||
{#if (data.savedWishlists || []).filter(saved => !saved.wishlist?.ownerToken).length > 0}
|
||||
<SearchBar bind:value={savedWishlistsSearch} />
|
||||
{/if}
|
||||
{/snippet}
|
||||
|
||||
{#snippet children(saved)}
|
||||
<WishlistCard
|
||||
title={saved.wishlist?.title}
|
||||
@@ -219,16 +259,18 @@
|
||||
>
|
||||
{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>
|
||||
{#if savedWishlistsUnlocked}
|
||||
<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>
|
||||
</WishlistCard>
|
||||
{/snippet}
|
||||
|
||||
Reference in New Issue
Block a user