From dd45992422ed507547e017ea64f42e1d20943e7b Mon Sep 17 00:00:00 2001 From: Antonin Date: Fri, 27 Jun 2025 22:45:14 +0200 Subject: [PATCH] Mobile support added --- .../app/components/Banner/Banner.module.scss | 1 + src/modules/app/components/Banner/Banner.tsx | 9 ++- .../DiscordLoginOverlay.tsx | 8 +-- .../AdminLinks/AdminLinks.tsx | 33 ++++----- .../{Sidebar => Navbar}/AdminLinks/index.ts | 0 .../Links/Links.module.scss | 0 .../{Sidebar => Navbar}/Links/Links.tsx | 40 +++++------ .../{Sidebar => Navbar}/Links/index.ts | 0 .../{Sidebar => Navbar}/Logo/Logo.module.scss | 0 .../{Sidebar => Navbar}/Logo/Logo.tsx | 0 .../{Sidebar => Navbar}/Logo/index.ts | 0 .../Navbar/MobileMenu/MobileMenu.tsx | 68 +++++++++++++++++++ .../components/Navbar/MobileMenu/index.ts | 1 + .../{Sidebar => Navbar}/Navbar.module.scss | 0 .../layout/components/Navbar/Navbar.tsx | 48 +++++++++++++ .../components/{Sidebar => Navbar}/index.ts | 1 + .../layout/components/Sidebar/Navbar.tsx | 34 ---------- src/modules/layout/components/index.ts | 2 +- src/modules/system/hooks/index.ts | 1 + src/modules/system/hooks/useIsMobile.tsx | 6 ++ .../components/CurrentUser/CurrentUser.tsx | 33 ++++++--- 21 files changed, 198 insertions(+), 87 deletions(-) rename src/modules/layout/components/{Sidebar => Navbar}/AdminLinks/AdminLinks.tsx (74%) rename src/modules/layout/components/{Sidebar => Navbar}/AdminLinks/index.ts (100%) rename src/modules/layout/components/{Sidebar => Navbar}/Links/Links.module.scss (100%) rename src/modules/layout/components/{Sidebar => Navbar}/Links/Links.tsx (71%) rename src/modules/layout/components/{Sidebar => Navbar}/Links/index.ts (100%) rename src/modules/layout/components/{Sidebar => Navbar}/Logo/Logo.module.scss (100%) rename src/modules/layout/components/{Sidebar => Navbar}/Logo/Logo.tsx (100%) rename src/modules/layout/components/{Sidebar => Navbar}/Logo/index.ts (100%) create mode 100644 src/modules/layout/components/Navbar/MobileMenu/MobileMenu.tsx create mode 100644 src/modules/layout/components/Navbar/MobileMenu/index.ts rename src/modules/layout/components/{Sidebar => Navbar}/Navbar.module.scss (100%) create mode 100644 src/modules/layout/components/Navbar/Navbar.tsx rename src/modules/layout/components/{Sidebar => Navbar}/index.ts (77%) delete mode 100644 src/modules/layout/components/Sidebar/Navbar.tsx create mode 100644 src/modules/system/hooks/useIsMobile.tsx diff --git a/src/modules/app/components/Banner/Banner.module.scss b/src/modules/app/components/Banner/Banner.module.scss index 7183f11..3f25880 100644 --- a/src/modules/app/components/Banner/Banner.module.scss +++ b/src/modules/app/components/Banner/Banner.module.scss @@ -2,6 +2,7 @@ font-size: 5vw; font-weight: 900; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); + text-align: center; } .undertitle { diff --git a/src/modules/app/components/Banner/Banner.tsx b/src/modules/app/components/Banner/Banner.tsx index 66986aa..8e4568e 100644 --- a/src/modules/app/components/Banner/Banner.tsx +++ b/src/modules/app/components/Banner/Banner.tsx @@ -6,8 +6,6 @@ import { useQuery } from "@tanstack/react-query"; import styles from "./Banner.module.scss"; export function Banner() { - // fetch randomfunny api using react query - const { data: randomFunny, isLoading } = useQuery({ queryKey: ["randomFunny"], queryFn: async () => { @@ -32,7 +30,12 @@ export function Banner() { {isLoading ? ( ) : ( - + "{randomFunny?.text.replaceAll('"', "")}" diff --git a/src/modules/app/components/DiscordLoginOverlay/DiscordLoginOverlay.tsx b/src/modules/app/components/DiscordLoginOverlay/DiscordLoginOverlay.tsx index f93245a..393c871 100644 --- a/src/modules/app/components/DiscordLoginOverlay/DiscordLoginOverlay.tsx +++ b/src/modules/app/components/DiscordLoginOverlay/DiscordLoginOverlay.tsx @@ -2,16 +2,16 @@ import { Button, Flex, Overlay, Title } from "@mantine/core"; import { IconBrandDiscord } from "@tabler/icons-react"; -import { Logo } from "~/modules/layout"; import { signIn } from "next-auth/react"; export function DiscordLoginOverlay() { // zIndex 100 is navbar, 99 ensures you can interact with navbar still return ( - - - This website requires you to be logged in. + + + This website requires you to be logged in. + diff --git a/src/modules/layout/components/Sidebar/AdminLinks/AdminLinks.tsx b/src/modules/layout/components/Navbar/AdminLinks/AdminLinks.tsx similarity index 74% rename from src/modules/layout/components/Sidebar/AdminLinks/AdminLinks.tsx rename to src/modules/layout/components/Navbar/AdminLinks/AdminLinks.tsx index c0ce5fd..de00832 100644 --- a/src/modules/layout/components/Sidebar/AdminLinks/AdminLinks.tsx +++ b/src/modules/layout/components/Navbar/AdminLinks/AdminLinks.tsx @@ -1,7 +1,8 @@ "use client"; import React, { type JSX } from "react"; -import AdminLink from "next/link"; +import type AdminLink from "next/link"; +import Link from "next/link"; import { ActionIcon, Menu } from "@mantine/core"; import { IconLayoutDashboard, IconSpiral, IconUsersGroup } from "@tabler/icons-react"; import { Routes } from "~/constants/routes"; @@ -15,23 +16,23 @@ interface AdminLink { href: string; } +export const adminLinks = (iconSize = 24): AdminLink[] => [ + { + icon: , + label: "Dashboard", + href: Routes.ADMIN_DASHBOARD, + }, + { + icon: , + label: "Users", + href: Routes.ADMIN_USERS, + }, +]; + /** * Renders admin links for sidebar */ export function AdminLinks() { - const adminLinks: AdminLink[] = [ - { - icon: , - label: "Dashboard", - href: Routes.ADMIN_DASHBOARD, - }, - { - icon: , - label: "Users", - href: Routes.ADMIN_USERS, - }, - ]; - return ( <> @@ -43,14 +44,14 @@ export function AdminLinks() { Admin Menu - {adminLinks.map((link, index) => ( + {adminLinks().map((link, index) => ( {link.label} diff --git a/src/modules/layout/components/Sidebar/AdminLinks/index.ts b/src/modules/layout/components/Navbar/AdminLinks/index.ts similarity index 100% rename from src/modules/layout/components/Sidebar/AdminLinks/index.ts rename to src/modules/layout/components/Navbar/AdminLinks/index.ts diff --git a/src/modules/layout/components/Sidebar/Links/Links.module.scss b/src/modules/layout/components/Navbar/Links/Links.module.scss similarity index 100% rename from src/modules/layout/components/Sidebar/Links/Links.module.scss rename to src/modules/layout/components/Navbar/Links/Links.module.scss diff --git a/src/modules/layout/components/Sidebar/Links/Links.tsx b/src/modules/layout/components/Navbar/Links/Links.tsx similarity index 71% rename from src/modules/layout/components/Sidebar/Links/Links.tsx rename to src/modules/layout/components/Navbar/Links/Links.tsx index 5551fda..a21e46d 100644 --- a/src/modules/layout/components/Sidebar/Links/Links.tsx +++ b/src/modules/layout/components/Navbar/Links/Links.tsx @@ -15,35 +15,35 @@ interface Link { href: string; } +// Links that probably every user should see, e.g. dashboard +export const links = (iconSize = 24): Link[] => [ + { + icon: , + label: "Home", + href: Routes.HOME, + }, + { + icon: , + label: "Link", + href: Routes.LINKING, + }, + { + icon: , + label: "Funnies", + href: Routes.FUNNY, + }, +]; + /** * Renders links for sidebar */ export function Links() { const pathname = usePathname(); - // Links that probably every user should see, e.g. dashboard - const links: Link[] = [ - { - icon: , - label: "Home", - href: Routes.HOME, - }, - { - icon: , - label: "Link", - href: Routes.LINKING, - }, - { - icon: , - label: "Funnies", - href: Routes.FUNNY, - }, - ]; - return ( <> - {links.map((link, index) => ( + {links().map((link, index) => ( + + + {opened ? : } + + + + + {links(16).map((link, index) => ( + + {link.label} + + ))} + + + Admin Menu + {adminLinks(16).map((link, index) => ( + + {link.label} + + ))} + + {session && ( + <> + + + + )} + + + ); +} diff --git a/src/modules/layout/components/Navbar/MobileMenu/index.ts b/src/modules/layout/components/Navbar/MobileMenu/index.ts new file mode 100644 index 0000000..1d9cb8f --- /dev/null +++ b/src/modules/layout/components/Navbar/MobileMenu/index.ts @@ -0,0 +1 @@ +export * from "./MobileMenu"; diff --git a/src/modules/layout/components/Sidebar/Navbar.module.scss b/src/modules/layout/components/Navbar/Navbar.module.scss similarity index 100% rename from src/modules/layout/components/Sidebar/Navbar.module.scss rename to src/modules/layout/components/Navbar/Navbar.module.scss diff --git a/src/modules/layout/components/Navbar/Navbar.tsx b/src/modules/layout/components/Navbar/Navbar.tsx new file mode 100644 index 0000000..f551618 --- /dev/null +++ b/src/modules/layout/components/Navbar/Navbar.tsx @@ -0,0 +1,48 @@ +"use client"; + +import { Flex } from "@mantine/core"; +import { useIsMobile } from "~/modules/system"; +import { CurrentUser } from "~/modules/users"; + +import { AdminLinks } from "./AdminLinks/AdminLinks"; +import { Links } from "./Links"; +import { Logo } from "./Logo"; +import { MobileMenu } from "./MobileMenu"; +import classes from "./Navbar.module.scss"; + +export function Navbar() { + const isMobile = useIsMobile(); + + return ( + + {!isMobile ? ( + <> + + + + + + + + + + + ) : ( + + + + + )} + + ); +} diff --git a/src/modules/layout/components/Sidebar/index.ts b/src/modules/layout/components/Navbar/index.ts similarity index 77% rename from src/modules/layout/components/Sidebar/index.ts rename to src/modules/layout/components/Navbar/index.ts index 4720e7a..c88ec32 100644 --- a/src/modules/layout/components/Sidebar/index.ts +++ b/src/modules/layout/components/Navbar/index.ts @@ -2,3 +2,4 @@ export * from "./AdminLinks"; export * from "./Links"; export * from "./Logo"; export * from "./Navbar"; +export * from "./MobileMenu"; diff --git a/src/modules/layout/components/Sidebar/Navbar.tsx b/src/modules/layout/components/Sidebar/Navbar.tsx deleted file mode 100644 index 9be35dc..0000000 --- a/src/modules/layout/components/Sidebar/Navbar.tsx +++ /dev/null @@ -1,34 +0,0 @@ -"use client"; - -import { Flex } from "@mantine/core"; -import { CurrentUser } from "~/modules/users"; - -import { AdminLinks } from "./AdminLinks/AdminLinks"; -import { Links } from "./Links"; -import { Logo } from "./Logo"; -import classes from "./Navbar.module.scss"; - -export function Navbar() { - return ( - - - - - - - - - - - - ); -} diff --git a/src/modules/layout/components/index.ts b/src/modules/layout/components/index.ts index d539674..c1001b9 100644 --- a/src/modules/layout/components/index.ts +++ b/src/modules/layout/components/index.ts @@ -1,2 +1,2 @@ export * from "./Layout"; -export * from "./Sidebar"; +export * from "./Navbar"; diff --git a/src/modules/system/hooks/index.ts b/src/modules/system/hooks/index.ts index 733ace7..624113e 100644 --- a/src/modules/system/hooks/index.ts +++ b/src/modules/system/hooks/index.ts @@ -1,2 +1,3 @@ export * from "./useConfirmModal"; export * from "./useRoleColor"; +export * from "./useIsMobile"; diff --git a/src/modules/system/hooks/useIsMobile.tsx b/src/modules/system/hooks/useIsMobile.tsx new file mode 100644 index 0000000..ad70add --- /dev/null +++ b/src/modules/system/hooks/useIsMobile.tsx @@ -0,0 +1,6 @@ +import { em } from "@mantine/core"; +import { useMediaQuery } from "@mantine/hooks"; + +export function useIsMobile(): boolean { + return useMediaQuery(`(max-width: ${em(750)})`); +} diff --git a/src/modules/users/components/CurrentUser/CurrentUser.tsx b/src/modules/users/components/CurrentUser/CurrentUser.tsx index 44e28f5..e341133 100644 --- a/src/modules/users/components/CurrentUser/CurrentUser.tsx +++ b/src/modules/users/components/CurrentUser/CurrentUser.tsx @@ -1,8 +1,8 @@ "use client"; -import { ActionIcon, Badge, Box, Flex, Text } from "@mantine/core"; +import { ActionIcon, Badge, Box, Flex, Menu, Text } from "@mantine/core"; import { IconLogout } from "@tabler/icons-react"; -import { useConfirmModal, useRoleColor } from "~/modules"; +import { useConfirmModal, useIsMobile, useRoleColor } from "~/modules"; import { signOut, useSession } from "next-auth/react"; import { PunchableAvatar } from "../PunchableAvatar"; @@ -13,6 +13,8 @@ import styles from "./CurrentUser.module.scss"; */ export function CurrentUser() { const { data } = useSession({ required: false }); + const isMobile = useIsMobile(); + const user = data?.user; const { openConfirmModal } = useConfirmModal({ @@ -36,13 +38,18 @@ export function CurrentUser() { return ( <> - - - - - - - {user?.name} + + + {!isMobile && ( + + + + )} + + + + {user?.name} + {user?.role} @@ -58,6 +65,14 @@ export function CurrentUser() { /> + {isMobile && ( + <> + + logout()} leftSection={}> + Logout + + + )} );