Files
korean-frontend/src/lib/components/layouts/Navbar.svelte
2025-11-03 13:35:27 +05:45

247 lines
8.3 KiB
Svelte

<script lang="ts">
import { tick } from 'svelte';
import { goto } from '$app/navigation';
import { enhance } from '$app/forms';
import {
ShoppingBag,
CircleUserRound,
Search,
SlidersHorizontal,
LogOut,
UserRound
} from '@lucide/svelte';
import logo from '$lib/assets/img/logo/full_logo.png?enhanced';
import { Button } from '$lib/components/ui/button';
import * as Sheet from '$lib/components/ui/sheet/index.js';
import { ScrollArea } from '$lib/components/ui/scroll-area/index.js';
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
import * as NavigationMenu from '$lib/components/ui/navigation-menu/index.js';
const languages = [
{
value: 'English',
label: 'English',
code: 'Us'
},
{
value: 'Nepali',
label: 'Nepali',
code: 'Np'
}
];
let { user, category } = $props();
let open = $state(false);
let value = $state(languages[0].value);
let triggerRef = $state<HTMLButtonElement>(null!);
let searchInputText = $state('');
const selectedValue = $derived(languages.find((f) => f.value === value)?.label);
function closeAndFocusTrigger() {
open = false;
tick().then(() => {
triggerRef.focus();
});
}
function searchInput(e: Event) {
e.preventDefault();
goto(`/category/search/${searchInputText}?q=${searchInputText}`, {
invalidateAll: true,
keepFocus: false,
replaceState: true
});
}
</script>
<header class="sticky top-0 z-50 border-y border-gray-200 bg-white">
<div
class="max-xs:gap-0 mx-auto flex max-w-screen-2xl items-center justify-between gap-10 px-10 py-4 max-lg:flex-wrap max-lg:gap-4 max-md:px-6 max-sm:border-y-0 max-sm:border-b max-sm:px-4"
>
<div class="max-xs:w-32 w-40 max-sm:w-32">
<a href="/" aria-label="Logo">
<enhanced:img src={logo} alt="Logo" class="w-64" />
</a>
</div>
<div class="flex w-full items-center gap-2 max-lg:order-3 max-lg:w-full">
<Sheet.Root {open}>
<Sheet.Trigger
onclick={() => {
open = true;
}}
>
<!-- <SlidersHorizontal class="md:hidden" strokeWidth={1.8} size={20} /> -->
<p class="text-sm font-medium md:hidden">Categories</p>
</Sheet.Trigger>
<Sheet.Content side="left" class="flex w-full flex-col gap-8 px-4 sm:w-full">
<Sheet.Header class="text-start">
<Sheet.Title>Categories</Sheet.Title>
</Sheet.Header>
<ScrollArea
class="w-full [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
scrollbarXClasses="border-none"
>
<div class="flex flex-col gap-4">
<!-- {#await category then categoryItem} -->
{#each category?.categories as item}
{#if item?.status !== 'draft'}
<a
href="/category/{item?.id}/{item?.slug}"
class="text-nowrap"
onclick={() => {
open = false;
}}>{item?.title}</a
>
{/if}
{/each}
<!-- {/await} -->
</div>
</ScrollArea>
</Sheet.Content>
</Sheet.Root>
<NavigationMenu.Root>
<NavigationMenu.List class="gap-0">
<NavigationMenu.Item class="max-md:hidden">
<NavigationMenu.Trigger>Categories</NavigationMenu.Trigger>
<NavigationMenu.Content>
<ul class="grid w-[400px] gap-1 p-2 md:w-[500px] md:grid-cols-2 lg:w-[600px]">
<!-- {#await category then categoryItem} -->
{#each category?.categories as item}
{#if item?.status !== 'draft'}
<li>
<NavigationMenu.Link
href="/category/{item?.id}/{item?.slug}"
class="text-nowrap"
>
{item?.title}
</NavigationMenu.Link>
</li>
{/if}
{/each}
<!-- {/await} -->
</ul>
</NavigationMenu.Content>
</NavigationMenu.Item>
<NavigationMenu.Item>
<NavigationMenu.Link href="/brand" class="text-sm font-medium text-nowrap">
Brands
</NavigationMenu.Link>
</NavigationMenu.Item>
</NavigationMenu.List>
</NavigationMenu.Root>
<form class="max-xs:mt-2 w-full max-lg:w-full max-md:hidden" onsubmit={searchInput}>
<div
class="flex w-full items-center gap-1 rounded-lg border-[1.6px] border-gray-200 p-1 pl-4 focus-within:border-primary/40 max-sm:gap-2 max-sm:pl-3"
>
<Search strokeWidth={1.5} class="text-primary/45 max-sm:w-5" />
<input
type="text"
placeholder="Search for products..."
class="max-xs:text-xs w-full text-sm tracking-tight focus-visible:ring-0 focus-visible:outline-none max-sm:py-2"
bind:value={searchInputText}
/>
<Button
class="max-xs:text-xs rounded-md border border-primary px-4 py-2 text-sm font-semibold tracking-tight text-primary max-sm:hidden"
type="submit"
variant="outline">Search</Button
>
</div>
</form>
</div>
<div class="flex items-center gap-5 max-sm:gap-3">
<Sheet.Root>
<Sheet.Trigger class="flex flex-col items-center justify-center gap-2 md:hidden">
<Search class="md:hidden" strokeWidth={1.8} size={20} />
<p class="text-xs font-medium text-nowrap">Search</p>
</Sheet.Trigger>
<Sheet.Content side="right" class="flex w-full flex-col gap-0 sm:w-full">
<Sheet.Header class="text-start">
<Sheet.Title>Search</Sheet.Title>
</Sheet.Header>
<form class="w-full px-2 max-lg:w-full md:hidden" onsubmit={searchInput}>
<div
class="flex w-full items-center gap-1 rounded-lg border-[1.6px] border-gray-200 p-1 pl-4 focus-within:border-primary/40 max-sm:gap-2 max-sm:pl-3"
>
<Search strokeWidth={1.5} class="text-primary/45 max-sm:w-5" />
<input
type="text"
placeholder="Search for products..."
class="max-xs:text-xs w-full text-sm tracking-tight focus-visible:ring-0 focus-visible:outline-none max-sm:py-2"
bind:value={searchInputText}
/>
<Button
class="max-xs:text-xs rounded-md border border-primary px-4 py-2 text-sm font-semibold tracking-tight text-primary max-sm:hidden"
type="submit"
variant="outline">Search</Button
>
</div>
</form>
</Sheet.Content>
</Sheet.Root>
<div class="max-xs:gap-4 flex items-center gap-4 max-sm:gap-3">
<a
href={user?.authenticated ? '/cart' : '/login'}
class="max-xs:gap-0 flex flex-col items-center gap-1"
>
<ShoppingBag strokeWidth={1.2} class="max-xs:w-5" />
<p class="text-xs font-medium text-nowrap">Cart</p>
</a>
{#if user?.authenticated}
<DropdownMenu.Root>
<DropdownMenu.Trigger class="cursor-pointer">
<div class="flex flex-col items-center">
{#if user?.user?.profileImage}
<img
src={user?.user?.profileImage}
alt="{user?.user?.name} avatar"
class="aspect-square h-7 w-7 rounded-full object-cover object-center"
/>
{:else}
<p class="flex h-7 w-7 items-center justify-center rounded-full bg-slate-200">
{user?.user?.name.slice(0, 1)}
</p>
{/if}
<p class="text-xs font-medium">{user?.user?.name.split(' ')[0]}</p>
</div>
</DropdownMenu.Trigger>
<DropdownMenu.Content align="end" class="min-w-40">
<DropdownMenu.Group>
<DropdownMenu.GroupHeading>My Account</DropdownMenu.GroupHeading>
<DropdownMenu.Separator class="bg-primary/15 " />
<a href="/profile">
<DropdownMenu.Item class="cursor-pointer">
<UserRound size={20} strokeWidth={1.5} />
<span> Profile </span>
</DropdownMenu.Item>
</a>
<DropdownMenu.Item class="flex cursor-pointer items-center text-primary">
<form method="POST" action="/logout" use:enhance>
<button type="submit" class="flex items-center gap-2">
<LogOut size={20} strokeWidth={1.5} />
<p>Logout</p>
</button>
</form>
</DropdownMenu.Item>
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu.Root>
{:else}
<a href="/login" class="max-xs:gap-0 flex flex-col flex-nowrap items-center gap-1">
<CircleUserRound strokeWidth={1.2} class="max-xs:w-5" />
<p class="text-xs font-medium text-nowrap">Log in</p>
</a>
{/if}
</div>
<!-- <a
href="/booking"
class="text-nowrap rounded-md bg-primary px-5 py-3 text-sm font-semibold tracking-tight text-white max-md:px-3 max-md:py-3 max-md:text-xs max-xs:hidden"
>Book Appointment</a
> -->
</div>
</div>
</header>