diff --git a/src/routes/dashboard/+page.svelte b/src/routes/dashboard/+page.svelte
index 69d67a7..be4572c 100644
--- a/src/routes/dashboard/+page.svelte
+++ b/src/routes/dashboard/+page.svelte
@@ -13,8 +13,23 @@
const t = $derived(languageStore.t);
+ // Combine owned and claimed wishlists for "My Wishlists"
+ const allMyWishlists = $derived(() => {
+ const owned = data.wishlists || [];
+ // Only include claimed wishlists (those with ownerToken, meaning they were claimed via edit link)
+ const claimed = (data.savedWishlists || [])
+ .filter(saved => saved.wishlist?.ownerToken) // Has edit access
+ .map(saved => ({
+ ...saved.wishlist,
+ isFavorite: saved.isFavorite,
+ isClaimed: true,
+ savedId: saved.id
+ }));
+ return [...owned, ...claimed];
+ });
+
const sortedWishlists = $derived(
- [...data.wishlists].sort((a, b) => {
+ [...allMyWishlists()].sort((a, b) => {
if (a.isFavorite && !b.isFavorite) return -1;
if (!a.isFavorite && b.isFavorite) return 1;
@@ -32,23 +47,26 @@
})
);
+ // Saved wishlists are those WITHOUT ownerToken (saved from public view only)
const sortedSavedWishlists = $derived(
- [...data.savedWishlists].sort((a, b) => {
- if (a.isFavorite && !b.isFavorite) return -1;
- if (!a.isFavorite && b.isFavorite) return 1;
+ [...(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 aHasEndDate = !!a.wishlist?.endDate;
- const bHasEndDate = !!b.wishlist?.endDate;
+ const aHasEndDate = !!a.wishlist?.endDate;
+ const bHasEndDate = !!b.wishlist?.endDate;
- if (aHasEndDate && !bHasEndDate) return -1;
- if (!aHasEndDate && bHasEndDate) return 1;
+ 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();
- }
+ 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();
- })
+ return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
+ })
);
function formatEndDate(date: Date | string | null): string | null {
@@ -107,17 +125,33 @@
color={wishlist.color}
>
-
+ {#if wishlist.isClaimed}
+
+
+ {:else}
+
+
+ {/if}
(window.location.href = `/wishlist/${wishlist.ownerToken}/edit`)}
@@ -135,6 +169,19 @@
>
{t.dashboard.copyLink}
+ {#if wishlist.isClaimed}
+
+
+ {/if}
{/snippet}
diff --git a/src/routes/wishlist/[token]/edit/+page.server.ts b/src/routes/wishlist/[token]/edit/+page.server.ts
index 299c845..31a8bda 100644
--- a/src/routes/wishlist/[token]/edit/+page.server.ts
+++ b/src/routes/wishlist/[token]/edit/+page.server.ts
@@ -1,8 +1,8 @@
import { error } from '@sveltejs/kit';
import type { PageServerLoad, Actions } from './$types';
import { db } from '$lib/server/db';
-import { wishlists, items } from '$lib/server/schema';
-import { eq } from 'drizzle-orm';
+import { wishlists, items, savedWishlists } from '$lib/server/schema';
+import { eq, and } from 'drizzle-orm';
export const load: PageServerLoad = async ({ params, locals }) => {
const wishlist = await db.query.wishlists.findFirst({
@@ -19,11 +19,29 @@ export const load: PageServerLoad = async ({ params, locals }) => {
}
const session = await locals.auth();
+ let hasClaimed = false;
+ let isOwner = false;
+
+ if (session?.user?.id) {
+ // Check if user is the owner
+ isOwner = wishlist.userId === session.user.id;
+
+ // Check if user has claimed this wishlist
+ const savedWishlist = await db.query.savedWishlists.findFirst({
+ where: and(
+ eq(savedWishlists.userId, session.user.id),
+ eq(savedWishlists.wishlistId, wishlist.id)
+ )
+ });
+ hasClaimed = !!savedWishlist;
+ }
return {
wishlist,
publicUrl: `/wishlist/${wishlist.publicToken}`,
- isAuthenticated: !!session?.user
+ isAuthenticated: !!session?.user,
+ hasClaimed,
+ isOwner
};
};
@@ -224,5 +242,66 @@ export const actions: Actions = {
.where(eq(wishlists.id, wishlist.id));
return { success: true };
+ },
+
+ claimWishlist: async ({ params, locals }) => {
+ const session = await locals.auth();
+
+ if (!session?.user?.id) {
+ throw error(401, 'You must be signed in to claim a wishlist');
+ }
+
+ const wishlist = await db.query.wishlists.findFirst({
+ where: eq(wishlists.ownerToken, params.token)
+ });
+
+ if (!wishlist) {
+ throw error(404, 'Wishlist not found');
+ }
+
+ // Check if already claimed
+ const existing = await db.query.savedWishlists.findFirst({
+ where: and(
+ eq(savedWishlists.userId, session.user.id),
+ eq(savedWishlists.wishlistId, wishlist.id)
+ )
+ });
+
+ if (existing) {
+ return { success: true, message: 'Already claimed' };
+ }
+
+ await db.insert(savedWishlists).values({
+ userId: session.user.id,
+ wishlistId: wishlist.id,
+ isFavorite: false
+ });
+
+ return { success: true, message: 'Wishlist claimed successfully' };
+ },
+
+ unclaimWishlist: async ({ params, locals }) => {
+ const session = await locals.auth();
+
+ if (!session?.user?.id) {
+ throw error(401, 'You must be signed in');
+ }
+
+ const wishlist = await db.query.wishlists.findFirst({
+ where: eq(wishlists.ownerToken, params.token)
+ });
+
+ if (!wishlist) {
+ throw error(404, 'Wishlist not found');
+ }
+
+ await db.delete(savedWishlists).where(
+ and(
+ eq(savedWishlists.userId, session.user.id),
+ eq(savedWishlists.wishlistId, wishlist.id)
+ )
+ );
+
+ return { success: true, message: 'Wishlist unclaimed' };
}
};
diff --git a/src/routes/wishlist/[token]/edit/+page.svelte b/src/routes/wishlist/[token]/edit/+page.svelte
index 69d1476..1e50c16 100644
--- a/src/routes/wishlist/[token]/edit/+page.svelte
+++ b/src/routes/wishlist/[token]/edit/+page.svelte
@@ -206,6 +206,44 @@
ownerUrl="/wishlist/{data.wishlist.ownerToken}/edit"
/>
+ {#if data.isAuthenticated}
+
+ {#if data.isOwner}
+
+ You Own This Wishlist
+
+
+ This wishlist is already in your dashboard as the owner.
+
+ {:else}
+
+
+ {#if data.hasClaimed}
+ You have claimed this wishlist. It will appear in your dashboard.
+ {:else}
+ Claim this wishlist to add it to your dashboard for easy access.
+ {/if}
+
+ {/if}
+
+ {/if}
+