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

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
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: 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
13 changes: 11 additions & 2 deletions src/components/layout/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Link } from '@/lib/locale/navigation';
import { BugIcon, MailIcon } from 'lucide-react';
import { useTranslations } from 'next-intl';
import ExternalLink from 'next/link';
import { MatrixButton } from './header/MatrixButton';

function Footer() {
const t = useTranslations('layout');
Expand All @@ -21,7 +22,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 All @@ -47,6 +53,9 @@ function Footer() {
<div>
<h4>{t('socialMedia')}</h4>
<ul className='grid grid-flow-row grid-cols-2-auto justify-start text-foreground/80 sm:grid-cols-3-auto xl:grid-flow-col xl:grid-cols-none'>
<li className='xs:hidden'>
<MatrixButton size='sm-icon' />
</li>
<li>
<Button asChild variant='ghost' size='sm-icon'>
<ExternalLink
Expand Down Expand Up @@ -114,7 +123,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
37 changes: 29 additions & 8 deletions src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
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'>
<div className='flex gap-2'>
Expand All @@ -18,21 +21,39 @@ function Header() {
news: t('news'),
events: t('events'),
about: t('about'),
storage: t('storage'),
shiftSchedule: t('shiftSchedule'),
hackerspaceHome: t('hackerspaceHome'),
close: useTranslations('ui')('close'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated to this issue but the 'ui' namespaces is available in all client components so when we use from it we dont have to pass it as a prop we can use useTranslations('ui') within the client component

}}
/>
<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 className='xs:flex hidden' size='icon' />
<LocaleMenu
t={{
changeLocale: t('changeLocale'),
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
19 changes: 14 additions & 5 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 @@ -26,10 +25,20 @@ function DarkModeMenu({ t }: DarkModeMenuProps) {
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}
>
<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 };
11 changes: 7 additions & 4 deletions src/components/layout/header/LocaleMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ 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 } }) {
const router = useRouter();
Expand All @@ -20,9 +19,13 @@ function LocaleMenu({ t }: { t: { changeLocale: string } }) {
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}
>
<Globe2Icon className='h-[1.2rem] w-[1.2rem]' aria-hidden='true' />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className='min-w-[6rem]' align='end'>
Expand Down
26 changes: 26 additions & 0 deletions src/components/layout/header/MatrixButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Button } from '@/components/ui/Button';
import { MessageSquareMoreIcon } from 'lucide-react';
import { useTranslations } from 'next-intl';
import Link from 'next/link';

type MatrixButtonProps = {
className?: string;
size?: 'icon' | 'sm-icon'; // This will be changed when I create the new link component so it can actually accept all sizes
};

function MatrixButton({ className, size }: MatrixButtonProps) {
const t = useTranslations('layout');

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

export { MatrixButton };
Loading
Loading