Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: menu for hidden nav items #77

Merged
merged 12 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ FEIDE_CLIENT_SECRET=" "
FEIDE_AUTHORIZATION_ENDPOINT="https://auth.dataporten.no/oauth/authorization"
FEIDE_TOKEN_ENDPOINT="https://auth.dataporten.no/oauth/token"
FEIDE_USERINFO_ENDPOINT="https://auth.dataporten.no/openid/userinfo"
REGISTRATION_SHARED_SECRET_MATRIX=" "
REGISTRATION_SHARED_SECRET_MATRIX=" "
Binary file modified bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
"storage": "Storage",
"about": "About",
"shiftSchedule": "Shift Schedule",
"desktopNavMenu": "{open, select, true {Open} other {Close}} navigation menu",
"matrix": "Go to matrix",
"changeLocale": "Change language",
"toggleTheme": "Toggle theme",
"light": "Light",
Expand Down
2 changes: 2 additions & 0 deletions messages/no.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
"storage": "Lager",
"about": "Om oss",
"shiftSchedule": "Vaktliste",
"desktopNavMenu": "{open, select, true {Åpne} other {Lukk}} navigasjonsmeny",
"matrix": "Dra til matrix",
"changeLocale": "Bytt språk",
"toggleTheme": "Bytt tema",
"light": "Lys",
Expand Down
2 changes: 1 addition & 1 deletion src/components/composites/ResponsiveDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ interface ResponsiveDialogProps extends BaseProps {
asChild?: true;
}

const desktop = '(min-width: 768px)';
const desktop = '(min-width: 48rem)';

/**
* This uses a drawer on mobile and a dialog on desktop so it is usually the preffered way to use dialogs in the app for a repsonsive experience.
Expand Down
9 changes: 7 additions & 2 deletions src/components/layout/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ function Footer() {
<div className='grid grid-cols-1 xs:grid-cols-2 gap-x-4 gap-y-12 sm:grid-cols-3 lg:grid-cols-4'>
<div>
<div className='flex'>
<LogoLink className='justify-start' />
<LogoLink
className='justify-start'
t={{
hackerspaceHome: t('hackerspaceHome'),
}}
/>
</div>
<p className='ml-2 leading-tight'>
<strong>{t('openingHours')}:</strong>
Expand Down Expand Up @@ -114,7 +119,7 @@ function Footer() {
<div>
<h4>{t('links')}</h4>
<Nav
className='mt-2 ml-2 space-y-1.5'
className='mt-2 ml-2 flex flex-col items-start gap-1.5'
t={{
news: t('news'),
events: t('events'),
Expand Down
47 changes: 38 additions & 9 deletions src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { LogoLink } from '@/components/layout/LogoLink';
import { DarkModeMenu } from '@/components/layout/header/DarkModeMenu';
import { DesktopNavMenu } from '@/components/layout/header/DesktopNavMenu';
import { LocaleMenu } from '@/components/layout/header/LocaleMenu';
import { MobileSheet } from '@/components/layout/header/MobileSheet';
import { Nav } from '@/components/layout/header/Nav';
import { ProfileMenu } from '@/components/layout/header/ProfileMenu';
import { useTranslations } from 'next-intl';
import { MatrixButton } from './header/MatrixButton';

function Header() {
const t = useTranslations('layout');

return (
<header className='~px-4/24 sticky top-0 z-20 mx-auto flex min-h-14 w-full max-w-screen-2xl items-center justify-between border-border/40 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60'>
<header className='~px-1/24 sticky top-0 z-20 mx-auto flex min-h-14 w-full max-w-screen-2xl items-center justify-between border-border/40 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60'>
<div className='flex gap-2'>
<MobileSheet
className='flex md:hidden'
Expand All @@ -18,25 +21,50 @@ function Header() {
news: t('news'),
events: t('events'),
about: t('about'),
storage: t('storage'),
shiftSchedule: t('shiftSchedule'),
hackerspaceHome: t('hackerspaceHome'),
matrix: t('matrix'),
changeLocale: t('changeLocale'),
toggleTheme: t('toggleTheme'),
light: t('light'),
dark: t('dark'),
system: t('system'),
close: useTranslations('ui')('close'),
seandreassen marked this conversation as resolved.
Show resolved Hide resolved
}}
/>
<LogoLink />
</div>
<div className='flex gap-10'>
<Nav
className='hidden items-center gap-6 text-sm md:flex'
<LogoLink
t={{
news: t('news'),
events: t('events'),
about: t('about'),
hackerspaceHome: t('hackerspaceHome'),
}}
/>
</div>
<div className='flex gap-6'>
<div className='hidden items-center gap-6 md:flex'>
<Nav
className='flex items-center gap-6 text-sm'
t={{
news: t('news'),
events: t('events'),
about: t('about'),
}}
/>
<DesktopNavMenu
t={{
open: t('desktopNavMenu', { open: true }),
close: t('desktopNavMenu', { open: false }),
storage: t('storage'),
shiftSchedule: t('shiftSchedule'),
}}
/>
</div>
<div className='flex'>
<MatrixButton t={{ title: t('matrix') }} className='xs:flex hidden' />
<LocaleMenu
t={{
changeLocale: t('changeLocale'),
}}
classname='hidden xs:flex'
/>
<DarkModeMenu
t={{
Expand All @@ -45,6 +73,7 @@ function Header() {
dark: t('dark'),
system: t('system'),
}}
classname='hidden xs:flex'
/>
<ProfileMenu
t={{
Expand Down
16 changes: 8 additions & 8 deletions src/components/layout/LogoLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@ import { Logo } from '@/components/assets/Logo';
import { Button } from '@/components/ui/Button';
import { Link } from '@/lib/locale/navigation';
import { cx } from '@/lib/utils';
import { useTranslations } from 'next-intl';

function LogoLink({
className,
onClick,
}: {
type LogoLinkProps = {
className?: string;
onClick?: () => void;
}) {
const t = useTranslations('layout');
t: {
hackerspaceHome: string;
};
};

function LogoLink({ className, onClick, t }: LogoLinkProps) {
return (
<Button
className={cx('flex items-center space-x-2', className)}
asChild
variant='none'
size='none'
>
<Link href='/' aria-label={t('hackerspaceHome')} onClick={onClick}>
<Link href='/' aria-label={t.hackerspaceHome} onClick={onClick}>
<Logo className='size-6 md:size-8 lg:size-10' />
<span className='font-bold font-montserrat text-md md:text-lg lg:text-2xl'>
HACKERSPACE
Expand Down
23 changes: 17 additions & 6 deletions src/components/layout/header/DarkModeMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
} from '@/components/ui/DropdownMenu';
import { MoonIcon, SunIcon } from 'lucide-react';
import { useTheme } from 'next-themes';
import * as React from 'react';

type DarkModeMenuProps = {
t: {
Expand All @@ -18,18 +17,30 @@ type DarkModeMenuProps = {
dark: string;
system: string;
};
classname?: string;
};

function DarkModeMenu({ t }: DarkModeMenuProps) {
function DarkModeMenu({ t, classname }: DarkModeMenuProps) {
const { setTheme } = useTheme();

return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant='ghost' size='icon'>
<SunIcon className='dark:-rotate-90 h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:scale-0' />
<MoonIcon className='absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100' />
<span className='sr-only'>{t.toggleTheme}</span>
<Button
variant='ghost'
size='icon'
title={t.toggleTheme}
aria-label={t.toggleTheme}
className={classname}
>
<SunIcon
className='dark:-rotate-90 h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:scale-0'
aria-hidden='true'
/>
<MoonIcon
className='absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100'
aria-hidden='true'
/>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className='min-w-[6rem]' align='end'>
Expand Down
58 changes: 58 additions & 0 deletions src/components/layout/header/DesktopNavMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use client';

import { SecondaryNav } from '@/components/layout/header/SecondaryNav';
import { Button } from '@/components/ui/Button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuTrigger,
} from '@/components/ui/DropdownMenu';
import { useMediaQuery } from '@/lib/hooks/useMediaQuery';
import { EllipsisIcon } from 'lucide-react';
import { useEffect, useState } from 'react';

type DesktopNavMenuProps = {
className?: string;
t: {
open: string;
close: string;
storage: string;
shiftSchedule: string;
};
};

function DesktopNavMenu({ t }: DesktopNavMenuProps) {
const [open, setOpen] = useState(false);
const visible = useMediaQuery('(min-width: 48rem)');

useEffect(() => {
if (!visible) {
setOpen(false);
}
}, [visible]);

return (
<DropdownMenu open={open} onOpenChange={setOpen}>
<DropdownMenuTrigger asChild>
<Button
className='h-fit'
variant='nav'
size='none'
aria-label={open ? t.close : t.open}
>
<EllipsisIcon aria-hidden='true' />
</Button>
</DropdownMenuTrigger>
<SecondaryNav
asDropDown
onClick={() => setOpen(false)}
t={{
storage: t.storage,
shiftSchedule: t.shiftSchedule,
}}
/>
</DropdownMenu>
);
}

export { DesktopNavMenu };
21 changes: 16 additions & 5 deletions src/components/layout/header/LocaleMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,29 @@ import { localeIcons, routing } from '@/lib/locale';
import { usePathname, useRouter } from '@/lib/locale/navigation';
import { Globe2Icon } from 'lucide-react';
import { useParams } from 'next/navigation';
import * as React from 'react';

function LocaleMenu({ t }: { t: { changeLocale: string } }) {
type LocaleMenuProps = {
t: {
changeLocale: string;
};
classname?: string;
};

function LocaleMenu({ t, classname }: LocaleMenuProps) {
const router = useRouter();
const pathname = usePathname();
const params = useParams();
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant='ghost' size='icon'>
<Globe2Icon className='h-[1.2rem] w-[1.2rem]' />
<span className='sr-only'>{t.changeLocale}</span>
<Button
variant='ghost'
size='icon'
title={t.changeLocale}
aria-label={t.changeLocale}
className={classname}
>
<Globe2Icon className='h-[1.2rem] w-[1.2rem]' aria-hidden='true' />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className='min-w-[6rem]' align='end'>
Expand Down
25 changes: 25 additions & 0 deletions src/components/layout/header/MatrixButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Button } from '@/components/ui/Button';
import { MessageSquareMoreIcon } from 'lucide-react';
import Link from 'next/link';

type MatrixButtonProps = {
className?: string;
t: {
title: string;
};
};

function MatrixButton({ className, t }: MatrixButtonProps) {
return (
<Button variant='ghost' size='icon' className={className} asChild>
<Link href='/' title={t.title} aria-label={t.title}>
<MessageSquareMoreIcon
className='h-[1.2rem] w-[1.2rem]'
aria-hidden='true'
/>
</Link>
</Button>
);
}

export { MatrixButton };
Loading
Loading