add: themes for wishlists and dashboards
This commit is contained in:
@@ -43,15 +43,25 @@
|
||||
items: [] // We don't have item data in localStorage
|
||||
}));
|
||||
});
|
||||
|
||||
// Description depends on authentication status
|
||||
const sectionDescription = $derived(() => {
|
||||
if (isAuthenticated) {
|
||||
return t.dashboard.localWishlistsAuthDescription || "Wishlists stored in your browser that haven't been claimed yet.";
|
||||
}
|
||||
return t.dashboard.localWishlistsDescription || "Wishlists stored in your browser. Sign in to save them permanently.";
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if localWishlists.length > 0}
|
||||
<WishlistSection
|
||||
title={t.dashboard.localWishlists || "Local Wishlists"}
|
||||
description={t.dashboard.localWishlistsDescription || "Wishlists stored in your browser. Sign in to save them permanently."}
|
||||
items={transformedWishlists()}
|
||||
emptyMessage=""
|
||||
>
|
||||
<WishlistSection
|
||||
title={t.dashboard.localWishlists || "Local Wishlists"}
|
||||
description={sectionDescription()}
|
||||
items={transformedWishlists()}
|
||||
emptyMessage={t.dashboard.emptyLocalWishlists || "No local wishlists yet"}
|
||||
emptyActionLabel={t.dashboard.createLocalWishlist || "Create local wishlist"}
|
||||
emptyActionHref="/"
|
||||
showCreateButton={true}
|
||||
>
|
||||
{#snippet actions(wishlist, unlocked)}
|
||||
<div class="flex gap-2 flex-wrap">
|
||||
<Button
|
||||
@@ -89,5 +99,4 @@
|
||||
{/if}
|
||||
</div>
|
||||
{/snippet}
|
||||
</WishlistSection>
|
||||
{/if}
|
||||
</WishlistSection>
|
||||
|
||||
@@ -10,32 +10,35 @@
|
||||
let {
|
||||
userName,
|
||||
userEmail,
|
||||
dashboardTheme = 'none'
|
||||
dashboardTheme = 'none',
|
||||
isAuthenticated = false,
|
||||
onThemeUpdate
|
||||
}: {
|
||||
userName?: string | null;
|
||||
userEmail?: string | null;
|
||||
dashboardTheme?: string;
|
||||
isAuthenticated?: boolean;
|
||||
onThemeUpdate?: (theme: string | null) => void;
|
||||
} = $props();
|
||||
|
||||
const t = $derived(languageStore.t);
|
||||
const isAuthenticated = $derived(!!userName || !!userEmail);
|
||||
|
||||
let currentTheme = $state(dashboardTheme);
|
||||
|
||||
async function handleThemeChange(theme: string) {
|
||||
currentTheme = theme;
|
||||
// Update theme immediately for instant visual feedback
|
||||
if (onThemeUpdate) {
|
||||
onThemeUpdate(theme);
|
||||
}
|
||||
|
||||
// Submit form to update theme
|
||||
const formData = new FormData();
|
||||
formData.append('theme', theme);
|
||||
// Only submit to database for authenticated users
|
||||
if (isAuthenticated) {
|
||||
const formData = new FormData();
|
||||
formData.append('theme', theme);
|
||||
|
||||
await fetch('?/updateDashboardTheme', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
|
||||
// Reload to apply new theme
|
||||
window.location.reload();
|
||||
await fetch('?/updateDashboardTheme', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -49,9 +52,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex items-center gap-1 sm:gap-2 flex-shrink-0">
|
||||
{#if isAuthenticated}
|
||||
<ThemePicker value={currentTheme} onValueChange={handleThemeChange} />
|
||||
{/if}
|
||||
<ThemePicker value={dashboardTheme} onValueChange={handleThemeChange} />
|
||||
<LanguageToggle />
|
||||
<ThemeToggle />
|
||||
{#if isAuthenticated}
|
||||
|
||||
@@ -17,6 +17,11 @@ export const load: PageServerLoad = async (event) => {
|
||||
};
|
||||
}
|
||||
|
||||
// Fetch user with theme
|
||||
const user = await db.query.users.findFirst({
|
||||
where: eq(users.id, session.user.id)
|
||||
});
|
||||
|
||||
const userWishlists = await db.query.wishlists.findMany({
|
||||
where: eq(wishlists.userId, session.user.id),
|
||||
with: {
|
||||
@@ -57,7 +62,7 @@ export const load: PageServerLoad = async (event) => {
|
||||
}));
|
||||
|
||||
return {
|
||||
user: session.user,
|
||||
user: user,
|
||||
wishlists: userWishlists,
|
||||
savedWishlists: savedWithAccess,
|
||||
isAuthenticated: true
|
||||
|
||||
@@ -11,6 +11,30 @@
|
||||
|
||||
let { data }: { data: PageData } = $props();
|
||||
|
||||
// For anonymous users, get theme from localStorage
|
||||
function getInitialTheme() {
|
||||
if (data.isAuthenticated) {
|
||||
return data.user?.dashboardTheme || 'none';
|
||||
} else {
|
||||
// Anonymous user - get from localStorage
|
||||
if (typeof window !== 'undefined') {
|
||||
return localStorage.getItem('dashboardTheme') || 'none';
|
||||
}
|
||||
return 'none';
|
||||
}
|
||||
}
|
||||
|
||||
let currentTheme = $state(getInitialTheme());
|
||||
|
||||
// Save to localStorage when theme changes for anonymous users
|
||||
function handleThemeUpdate(theme: string | null) {
|
||||
currentTheme = theme || 'none';
|
||||
|
||||
if (!data.isAuthenticated && typeof window !== 'undefined') {
|
||||
localStorage.setItem('dashboardTheme', currentTheme);
|
||||
}
|
||||
}
|
||||
|
||||
const t = $derived(languageStore.t);
|
||||
|
||||
// Only owned wishlists for "My Wishlists"
|
||||
@@ -34,11 +58,13 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<PageContainer theme={data.user?.dashboardTheme} themeColor="hsl(var(--primary))">
|
||||
<PageContainer theme={currentTheme} themeColor="#3b82f6">
|
||||
<DashboardHeader
|
||||
userName={data.user?.name}
|
||||
userEmail={data.user?.email}
|
||||
dashboardTheme={data.user?.dashboardTheme || 'none'}
|
||||
dashboardTheme={currentTheme}
|
||||
isAuthenticated={data.isAuthenticated}
|
||||
onThemeUpdate={handleThemeUpdate}
|
||||
/>
|
||||
|
||||
<!-- Local Wishlists Section (for anonymous and authenticated users) -->
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
let addFormElement = $state<HTMLElement | null>(null);
|
||||
let editFormElement = $state<HTMLElement | null>(null);
|
||||
let searchQuery = $state("");
|
||||
let currentTheme = $state(data.wishlist.theme || 'none');
|
||||
|
||||
let items = $state<Item[]>([]);
|
||||
|
||||
@@ -105,9 +106,14 @@
|
||||
items = newItems;
|
||||
await handleReorder(newItems);
|
||||
}
|
||||
|
||||
async function handleThemeUpdate(theme: string | null) {
|
||||
currentTheme = theme || 'none';
|
||||
await wishlistUpdates.updateTheme(theme);
|
||||
}
|
||||
</script>
|
||||
|
||||
<PageContainer maxWidth="4xl" theme={data.wishlist.theme} themeColor={data.wishlist.color}>
|
||||
<PageContainer maxWidth="4xl" theme={currentTheme} themeColor={data.wishlist.color}>
|
||||
<Navigation
|
||||
isAuthenticated={data.isAuthenticated}
|
||||
showDashboardLink={true}
|
||||
@@ -119,7 +125,7 @@
|
||||
onDescriptionUpdate={wishlistUpdates.updateDescription}
|
||||
onColorUpdate={wishlistUpdates.updateColor}
|
||||
onEndDateUpdate={wishlistUpdates.updateEndDate}
|
||||
onThemeUpdate={wishlistUpdates.updateTheme}
|
||||
onThemeUpdate={handleThemeUpdate}
|
||||
/>
|
||||
|
||||
<ShareLinks
|
||||
@@ -169,7 +175,7 @@
|
||||
{rearranging}
|
||||
onStartEditing={startEditing}
|
||||
onReorder={handleReorder}
|
||||
theme={data.wishlist.theme}
|
||||
theme={currentTheme}
|
||||
/>
|
||||
|
||||
<DangerZone bind:unlocked={rearranging} />
|
||||
|
||||
Reference in New Issue
Block a user