update main-nav refactoring, working,
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
# GUIDELINE
|
||||||
|
|
||||||
|
- please keep one default `export` per file
|
@@ -0,0 +1,73 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import Popover from '@mui/material/Popover';
|
||||||
|
import List from '@mui/material/List';
|
||||||
|
import ListItem from '@mui/material/ListItem';
|
||||||
|
import ListItemButton from '@mui/material/ListItemButton';
|
||||||
|
import ListItemIcon from '@mui/material/ListItemIcon';
|
||||||
|
import ListItemText from '@mui/material/ListItemText';
|
||||||
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
|
import { ChatCenteredDots as ChatCenteredDotsIcon } from '@phosphor-icons/react/dist/ssr/ChatCenteredDots';
|
||||||
|
import { EnvelopeSimple as EnvelopeSimpleIcon } from '@phosphor-icons/react/dist/ssr/EnvelopeSimple';
|
||||||
|
import { User as UserIcon } from '@phosphor-icons/react/dist/ssr/User';
|
||||||
|
|
||||||
|
export function ContactsButton(): React.JSX.Element {
|
||||||
|
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null);
|
||||||
|
|
||||||
|
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
setAnchorEl(event.currentTarget);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setAnchorEl(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const open = Boolean(anchorEl);
|
||||||
|
const id = open ? 'contacts-popover' : undefined;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Tooltip title="Contacts">
|
||||||
|
<IconButton onClick={handleClick}>
|
||||||
|
<ChatCenteredDotsIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
<Popover
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
|
||||||
|
id={id}
|
||||||
|
onClose={handleClose}
|
||||||
|
open={open}
|
||||||
|
slotProps={{ paper: { sx: { width: '280px' } } }}
|
||||||
|
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
|
||||||
|
>
|
||||||
|
<List sx={{ p: 0 }}>
|
||||||
|
<ListItem disablePadding>
|
||||||
|
<ListItemButton
|
||||||
|
component="a"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<ListItemIcon>
|
||||||
|
<UserIcon />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText primary="Profile" />
|
||||||
|
</ListItemButton>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem disablePadding>
|
||||||
|
<ListItemButton
|
||||||
|
component="a"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<ListItemIcon>
|
||||||
|
<EnvelopeSimpleIcon />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText primary="Messages" />
|
||||||
|
</ListItemButton>
|
||||||
|
</ListItem>
|
||||||
|
</List>
|
||||||
|
</Popover>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
@@ -19,13 +19,15 @@ import type { User } from '@/types/user';
|
|||||||
import { useDialog } from '@/hooks/use-dialog';
|
import { useDialog } from '@/hooks/use-dialog';
|
||||||
import { usePopover } from '@/hooks/use-popover';
|
import { usePopover } from '@/hooks/use-popover';
|
||||||
|
|
||||||
import { ContactsPopover } from '../contacts-popover';
|
import { ContactsPopover } from '../../contacts-popover';
|
||||||
import { languageFlags, LanguagePopover } from '../language-popover';
|
import { languageFlags, LanguagePopover } from '../../language-popover';
|
||||||
import type { Language } from '../language-popover';
|
import type { Language } from '../../language-popover';
|
||||||
import { MobileNav } from '../mobile-nav';
|
import { MobileNav } from '../../mobile-nav';
|
||||||
import { NotificationsPopover } from '../notifications-popover';
|
import { NotificationsPopover } from '../../notifications-popover';
|
||||||
import { SearchDialog } from '../search-dialog';
|
import { SearchDialog } from '../../search-dialog';
|
||||||
import { UserPopover } from '../user-popover/user-popover';
|
import { UserPopover } from '../../user-popover/user-popover';
|
||||||
|
import { NotificationsButton } from './notifications-button';
|
||||||
|
import { LanguageSwitch } from './language-switch';
|
||||||
|
|
||||||
export interface MainNavProps {
|
export interface MainNavProps {
|
||||||
items: NavItemConfig[];
|
items: NavItemConfig[];
|
||||||
@@ -146,35 +148,7 @@ function ContactsButton(): React.JSX.Element {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function NotificationsButton(): React.JSX.Element {
|
function LanguageSwitch1(): React.JSX.Element {
|
||||||
const popover = usePopover<HTMLButtonElement>();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<Tooltip title="Notifications">
|
|
||||||
<Badge
|
|
||||||
color="error"
|
|
||||||
sx={{ '& .MuiBadge-dot': { borderRadius: '50%', height: '10px', right: '6px', top: '6px', width: '10px' } }}
|
|
||||||
variant="dot"
|
|
||||||
>
|
|
||||||
<IconButton
|
|
||||||
onClick={popover.handleOpen}
|
|
||||||
ref={popover.anchorRef}
|
|
||||||
>
|
|
||||||
<BellIcon />
|
|
||||||
</IconButton>
|
|
||||||
</Badge>
|
|
||||||
</Tooltip>
|
|
||||||
<NotificationsPopover
|
|
||||||
anchorEl={popover.anchorRef.current}
|
|
||||||
onClose={popover.handleClose}
|
|
||||||
open={popover.open}
|
|
||||||
/>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function LanguageSwitch(): React.JSX.Element {
|
|
||||||
const { i18n } = useTranslation();
|
const { i18n } = useTranslation();
|
||||||
const popover = usePopover<HTMLButtonElement>();
|
const popover = usePopover<HTMLButtonElement>();
|
||||||
const language = (i18n.language || 'en') as Language;
|
const language = (i18n.language || 'en') as Language;
|
@@ -0,0 +1,62 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import Avatar from '@mui/material/Avatar';
|
||||||
|
import Badge from '@mui/material/Badge';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import Divider from '@mui/material/Divider';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import Stack from '@mui/material/Stack';
|
||||||
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
|
import { Bell as BellIcon } from '@phosphor-icons/react/dist/ssr/Bell';
|
||||||
|
import { List as ListIcon } from '@phosphor-icons/react/dist/ssr/List';
|
||||||
|
import { MagnifyingGlass as MagnifyingGlassIcon } from '@phosphor-icons/react/dist/ssr/MagnifyingGlass';
|
||||||
|
import { Users as UsersIcon } from '@phosphor-icons/react/dist/ssr/Users';
|
||||||
|
import { useTranslation } from 'next-i18next';
|
||||||
|
|
||||||
|
import type { NavItemConfig } from '@/types/nav';
|
||||||
|
import type { User } from '@/types/user';
|
||||||
|
import { useDialog } from '@/hooks/use-dialog';
|
||||||
|
import { usePopover } from '@/hooks/use-popover';
|
||||||
|
|
||||||
|
import { ContactsPopover } from '../../contacts-popover';
|
||||||
|
import { languageFlags, LanguagePopover } from '../../language-popover';
|
||||||
|
import type { Language } from '../../language-popover';
|
||||||
|
import { MobileNav } from '../../mobile-nav';
|
||||||
|
import { NotificationsPopover } from '../../notifications-popover';
|
||||||
|
import { SearchDialog } from '../../search-dialog';
|
||||||
|
import { UserPopover } from '../../user-popover/user-popover';
|
||||||
|
import { NotificationsButton } from './notifications-button';
|
||||||
|
|
||||||
|
export function LanguageSwitch(): React.JSX.Element {
|
||||||
|
const { i18n } = useTranslation();
|
||||||
|
const popover = usePopover<HTMLButtonElement>();
|
||||||
|
const language = (i18n.language || 'en') as Language;
|
||||||
|
const flag = languageFlags[language];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Tooltip title="Language">
|
||||||
|
<IconButton
|
||||||
|
onClick={popover.handleOpen}
|
||||||
|
ref={popover.anchorRef}
|
||||||
|
sx={{ display: { xs: 'none', lg: 'inline-flex' } }}
|
||||||
|
>
|
||||||
|
<Box sx={{ height: '24px', width: '24px' }}>
|
||||||
|
<Box
|
||||||
|
alt={language}
|
||||||
|
component="img"
|
||||||
|
src={flag}
|
||||||
|
sx={{ height: 'auto', width: '100%' }}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
<LanguagePopover
|
||||||
|
anchorEl={popover.anchorRef.current}
|
||||||
|
onClose={popover.handleClose}
|
||||||
|
open={popover.open}
|
||||||
|
/>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
@@ -0,0 +1,49 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import Badge from '@mui/material/Badge';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import Popover from '@mui/material/Popover';
|
||||||
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
|
import { Bell as BellIcon } from '@phosphor-icons/react/dist/ssr/Bell';
|
||||||
|
|
||||||
|
export function NotificationsButton(): React.JSX.Element {
|
||||||
|
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null);
|
||||||
|
|
||||||
|
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
setAnchorEl(event.currentTarget);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setAnchorEl(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const open = Boolean(anchorEl);
|
||||||
|
const id = open ? 'notifications-popover' : undefined;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Tooltip title="Notifications">
|
||||||
|
<IconButton onClick={handleClick}>
|
||||||
|
<Badge
|
||||||
|
badgeContent={4}
|
||||||
|
color="error"
|
||||||
|
>
|
||||||
|
<BellIcon />
|
||||||
|
</Badge>
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
<Popover
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
|
||||||
|
id={id}
|
||||||
|
onClose={handleClose}
|
||||||
|
open={open}
|
||||||
|
slotProps={{ paper: { sx: { width: '280px' } } }}
|
||||||
|
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
|
||||||
|
>
|
||||||
|
{/* Notification content would go here */}
|
||||||
|
</Popover>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
@@ -0,0 +1,29 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
|
import { MagnifyingGlass as MagnifyingGlassIcon } from '@phosphor-icons/react/dist/ssr/MagnifyingGlass';
|
||||||
|
import { useDialog } from '@/hooks/use-dialog';
|
||||||
|
import { SearchDialog } from '../../search-dialog';
|
||||||
|
|
||||||
|
export function SearchButton(): React.JSX.Element {
|
||||||
|
const dialog = useDialog();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Tooltip title="Search">
|
||||||
|
<IconButton
|
||||||
|
onClick={dialog.handleOpen}
|
||||||
|
sx={{ display: { xs: 'none', lg: 'inline-flex' } }}
|
||||||
|
>
|
||||||
|
<MagnifyingGlassIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
<SearchDialog
|
||||||
|
onClose={dialog.handleClose}
|
||||||
|
open={dialog.open}
|
||||||
|
/>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
@@ -0,0 +1,44 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import { User as UserIcon } from '@phosphor-icons/react/dist/ssr/User';
|
||||||
|
import { Avatar, Popover, Tooltip } from '@mui/material';
|
||||||
|
|
||||||
|
export function UserButton(): React.JSX.Element {
|
||||||
|
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null);
|
||||||
|
|
||||||
|
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
setAnchorEl(event.currentTarget);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setAnchorEl(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const open = Boolean(anchorEl);
|
||||||
|
const id = open ? 'user-popover' : undefined;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Tooltip title="User">
|
||||||
|
<Avatar
|
||||||
|
onClick={handleClick}
|
||||||
|
sx={{ cursor: 'pointer', height: 32, width: 32 }}
|
||||||
|
>
|
||||||
|
<UserIcon fontSize="var(--Icon-fontSize)" />
|
||||||
|
</Avatar>
|
||||||
|
</Tooltip>
|
||||||
|
<Popover
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
|
||||||
|
id={id}
|
||||||
|
onClose={handleClose}
|
||||||
|
open={open}
|
||||||
|
slotProps={{ paper: { sx: { width: '240px' } } }}
|
||||||
|
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
|
||||||
|
>
|
||||||
|
{/* User menu content would go here */}
|
||||||
|
</Popover>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
'use client';
|
||||||
|
import type { User } from '@/types/user';
|
||||||
|
|
||||||
|
export const user = {
|
||||||
|
id: 'USR-000',
|
||||||
|
name: 'Sofia Rivers',
|
||||||
|
avatar: '/assets/avatar.png',
|
||||||
|
email: 'sofia@devias.io',
|
||||||
|
} satisfies User;
|
Reference in New Issue
Block a user