From 8eb44d0f0a5e8f11c4ceb4fec0ed7d9c2bad1484 Mon Sep 17 00:00:00 2001 From: Mads Hermansen <119772939+madshermansen@users.noreply.github.com> Date: Mon, 18 Mar 2024 15:58:53 +0100 Subject: [PATCH] 66 make the navbar responsive (#149) * feat(frontend): :sparkles: Add responsive navbar for mobile * feat(frontend): :sparkles: Navbar drawer positon change added logo * feat(frontend): :sparkles: responsive navbar * refactor: :memo: run prettier and fix linting * refactor(frontend): :art: remove dark mode comments * refactor(frontend): :art: run prettier --- frontend/package-lock.json | 80 +++++++- frontend/package.json | 5 +- .../public/images/ntnu-white-logo-mobile.svg | 106 +++++++++++ frontend/public/images/ntnu-white-logo.svg | 175 ++++++++++++++++++ frontend/src/components/Navbar.tsx | 131 ++++++------- frontend/src/components/ui/drawer.tsx | 120 ++++++++++++ 6 files changed, 542 insertions(+), 75 deletions(-) create mode 100644 frontend/public/images/ntnu-white-logo-mobile.svg create mode 100644 frontend/public/images/ntnu-white-logo.svg create mode 100644 frontend/src/components/ui/drawer.tsx diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a73a5f2..9479f0c 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -12,6 +12,7 @@ "@apollo/experimental-nextjs-app-support": "^0.6.0", "@gsap/react": "^2.1.0", "@radix-ui/react-avatar": "^1.0.4", + "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-separator": "^1.0.3", @@ -39,13 +40,15 @@ "satellite.js": "^5.0.0", "tailwind-merge": "^2.2.0", "tailwindcss-animate": "^1.0.7", - "three": "^0.161.0" + "three": "^0.161.0", + "vaul": "^0.9.0" }, "devDependencies": { "@cloudflare/next-on-pages": "^1.8.3", "@graphql-codegen/cli": "^5.0.0", "@graphql-codegen/client-preset": "^4.1.0", "@graphql-typed-document-node/core": "^3.2.0", + "@iconify-icon/react": "^2.0.1", "@iconify/react": "^4.1.1", "@playwright/test": "^1.41.2", "@tailwindcss/typography": "^0.5.10", @@ -3188,6 +3191,21 @@ "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, + "node_modules/@iconify-icon/react": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@iconify-icon/react/-/react-2.0.1.tgz", + "integrity": "sha512-1m6L2yNsSJ25k5baQRqNqh2J0w+91PwOn1WdBIR6ZTwxePbsZC8k3NNVc6m9BJObsIQdUlMA1NGj8el4tfbsVg==", + "dev": true, + "dependencies": { + "iconify-icon": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/cyberalien" + }, + "peerDependencies": { + "react": ">=16" + } + }, "node_modules/@iconify/react": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/@iconify/react/-/react-4.1.1.tgz", @@ -3990,6 +4008,42 @@ } } }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz", + "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-direction": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz", @@ -11411,6 +11465,18 @@ "node": ">=8.12.0" } }, + "node_modules/iconify-icon": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/iconify-icon/-/iconify-icon-2.0.0.tgz", + "integrity": "sha512-38ArOkxmyD9oDbJBkxaFpE6eZ0K3F9Sk+3x4mWGfjMJaxi3EKrix9Du4iWhgBFT3imKC4FJJE34ur2Rc7Xm+Uw==", + "dev": true, + "dependencies": { + "@iconify/types": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/cyberalien" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -17971,6 +18037,18 @@ "node": ">=12" } }, + "node_modules/vaul": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/vaul/-/vaul-0.9.0.tgz", + "integrity": "sha512-bZSySGbAHiTXmZychprnX/dE0EsSige88xtyyL3/MCRbrFotRPQZo7UdydGXZWw+CKbNOw5Ow8gwAo93/nB/Cg==", + "dependencies": { + "@radix-ui/react-dialog": "^1.0.4" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, "node_modules/vercel": { "version": "33.2.0", "resolved": "https://registry.npmjs.org/vercel/-/vercel-33.2.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 01e38e4..b9f1aa4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,6 +17,7 @@ "@apollo/experimental-nextjs-app-support": "^0.6.0", "@gsap/react": "^2.1.0", "@radix-ui/react-avatar": "^1.0.4", + "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-separator": "^1.0.3", @@ -44,13 +45,15 @@ "satellite.js": "^5.0.0", "tailwind-merge": "^2.2.0", "tailwindcss-animate": "^1.0.7", - "three": "^0.161.0" + "three": "^0.161.0", + "vaul": "^0.9.0" }, "devDependencies": { "@cloudflare/next-on-pages": "^1.8.3", "@graphql-codegen/cli": "^5.0.0", "@graphql-codegen/client-preset": "^4.1.0", "@graphql-typed-document-node/core": "^3.2.0", + "@iconify-icon/react": "^2.0.1", "@iconify/react": "^4.1.1", "@playwright/test": "^1.41.2", "@tailwindcss/typography": "^0.5.10", diff --git a/frontend/public/images/ntnu-white-logo-mobile.svg b/frontend/public/images/ntnu-white-logo-mobile.svg new file mode 100644 index 0000000..f1bc6c5 --- /dev/null +++ b/frontend/public/images/ntnu-white-logo-mobile.svg @@ -0,0 +1,106 @@ + + diff --git a/frontend/public/images/ntnu-white-logo.svg b/frontend/public/images/ntnu-white-logo.svg new file mode 100644 index 0000000..ec8d7dd --- /dev/null +++ b/frontend/public/images/ntnu-white-logo.svg @@ -0,0 +1,175 @@ + + diff --git a/frontend/src/components/Navbar.tsx b/frontend/src/components/Navbar.tsx index 94d2e99..68f1520 100644 --- a/frontend/src/components/Navbar.tsx +++ b/frontend/src/components/Navbar.tsx @@ -2,14 +2,33 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; import { Button } from "@/components/ui/button"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; -import { useTheme } from "next-themes"; -import { Icon } from "@iconify/react"; +import { Drawer, DrawerContent, DrawerTrigger } from "@/components/ui/drawer"; + +import type { SVGProps } from "react"; + +export function IconParkHamburgerButton(props: SVGProps) { + return ( + + + + + + + + ); +} export default function Navbar() { const dropdownPaths = [ @@ -30,32 +49,44 @@ export default function Navbar() { return pathname === path ? "secondary" : "ghost"; }; - const { theme, setTheme } = useTheme(); - const isLightTheme = theme === "light"; - - const toggleTheme = () => { - setTheme(isLightTheme ? "dark" : "light"); - }; - return ( ); } diff --git a/frontend/src/components/ui/drawer.tsx b/frontend/src/components/ui/drawer.tsx new file mode 100644 index 0000000..33a4a48 --- /dev/null +++ b/frontend/src/components/ui/drawer.tsx @@ -0,0 +1,120 @@ +"use client"; + +import * as React from "react"; +import { Drawer as DrawerPrimitive } from "vaul"; + +import { cn } from "@/lib/utils"; + +const Drawer = ({ + shouldScaleBackground = true, + direction = "top", + ...props +}: React.ComponentProps) => ( + +); +Drawer.displayName = "Drawer"; + +const DrawerTrigger = DrawerPrimitive.Trigger; + +const DrawerPortal = DrawerPrimitive.Portal; + +const DrawerClose = DrawerPrimitive.Close; + +const DrawerOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName; + +const DrawerContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + {children} +
+ + +)); +DrawerContent.displayName = "DrawerContent"; + +const DrawerHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DrawerHeader.displayName = "DrawerHeader"; + +const DrawerFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DrawerFooter.displayName = "DrawerFooter"; + +const DrawerTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DrawerTitle.displayName = DrawerPrimitive.Title.displayName; + +const DrawerDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DrawerDescription.displayName = DrawerPrimitive.Description.displayName; + +export { + Drawer, + DrawerPortal, + DrawerOverlay, + DrawerTrigger, + DrawerClose, + DrawerContent, + DrawerHeader, + DrawerFooter, + DrawerTitle, + DrawerDescription, +};