diff options
Diffstat (limited to 'src/core/components/elements/Sidebar')
| -rw-r--r-- | src/core/components/elements/Sidebar/Sidebar.jsx | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/src/core/components/elements/Sidebar/Sidebar.jsx b/src/core/components/elements/Sidebar/Sidebar.jsx new file mode 100644 index 00000000..c39b5e34 --- /dev/null +++ b/src/core/components/elements/Sidebar/Sidebar.jsx @@ -0,0 +1,220 @@ +import Link from '../Link/Link' +import greeting from '@/core/utils/greeting' +import useAuth from '@/core/hooks/useAuth' +import { AnimatePresence, motion } from 'framer-motion' +import { ChevronDownIcon, ChevronUpIcon, CogIcon } from '@heroicons/react/24/outline' +import { Fragment, useEffect, useState } from 'react' +import odooApi from '@/core/api/odooApi' + +const Sidebar = ({ active, close }) => { + const auth = useAuth() + + const SidebarLink = ({ children, ...props }) => ( + <Link + {...props} + onClick={close} + > + {children} + </Link> + ) + + const itemClassName = 'px-4 py-3 block !text-gray_r-12/80 font-normal' + const transition = { ease: 'linear', duration: 0.2 } + + const [isOpenCategory, setOpenCategory] = useState(false) + const [categories, setCategories] = useState([]) + + useEffect(() => { + const loadCategories = async () => { + if (isOpenCategory && categories.length == 0) { + let dataCategories = await odooApi('GET', '/api/v1/category/tree') + dataCategories = dataCategories.map((category) => { + category.childs = category.childs.map((child1Category) => { + return { + ...child1Category, + isOpen: false + } + }) + return { + ...category, + isOpen: false + } + }) + setCategories(dataCategories) + } + } + loadCategories() + }, [isOpenCategory, categories]) + + const toggleCategories = (id = 0) => { + let newCategories = categories.map((category) => { + category.childs = category.childs.map((child1Category) => { + return { + ...child1Category, + isOpen: id == child1Category.id ? !child1Category.isOpen : child1Category.isOpen + } + }) + return { + ...category, + isOpen: id == category.id ? !category.isOpen : category.isOpen + } + }) + setCategories(newCategories) + } + + return ( + <> + <AnimatePresence> + {active && ( + <> + <motion.div + className='overlay z-50' + initial={{ opacity: 0 }} + animate={{ opacity: 1 }} + exit={{ opacity: 0 }} + transition={transition} + onClick={close} + /> + <motion.div + className='fixed z-[55] top-0 h-full w-[80%] bg-white' + initial={{ left: '-80%' }} + animate={{ left: 0 }} + exit={{ left: '-80%' }} + transition={transition} + > + <div className='divide-y divide-gray_r-6'> + <div className='p-4 flex gap-x-3'> + {!auth && ( + <> + <Link + onClick={close} + href='/register' + className='btn-yellow !text-gray_r-12 py-2 flex-1' + > + Daftar + </Link> + <Link + onClick={close} + href='/login' + className='btn-solid-red !text-gray_r-1 py-2 flex-1' + > + Masuk + </Link> + </> + )} + {auth && ( + <> + <div className='text-caption-2 text-gray_r-11'> + {greeting()}, + <span className='text-body-2 text-gray_r-12 block mt-1 font-medium'> + {auth?.name} + </span> + </div> + <Link + onClick={close} + href='/my/menu' + className='!text-gray_r-11 ml-auto my-auto' + > + <CogIcon className='w-6' /> + </Link> + </> + )} + </div> + <SidebarLink + className={itemClassName} + href='/shop/brands' + > + Semua Brand + </SidebarLink> + <SidebarLink + className={itemClassName} + href='/' + > + Tentang Indoteknik + </SidebarLink> + <SidebarLink + className={itemClassName} + href='/' + > + Pusat Bantuan + </SidebarLink> + <button + className={`${itemClassName} w-full text-left flex`} + onClick={() => setOpenCategory(!isOpenCategory)} + > + Kategori + <div className='ml-auto'> + {!isOpenCategory && <ChevronDownIcon className='text-gray_r-12 w-5' />} + {isOpenCategory && <ChevronUpIcon className='text-gray_r-12 w-5' />} + </div> + </button> + {isOpenCategory && + categories.map((category) => ( + <Fragment key={category.id}> + <div className='flex w-full text-gray_r-11 border-b border-gray_r-6 px-4 pl-8 items-center'> + <Link + href={`/shop/search?category=${category.name}`} + className='flex-1 font-normal !text-gray_r-11 py-4' + > + {category.name} + </Link> + <div + className='ml-4 h-full py-4' + onClick={() => toggleCategories(category.id)} + > + {!category.isOpen && <ChevronDownIcon className='text-gray_r-11 w-5' />} + {category.isOpen && <ChevronUpIcon className='text-gray_r-11 w-5' />} + </div> + </div> + {category.isOpen && + category.childs.map((child1Category) => ( + <Fragment key={child1Category.id}> + <div + className={`flex w-full !text-gray_r-11 border-b border-gray_r-6 p-4 pl-12 ${ + category.isOpen ? 'bg-gray_r-2' : '' + }`} + > + <Link + href={`/shop/search?category=${child1Category.name}`} + className='flex-1 font-normal !text-gray_r-11' + > + {child1Category.name} + </Link> + {child1Category.childs.length > 0 && ( + <div + className='ml-4 h-full' + onClick={() => toggleCategories(child1Category.id)} + > + {!child1Category.isOpen && ( + <ChevronDownIcon className='text-gray_r-11 w-5' /> + )} + {child1Category.isOpen && ( + <ChevronUpIcon className='text-gray_r-11 w-5' /> + )} + </div> + )} + </div> + {child1Category.isOpen && + child1Category.childs.map((child2Category) => ( + <Link + key={child2Category.id} + href={`/shop/search?category=${child2Category.name}`} + className='flex w-full font-normal !text-gray_r-11 border-b border-gray_r-6 p-4 pl-16' + > + {child2Category.name} + </Link> + ))} + </Fragment> + ))} + </Fragment> + ))} + </div> + </motion.div> + </> + )} + </AnimatePresence> + </> + ) +} + +export default Sidebar |
