base commit

This commit is contained in:
@kirill.komarov
2026-04-29 20:23:30 +05:00
parent f26223091a
commit 123d86091d
25 changed files with 525 additions and 159 deletions
+43 -5
View File
@@ -37,8 +37,11 @@ export function CheckoutPage() {
enabled: Boolean(user),
})
const defaultAddressId = addressesQuery.data?.items?.find((a) => a.isDefault)?.id ?? ''
const selectedAddressId = addressId || defaultAddressId
const createMut = useMutation({
mutationFn: () => createOrder({ addressId, comment: comment.trim() || null }),
mutationFn: () => createOrder({ addressId: selectedAddressId, comment: comment.trim() || null }),
onSuccess: async (res) => {
await qc.invalidateQueries({ queryKey: ['me', 'cart'] })
navigate(`/me/orders/${res.orderId}`, { replace: true })
@@ -60,8 +63,8 @@ export function CheckoutPage() {
const items = cartQuery.data?.items ?? []
const total = items.reduce((s, x) => s + x.product.priceCents * x.qty, 0)
const addresses = addressesQuery.data?.items ?? []
const defaultAddr = addresses.find((a) => a.isDefault)
const hasOverLimit = items.some((x) => x.qty > (x.product.inStock ? x.product.quantity : 1))
const hasMadeToOrder = items.some((x) => !x.product.inStock)
return (
<Box>
@@ -80,12 +83,45 @@ export function CheckoutPage() {
)}
<Stack spacing={2} sx={{ maxWidth: 720 }}>
{items.length > 0 && (
<Box sx={{ border: 1, borderColor: 'divider', borderRadius: 2, p: 2, bgcolor: 'background.paper' }}>
<Typography sx={{ fontWeight: 700, mb: 1 }}>Позиции</Typography>
<Stack spacing={0.5}>
{items.map((x) => {
const available = x.product.inStock ? x.product.quantity : 1
const over = x.qty > available
return (
<Typography key={x.id} color={over ? 'error' : 'text.primary'}>
{x.product.title}: {x.qty} шт. (доступно {available})
</Typography>
)
})}
</Stack>
</Box>
)}
{hasOverLimit && (
<Alert severity="warning">
Некоторые позиции превышают доступное количество. Вернитесь в{' '}
<Typography component={RouterLink} to="/cart" sx={{ textDecoration: 'underline' }}>
корзину
</Typography>{' '}
и скорректируйте количество.
</Alert>
)}
{hasMadeToOrder && (
<Alert severity="info">
В заказе есть товары «под заказ». Доставка будет после изготовления (срок указан в карточке товара).
</Alert>
)}
<FormControl size="small" fullWidth>
<InputLabel id="addr-label">Адрес доставки</InputLabel>
<Select
labelId="addr-label"
label="Адрес доставки"
value={addressId || (defaultAddr?.id ?? '')}
value={selectedAddressId}
onChange={(e) => setAddressId(String(e.target.value))}
>
{addresses.map((a) => (
@@ -119,7 +155,9 @@ export function CheckoutPage() {
<Button
variant="contained"
disabled={items.length === 0 || addresses.length === 0 || createMut.isPending}
disabled={
items.length === 0 || addresses.length === 0 || !selectedAddressId || hasOverLimit || createMut.isPending
}
onClick={() => createMut.mutate()}
>
Создать заказ