base commit
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
import type { ReactNode } from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
import AssignmentOutlinedIcon from '@mui/icons-material/AssignmentOutlined'
|
||||
import MenuOutlinedIcon from '@mui/icons-material/MenuOutlined'
|
||||
import PeopleOutlinedIcon from '@mui/icons-material/PeopleOutlined'
|
||||
import RateReviewOutlinedIcon from '@mui/icons-material/RateReviewOutlined'
|
||||
import StorefrontOutlinedIcon from '@mui/icons-material/StorefrontOutlined'
|
||||
import Box from '@mui/material/Box'
|
||||
import Divider from '@mui/material/Divider'
|
||||
import Drawer from '@mui/material/Drawer'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import List from '@mui/material/List'
|
||||
import ListItemButton from '@mui/material/ListItemButton'
|
||||
import ListItemIcon from '@mui/material/ListItemIcon'
|
||||
import ListItemText from '@mui/material/ListItemText'
|
||||
import Stack from '@mui/material/Stack'
|
||||
import { useTheme } from '@mui/material/styles'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import useMediaQuery from '@mui/material/useMediaQuery'
|
||||
import { Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom'
|
||||
import { AdminPage } from '@/pages/admin'
|
||||
import { AdminOrdersPage } from '@/pages/admin-orders'
|
||||
import { AdminReviewsPage } from '@/pages/admin-reviews'
|
||||
import { AdminUsersPage } from '@/pages/admin-users'
|
||||
|
||||
type NavItem = {
|
||||
to: string
|
||||
label: string
|
||||
icon: ReactNode
|
||||
}
|
||||
|
||||
export function AdminLayoutPage() {
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
const theme = useTheme()
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down('md'))
|
||||
const [mobileOpen, setMobileOpen] = useState(false)
|
||||
|
||||
const navItems: NavItem[] = useMemo(
|
||||
() => [
|
||||
{ to: '/admin', label: 'Товары', icon: <StorefrontOutlinedIcon /> },
|
||||
{ to: '/admin/orders', label: 'Заказы', icon: <AssignmentOutlinedIcon /> },
|
||||
{ to: '/admin/reviews', label: 'Отзывы', icon: <RateReviewOutlinedIcon /> },
|
||||
{ to: '/admin/users', label: 'Пользователи', icon: <PeopleOutlinedIcon /> },
|
||||
],
|
||||
[],
|
||||
)
|
||||
|
||||
const activeTo =
|
||||
navItems.find((x) => location.pathname === x.to)?.to ??
|
||||
navItems.find((x) => location.pathname.startsWith(`${x.to}/`))?.to ??
|
||||
null
|
||||
|
||||
const nav = (
|
||||
<Box sx={{ width: 280, maxWidth: '85vw' }}>
|
||||
<Box sx={{ p: 2 }}>
|
||||
<Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
|
||||
Админка
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Управление магазином
|
||||
</Typography>
|
||||
</Box>
|
||||
<Divider />
|
||||
<List disablePadding>
|
||||
{navItems.map((i) => (
|
||||
<ListItemButton
|
||||
key={i.to}
|
||||
selected={activeTo === i.to}
|
||||
onClick={() => {
|
||||
navigate(i.to)
|
||||
setMobileOpen(false)
|
||||
}}
|
||||
>
|
||||
<ListItemIcon>{i.icon}</ListItemIcon>
|
||||
<ListItemText primary={i.label} />
|
||||
</ListItemButton>
|
||||
))}
|
||||
</List>
|
||||
</Box>
|
||||
)
|
||||
|
||||
return (
|
||||
<Stack direction={{ xs: 'column', md: 'row' }} spacing={3} sx={{ alignItems: 'flex-start' }}>
|
||||
{isMobile ? (
|
||||
<>
|
||||
<Stack direction="row" spacing={1} sx={{ width: '100%', alignItems: 'center' }}>
|
||||
<IconButton onClick={() => setMobileOpen(true)} aria-label="Открыть меню админки">
|
||||
<MenuOutlinedIcon />
|
||||
</IconButton>
|
||||
<Typography variant="h5" sx={{ fontWeight: 700 }}>
|
||||
Админка
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Drawer open={mobileOpen} onClose={() => setMobileOpen(false)} ModalProps={{ keepMounted: true }}>
|
||||
{nav}
|
||||
</Drawer>
|
||||
</>
|
||||
) : (
|
||||
<Box
|
||||
sx={{
|
||||
position: 'sticky',
|
||||
top: 88,
|
||||
alignSelf: 'flex-start',
|
||||
border: 1,
|
||||
borderColor: 'divider',
|
||||
borderRadius: 2,
|
||||
bgcolor: 'background.paper',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
{nav}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Box sx={{ flexGrow: 1, minWidth: 0, width: '100%' }}>
|
||||
<Routes>
|
||||
<Route index element={<AdminPage />} />
|
||||
<Route path="orders" element={<AdminOrdersPage />} />
|
||||
<Route path="reviews" element={<AdminReviewsPage />} />
|
||||
<Route path="users" element={<AdminUsersPage />} />
|
||||
<Route path="*" element={<Navigate to="/admin" replace />} />
|
||||
</Routes>
|
||||
</Box>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user