117 lines
3.3 KiB
TypeScript
117 lines
3.3 KiB
TypeScript
'use client';
|
|
|
|
import * as React from 'react';
|
|
import RouterLink from 'next/link';
|
|
import { usePathname, useRouter } from 'next/navigation';
|
|
import { COL_USER_METAS } from '@/constants';
|
|
import { LoadingButton } from '@mui/lab';
|
|
import Avatar from '@mui/material/Avatar';
|
|
import Stack from '@mui/material/Stack';
|
|
import Typography from '@mui/material/Typography';
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
import { paths } from '@/paths';
|
|
import { logger } from '@/lib/default-logger';
|
|
import { fileToBase64 } from '@/lib/file-to-base64';
|
|
import getImageUrlFromFile from '@/lib/get-image-url-from-file.ts';
|
|
import { pb } from '@/lib/pb';
|
|
import { useUser } from '@/hooks/use-user';
|
|
import { toast } from '@/components/core/toaster';
|
|
import FormLoading from '@/components/loading';
|
|
|
|
import ErrorDisplay from '../../error';
|
|
import { NavItem } from './nav-item';
|
|
import { navItems } from './navItems';
|
|
|
|
export function SideNav(): React.JSX.Element {
|
|
const router = useRouter();
|
|
const { t } = useTranslation();
|
|
const { user, isLoading } = useUser();
|
|
const pathname = usePathname();
|
|
const [isUpdating, setIsUpdating] = React.useState<boolean>(false);
|
|
|
|
const [showLoading, setShowLoading] = React.useState<boolean>(false);
|
|
const [showError, setShowError] = React.useState({ show: false, detail: '' });
|
|
|
|
if (showLoading) return <FormLoading />;
|
|
if (!user) return <>loading</>;
|
|
|
|
if (showError.show)
|
|
return (
|
|
<ErrorDisplay
|
|
message={t('error.unable-to-process-request')}
|
|
code="500"
|
|
details={showError.detail}
|
|
/>
|
|
);
|
|
|
|
return (
|
|
<div>
|
|
<Stack
|
|
spacing={3}
|
|
sx={{
|
|
flex: '0 0 auto',
|
|
flexDirection: { xs: 'column-reverse', md: 'column' },
|
|
position: { md: 'sticky' },
|
|
top: '64px',
|
|
width: { xs: '100%', md: '240px' },
|
|
}}
|
|
>
|
|
<Stack
|
|
component="ul"
|
|
spacing={3}
|
|
sx={{ listStyle: 'none', m: 0, p: 0 }}
|
|
>
|
|
{navItems.map((group) => (
|
|
<Stack
|
|
component="li"
|
|
key={group.key}
|
|
spacing={2}
|
|
>
|
|
{group.title ? (
|
|
<div>
|
|
<Typography
|
|
color="text.secondary"
|
|
variant="caption"
|
|
>
|
|
{group.title}
|
|
</Typography>
|
|
</div>
|
|
) : null}
|
|
<Stack
|
|
component="ul"
|
|
spacing={1}
|
|
sx={{ listStyle: 'none', m: 0, p: 0 }}
|
|
>
|
|
{group.items.map((item) => (
|
|
<NavItem
|
|
{...item}
|
|
key={item.key}
|
|
pathname={pathname}
|
|
/>
|
|
))}
|
|
</Stack>
|
|
</Stack>
|
|
))}
|
|
</Stack>
|
|
<Stack
|
|
direction="row"
|
|
spacing={2}
|
|
sx={{ alignItems: 'center' }}
|
|
>
|
|
<Avatar src={getImageUrlFromFile(user.collectionId, user.id, user.avatar)}>{user.name}</Avatar>
|
|
<div>
|
|
<Typography variant="subtitle1">{user.name}</Typography>
|
|
<Typography
|
|
color="text.secondary"
|
|
variant="caption"
|
|
>
|
|
{user.email}
|
|
</Typography>
|
|
</div>
|
|
</Stack>
|
|
</Stack>
|
|
</div>
|
|
);
|
|
}
|