297 lines
7.6 KiB
TypeScript
297 lines
7.6 KiB
TypeScript
import React, { useState } from 'react';
|
|
import {
|
|
createBrowserRouter,
|
|
RouterProvider,
|
|
Navigate,
|
|
Outlet,
|
|
useLocation,
|
|
} from 'react-router-dom';
|
|
import { SideNav, type NavItemConfig } from '@rkheftan/harmony-ui';
|
|
import {
|
|
Devices,
|
|
LocationTick,
|
|
Mobile,
|
|
PasswordCheck,
|
|
Personalcard,
|
|
ProfileCircle,
|
|
Setting as SettingIcon,
|
|
Shield,
|
|
Sms,
|
|
Menu,
|
|
} from 'iconsax-react';
|
|
import {
|
|
Box,
|
|
Typography,
|
|
useTheme,
|
|
useMediaQuery,
|
|
Drawer,
|
|
AppBar,
|
|
Toolbar,
|
|
IconButton,
|
|
} from '@mui/material';
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
import { ActiveDevices } from '../components/activeDevices/ActiveDevices';
|
|
import { Setting } from '../components/setting/Setting';
|
|
import { RecentLogins } from '../components/security/RecentLogins';
|
|
import { PasswordSecurity } from '../components/security/PasswordSecurity';
|
|
import { PersonalInformation } from '../components/userInformation/PersonalInformation';
|
|
import { PhoneNumber } from '../components/userInformation/PhoneNumber';
|
|
import { SocialMedia } from '../components/userInformation/SocialMedia';
|
|
|
|
function Header() {
|
|
const headers = [{ name: 'محمدحسین برزه گر', phone: '09123456789' }];
|
|
return (
|
|
<Box
|
|
sx={{
|
|
height: 84,
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
justifyContent: 'center',
|
|
px: 2,
|
|
}}
|
|
>
|
|
{headers.map((h) => (
|
|
<Box key={h.phone}>
|
|
<Typography variant="body2">{h.name}</Typography>
|
|
<Typography variant="body2" color="text.secondary">
|
|
{h.phone}
|
|
</Typography>
|
|
</Box>
|
|
))}
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
export function Layout() {
|
|
const theme = useTheme();
|
|
const isMdUp = useMediaQuery(theme.breakpoints.up('md'));
|
|
const location = useLocation();
|
|
const { t } = useTranslation('sideMap');
|
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
|
|
const contentMaxWidth = '100%';
|
|
const contentWidthMd = '810px';
|
|
const navWidthMd = '274px';
|
|
|
|
const navConfig: NavItemConfig[] = [
|
|
{
|
|
text: t('side.account'),
|
|
getIcon: (sel) =>
|
|
sel ? (
|
|
<ProfileCircle size={24} color="#1976d2" variant="Bold" />
|
|
) : (
|
|
<ProfileCircle size={24} color="#82B1FF" />
|
|
),
|
|
path: '/profile',
|
|
children: [
|
|
{
|
|
text: t('side.personalInfo'),
|
|
getIcon: (sel) =>
|
|
sel ? (
|
|
<Personalcard size={24} color="#1976d2" variant="Bold" />
|
|
) : (
|
|
<Personalcard size={24} color="#82B1FF" />
|
|
),
|
|
path: '/profile#info',
|
|
},
|
|
{
|
|
text: t('side.phoneNumber'),
|
|
getIcon: (sel) =>
|
|
sel ? (
|
|
<Mobile size={24} color="#1976d2" variant="Bold" />
|
|
) : (
|
|
<Mobile size={24} color="#82B1FF" />
|
|
),
|
|
path: '/profile#contact-info',
|
|
},
|
|
{
|
|
text: t('side.email'),
|
|
getIcon: (sel) =>
|
|
sel ? (
|
|
<Sms size={24} color="#1976d2" variant="Bold" />
|
|
) : (
|
|
<Sms size={24} color="#82B1FF" />
|
|
),
|
|
path: '/profile#email',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
text: t('side.security'),
|
|
getIcon: (sel) =>
|
|
sel ? (
|
|
<Shield size={24} color="#1976d2" variant="Bold" />
|
|
) : (
|
|
<Shield size={24} color="#82B1FF" />
|
|
),
|
|
path: '/security',
|
|
children: [
|
|
{
|
|
text: t('side.password'),
|
|
getIcon: (sel) =>
|
|
sel ? (
|
|
<PasswordCheck size={24} color="#1976d2" variant="Bold" />
|
|
) : (
|
|
<PasswordCheck size={24} color="#82B1FF" />
|
|
),
|
|
path: '/security#password',
|
|
},
|
|
{
|
|
text: t('side.verifiedAddress'),
|
|
getIcon: (sel) =>
|
|
sel ? (
|
|
<LocationTick size={24} color="#1976d2" variant="Bold" />
|
|
) : (
|
|
<LocationTick size={24} color="#82B1FF" />
|
|
),
|
|
path: '/security#locations',
|
|
},
|
|
{
|
|
text: t('side.recentLogins'),
|
|
getIcon: (sel) =>
|
|
sel ? (
|
|
<Devices size={24} color="#1976d2" variant="Bold" />
|
|
) : (
|
|
<Devices size={24} color="#82B1FF" />
|
|
),
|
|
path: '/security#sessions',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
text: t('side.activeDevices'),
|
|
getIcon: (sel) =>
|
|
sel ? (
|
|
<Devices size={24} color="#1976d2" variant="Bold" />
|
|
) : (
|
|
<Devices size={24} color="#82B1FF" />
|
|
),
|
|
path: '/devices',
|
|
},
|
|
{
|
|
text: t('side.settings'),
|
|
getIcon: (sel) =>
|
|
sel ? (
|
|
<SettingIcon size={24} color="#1976d2" variant="Bold" />
|
|
) : (
|
|
<SettingIcon size={24} color="#82B1FF" />
|
|
),
|
|
path: '/setting',
|
|
},
|
|
];
|
|
|
|
return (
|
|
<Box
|
|
display="flex"
|
|
flexDirection="column"
|
|
justifyContent="center"
|
|
alignItems="center"
|
|
minHeight="100vh"
|
|
px={{ xs: 2, sm: 3 }}
|
|
>
|
|
{!isMdUp && (
|
|
<AppBar position="static">
|
|
<Toolbar sx={{ backgroundColor: 'background.paper' }}>
|
|
<IconButton
|
|
edge="start"
|
|
color="inherit"
|
|
onClick={() => setDrawerOpen(true)}
|
|
>
|
|
<Menu size={24} color="#1976d2" variant="Bold" />
|
|
</IconButton>
|
|
</Toolbar>
|
|
</AppBar>
|
|
)}
|
|
<Box display="flex" width="100%" maxWidth="100vw">
|
|
{isMdUp && (
|
|
<Box flex="0 0 auto" width={navWidthMd} position="relative">
|
|
<SideNav
|
|
navConfig={navConfig}
|
|
header={<Header />}
|
|
activePath={location.pathname + location.hash}
|
|
sideNavVariant="full"
|
|
positioning="absolute"
|
|
/>
|
|
</Box>
|
|
)}
|
|
<Box
|
|
flexGrow={1}
|
|
width="auto"
|
|
maxWidth={contentMaxWidth}
|
|
height={{ xs: 'auto', md: '78vh' }}
|
|
sx={{
|
|
bgcolor: 'background.paper',
|
|
px: { xs: 2, sm: 3 },
|
|
overflowY: 'auto',
|
|
}}
|
|
>
|
|
<Outlet />
|
|
</Box>
|
|
</Box>
|
|
{!isMdUp && (
|
|
<Drawer
|
|
anchor="left"
|
|
open={drawerOpen}
|
|
onClose={() => setDrawerOpen(false)}
|
|
>
|
|
<Box width={navWidthMd}>
|
|
<SideNav
|
|
navConfig={navConfig}
|
|
header={<Header />}
|
|
activePath={location.pathname + location.hash}
|
|
sideNavVariant="full"
|
|
/>
|
|
</Box>
|
|
</Drawer>
|
|
)}
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
const router = createBrowserRouter([
|
|
{
|
|
path: '/',
|
|
element: <Layout />,
|
|
children: [
|
|
{ path: '/', element: <Navigate to="/profile" replace /> },
|
|
{
|
|
path: '/profile',
|
|
element: (
|
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
<div id="info">
|
|
<PersonalInformation />
|
|
</div>
|
|
<div id="contact-info">
|
|
<PhoneNumber />
|
|
</div>
|
|
<div id="email">
|
|
<SocialMedia />
|
|
</div>
|
|
</Box>
|
|
),
|
|
},
|
|
{
|
|
path: '/security',
|
|
element: (
|
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
<div id="password">
|
|
<PasswordSecurity />
|
|
</div>
|
|
<div id="locations"></div>
|
|
<div id="sessions">
|
|
<RecentLogins />
|
|
</div>
|
|
</Box>
|
|
),
|
|
},
|
|
{ path: '/devices', element: <ActiveDevices /> },
|
|
{ path: '/setting', element: <Setting /> },
|
|
],
|
|
},
|
|
]);
|
|
|
|
export function Settings() {
|
|
return <RouterProvider router={router} />;
|
|
}
|