order page: integration

This commit is contained in:
2025-10-18 09:26:03 +03:00
parent 039bf64b46
commit 9d4621d0a4
14 changed files with 376 additions and 129 deletions

View File

@@ -0,0 +1,228 @@
import { Variant } from "pages/orders/types"
import { Extra3 } from "utils/types/appTypes"
export interface OrderDetails {
orderItems: OrderItem[]
order: Order
status: Status[]
laststatus: Status2[]
restaurant: string
restaurantAR: string
restaurantID: number
global_currency: string
local_currency: string
address: string
phone: string
restaurant_iimage: string
itemsImagePrefixOld: string
itemsImagePrefix: string
}
export interface OrderItem {
id: number
is_loyalty_used: number
no_of_stamps_give: number
isHasLoyalty: boolean
is_vat_disabled: number
name: string
price: number
qty: number
variant_price: string
image: string
imageName: string
variantName: string
variantLocalName?: string
extras: any[]
itemline: string
itemlineAR: string
itemlineAREN: string
extrasgroups: any[]
itemComment: string
variant?: Variant
itemExtras: any[]
AvaiilableVariantExtras: Extra3[]
isPrinted: number
category_id: number
pos_order_id: string
updated_at: string
created_at: string
old_qty: number
new_qty: number
last_printed_qty: number
deleted_qty: number
discount_value: any
discount_type_id: any
original_price: number
pricing_method: string
is_already_paid: number
hash_item: string
}
export interface Order {
id: number
pos_order_id: string
created_at: string
updated_at: string
table: string
phone: string
user_name: string
restaurant_name: string
lat: string
lng: string
restaurant_icon: string
location: any
status: string
status_id: number
delivery_method: number
orderItems: OrderItem2[]
discount: string
vat: number
total_price: number
comment: string
pickup_comments: any
car_plate: string
pickup_time: any
pickup_date: any
delivery_pickup_interval: any
office_no: any
room_no: any
time_to_prepare: any
last_status_id: number
currency: string
gift_id: any
is_loyalty_used: number
payment_status: string
created_by: string
split_order_group_id: any
split_sequence: any
is_split_order: number
split_at: any
split_by_user_id: any
}
export interface OrderItem2 {
id: number
is_loyalty_used: number
no_of_stamps_give: number
isHasLoyalty: boolean
is_vat_disabled: number
name: string
price: number
qty: number
variant_price: string
image: string
imageName: string
variantName: string
variantLocalName?: string
extras: any[]
itemline: string
itemlineAR: string
itemlineAREN: string
extrasgroups: any[]
itemComment: string
variant?: Variant2
itemExtras: any[]
AvaiilableVariantExtras: AvaiilableVariantExtra2[]
isPrinted: number
category_id: number
pos_order_id: string
updated_at: string
created_at: string
old_qty: number
new_qty: number
last_printed_qty: number
deleted_qty: number
discount_value: any
discount_type_id: any
original_price: number
pricing_method: string
is_already_paid: number
hash_item: string
}
export interface Status {
id: number
name: string
alias: string
pivot: Pivot5
}
export interface Pivot5 {
order_id: number
status_id: number
user_id: number
created_at: string
comment: string
}
export interface Status2 {
id: number
name: string
alias: string
pivot: Pivot6
}
export interface Pivot6 {
order_id: number
status_id: number
user_id: number
created_at: string
comment: string
}
export interface Variant2 {
id: number
price: number
options: string
local_name: any
optionsArray: OptionsArray2[]
OptionsList: string
extras: Extra2[]
}
export interface OptionsArray2 {
id: number
name: string
}
export interface Extra2 {
id: number
item_id: number
price: number
name: string
nameAR: string
created_at: string
updated_at: string
deleted_at: any
extra_for_all_variants: number
is_custome: number
is_available: number
modifier_id: any
pivot: Pivot3
}
export interface Pivot3 {
variant_id: number
extra_id: number
}
export interface AvaiilableVariantExtra2 {
id: number
item_id: number
price: number
name: string
nameAR: string
created_at: string
updated_at: string
deleted_at: any
extra_for_all_variants: number
is_custome: number
is_available: number
modifier_id: any
pivot: Pivot4
}
export interface Pivot4 {
variant_id: number
extra_id: number
}

View File

@@ -1,5 +1,7 @@
import { message } from "antd";
import { clearCart, selectCart } from "features/order/orderSlice";
import { useCallback } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom";
import { useCreateOrderMutation } from "redux/api/others";
import { useAppDispatch, useAppSelector } from "redux/hooks";
@@ -8,6 +10,7 @@ import { Customer } from "../../otp/types";
export default function useOrder() {
const dispatch = useAppDispatch();
const router = useNavigate();
const { t } = useTranslation();
const { id } = useParams();
const restaurantID = localStorage.getItem("restaurantID");
const { mobilenumber, user_uuid } = JSON.parse(
@@ -59,11 +62,15 @@ export default function useOrder() {
useWallet: 0,
tip,
})
.then(() => {
dispatch(clearCart());
router(`/${id}/order`);
.then((res: any) => {
if (res.error)
message.error(res.error.data.message || t("order.createOrderFailed"));
else {
dispatch(clearCart());
router(`/${id}/order/${res.data.result.orderID}`);
}
})
.catch((error) => {
.catch((error: any) => {
console.error("Create Order failed:", error);
});
}, [
@@ -80,6 +87,7 @@ export default function useOrder() {
user_uuid,
estimateTime,
tip,
t,
dispatch,
router,
]);

View File

@@ -2,7 +2,9 @@ import { Form } from "antd";
import OrderSummary from "components/OrderSummary/OrderSummary";
import PaymentMethods from "components/PaymentMethods/PaymentMethods";
import ProHeader from "components/ProHeader/ProHeader";
import { selectCart } from "features/order/orderSlice";
import { useTranslation } from "react-i18next";
import { useAppSelector } from "redux/hooks";
import styles from "../address/address.module.css";
import { AddressSummary } from "./components/AddressSummary";
import BriefMenu from "./components/BriefMenu";
@@ -15,23 +17,28 @@ import PhoneCard from "./components/phoneCard";
export default function CheckoutPage() {
const { t } = useTranslation();
const [form] = Form.useForm();
const { phone } = useAppSelector(selectCart);
return (
<>
<Form form={form}>
<ProHeader>{t("checkout.title")}</ProHeader>
<div className={styles.checkoutContainer}>
<AddressSummary />
<RoomDetails />
<OfficeDetails />
<GiftDetails />
<BriefMenu />
<PhoneCard />
<PaymentMethods />
<OrderSummary />
</div>
<Form
form={form}
initialValues={{
phone,
}}
>
<ProHeader>{t("checkout.title")}</ProHeader>
<div className={styles.checkoutContainer}>
<AddressSummary />
<RoomDetails />
<OfficeDetails />
<GiftDetails />
<BriefMenu />
<PhoneCard />
<PaymentMethods />
<OrderSummary />
</div>
<CheckoutButton form={form} />
<CheckoutButton form={form} />
</Form>
</>
);

View File

@@ -2,6 +2,12 @@
padding: 16px !important;
}
.profileImage {
border-radius: 50%;
width: 50px;
height: 50px;
}
/* Enhanced responsive order summary */
@media (min-width: 769px) and (max-width: 1024px) {
.orderSummary {
@@ -9,7 +15,7 @@
}
}
.fascanoIcon {
.fascanoIcon {
position: relative;
top: 3px;
}

View File

@@ -1,7 +1,6 @@
import { Button, Card, Divider } from "antd";
import { Button, Card, Divider, Image } from "antd";
import Ads2 from "components/Ads/Ads2";
import { CancelOrderBottomSheet } from "components/CustomBottomSheet/CancelOrderBottomSheet";
import Fascano50X50Icon from "components/Icons/fascano/Fascano50X50Icon";
import LocationIcon from "components/Icons/LocationIcon";
import InvoiceIcon from "components/Icons/order/InvoiceIcon";
import TimeIcon from "components/Icons/order/TimeIcon";
@@ -12,15 +11,28 @@ import ProInputCard from "components/ProInputCard/ProInputCard";
import ProText from "components/ProText";
import ProTitle from "components/ProTitle";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";
import { useGetOrderDetailsQuery } from "redux/api/others";
import { useAppSelector } from "redux/hooks";
import Stepper from "./components/Stepper";
import styles from "./order.module.css";
export default function OrderPage() {
const { t } = useTranslation();
const { orderId } = useParams();
const { isRTL } = useAppSelector((state) => state.locale);
// const subtotal = getTotal();
// const tax = subtotal * 0.1; // 10% tax
// const total = subtotal + tax;
const { data: orderDetails } = useGetOrderDetailsQuery(
{
orderID: orderId || "",
restaurantID: localStorage.getItem("restaurantID") || "",
},
{
skip: !orderId,
},
);
console.log(orderDetails);
return (
<>
@@ -54,7 +66,12 @@ export default function OrderPage() {
backgroundColor: "rgba(255, 183, 0, 0.08)",
}}
>
<Fascano50X50Icon className={styles.fascanoIcon} />
<Image
src={orderDetails?.restaurant_iimage}
className={styles.profileImage}
width={50}
height={50}
/>
</Button>
<div>
<ProText style={{ fontSize: "1rem" }}>
@@ -63,7 +80,7 @@ export default function OrderPage() {
<br />
<ProText type="secondary">
<LocationIcon className={styles.locationIcon} />{" "}
{t("order.muscat")}
{isRTL ? orderDetails?.restaurantAR : orderDetails?.restaurant}
</ProText>
</div>
</div>
@@ -84,11 +101,11 @@ export default function OrderPage() {
<div style={{ display: "flex", flexDirection: "row", gap: 8 }}>
<InvoiceIcon className={styles.invoiceIcon} />
<ProText type="secondary" style={{ fontSize: "14px" }}>
#A54363
#{orderDetails?.order.id}
</ProText>
<TimeIcon className={styles.timeIcon} />
<ProText type="secondary" style={{ fontSize: "14px" }}>
ordered :- Today - 13:55 PM
ordered :- Today - {orderDetails?.status[0]?.pivot?.created_at.split(" ")[1]} PM
</ProText>
</div>
@@ -117,11 +134,7 @@ export default function OrderPage() {
<div
style={{ display: "flex", flexDirection: "column", gap: "1rem" }}
>
{[
{ id: 1, name: "Lazord Grill - half kilo" },
{ id: 2, name: "Lazord Grill - half kilo" },
{ id: 3, name: "Lazord Grill - half kilo" },
].map((item, index) => (
{orderDetails?.orderItems.map((item, index) => (
<div key={item.id}>
<div
style={{
@@ -153,7 +166,7 @@ export default function OrderPage() {
</div>
</ProInputCard>
<PaymentDetails />
<PaymentDetails order={orderDetails?.order} />
<CancelOrderBottomSheet />
</div>