base commit

This commit is contained in:
@kirill.komarov
2026-05-03 19:57:12 +05:00
parent 9139a24093
commit fe10f25b8c
53 changed files with 2064 additions and 1071 deletions
+2
View File
@@ -6,6 +6,7 @@ import { AuthCallbackPage, AuthPage } from '@/pages/auth'
import { CartPage } from '@/pages/cart'
import { CheckoutPage } from '@/pages/checkout'
import { HomePage } from '@/pages/home'
import { InfoPage } from '@/pages/info'
import { MeLayoutPage } from '@/pages/me'
import { ProductPage } from '@/pages/product'
@@ -21,6 +22,7 @@ export function App() {
<Route path="/auth/callback" element={<AuthCallbackPage />} />
<Route path="/cart" element={<CartPage />} />
<Route path="/checkout" element={<CheckoutPage />} />
<Route path="/info" element={<InfoPage />} />
<Route path="/me/*" element={<MeLayoutPage />} />
<Route path="/products/:id" element={<ProductPage />} />
<Route path="*" element={<Navigate to="/" replace />} />
+54 -28
View File
@@ -2,6 +2,7 @@ import { useState } from 'react'
import AccountCircleOutlinedIcon from '@mui/icons-material/AccountCircleOutlined'
import DarkModeOutlinedIcon from '@mui/icons-material/DarkModeOutlined'
import LightModeOutlinedIcon from '@mui/icons-material/LightModeOutlined'
import LocalShippingOutlinedIcon from '@mui/icons-material/LocalShippingOutlined'
import MenuOutlinedIcon from '@mui/icons-material/MenuOutlined'
import ShoppingCartOutlinedIcon from '@mui/icons-material/ShoppingCartOutlined'
import AppBar from '@mui/material/AppBar'
@@ -29,6 +30,7 @@ import { Link as RouterLink, useNavigate } from 'react-router-dom'
import type { ColorScheme } from '@/app/providers/theme-controller'
import { useThemeController } from '@/app/providers/theme-controller'
import { fetchMyCart } from '@/entities/cart/api/cart-api'
import { fetchMyOrders } from '@/entities/order/api/order-api'
import { STORE_NAME } from '@/shared/config'
import { $user, logout, tokenSet } from '@/shared/model/auth'
import { BearLogo } from '@/shared/ui/BearLogo'
@@ -37,7 +39,7 @@ type NavItem = { label: string; to: string }
const navItems: NavItem[] = [
{ label: 'Каталог', to: '/' },
{ label: 'Админка', to: '/admin' },
{ label: 'О покупке', to: '/info' },
]
function ThemeControlsDesktop(props: {
@@ -168,15 +170,26 @@ export function AppHeader() {
const { mode, resolvedMode, scheme, setMode, setScheme, cycleMode } = useThemeController()
const user = useUnit($user)
const navigate = useNavigate()
const isAdmin = Boolean(user?.isAdmin)
const cartQuery = useQuery({
queryKey: ['me', 'cart'],
queryFn: fetchMyCart,
enabled: Boolean(user),
enabled: Boolean(user) && !isAdmin,
})
const cartCount = cartQuery.data?.items?.length ?? 0
const ordersQuery = useQuery({
queryKey: ['me', 'orders'],
queryFn: fetchMyOrders,
enabled: Boolean(user) && !isAdmin,
})
const activeOrdersCount = (ordersQuery.data?.items ?? []).filter(
(o) => o.status !== 'DONE' && o.status !== 'CANCELLED',
).length
const [userAnchorEl, setUserAnchorEl] = useState<null | HTMLElement>(null)
const userMenuOpen = Boolean(userAnchorEl)
@@ -249,24 +262,35 @@ export function AppHeader() {
</Button>
))}
<Tooltip title={user ? 'Корзина' : 'Авторизуйтесь для совершения покупок'}>
<span>
<IconButton
color="inherit"
sx={{ ml: 1 }}
disabled={!user}
onClick={() => {
if (!user) navigate('/auth')
else navigate('/cart')
}}
aria-label="Корзина"
>
<Badge color="secondary" badgeContent={user ? cartCount : 0} invisible={!user || cartCount === 0}>
<ShoppingCartOutlinedIcon />
</Badge>
</IconButton>
</span>
</Tooltip>
{!isAdmin && (
<>
{user && (
<Tooltip title="Заказы">
<IconButton color="inherit" sx={{ ml: 1 }} onClick={() => navigate('/me/orders')} aria-label="Заказы">
<Badge color="secondary" badgeContent={activeOrdersCount} invisible={activeOrdersCount === 0}>
<LocalShippingOutlinedIcon />
</Badge>
</IconButton>
</Tooltip>
)}
<Tooltip title={user ? 'Корзина' : 'Авторизуйтесь для совершения покупок'}>
<IconButton
color="inherit"
sx={{ ml: 1 }}
onClick={() => {
if (!user) navigate('/auth')
else navigate('/cart')
}}
aria-label="Корзина"
>
<Badge color="secondary" badgeContent={user ? cartCount : 0} invisible={!user || cartCount === 0}>
<ShoppingCartOutlinedIcon />
</Badge>
</IconButton>
</Tooltip>
</>
)}
<IconButton color="inherit" onClick={openUserMenu} sx={{ ml: 1 }} aria-label="Пользователь">
<Badge
@@ -330,14 +354,16 @@ export function AppHeader() {
{i.label}
</Button>
))}
<Button
variant="text"
onClick={() => go(user ? '/cart' : '/auth')}
sx={{ justifyContent: 'flex-start' }}
disabled={!user}
>
Корзина
</Button>
{!isAdmin && (
<Button variant="text" onClick={() => go(user ? '/cart' : '/auth')} sx={{ justifyContent: 'flex-start' }}>
Корзина
</Button>
)}
{user && !isAdmin && (
<Button variant="text" onClick={() => go('/me/orders')} sx={{ justifyContent: 'flex-start' }}>
Заказы
</Button>
)}
<Button variant="text" onClick={() => go(user ? '/me' : '/auth')} sx={{ justifyContent: 'flex-start' }}>
{user ? 'Профиль' : 'Вход / регистрация'}
</Button>