From 135d8f59f4f7bba5dcbfdcd3ef4ea5b1f5431442 Mon Sep 17 00:00:00 2001 From: Matt Kirby <MattJKirby@outlook.com> Date: Tue, 14 Mar 2023 18:12:33 +0000 Subject: [PATCH] Added basic navbar component --- .../src/components/navigation/NavBar.tsx | 196 ++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 daily-thought-frontend/src/components/navigation/NavBar.tsx diff --git a/daily-thought-frontend/src/components/navigation/NavBar.tsx b/daily-thought-frontend/src/components/navigation/NavBar.tsx new file mode 100644 index 00000000..546fc023 --- /dev/null +++ b/daily-thought-frontend/src/components/navigation/NavBar.tsx @@ -0,0 +1,196 @@ +import { FC, Fragment, PropsWithChildren } from 'react' +import { Disclosure, Menu, Transition } from '@headlessui/react' +import { Bars3Icon, BellIcon, XMarkIcon } from '@heroicons/react/24/outline' +import { User } from '@/types/user' + +const user = { + Name: 'Tom Cook', + email: 'tom@example.com', + username: 'TomCook', + imageUrl: + 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80', +} +const navigation = [ + { name: 'My Feed', href: '#', current: true } +] +const userNavigation = [ + { name: 'Your Profile', href: '#' }, + { name: 'Settings', href: '#' }, + { name: 'Sign out', href: '#' }, +] + +function classNames(...classes: any) { + return classes.filter(Boolean).join(' ') +} + +type NavBarProps = { + user: User | null; +} + +const NavBar: FC<PropsWithChildren<NavBarProps>> = ({ + children, + user +}) => { + return ( + <> + <div className="min-h-full"> + <Disclosure as="nav" className="bg-white border-b border-gray-200"> + {({ open }) => ( + <> + <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> + <div className="flex h-16 items-center justify-between"> + + {user !== null && + <div className="flex items-center"> + <div className="hidden md:block"> + <div className="flex items-baseline space-x-4"> + {navigation.map((item) => ( + <a + key={item.name} + href={item.href} + className={classNames( + item.current + ? 'bg-pink-400 text-white' + : 'text-pink-400 hover:bg-pink-400 hover:text-white', + 'rounded-md px-3 py-2 text-sm font-medium' + )} + aria-current={item.current ? 'page' : undefined} + > + {item.name} + </a> + ))} + </div> + </div> + </div> + } + <div> + <h1 className="text-2xl font-bold tracking-tight text-gray-900">Daily</h1> + </div> + + {user !== null && + <div className="hidden md:block"> + <div className="ml-4 flex items-center md:ml-6"> + <button + type="button" + className="rounded-full bg-pink-400 p-1 text-white hover:text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-pink-400" + > + <span className="sr-only">View notifications</span> + <BellIcon className="h-6 w-6" aria-hidden="true" /> + </button> + + {/* Profile dropdown */} + <Menu as="div" className="relative ml-3"> + <div> + <Menu.Button className="flex max-w-xs items-center rounded-full bg-green-400 text-sm focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-pink-400"> + <span className="sr-only">Open user menu</span> + <img className="h-8 w-8 rounded-full" src={user.imageUrl} alt="" /> + </Menu.Button> + </div> + <Transition + as={Fragment} + enter="transition ease-out duration-100" + enterFrom="transform opacity-0 scale-95" + enterTo="transform opacity-100 scale-100" + leave="transition ease-in duration-75" + leaveFrom="transform opacity-100 scale-100" + leaveTo="transform opacity-0 scale-95" + > + <Menu.Items className="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"> + {userNavigation.map((item) => ( + <Menu.Item key={item.name}> + {({ active }) => ( + <a + href={item.href} + className={classNames( + active ? 'bg-gray-100' : '', + 'block px-4 py-2 text-sm text-gray-700' + )} + > + {item.name} + </a> + )} + </Menu.Item> + ))} + </Menu.Items> + </Transition> + </Menu> + </div> + </div> + } + + {user !== null && + <div className="-mr-2 flex md:hidden"> + {/* Mobile menu button */} + <Disclosure.Button className="inline-flex items-center justify-center rounded-md bg-white p-2 text-pink-400 hover:bg-pink-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-pink-400"> + <span className="sr-only">Open main menu</span> + {open ? ( + <XMarkIcon className="block h-6 w-6" aria-hidden="true" /> + ) : ( + <Bars3Icon className="block h-6 w-6" aria-hidden="true" /> + )} + </Disclosure.Button> + </div> + } + </div> + </div> + + <Disclosure.Panel className="md:hidden"> + <div className="space-y-1 px-2 pt-2 pb-3 sm:px-3"> + {navigation.map((item) => ( + <Disclosure.Button + key={item.name} + as="a" + href={item.href} + className={classNames( + item.current ? 'bg-pink-400 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white', + 'block rounded-md px-3 py-2 text-base font-medium' + )} + aria-current={item.current ? 'page' : undefined} + > + {item.name} + </Disclosure.Button> + ))} + </div> + <div className="border-t border-gray-200 pt-4 pb-3"> + <div className="flex items-center px-5"> + <div className="flex-shrink-0"> + <img className="h-10 w-10 rounded-full" src={user?.Avatar} alt="" /> + </div> + <div className="ml-3"> + <div className="text-base font-medium leading-none text-grey-600">{user?.Name}</div> + <div className="text-sm font-medium leading-none text-gray-400">{`@${user?.Username}`}</div> + </div> + <button + type="button" + className="ml-auto flex-shrink-0 rounded-full bg-pink-400 p-1 text-white hover:text-pink-400 hover:bg-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-pink-400" + > + <span className="sr-only">View notifications</span> + <BellIcon className="h-6 w-6" aria-hidden="true" /> + </button> + </div> + <div className="mt-3 space-y-1 px-2"> + {userNavigation.map((item) => ( + <Disclosure.Button + key={item.name} + as="a" + href={item.href} + className="block rounded-md px-3 py-2 text-base font-medium text-gray-900 hover:bg-pink-300 hover:text-green-200" + > + {item.name} + </Disclosure.Button> + ))} + </div> + </div> + </Disclosure.Panel> + </> + )} + </Disclosure> + <main> + <div className="mx-auto max-w-7xl py-6 sm:px-6 lg:px-8">{children}</div> + </main> + </div> + </> + ) +} + +export default NavBar; \ No newline at end of file -- GitLab