base commit

This commit is contained in:
@kirill.komarov
2026-04-29 19:29:24 +05:00
parent bfc9661d22
commit f26223091a
22 changed files with 987 additions and 931 deletions
@@ -27,6 +27,7 @@ import {
postAdminOrderMessage,
setAdminOrderStatus,
} from '@/entities/order/api/admin-order-api'
import { ORDER_STATUS_TRANSITIONS, type OrderStatus } from '@/shared/constants/order'
import { clearAdminToken, getAdminToken, setAdminToken } from '@/shared/lib/admin-token'
import { formatPriceRub } from '@/shared/lib/format-price'
@@ -98,14 +99,7 @@ export function AdminOrdersPage() {
const nextStatuses = useMemo(() => {
const s = detail?.status
if (!s) return []
const map: Record<string, string[]> = {
DRAFT: ['PENDING_PAYMENT', 'CANCELLED'],
PENDING_PAYMENT: ['PAID', 'CANCELLED'],
PAID: ['IN_PROGRESS', 'CANCELLED'],
IN_PROGRESS: ['SHIPPED', 'CANCELLED'],
SHIPPED: ['DONE'],
}
return map[s] ?? []
return ORDER_STATUS_TRANSITIONS[s as OrderStatus] ?? []
}, [detail?.status])
return (
@@ -168,7 +162,7 @@ export function AdminOrdersPage() {
<MenuItem value="">
<em>Все</em>
</MenuItem>
{['DRAFT', 'PENDING_PAYMENT', 'PAID', 'IN_PROGRESS', 'SHIPPED', 'DONE', 'CANCELLED'].map((s) => (
{Object.keys(ORDER_STATUS_TRANSITIONS).map((s) => (
<MenuItem key={s} value={s}>
{s}
</MenuItem>
+1 -1
View File
@@ -7,8 +7,8 @@ import Stack from '@mui/material/Stack'
import TextField from '@mui/material/TextField'
import Typography from '@mui/material/Typography'
import { useMutation } from '@tanstack/react-query'
import { useForm } from 'react-hook-form'
import { useUnit } from 'effector-react'
import { useForm } from 'react-hook-form'
import { useNavigate } from 'react-router-dom'
import { apiClient } from '@/shared/api/client'
import { $user, tokenSet } from '@/shared/model/auth'
+1 -1
View File
@@ -12,8 +12,8 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useUnit } from 'effector-react'
import { Link as RouterLink } from 'react-router-dom'
import { fetchMyCart, removeCartItem, setCartQty } from '@/entities/cart/api/cart-api'
import { $user } from '@/shared/model/auth'
import { formatPriceRub } from '@/shared/lib/format-price'
import { $user } from '@/shared/model/auth'
export function CartPage() {
const user = useUnit($user)
@@ -1,3 +1,4 @@
import { useState } from 'react'
import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
@@ -9,9 +10,8 @@ import Stack from '@mui/material/Stack'
import TextField from '@mui/material/TextField'
import Typography from '@mui/material/Typography'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useState } from 'react'
import { Link as RouterLink, useNavigate } from 'react-router-dom'
import { useUnit } from 'effector-react'
import { Link as RouterLink, useNavigate } from 'react-router-dom'
import { fetchMyCart } from '@/entities/cart/api/cart-api'
import { createOrder } from '@/entities/order/api/order-api'
import { fetchMyAddresses } from '@/entities/user/api/address-api'
+6 -1
View File
@@ -21,6 +21,7 @@ import Typography from '@mui/material/Typography'
import { useQuery } from '@tanstack/react-query'
import { fetchCategories, fetchPublicProducts } from '@/entities/product/api/product-api'
import { ProductCard } from '@/entities/product/ui/ProductCard'
import { AddToCartButton } from '@/features/cart/add-to-cart'
export function HomePage() {
const [categorySlug, setCategorySlug] = useState<string>('')
@@ -315,7 +316,11 @@ export function HomePage() {
<Grid container spacing={2}>
{products.map((p) => (
<Grid size={{ xs: 12, sm: 6, md: 4 }} key={p.id}>
<ProductCard product={p} mediaHeight={mediaHeight} />
<ProductCard
product={p}
mediaHeight={mediaHeight}
actions={<AddToCartButton productId={p.id} variant="contained" size="small" />}
/>
</Grid>
))}
</Grid>
@@ -1,3 +1,4 @@
import { useMemo, useState } from 'react'
import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
@@ -6,7 +7,6 @@ import Stack from '@mui/material/Stack'
import TextField from '@mui/material/TextField'
import Typography from '@mui/material/Typography'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useMemo, useState } from 'react'
import { Link as RouterLink, useParams } from 'react-router-dom'
import { fetchMyOrder, payOrderStub, postOrderMessage } from '@/entities/order/api/order-api'
import { formatPriceRub } from '@/shared/lib/format-price'
+4 -25
View File
@@ -2,28 +2,23 @@ import { useMemo, useState } from 'react'
import CloseIcon from '@mui/icons-material/Close'
import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import Chip from '@mui/material/Chip'
import Dialog from '@mui/material/Dialog'
import IconButton from '@mui/material/IconButton'
import Skeleton from '@mui/material/Skeleton'
import Typography from '@mui/material/Typography'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useQuery } from '@tanstack/react-query'
import { useParams } from 'react-router-dom'
import { Swiper, SwiperSlide } from 'swiper/react'
import { Navigation } from 'swiper/modules'
import { Swiper, SwiperSlide } from 'swiper/react'
import 'swiper/css'
import 'swiper/css/navigation'
import { useUnit } from 'effector-react'
import { addToCart } from '@/entities/cart/api/cart-api'
import { fetchPublicProduct } from '@/entities/product/api/product-api'
import { AddToCartButton } from '@/features/cart/add-to-cart'
import { formatPriceRub } from '@/shared/lib/format-price'
import { $user } from '@/shared/model/auth'
export function ProductPage() {
const { id } = useParams()
const qc = useQueryClient()
const user = useUnit($user)
const [viewerOpen, setViewerOpen] = useState(false)
const [viewerIndex, setViewerIndex] = useState(0)
@@ -33,15 +28,6 @@ export function ProductPage() {
enabled: Boolean(id),
})
const addMut = useMutation({
mutationFn: async () => {
const pid = productQuery.data?.id
if (!pid) throw new Error('Товар ещё не загружен')
await addToCart({ productId: pid, qty: 1 })
},
onSuccess: () => void qc.invalidateQueries({ queryKey: ['me', 'cart'] }),
})
const imageUrls = useMemo(() => {
const p = productQuery.data
if (!p) return []
@@ -151,14 +137,7 @@ export function ProductPage() {
{formatPriceRub(p.priceCents)}
</Typography>
<Button
variant="contained"
disabled={!user || addMut.isPending || !p}
onClick={() => addMut.mutate()}
sx={{ alignSelf: 'flex-start' }}
>
{user ? 'В корзину' : 'Войдите, чтобы купить'}
</Button>
<AddToCartButton productId={p.id} variant="contained" sx={{ alignSelf: 'flex-start' }} />
{p.description ? (
<Typography sx={{ whiteSpace: 'pre-wrap' }}>{p.description}</Typography>