remix-demo

react router (remix) demo

git clone https://9o.is/git/remix-demo.git

MainNavigation.tsx

(3131B)


      1 import { Role } from "@prisma/client";
      2 import { Form } from "@remix-run/react";
      3 import { useState } from "react";
      4 import { NavLink } from "react-router-dom";
      5 import { useOptionalUser } from "~/utils/hooks";
      6 
      7 export default function MainNavigation() {
      8   const user = useOptionalUser();
      9   const menus = [
     10     { name: "Food Entries", link: "/food-entries" },
     11     { name: "Report", link: "/report" },
     12     { name: "Invite User", link: "/invite" },
     13   ];
     14 
     15   if (user?.role === Role.ADMIN) {
     16     menus.push({ name: "Admin Report", link: "/admin/report" });
     17   }
     18 
     19   const [dropdownHidden, setDropdownHidden] = useState(true);
     20   const toggleDropdown = () => setDropdownHidden(!dropdownHidden);
     21 
     22   return (
     23     <nav className="flex flex-wrap items-center justify-between py-2.5">
     24       <div>
     25         {user ? (
     26           <>
     27             <span className="font-semibold">{user.name}</span>
     28             <Form action="/logout" method="post" className="inline">
     29               <button
     30                 type="submit"
     31                 className="ml-2 text-sm text-red-600 hover:underline"
     32               >
     33                 Logout
     34               </button>
     35             </Form>
     36           </>
     37         ) : null}
     38       </div>
     39       <button
     40         onClick={toggleDropdown}
     41         data-collapse-toggle="navbar-default"
     42         type="button"
     43         className="ml-3 inline-flex items-center rounded-lg p-2 text-sm text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 md:hidden"
     44         aria-label="Toggle Main Menu"
     45         aria-controls="navbar-default"
     46         aria-expanded="false"
     47       >
     48         <span className="sr-only">Open main menu</span>
     49         <svg
     50           className="h-6 w-6"
     51           aria-hidden="true"
     52           fill="currentColor"
     53           viewBox="0 0 20 20"
     54           xmlns="http://www.w3.org/2000/svg"
     55         >
     56           <path
     57             fillRule="evenodd"
     58             d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
     59             clipRule="evenodd"
     60           ></path>
     61         </svg>
     62       </button>
     63       <div
     64         className={`${
     65           dropdownHidden ? "hidden" : ""
     66         } w-full md:block md:w-auto`}
     67         id="navbar-default"
     68       >
     69         <ul className="mt-4 flex flex-col rounded-lg border border-gray-100 bg-gray-50 p-4 md:mt-0 md:flex-row md:space-x-8 md:border-0 md:bg-white md:text-sm md:font-medium">
     70           {menus.map((menu) => (
     71             <li key={menu.link}>
     72               <NavLink
     73                 to={menu.link}
     74                 onClick={toggleDropdown}
     75                 className={({ isActive }: { isActive: boolean }) =>
     76                   "block rounded py-2 pr-4 pl-3 " +
     77                   (isActive
     78                     ? "bg-blue-700 text-white md:bg-transparent md:p-0 md:text-blue-700"
     79                     : "text-gray-700 hover:bg-gray-100 md:border-0 md:p-0 md:hover:bg-transparent md:hover:text-blue-700")
     80                 }
     81               >
     82                 {menu.name}
     83               </NavLink>
     84             </li>
     85           ))}
     86         </ul>
     87       </div>
     88     </nav>
     89   );
     90 }