diff --git a/src/lib/components/dashboard/WishlistGrid.svelte b/src/lib/components/dashboard/WishlistGrid.svelte index 41f1494..b04f6a4 100644 --- a/src/lib/components/dashboard/WishlistGrid.svelte +++ b/src/lib/components/dashboard/WishlistGrid.svelte @@ -14,6 +14,7 @@ emptyActionLabel, emptyActionHref, headerAction, + searchBar, children }: { title: string; @@ -24,6 +25,7 @@ emptyActionLabel?: string; emptyActionHref?: string; headerAction?: Snippet; + searchBar?: Snippet; children: Snippet<[any]>; } = $props(); @@ -53,6 +55,11 @@ {@render headerAction()} {/if} + {#if searchBar} +
+ {@render searchBar()} +
+ {/if} {#if items && items.length > 0} diff --git a/src/lib/components/ui/SearchBar.svelte b/src/lib/components/ui/SearchBar.svelte new file mode 100644 index 0000000..87b001a --- /dev/null +++ b/src/lib/components/ui/SearchBar.svelte @@ -0,0 +1,18 @@ + + + diff --git a/src/lib/components/ui/UnlockButton.svelte b/src/lib/components/ui/UnlockButton.svelte new file mode 100644 index 0000000..bc420fb --- /dev/null +++ b/src/lib/components/ui/UnlockButton.svelte @@ -0,0 +1,31 @@ + + + diff --git a/src/routes/dashboard/+page.svelte b/src/routes/dashboard/+page.svelte index be4572c..ffa3a70 100644 --- a/src/routes/dashboard/+page.svelte +++ b/src/routes/dashboard/+page.svelte @@ -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 @@ {#snippet headerAction()} - +
+ + +
+ {/snippet} + + {#snippet searchBar()} + {#if allMyWishlists().length > 0} + + {/if} {/snippet} {#snippet children(wishlist)} @@ -169,7 +199,7 @@ > {t.dashboard.copyLink} - {#if wishlist.isClaimed} + {#if wishlist.isClaimed && myWishlistsUnlocked}
{ return async ({ update }) => { @@ -190,10 +220,20 @@ + {#snippet headerAction()} + + {/snippet} + + {#snippet searchBar()} + {#if (data.savedWishlists || []).filter(saved => !saved.wishlist?.ownerToken).length > 0} + + {/if} + {/snippet} + {#snippet children(saved)} {t.dashboard.viewWishlist} - { - return async ({ update }) => { - await update({ reset: false }); - }; - }}> - - - + {#if savedWishlistsUnlocked} +
{ + return async ({ update }) => { + await update({ reset: false }); + }; + }}> + + +
+ {/if}
{/snippet} diff --git a/src/routes/wishlist/[token]/+page.svelte b/src/routes/wishlist/[token]/+page.svelte index e026e14..6a9aec8 100644 --- a/src/routes/wishlist/[token]/+page.svelte +++ b/src/routes/wishlist/[token]/+page.svelte @@ -18,6 +18,7 @@ import { enhance } from "$app/forms"; import { getCardStyle } from "$lib/utils/colors"; import { languageStore } from '$lib/stores/language.svelte'; + import SearchBar from "$lib/components/ui/SearchBar.svelte"; let { data }: { data: PageData } = $props(); @@ -124,11 +125,7 @@ {#if data.wishlist.items && data.wishlist.items.length > 0} - + {/if} diff --git a/src/routes/wishlist/[token]/edit/+page.svelte b/src/routes/wishlist/[token]/edit/+page.svelte index f460f84..227ef20 100644 --- a/src/routes/wishlist/[token]/edit/+page.svelte +++ b/src/routes/wishlist/[token]/edit/+page.svelte @@ -9,11 +9,11 @@ import WishlistActionButtons from "$lib/components/wishlist/WishlistActionButtons.svelte"; import EditableItemsList from "$lib/components/wishlist/EditableItemsList.svelte"; import type { Item } from "$lib/server/schema"; - import { Input } from "$lib/components/ui/input"; import { Button } from "$lib/components/ui/button"; - import { Search, Lock, LockOpen } from "lucide-svelte"; import { enhance } from "$app/forms"; 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(); @@ -274,15 +274,7 @@ {/if} {#if sortedItems.length > 5} -
- - -
+ {/if}
- + {#if rearranging}