base commit
This commit is contained in:
@@ -7,6 +7,7 @@ import Button from '@mui/material/Button'
|
||||
import Divider from '@mui/material/Divider'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import Stack from '@mui/material/Stack'
|
||||
import Tooltip from '@mui/material/Tooltip'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { useUnit } from 'effector-react'
|
||||
@@ -62,57 +63,104 @@ export function CartPage() {
|
||||
|
||||
{items.length > 0 && (
|
||||
<Stack spacing={2}>
|
||||
{items.map((x) => (
|
||||
<Box
|
||||
key={x.id}
|
||||
sx={{
|
||||
border: 1,
|
||||
borderColor: 'divider',
|
||||
borderRadius: 2,
|
||||
p: 2,
|
||||
bgcolor: 'background.paper',
|
||||
}}
|
||||
>
|
||||
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} alignItems={{ sm: 'center' }}>
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
<Typography sx={{ fontWeight: 700 }}>{x.product.title}</Typography>
|
||||
<Typography color="text.secondary" variant="body2">
|
||||
{formatPriceRub(x.product.priceCents)} · {x.qty} шт.
|
||||
</Typography>
|
||||
{items.map((x) =>
|
||||
(() => {
|
||||
const available = x.product.inStock ? x.product.quantity : 1
|
||||
const canInc = x.qty < available
|
||||
const over = x.qty > available
|
||||
return (
|
||||
<Box
|
||||
key={x.id}
|
||||
sx={{
|
||||
border: 1,
|
||||
borderColor: over ? 'error.light' : 'divider',
|
||||
borderRadius: 2,
|
||||
p: 2,
|
||||
bgcolor: over ? 'error.50' : 'background.paper',
|
||||
}}
|
||||
>
|
||||
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ alignItems: { sm: 'center' } }}>
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
<Typography sx={{ fontWeight: 700 }}>{x.product.title}</Typography>
|
||||
<Typography color="text.secondary" variant="body2">
|
||||
{formatPriceRub(x.product.priceCents)} · {x.qty} шт. · Доступно: {available}
|
||||
</Typography>
|
||||
{!x.product.inStock && (
|
||||
<Typography color="text.secondary" variant="caption">
|
||||
Под заказ — доставка после изготовления
|
||||
</Typography>
|
||||
)}
|
||||
{over && (
|
||||
<Typography color="error" variant="caption" sx={{ display: 'block', mt: 0.5 }}>
|
||||
Недостаточно товара. Уменьшите количество до {available}.
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<Stack
|
||||
direction="row"
|
||||
spacing={0.5}
|
||||
sx={{
|
||||
bgcolor: 'background.default',
|
||||
borderRadius: 999,
|
||||
px: 0.75,
|
||||
height: 40,
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<IconButton
|
||||
onClick={() => qtyMut.mutate({ id: x.id, qty: Math.max(0, x.qty - 1) })}
|
||||
disabled={qtyMut.isPending}
|
||||
aria-label="Уменьшить количество"
|
||||
size="small"
|
||||
sx={{ width: 32, height: 32 }}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</IconButton>
|
||||
<Typography
|
||||
sx={{
|
||||
minWidth: 28,
|
||||
textAlign: 'center',
|
||||
lineHeight: 1,
|
||||
fontWeight: 700,
|
||||
fontVariantNumeric: 'tabular-nums',
|
||||
}}
|
||||
>
|
||||
{x.qty}
|
||||
</Typography>
|
||||
<Tooltip title={!canInc ? `Доступно: ${available}` : 'Увеличить количество'}>
|
||||
<span>
|
||||
<IconButton
|
||||
onClick={() => qtyMut.mutate({ id: x.id, qty: x.qty + 1 })}
|
||||
disabled={qtyMut.isPending || !canInc}
|
||||
aria-label="Увеличить количество"
|
||||
size="small"
|
||||
sx={{ width: 32, height: 32 }}
|
||||
>
|
||||
<AddIcon />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
|
||||
<IconButton
|
||||
onClick={() => removeMut.mutate(x.id)}
|
||||
disabled={removeMut.isPending}
|
||||
aria-label="Удалить"
|
||||
size="small"
|
||||
sx={{ width: 32, height: 32 }}
|
||||
>
|
||||
<DeleteOutlineOutlinedIcon />
|
||||
</IconButton>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Box>
|
||||
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<IconButton
|
||||
onClick={() => qtyMut.mutate({ id: x.id, qty: Math.max(0, x.qty - 1) })}
|
||||
disabled={qtyMut.isPending}
|
||||
aria-label="Уменьшить количество"
|
||||
>
|
||||
<RemoveIcon />
|
||||
</IconButton>
|
||||
<Typography sx={{ minWidth: 24, textAlign: 'center' }}>{x.qty}</Typography>
|
||||
<IconButton
|
||||
onClick={() => qtyMut.mutate({ id: x.id, qty: x.qty + 1 })}
|
||||
disabled={qtyMut.isPending}
|
||||
aria-label="Увеличить количество"
|
||||
>
|
||||
<AddIcon />
|
||||
</IconButton>
|
||||
|
||||
<IconButton
|
||||
onClick={() => removeMut.mutate(x.id)}
|
||||
disabled={removeMut.isPending}
|
||||
aria-label="Удалить"
|
||||
>
|
||||
<DeleteOutlineOutlinedIcon />
|
||||
</IconButton>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Box>
|
||||
))}
|
||||
)
|
||||
})(),
|
||||
)}
|
||||
|
||||
<Divider />
|
||||
|
||||
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} alignItems={{ sm: 'center' }}>
|
||||
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ alignItems: { sm: 'center' } }}>
|
||||
<Typography variant="h6" sx={{ flexGrow: 1 }}>
|
||||
Итого: {formatPriceRub(total)}
|
||||
</Typography>
|
||||
|
||||
Reference in New Issue
Block a user