order create

This commit is contained in:
Samandar Turgunboyev
2026-01-23 19:29:04 +05:00
parent a5e100ed90
commit c2a2c2b09b
11 changed files with 187 additions and 60 deletions

View File

@@ -5,25 +5,71 @@ import { AxiosResponse } from 'axios';
interface CartItem {
id: string;
cart_item: {
id: string;
product_name: string;
product_id: string;
product_image: string;
id: number;
product: {
id: number;
images: {
id: number;
image: string;
}[];
liked: boolean;
meansurement: null | string;
inventory_id: null | string;
product_id: string;
code: string;
name: string;
short_name: string;
weight_netto: null | string;
weight_brutto: null | string;
litr: null | string;
box_type_code: null | string;
box_quant: null | string;
groups: number[];
state: 'A' | 'P';
barcodes: string | null;
article_code: null | string;
marketing_group_code: null | string;
inventory_kinds: { id: number; name: string }[];
sector_codes: { id: number; code: string }[];
prices: {
id: number;
price: string;
price_type: {
id: number;
name: string;
code: string;
};
}[];
};
quantity: number;
product_price: number;
}[];
}
export interface OrderCreateBody {
items: {
product_id: number;
quantity: number;
order: {
filial_code: string;
delivery_date: string;
room_code: string;
robot_code: string;
deal_time: string;
status: string;
sales_manager_code: string;
person_code: string;
currency_code: string;
owner_person_code: string;
note: string;
order_products: [
{
inventory_kind: string;
product_code: string;
on_balance: string;
order_quant: number;
price_type_code: string;
product_price: string;
warehouse_code: string;
},
];
}[];
comment: string;
long: number;
lat: number;
date: string;
time: string;
}
export const cart_api = {

View File

@@ -21,6 +21,7 @@ import { useTranslations } from 'next-intl';
import Image from 'next/image';
import { useEffect, useRef, useState } from 'react';
import { toast } from 'sonner';
import ProductBanner from '@/assets/product.png';
const CartPage = () => {
const { cart_id } = useCartId();
@@ -102,7 +103,10 @@ const CartPage = () => {
);
const subtotal = cartItems.reduce(
(sum, item) => sum + item.product_price * Number(item.quantity),
(sum, item) =>
sum +
Math.max(...item.product.prices.map((e) => Number(e.price))) *
Number(item.quantity),
0,
);
@@ -145,7 +149,9 @@ const CartPage = () => {
<Button
variant="destructive"
size="icon"
onClick={() => deleteCartItem({ cart_item_id: item.id })}
onClick={() =>
deleteCartItem({ cart_item_id: String(item.id) })
}
className="absolute right-2 w-7 h-7 top-2 cursor-pointer"
>
<Trash className="size-4" />
@@ -153,8 +159,12 @@ const CartPage = () => {
<div className="w-24 h-40 bg-gray-100 rounded-lg flex-shrink-0 overflow-hidden">
<Image
src={BASE_URL + item.product_image}
alt={item.product_name}
src={
item.product.images.length > 0
? BASE_URL + item.product.images[0].image
: ProductBanner
}
alt={item.product.name}
width={500}
height={500}
className="object-cover"
@@ -164,11 +174,16 @@ const CartPage = () => {
<div className="flex-1">
<h3 className="font-semibold text-lg mb-1">
{item.product_name}
{item.product.name}
</h3>
<div className="flex items-center gap-2 mb-3 max-lg:flex-col max-lg:items-start max-lg:gap-1">
<span className="text-blue-600 font-bold text-xl">
{formatPrice(item.product_price, true)}
{formatPrice(
Math.max(
...item.product.prices.map((e) => Number(e.price)),
),
true,
)}
</span>
</div>
@@ -176,7 +191,7 @@ const CartPage = () => {
<button
onClick={() =>
handleQuantityChange(
item.id,
String(item.id),
Number(quantities[item.id]) - 1,
)
}
@@ -197,7 +212,7 @@ const CartPage = () => {
// Debounce bilan update
const valNum = Number(val);
if (!isNaN(valNum))
handleQuantityChange(item.id, valNum);
handleQuantityChange(String(item.id), valNum);
}}
type="text"
className="w-16 text-center"
@@ -206,7 +221,7 @@ const CartPage = () => {
<button
onClick={() =>
handleQuantityChange(
item.id,
String(item.id),
Number(quantities[item.id]) + 1,
)
}

View File

@@ -95,10 +95,19 @@ const OrderPage = () => {
const { mutate, isPending } = useMutation({
mutationFn: (body: OrderCreateBody) => cart_api.createOrder(body),
onSuccess: () => {
setOrderSuccess(true);
setCart(cart_id);
queryClinet.refetchQueries({ queryKey: ['cart_items'] });
onSuccess: (res) => {
const message = JSON.parse(res.data.response);
if (message.successes.length > 0) {
setOrderSuccess(true);
setCart(cart_id);
queryClinet.refetchQueries({ queryKey: ['cart_items'] });
} else {
toast.error('Xatolik yuz berdi', {
richColors: true,
position: 'top-center',
});
}
},
onError: (error: AxiosError) => {
(
@@ -123,7 +132,10 @@ const OrderPage = () => {
const [selectedTimeSlot, setSelectedTimeSlot] = useState<string>('');
const subtotal = cartItems?.reduce(
(sum, item) => sum + item.product_price * item.quantity,
(sum, item) =>
sum +
Math.max(...item.product.prices.map((e) => Number(e.price))) *
item.quantity,
0,
);
@@ -247,18 +259,45 @@ const OrderPage = () => {
return;
}
const items = cartItems.map((item) => ({
product_id: Number(item.product_id),
quantity: item.quantity,
}));
const order_products: {
inventory_kind: sting;
product_code: sting;
on_balance: sting;
order_quant: number;
price_type_code: sting;
product_price: sting;
warehouse_code: sting;
}[] = [];
cartItems.forEach((e) => {
order_products.push({
inventory_kind: 'G',
product_code: e.product.code,
on_balance: 'Y',
order_quant: e.quantity,
price_type_code: e.product.prices[0].price_type.code,
product_price: e.product.prices[0].price,
warehouse_code: 'wh1',
});
});
mutate({
comment: value.comment,
items: items,
long: Number(value.long),
lat: Number(value.lat),
date: formatDate.format(deliveryDate, 'YYYY-MM-DD'),
time: selectedTimeSlot,
order: [
{
filial_code: 'dodge',
delivery_date: formatDate.format(deliveryDate, 'DD.MM.YYYY'),
room_code: '100',
deal_time: formatDate.format(deliveryDate, 'DD.MM.YYYY'),
robot_code: 'r2',
status: 'B#N',
sales_manager_code: '1',
person_code: '12345678',
currency_code: '860',
owner_person_code: '1234567',
note: value.comment,
order_products: order_products,
},
],
});
}

View File

@@ -91,7 +91,7 @@ const Product = () => {
{product &&
!isLoading &&
product.results
.filter((product) => product.is_active)
.filter((product) => product.state === 'A')
.map((item) => (
<ProductCard key={item.id} product={item} error={isError} />
))}