Advertisement
redo21

navba-react

Nov 26th, 2022
654
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React from "react";
  2.  
  3. const TorcheAppBar = () => {
  4.     const [isNavbarOpen, setIsNavbarOpen] = React.useState(false);
  5.  
  6.     const navbarDatas = [
  7.         {
  8.             title: 'Beranda',
  9.             href: '/',
  10.         },
  11.         {
  12.             title: 'Tentang Kami',
  13.             href: '/about',
  14.         },
  15.         {
  16.             title: 'Layanan',
  17.             href: '/service',
  18.         },
  19.         {
  20.             title: 'Tutor',
  21.             href: '/tuition',
  22.         },
  23.         {
  24.             title: 'Event',
  25.             href: '/event',
  26.         },
  27.         {
  28.             title: 'Kursus',
  29.             submenu: [
  30.                 {
  31.                     title: 'Mata kuliah',
  32.                     href: '/course/matkul'
  33.                 },
  34.                 {
  35.                     title: 'Mendaftar kelas',
  36.                     href: '/course/registration'
  37.                 },
  38.                 {
  39.                     title: 'Harga',
  40.                     href: '/course/price'
  41.                 },
  42.             ]
  43.         },
  44.         {
  45.             title: 'Apps',
  46.             submenu: [
  47.                 {
  48.                     title: 'Web Calculator',
  49.                     href: '/web-calc'
  50.                 },
  51.             ]
  52.         },
  53.         {
  54.             title: 'Karir',
  55.             href: '/career',
  56.         }
  57.     ]
  58.  
  59.     return (
  60.         <>
  61.             <div className="fixed top-0 w-full p-8 px-7 bg-[#0b122a] min-h-fit text-white flex items-center flex-row justify-between">
  62.                 <div>
  63.                     <h1>Torche</h1>
  64.                 </div>
  65.                 <div>
  66.                     <button onClick={() => setIsNavbarOpen(!isNavbarOpen)} className={`${isNavbarOpen && 'hidden'} lg:hidden hamburger`}>
  67.                         <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
  68.                             <path strokeLinecap="round" strokeLinejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
  69.                         </svg>
  70.                     </button>
  71.                     <ul className="lg:flex hidden flex-row items-center mt-0">
  72.                         {
  73.                             navbarDatas.map((data, index) => {
  74.                                 return (
  75.                                     <li key={index} className="relative lg:mx-3 lg:my-0 my-3 transition duration-200 font-light">
  76.                                         <List data={data} />
  77.                                     </li>
  78.                                 )
  79.                             })
  80.                         }
  81.                     </ul>
  82.                 </div>
  83.             </div>
  84.             <div className={`${isNavbarOpen ? 'block' : 'hidden'} backdrop lg:hidden absolute z-40 left-0 top-0 right-0 min-h-screen`} style={{background: 'rgba(23, 35, 46, 0.9)'}}/>
  85.             <button onClick={() => setIsNavbarOpen(!isNavbarOpen)} className={`${isNavbarOpen ? 'block' : 'hidden'} lg:hidden absolute right-5 top-5 z-50 text-white`}>
  86.                 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
  87.                     <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
  88.                 </svg>
  89.             </button>
  90.             <ul className={`${isNavbarOpen ? 'block' : 'hidden'} lg:hidden left-3 right-3 absolute top-14 text-white bg-[#0b122a] flex flex-col mt-0 bg-red p-3 z-50 min-h-[calc(100%-70px)]`}>
  91.                 {
  92.                     navbarDatas.map((data, index) => {
  93.                         return (
  94.                             <li key={index} className="relative lg:mx-3 lg:my-0 my-3 transition duration-200 font-light">
  95.                                 <List data={data} />
  96.                             </li>
  97.                         )
  98.                     })
  99.                 }
  100.             </ul>
  101.  
  102.         </>
  103.     );
  104. }
  105.  
  106. interface ListProps {
  107.     data: any,
  108. }
  109.  
  110. const List = ({ data }: ListProps) => {
  111.     const [isOpen, setIsOpen] = React.useState(false);
  112.  
  113.     return (
  114.         <li
  115.             onMouseOver={() => setIsOpen(true)}
  116.             onMouseOut={() => setIsOpen(false)}
  117.             className="relative mx-1 transition duration-200 font-light hover:text-blue-500">
  118.             {
  119.                 Object.keys(data).includes('submenu') ?
  120.                     <>
  121.                         <div className="flex items-center justify-between">
  122.                             <p className="cursor-pointer">{data.title}</p>
  123.                             <svg onClick={() => setIsOpen(!isOpen)} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className={`w-4 h-4 lg:mt-1 lg:ml-2 transition duration-200 ${isOpen && 'rotate-180'}`}>
  124.                                 <path strokeLinecap="round" strokeLinejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
  125.                             </svg>
  126.                         </div>
  127.  
  128.                         <div
  129.                             onMouseOver={() => setIsOpen(true)}
  130.                             onMouseOut={() => setIsOpen(false)}
  131.                             className={`${isOpen ? 'lg:absolute' : 'hidden'} z-50 bg-[#0b122a] p-5 min-w-[200px] lg:-ml-5`}>
  132.                             {
  133.                                 data.submenu !== undefined &&
  134.                                 data.submenu.map((item: { title: string, href: string }, index: number) => {
  135.                                     return (
  136.                                         <div>
  137.                                             <Submenu
  138.                                                 key={index}
  139.                                                 title={item.title}
  140.                                                 href={item.href}
  141.                                                 isOpen={isOpen}
  142.                                                 setIsOpen={setIsOpen}
  143.                                             />
  144.                                         </div>
  145.                                     )
  146.                                 })
  147.                             }
  148.                         </div>
  149.                     </>
  150.                     :
  151.                     <a href={data?.href}>{data.title}</a>
  152.             }
  153.         </li>
  154.     )
  155. }
  156.  
  157. interface SubmenuProps {
  158.     title?: string,
  159.     href?: string,
  160.     isOpen?: boolean,
  161.     setIsOpen: Function
  162. }
  163.  
  164. const Submenu = ({ title, href, isOpen, setIsOpen }: SubmenuProps) => {
  165.     return (
  166.         <div
  167.             className={`hover:text-blue-500 text-white transition duration-200 my-3`}>
  168.             <a href={href}>{title}</a>
  169.         </div>
  170.     );
  171. }
  172.  
  173. export default TorcheAppBar;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement