feat(#35): make basket more prominent in nav

This commit is contained in:
OllyNicholass
2024-10-29 20:44:45 +00:00
parent 7c6afd169c
commit 4be732005e
7 changed files with 84 additions and 47 deletions
+8 -8
View File
@@ -1,5 +1,7 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { signOut } from '$lib/utils/supabase/auth';
import type { SupabaseClient } from '@supabase/supabase-js';
const dispatch = createEventDispatcher();
function emitSignedOutEvent() {
@@ -7,14 +9,12 @@
}
// Access the supabase client from the layout data
export let supabase: any;
export let supabase: SupabaseClient | null;
async function signOut() {
// TODO use the error from the response
const { error } = await supabase.auth.signOut().then(() => {
emitSignedOutEvent();
});
}
async function signOutClick() {
if (!supabase) return;
await signOut(supabase, emitSignedOutEvent);
}
</script>
<button on:click={signOut}>Sign Out</button>
<button on:click={signOutClick}>Sign Out</button>
+4 -29
View File
@@ -44,17 +44,17 @@
</button>
</div>
<!-- Dropdown content -->
<NavLinks isMobile />
<NavLinks isMobile {session} {supabase} />
</Dropdown>
</div>
<a href="/" class="text-white font-bold text-xl">SvelteKit SaaS Boilerplate</a>
<div class="hidden lg:block">
<NavLinks />
<NavLinks {session} />
</div>
<!-- Right Side: Basket & User Account -->
<div class="flex items-center space-x-4">
<!-- Basket/Checkout Icon -->
<a href="/checkout" class="btn btn-ghost btn-circle hidden lg:flex">
<a href="/checkout" class="btn btn-ghost btn-circle">
<div class="indicator">
<svg
xmlns="http://www.w3.org/2000/svg"
@@ -78,7 +78,7 @@
<!-- User Account Dropdown -->
<Dropdown posRight>
<div slot="dropdown">
<div class="btn btn-ghost btn-circle avatar placeholder">
<div class="btn btn-ghost btn-circle avatar placeholder hidden md:flex">
<div class="w-10 rounded-full">
{#if session?.user}
<div class="user-circle text-primary-content border-primary-content">
@@ -100,32 +100,7 @@
</div>
<!-- Dropdown content -->
{#if session?.user}
<li class="lg:hidden">
<a href="/checkout">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"
/>
</svg>
Basket
{#if localBasket.items.length > 0}
<span class="badge badge-md indicator-item bg-primary text-primary-content"
>{localBasket.items.length}</span
>
{/if}
</a>
</li>
<li><a href="/account">Account</a></li>
<li><a href="/settings">Settings</a></li>
<li><SignOut {supabase} /></li>
{:else}
<MagicLink {supabase} />
@@ -0,0 +1,15 @@
<script lang="ts">
import type { NavLinkItem } from "$lib/types/Nav/NavLinkItem";
import type { SupabaseClient } from "@supabase/supabase-js";
import SignOut from "../SignOut.svelte";
export let linkItem: NavLinkItem;
export let supabase: SupabaseClient | null = null;
</script>
{#if !linkItem.isSignout}
<a href={linkItem.href}>{linkItem.text}</a>
{:else if supabase && linkItem.isSignout}
<SignOut {supabase} />
{/if}
@@ -3,19 +3,22 @@
import { cubicInOut } from 'svelte/easing';
import Dropdown from '../Dropdown.svelte';
import { slide } from 'svelte/transition';
import NavLink from './NavLink.svelte';
import type { SupabaseClient } from '@supabase/supabase-js';
export let text: string;
export let children: NavLinkItem[] | undefined;
export let linkItem: NavLinkItem;
export let isMobile: boolean;
export let supabase: SupabaseClient | null;
let isOpen = false;
</script>
{#if !isMobile}
<Dropdown indicator>
<div slot="dropdown">{text}</div>
{#each children ?? [] as child}
<li><a href={child.href}>{child.text}</a></li>
<div slot="dropdown">{linkItem.text}</div>
{#each linkItem.children ?? [] as child}
<li><NavLink linkItem={child} /></li>
{/each}
</Dropdown>
{:else}
@@ -24,15 +27,15 @@
class="menu-dropdown-toggle"
on:click={() => (isOpen = !isOpen)}
>
{text}
{linkItem.text}
</button>
{#if isOpen}
<ul
class="menu-dropdown menu-dropdown-show"
transition:slide={{ duration: 200, easing: cubicInOut }}
>
{#each children ?? [] as child}
<li><a href={child.href}>{child.text}</a></li>
{#each linkItem.children ?? [] as child}
<li><NavLink linkItem={child} {supabase} /></li>
{/each}
</ul>
{/if}
+38 -2
View File
@@ -1,10 +1,46 @@
<script lang="ts">
import { type NavLinkItem } from '$lib/types/Nav/NavLinkItem';
import type { Session } from '@supabase/supabase-js';
import NavLinkParent from './NavLinkParent.svelte';
import type SupabaseClient from '@supabase/supabase-js/dist/module/SupabaseClient';
export let session: Session | null;
export let supabase: SupabaseClient | null = null;
export let isMobile = false;
const userAccountLinks: NavLinkItem[] = [];
if (isMobile) {
if (session) {
userAccountLinks.push(
{
text: 'User', // TODO - replace with user's name - will require a database call to get the user's name - suggest setting up a user model to store user data.
isParent: true,
isUserAccount: true,
children: [
{
text: 'Account',
href: '/account'
},
{
text: 'Sign Out',
isSignout: true
}
]
}
);
} else {
userAccountLinks.push(
{
text: 'Log in',
href: '/login'
},
);
}
}
const links: NavLinkItem[] = [
...userAccountLinks,
{
text: 'Products',
href: '/products'
@@ -32,9 +68,9 @@
<ul class:flex={!isMobile} class:space-x-4={!isMobile}>
{#each links as link}
<li>
<li class:md:hidden={link.isUserAccount}>
{#if link.isParent}
<NavLinkParent text={link.text} children={link.children} {isMobile} />
<NavLinkParent linkItem={link} {isMobile} {supabase} />
{:else}
<a href={link.href}>{link.text}</a>
{/if}
+2
View File
@@ -3,4 +3,6 @@ export interface NavLinkItem {
href?: string;
isParent?: boolean;
children?: NavLinkItem[];
isSignout?: boolean;
isUserAccount?: boolean;
}
+6
View File
@@ -0,0 +1,6 @@
import type { SupabaseClient } from "@supabase/supabase-js";
export async function signOut(supabase: SupabaseClient, callback: () => void) {
// TODO use the error from the response
const { error } = await supabase.auth.signOut().then(callback);
}