From 0c4049f012f361fa68c13153d22bc7590ce7ff0d Mon Sep 17 00:00:00 2001
From: Sam Liu <luu.dat.tham@gmail.com>
Date: Wed, 12 Jun 2024 07:34:44 +0000
Subject: [PATCH] [FWA-8] Navbar

---
 frontend/src/components/Header.jsx         |   2 +-
 frontend/src/components/Navbar/Navbar.jsx  | 102 ++++++++++++++++++---
 frontend/src/components/Navbar/navbar.scss |  18 ----
 3 files changed, 89 insertions(+), 33 deletions(-)

diff --git a/frontend/src/components/Header.jsx b/frontend/src/components/Header.jsx
index f0a2a64..50df9d0 100644
--- a/frontend/src/components/Header.jsx
+++ b/frontend/src/components/Header.jsx
@@ -50,7 +50,7 @@ export default function Header() {
       <Show when={store.auth}>
         <div class="flex items-center justify-end">
           <div class="avatar hidden lg:block">
-            <div class="w-9 mask mask-hexagon">
+            <div class="w-9 rounded-full">
               <img
                 src={`https://ui-avatars.com/api/?name=${store.userInfo?.name}`}
                 alt="avatar"
diff --git a/frontend/src/components/Navbar/Navbar.jsx b/frontend/src/components/Navbar/Navbar.jsx
index bfeb854..64fe85f 100644
--- a/frontend/src/components/Navbar/Navbar.jsx
+++ b/frontend/src/components/Navbar/Navbar.jsx
@@ -4,7 +4,7 @@ import useLanguage from '@hooks/useLanguage'
 import { A } from '@solidjs/router'
 import { IconDashboard, IconLogout, IconTriangle } from '@tabler/icons-solidjs'
 import UserHelper from '@utils/auth'
-import { For, Show } from 'solid-js'
+import { For, Show, mergeProps } from 'solid-js'
 import { Dynamic } from 'solid-js/web'
 import './navbar.scss'
 
@@ -16,10 +16,36 @@ console.log(userHelper.isAdmin)
 const NAV_ITEM = [
   {
     path: '/dashboard',
-    show: false,
+    show: true,
     icon: IconDashboard,
     text: language?.ui.dashboard,
   },
+  {
+    show: true,
+    icon: IconTriangle,
+    text: 'API',
+    children: [
+      {
+        show: true,
+        icon: IconDashboard,
+        text: 'Test',
+        children: [
+          {
+            path: '/test',
+            show: true,
+            icon: IconDashboard,
+            text: 'Test',
+          },
+        ],
+      },
+      {
+        path: '/api',
+        show: true,
+        icon: IconDashboard,
+        text: 'Get',
+      },
+    ],
+  },
   {
     path: '/ware-house',
     show: true,
@@ -28,6 +54,52 @@ const NAV_ITEM = [
   },
 ]
 
+function NavbarItem(props) {
+  const merged = mergeProps({ active: true }, props)
+  return (
+    <Show
+      when={merged.active && merged.path}
+      fallback={
+        <>
+          <Dynamic component={merged.icon} />
+          {merged.text}
+        </>
+      }
+    >
+      <A href={merged.path}>
+        <Dynamic component={merged.icon} />
+        {merged.text}
+      </A>
+    </Show>
+  )
+}
+
+function NavbarWithChildren(props) {
+  return (
+    <li class="mb-2">
+      <h2 class="menu-title flex items-center gap-2">
+        <NavbarItem {...props} active={false} />
+      </h2>
+      <ul class="pl-4">
+        <For each={props.children}>
+          {(child) => {
+            if (!child.show) return
+            if (child.children) {
+              return <NavbarWithChildren {...child} />
+            } else {
+              return (
+                <li class="mb-2">
+                  <NavbarItem {...child} />
+                </li>
+              )
+            }
+          }}
+        </For>
+      </ul>
+    </li>
+  )
+}
+
 export default function Navbar() {
   const { store, setAuth } = useSiteContext()
   const { clickLogOut } = useAuth(setAuth)
@@ -49,7 +121,7 @@ export default function Navbar() {
       <label for="nav-menu" aria-label="close sidebar" class="drawer-overlay" />
       <div class="bg-base-200 w-80 min-h-full">
         <Show when={store.auth}>
-          <div class="flex items-center justify-between px-5 pt-5 lg:hidden">
+          <div class="flex items-center justify-between px-3 pt-5 lg:hidden">
             <div class="avatar">
               <div class="w-9 mask mask-hexagon">
                 <img
@@ -69,18 +141,20 @@ export default function Navbar() {
             <IconTriangle size={30} />
           </div>
         </Show>
-        <ul class="scrollnavbar menu p-4 w-80 text-base-content py-6 px-4">
+        <ul class="menu w-80 text-base-content pt-3 px-3 pb-6">
           <For each={NAV_ITEM}>
-            {(item) =>
-              item.show && (
-                <li class="mb-2">
-                  <A href={item.path}>
-                    <Dynamic component={item.icon} />
-                    {item.text}
-                  </A>
-                </li>
-              )
-            }
+            {(item) => {
+              if (!item.show) return
+              if (item.children) {
+                return <NavbarWithChildren {...item} />
+              } else {
+                return (
+                  <li class="mb-2">
+                    <NavbarItem {...item} />
+                  </li>
+                )
+              }
+            }}
           </For>
         </ul>
       </div>
diff --git a/frontend/src/components/Navbar/navbar.scss b/frontend/src/components/Navbar/navbar.scss
index af9bd03..e69de29 100644
--- a/frontend/src/components/Navbar/navbar.scss
+++ b/frontend/src/components/Navbar/navbar.scss
@@ -1,18 +0,0 @@
-.menu  {
-  li {
-    a {
-      color: var(--black);
-      font-weight: normal;
-
-      &:not(ul, .menu-title, details, .btn).active {
-        background-color: var(--primary);
-        color: var(--white);
-      }
-
-      &:hover {
-        background-color: rgba(var(--primary), 0.05);
-        color: var(--primary);
-      }
-    }
-  }
-}