Compare commits

..

11 Commits

27 changed files with 1188 additions and 1079 deletions

View File

@@ -37,6 +37,7 @@
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
"@vitejs/plugin-react": "^4.3.1",
"baseline-browser-mapping": "^2.9.11",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.7",

View File

@@ -175,8 +175,8 @@ export const themeConfig: ThemeConfig = {
boxShadow: "0 1px 3px rgba(0,0,0,0.1)",
padding: 16,
paddingLG: 16,
borderRadius: 24,
borderRadiusLG: 24,
borderRadius: 16,
borderRadiusLG: 16,
},
Carousel: {
colorBgContainer: lightColors["800"],

View File

@@ -167,6 +167,9 @@
"customizable": "قابل للتخصيص"
},
"cart": {
"addSpecialRequestOptional": "إضافة طلب خاص (اختياري)",
"continueToGiftDetails": "متابعة إلى تفاصيل الهدية",
"continueToGiftDetailsDescription": "يرجى إدخال تفاصيل المستلم والمرسل لمتابعة.",
"leaveANoteHere": "أي تعليمات خاصة لطلبك..",
"title": "السلة",
"emptyCart": "سلة المشتريات فارغة",
@@ -293,7 +296,8 @@
"pleaseEnterPhoneNumber": "يرجى إدخال رقم الهاتف",
"viewOrder": "عرض الطلب",
"itemsSummary": "ملخص العناصر",
"removeSplitBill": "إزالة التقسيم"
"removeSplitBill": "إزالة التقسيم",
"cardBalance": "رصيد البطاقة"
},
"address": {
"title": "العنوان",
@@ -374,6 +378,10 @@
"confirmOTPSuccess": "تم التحقق من رمز التحقق بنجاح"
},
"order": {
"whosPaidTheirShareSplitBill": "من قام بدفع نصيبه من الفاتورة؟",
"seeWhoPaidAndHowMuch": "اعرض من قام بدفع نصيبه من الفاتورة وكم يبلغ نصيبه",
"personHasPaid": "قام بدفع نصيبه من الفاتورة",
"inviteOthersToBill": "دع الآخرين يدفعوا معك",
"title": "الطلب",
"newOrder": "طلب جديد",
"paymentSummary": "ملخص الدفع",
@@ -434,6 +442,7 @@
"payButtonDescription": "الدفع للطلب"
},
"splitBill": {
"serviceFee": "نصيب الخدمة",
"title": "تقسيم الفاتورة",
"description": "تقسيم الفاتورة",
"splitBill": "تقسيم الفاتورة",
@@ -491,6 +500,10 @@
"eCardAmount": "مبلغ البطاقة الإلكترونية",
"receiverName": "اسم المستلم",
"edit": "تعديل",
"yourInformation": "تفاصيلك"
"yourInformation": "تفاصيلك",
"minimumAmountShouldBe1OMR": "يجب أن يكون المبلغ الأدنى 1 OMR",
"add": "أضف",
"senderNameRequired": "يجب أن يكون اسم المرسل مطلوب",
"receiverNameRequired": "يجب أن يكون اسم المستلم مطلوب"
}
}

View File

@@ -179,6 +179,9 @@
"customizable": "Customizable"
},
"cart": {
"addSpecialRequestOptional": "Add Special Request (Optional)",
"continueToGiftDetails": "Continue to Gift Details",
"continueToGiftDetailsDescription": "Please fill in the details of the gift recipient and sender to continue.",
"leaveANoteHere": "Leave a note here..",
"changeTable": "Change Table",
"title": "Cart",
@@ -305,7 +308,8 @@
"pleaseEnterPhoneNumber": "Please enter phone number",
"viewOrder": "View Order",
"itemsSummary": "Items Summary",
"removeSplitBill": "Remove Split Bill"
"removeSplitBill": "Remove Split Bill",
"cardBalance": "Card Balance"
},
"address": {
"title": "Address",
@@ -387,6 +391,10 @@
"confirmOTPSuccess": "OTP confirmed successfully"
},
"order": {
"whosPaidTheirShareSplitBill": "Who's paid their share of the split bill?",
"seeWhoPaidAndHowMuch": "See who paid and how much",
"personHasPaid": "Person has paid",
"inviteOthersToBill": "Invite others to bill",
"title": "Order",
"newOrder": "New Order",
"aStaffMemberWillCollectTheCashFromYouAtYourTable": "A staff member will collect the cash from you at your table",
@@ -446,6 +454,7 @@
"payButtonDescription": "Pay for your order"
},
"splitBill": {
"serviceFee": "Service Fee",
"title": "Split Bill",
"description": "Split Bill",
"splitBill": "Split Bill",
@@ -503,6 +512,10 @@
"eCardAmount": "E-Card Amount",
"receiverName": "Receiver Name",
"edit": "Edit",
"yourInformation": "Your Information"
"yourInformation": "Your Information",
"minimumAmountShouldBe1OMR": "Minimum amount should be 1 OMR",
"add": "Add",
"senderNameRequired": "Sender name is required",
"receiverNameRequired": "Receiver name is required"
}
}

View File

@@ -16,7 +16,7 @@ const InvoiceIcon = ({ className, onClick }: InvoiceIconType) => {
>
<path
d="M7.83317 7.41504H3.83317M5.1665 10.0817H3.83317M9.1665 4.74837H3.83317M11.8332 4.61504V11.5484C11.8332 12.6685 11.8332 13.2285 11.6152 13.6564C11.4234 14.0327 11.1175 14.3386 10.7412 14.5304C10.3133 14.7484 9.75328 14.7484 8.63317 14.7484H4.3665C3.2464 14.7484 2.68635 14.7484 2.25852 14.5304C1.8822 14.3386 1.57624 14.0327 1.38449 13.6564C1.1665 13.2285 1.1665 12.6685 1.1665 11.5484V4.61504C1.1665 3.49493 1.1665 2.93488 1.38449 2.50706C1.57624 2.13073 1.8822 1.82477 2.25852 1.63303C2.68635 1.41504 3.2464 1.41504 4.3665 1.41504H8.63317C9.75328 1.41504 10.3133 1.41504 10.7412 1.63303C11.1175 1.82477 11.4234 2.13073 11.6152 2.50706C11.8332 2.93488 11.8332 3.49493 11.8332 4.61504Z"
stroke="#666666"
stroke="#333333"
strokeLinecap="round"
strokeLinejoin="round"
/>

View File

@@ -17,7 +17,7 @@ const TimeIcon = ({ className, onClick }: TimeIconType) => {
<g clipPath="url(#clip0_2448_7814)">
<path
d="M8.50016 4.08171V8.08171L11.1668 9.41504M15.1668 8.08171C15.1668 11.7636 12.1821 14.7484 8.50016 14.7484C4.81826 14.7484 1.8335 11.7636 1.8335 8.08171C1.8335 4.39981 4.81826 1.41504 8.50016 1.41504C12.1821 1.41504 15.1668 4.39981 15.1668 8.08171Z"
stroke="#666666"
stroke="#333333"
strokeLinecap="round"
strokeLinejoin="round"
/>

View File

@@ -16,8 +16,31 @@ export default function PaymentDetails({ order }: { order?: Order }) {
<Divider style={{ margin: "15px 0 15px 0" }} />
<Space orientation="vertical" style={{ width: "100%" }}>
<div className={`${styles.summaryRow} ${styles.totalRow}`}>
<ProText strong>{t("cart.totalAmount")}</ProText>
<ArabicPrice price={order?.total_price || 0} strong />
<ProText
style={{
fontWeight: 600,
fontStyle: "SemiBold",
fontSize: 16,
lineHeight: "140%",
letterSpacing: "0%",
textAlign: "center",
color: "#333333",
}}
>
{t("cart.totalAmount")}
</ProText>
<ArabicPrice
price={order?.total_price || 0}
textStyle={{
fontWeight: 400,
fontStyle: "Regular",
fontSize: 16,
lineHeight: "140%",
letterSpacing: "0%",
textAlign: "center",
color: "#434E5C",
}}
/>
</div>
</Space>
</Card>

View File

@@ -23,15 +23,17 @@ export default function CardDetailsPage() {
const { giftDetails } = useAppSelector(selectCart);
const { isRTL } = useAppSelector((state) => state.locale);
const [currentIndex, setCurrentIndex] = useState(0);
const [isGiftAmountBottomSheetOpen, setIsGiftAmountBottomSheetOpen] = useState(false);
const [isGiftAmountBottomSheetOpen, setIsGiftAmountBottomSheetOpen] =
useState(false);
const { subdomain } = useParams();
const navigate = useNavigate();
const [form] = Form.useForm();
// Find the initial index based on selected cardId from gift details
useEffect(() => {
if (cards && giftDetails?.cardId) {
const index = cards.findIndex(
(card) => card?.id?.toString() === giftDetails.cardId,
(card) => card?.id?.toString() === giftDetails.cardId.toString(),
);
if (index !== -1) {
setCurrentIndex(index);
@@ -53,9 +55,29 @@ export default function CardDetailsPage() {
const currentCard = cards && cards.length > 0 ? cards[currentIndex] : null;
const handleCheckout = useCallback(() => {
const handleCheckout = useCallback(async () => {
try {
await form.validateFields();
navigate(`/${subdomain}/checkout`);
}, [subdomain]);
} catch (error) {
console.log(error);
}
}, [subdomain, form, navigate]);
useEffect(() => {
form.setFieldsValue({
receiverName: giftDetails?.receiverName,
senderName: giftDetails?.senderName,
senderPhone: giftDetails?.senderPhone,
senderEmail: giftDetails?.senderEmail,
receiverPhone: giftDetails?.receiverPhone,
message: giftDetails?.message,
amount: giftDetails?.amount,
cardId: giftDetails?.cardId,
giftType: giftDetails?.giftType,
isSecret: giftDetails?.isSecret,
});
}, [giftDetails?.receiverName, giftDetails?.senderName, form]);
return (
<>
@@ -73,10 +95,14 @@ export default function CardDetailsPage() {
gap: 8,
}}
>
<ProText style={{ fontSize: 16, fontWeight: 600, color: "#333333" }}>
<ProText
style={{ fontSize: 16, fontWeight: 600, color: "#333333" }}
>
{t("cardDetails.addGiftDetails")}
</ProText>
<ProText style={{ fontSize: 14, fontWeight: 400, color: "#95949C" }}>
<ProText
style={{ fontSize: 14, fontWeight: 400, color: "#95949C" }}
>
{t("cardDetails.description")}
</ProText>
</div>
@@ -131,10 +157,15 @@ export default function CardDetailsPage() {
</div>
)}
<Form
form={form}
layout="vertical"
style={{ display: "flex", flexDirection: "column", gap: 16 }}
>
{giftDetails?.giftType !== "items" && <GiftAmountCard onOpen={() => setIsGiftAmountBottomSheetOpen(true)} />}
{giftDetails?.giftType !== "items" && (
<GiftAmountCard
onOpen={() => setIsGiftAmountBottomSheetOpen(true)}
/>
)}
<ReceivernformationCard />
<SenderformationCard />
<TimeEstimateCard />
@@ -151,7 +182,10 @@ export default function CardDetailsPage() {
</Button>
</Layout.Footer>
</Layout>
<GiftAmountBottomSheet isOpen={isGiftAmountBottomSheetOpen} onClose={() => setIsGiftAmountBottomSheetOpen(false)} />
<GiftAmountBottomSheet
isOpen={isGiftAmountBottomSheetOpen}
onClose={() => setIsGiftAmountBottomSheetOpen(false)}
/>
</>
);
}

View File

@@ -24,9 +24,11 @@ export function GiftAmountBottomSheet({
}: SplitBillChoiceBottomSheetProps) {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const { giftDetails, } = useAppSelector(selectCart);
const { giftDetails } = useAppSelector(selectCart);
const [amount, setAmount] = useState<string>(
giftDetails?.amount && giftDetails?.amount > 0 ? giftDetails?.amount?.toString() : "",
giftDetails?.amount && giftDetails?.amount > 0
? giftDetails?.amount?.toString()
: "",
);
const handleSave = () => {
@@ -35,7 +37,6 @@ export function GiftAmountBottomSheet({
onClose();
};
return (
<ProBottomSheet
isOpen={isOpen}
@@ -51,13 +52,12 @@ export function GiftAmountBottomSheet({
>
<div
style={{
padding: "20px",
padding: "20px 20px 0 20px",
display: "flex",
flexDirection: "column",
gap: 20,
}}
>
<div style={{ display: "flex", flexDirection: "column", gap: 5 }}>
<div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
<ProText
style={{
fontWeight: 400,
@@ -65,7 +65,7 @@ export function GiftAmountBottomSheet({
fontSize: 16,
lineHeight: "140%",
letterSpacing: "0%",
color:"#333333"
color: "#333333",
}}
>
{t("cardDetails.enterCustomOucherAmount")}
@@ -75,12 +75,24 @@ export function GiftAmountBottomSheet({
value={amount}
onChange={(value) => {
setAmount(value?.toString() || "");
dispatch(updateSplitBillAmount(Number(value) || 0));
dispatch(updateGiftDetails({ amount: Number(value) || 0 }));
}}
placeholder={t("cardDetails.amount")}
min={0}
/>
</Form.Item>
<ProText
style={{
fontWeight: 500,
fontStyle: "Medium",
fontSize: 12,
lineHeight: "140%",
letterSpacing: "0%",
color: "#B1B0B6",
}}
>
{t("cardDetails.minimumAmountShouldBe1OMR")}
</ProText>
</div>
</div>

View File

@@ -16,3 +16,9 @@
gap: 8px;
}
}
.editIcon {
position: absolute;
top: -7px;
right: 5px;
}

View File

@@ -5,23 +5,52 @@ import styles from "./GiftAmountCard.module.css";
import ArabicPrice from "components/ArabicPrice";
import ProText from "components/ProText";
import EditIcon from "components/Icons/EditIcon";
import { useAppDispatch, useAppSelector } from "redux/hooks";
import { updateGiftDetails } from "features/order/orderSlice";
import { useState, useEffect, useMemo } from "react";
export default function GiftAmountCard({ onOpen }: { onOpen: () => void }) {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const { giftDetails } = useAppSelector((state) => state.order);
const [selectedAmount, setSelectedAmount] = useState<number | null>(null);
useEffect(() => {
const amount = giftDetails?.amount;
if (amount === 10 || amount === 20 || amount === 30) {
setSelectedAmount(amount);
} else {
setSelectedAmount(null);
}
}, [giftDetails?.amount]);
const handleAmountClick = (amount: number) => {
setSelectedAmount(amount);
dispatch(updateGiftDetails({ amount }));
};
const isDefaultAmount = useMemo(() => {
const amount = giftDetails?.amount;
return amount === 10 || amount === 20 || amount === 30;
}, [giftDetails?.amount]);
return (
<ProInputCard title={t("cardDetails.eCardAmount")}>
<div className={styles.customerInformationCard}>
<Button
onClick={() => handleAmountClick(10)}
style={{
borderRadius: 100,
height: 40,
border: "none",
backgroundColor: "#5F6C7B0D",
backgroundColor:
selectedAmount === 10 && isDefaultAmount
? "#FFB7001F"
: "#5F6C7B0D",
}}
>
<ArabicPrice
price={10.00}
price={10.0}
textStyle={{
fontWeight: 500,
fontStyle: "Medium",
@@ -29,20 +58,27 @@ export default function GiftAmountCard({ onOpen }: { onOpen: () => void }) {
lineHeight: "140%",
letterSpacing: "0%",
textAlign: "center",
color: "#5F6C7B",
color:
selectedAmount === 10 && isDefaultAmount
? "#CC9300"
: "#5F6C7B",
}}
/>
</Button>
<Button
onClick={() => handleAmountClick(20)}
style={{
borderRadius: 100,
height: 40,
border: "none",
backgroundColor: "#5F6C7B0D",
backgroundColor:
selectedAmount === 20 && isDefaultAmount
? "#FFB7001F"
: "#5F6C7B0D",
}}
>
<ArabicPrice
price={20.00}
price={20.0}
textStyle={{
fontWeight: 500,
fontStyle: "Medium",
@@ -50,20 +86,27 @@ export default function GiftAmountCard({ onOpen }: { onOpen: () => void }) {
lineHeight: "140%",
letterSpacing: "0%",
textAlign: "center",
color: "#5F6C7B",
color:
selectedAmount === 20 && isDefaultAmount
? "#CC9300"
: "#5F6C7B",
}}
/>
</Button>
<Button
onClick={() => handleAmountClick(30)}
style={{
borderRadius: 100,
height: 40,
border: "none",
backgroundColor: "#5F6C7B0D",
backgroundColor:
selectedAmount === 30 && isDefaultAmount
? "#FFB7001F"
: "#5F6C7B0D",
}}
>
<ArabicPrice
price={30.00}
price={30.0}
textStyle={{
fontWeight: 500,
fontStyle: "Medium",
@@ -71,7 +114,10 @@ export default function GiftAmountCard({ onOpen }: { onOpen: () => void }) {
lineHeight: "140%",
letterSpacing: "0%",
textAlign: "center",
color: "#5F6C7B",
color:
selectedAmount === 30 && isDefaultAmount
? "#CC9300"
: "#5F6C7B",
}}
/>
</Button>
@@ -83,23 +129,36 @@ export default function GiftAmountCard({ onOpen }: { onOpen: () => void }) {
width: "100%",
height: 40,
border: "none",
backgroundColor: "#030014",
backgroundColor:
giftDetails?.amount && !isDefaultAmount ? "#FFB7001F" : "#030014",
}}
icon={<EditIcon className={styles.editIcon} color="#FFF" />}
icon={
giftDetails?.amount && !isDefaultAmount ? (
<EditIcon
className={styles.editIcon}
color={
giftDetails?.amount && !isDefaultAmount ? "#CC9300" : "#FFF"
}
/>
) : undefined
}
iconPlacement="start"
onClick={onOpen}
>
<ProText
style={{
color: "#FFF",
color: giftDetails?.amount && !isDefaultAmount ? "#CC9300" : "#FFF",
fontWeight: 500,
fontStyle: "Medium",
fontSize: 14,
lineHeight: "140%",
letterSpacing: "0%",
textAlign: "center",
}}
>
{t("cardDetails.costumeAmount")}
{giftDetails?.amount && !isDefaultAmount
? giftDetails?.amount
: t("cardDetails.costumeAmount")}
</ProText>
</Button>
</ProInputCard>

View File

@@ -15,7 +15,7 @@ export default function ReceivernformationCard() {
return (
<ProInputCard title={t("cardDetails.receiverInformation")}>
<div className={styles.customerInformationCard}>
<Form.Item name="receiverName">
<Form.Item name="receiverName" rules={[{ required: true, message: t("cardDetails.receiverNameRequired") }]}>
<Input
placeholder={t("cardDetails.receiverName")}
size="large"

View File

@@ -15,7 +15,12 @@ export default function SenderformationCard() {
return (
<ProInputCard title={t("cardDetails.yourInformation")}>
<div className={styles.customerInformationCard}>
<Form.Item name="senderName">
<Form.Item
name="senderName"
rules={[
{ required: true, message: t("cardDetails.senderNameRequired") },
]}
>
<Input
placeholder={t("cardDetails.yourName")}
size="large"

View File

@@ -57,6 +57,8 @@ export default function ECardList() {
display: "grid",
gridTemplateColumns: "1fr 1fr",
padding: "8px",
placeItems: "center",
gap: "8px",
}}
>
{eGiftCards?.map((card: EGiftCard) => (

View File

@@ -3,6 +3,7 @@
transition: all 0.3s ease;
overflow: auto;
scrollbar-width: none;
height: calc(92vh - 80px);
}
.cartLayout {

View File

@@ -64,11 +64,6 @@ export default function TableNumberCard() {
>
{isEditing || table === "" ? (
<Form.Item
label={
orderType === OrderType.DineIn
? t("cart.tableNumber")
: t("cart.selectCompany")
}
name="table"
required
rules={[
@@ -81,7 +76,6 @@ export default function TableNumberCard() {
},
]}
initialValue={table}
style={{ position: "relative", top: -5 }}
>
<Select
value={table}
@@ -103,9 +97,8 @@ export default function TableNumberCard() {
borderRadius: 888,
}}
onChange={(value) => {
console.log(value);
dispatch(updateTables(value));
setIsEditing(false);
if(value) setIsEditing(false);
}}
onClear={() => {
dispatch(removeTable());

View File

@@ -29,7 +29,7 @@ export default function SpecialRequestCard() {
return (
<>
<ProInputCard
title={t("cart.specialRequest")}
title={t("cart.addSpecialRequestOptional")}
dividerStyle={{ margin: "5px 0 0 0" }}
>
<Form.Item name="specialRequest" style={{ marginTop: 12 }}>

View File

@@ -117,17 +117,6 @@ export default function YouMightAlsoLike() {
return (
<>
<div className={styles.youMightAlsoLikeTitle}>
<ProText
strong
style={{
fontSize: isMobile ? 18 : isTablet ? 18 : 20,
}}
>
{t("cart.youMightAlsoLike")}
</ProText>
</div>
<div
style={{
position: "relative",

View File

@@ -32,14 +32,13 @@ export default function BriefMenuCard() {
<>
<ProInputCard
title={t("checkout.orderSummary")}
dividerStyle={{ margin: "5px 0 0 0" }}
dividerStyle={{ margin: "3px 0 16px 0" }}
>
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
padding: "16px 0",
}}
onClick={() => {
if (orderId && location.pathname.includes("/order/")) {

View File

@@ -11,9 +11,10 @@ import { useNavigate, useParams } from "react-router-dom";
import InvoiceIcon from "components/Icons/order/InvoiceIcon";
import BackIcon from "components/Icons/BackIcon";
import NextIcon from "components/Icons/NextIcon";
import { useMemo } from "react";
import { useMemo, useState } from "react";
import CardAmountIcon from "components/Icons/CardAmountIcon";
import ArabicPrice from "components/ArabicPrice";
import { GiftAmountBottomSheet } from "pages/CardDetails/components/GiftAmountBottomSheet";
export function GiftCard() {
const { t } = useTranslation();
@@ -28,13 +29,32 @@ export function GiftCard() {
const totalItems = useMemo(() => {
return items.length || 0;
}, [items]);
const [isGiftAmountBottomSheetOpen, setIsGiftAmountBottomSheetOpen] =
useState(false);
return (
<>
<ProInputCard title={t("address.giftDetails")}>
<div className={styles.orderNotes}>
<Image src={currentCard?.imageURL} height={42} width={64} style={{height: 42, width: 64}} />
<div style={{ display: "flex", flexDirection: "column", gap: 4, width: "100%" }}>
<div
className={styles.orderNotes}
onClick={() => {
navigate(`/${subdomain}/card-details`);
}}
>
<Image
src={currentCard?.imageURL}
height={42}
width={64}
style={{ height: 42, width: 64 }}
/>
<div
style={{
display: "flex",
flexDirection: "column",
gap: 4,
width: "100%",
}}
>
<ProText
style={{
fontWeight: 500,
@@ -90,7 +110,65 @@ export function GiftCard() {
</div>
<Divider style={{ margin: "10px 0" }} />
{giftDetails?.giftType === "items" && (
{giftDetails?.giftType === "vouchers" ||
(giftDetails?.giftType === "itemsAndVouchers" && (
<div
className={styles.orderNotes}
onClick={() => {
setIsGiftAmountBottomSheetOpen(true);
}}
>
<div
style={{
height: 42,
width: 64,
backgroundColor: "var(--background)",
borderRadius: 8,
}}
>
<CardAmountIcon />
</div>
<div
style={{
display: "flex",
flexDirection: "column",
gap: 4,
width: "100%",
}}
>
<ProText
style={{
fontWeight: 500,
fontStyle: "Medium",
fontSize: 14,
lineHeight: "140%",
letterSpacing: "0%",
color: "#777580",
}}
>
{t("checkout.cardBalance")}
</ProText>
<ProText
style={{
fontWeight: 500,
fontStyle: "Medium",
fontSize: 14,
lineHeight: "140%",
letterSpacing: "0%",
color: "#333333",
}}
>
<ArabicPrice price={giftDetails?.amount || 0} />
</ProText>
</div>
{isRTL ? <BackIcon iconSize={24} /> : <NextIcon iconSize={24} />}
</div>
))}
<Divider style={{ margin: "10px 0" }} />
{giftDetails?.giftType === "items" ||
(giftDetails?.giftType === "itemsAndVouchers" && (
<div
style={{
display: "flex",
@@ -125,58 +203,12 @@ export function GiftCard() {
</ProText>
{isRTL ? <BackIcon /> : <NextIcon />}
</div>
)}
{giftDetails?.giftType === "vouchers" && (
<div className={styles.orderNotes}>
<div
style={{
height: 42,
width: 64,
backgroundColor: "var(--background)",
borderRadius: 8,
}}
>
<CardAmountIcon />
</div>
<div
style={{
display: "flex",
flexDirection: "column",
gap: 4,
width: "100%",
}}
>
<ProText
style={{
fontWeight: 500,
fontStyle: "Medium",
fontSize: 14,
lineHeight: "140%",
letterSpacing: "0%",
color: "#777580",
}}
>
{t("checkout.giftSummary")}
</ProText>
<ProText
style={{
fontWeight: 500,
fontStyle: "Medium",
fontSize: 14,
lineHeight: "140%",
letterSpacing: "0%",
color: "#333333",
}}
>
<ArabicPrice price={giftDetails?.amount || 0} />
</ProText>
</div>
{isRTL ? <BackIcon iconSize={24} /> : <NextIcon iconSize={24} />}
</div>
)}
))}
</ProInputCard>
<GiftAmountBottomSheet
isOpen={isGiftAmountBottomSheetOpen}
onClose={() => setIsGiftAmountBottomSheetOpen(false)}
/>
</>
);
}

View File

@@ -39,6 +39,7 @@ export default function useOrder() {
pickupTime,
pickupDate,
pickupType,
giftDetails,
order,
} = useAppSelector(selectCart);
const highestLoyaltyItem = useAppSelector(selectHighestPricedLoyaltyItem);
@@ -70,7 +71,7 @@ export default function useOrder() {
});
createOrder({
phone: mobilenumber || phone || order?.senderPhone,
phone: mobilenumber || phone || giftDetails?.senderPhone,
comment: specialRequest,
delivery_method: getDeliveryMethod(),
timeslot: "",
@@ -112,13 +113,13 @@ export default function useOrder() {
delivery_address: location?.address,
...(orderType === OrderType.Gift
? {
receiverName: order?.receiverName,
receiverPhone: order?.receiverPhone,
specialMessage: order?.message,
keepNameSecret: order?.isSecret,
senderEmail: order?.senderEmail,
senderPhone: order?.senderPhone,
senderName: order?.senderName,
receiverName: giftDetails?.receiverName,
receiverPhone: giftDetails?.receiverPhone,
specialMessage: giftDetails?.message,
keepNameSecret: giftDetails?.isSecret,
senderEmail: giftDetails?.senderEmail,
senderPhone: giftDetails?.senderPhone,
senderName: giftDetails?.senderName,
dineType: orderType,
}
: {}),
@@ -173,7 +174,7 @@ export default function useOrder() {
orderType,
restaurantID,
items,
order,
giftDetails,
discount.isDiscount,
discount.isGift,
discount.value,

View File

@@ -53,7 +53,7 @@ export default function OrderDetails() {
alignItems: "center",
justifyContent: "space-between",
height: "100%",
padding: 8
padding: 8,
}}
>
<Space orientation="vertical" size="small">
@@ -123,10 +123,20 @@ export default function OrderDetails() {
[isRTL ? "right" : "left"]: 8,
}}
>
<ArabicPrice
price={item.price}
style={{ fontStyle: "bold" }}
/>
<Button
shape="circle"
iconPlacement="start"
size="small"
className={styles.addButton}
style={{
background: "#F5F5F6",
width: 28,
height: 28,
border: "none",
}}
>
<ProText style={{color: "#1F1C2E"}}>{item.qty} </ProText>
</Button>
</div>
</Space>
<div style={{ position: "relative" }}>

View File

@@ -0,0 +1,146 @@
import { Button } from "antd";
import { ProBottomSheet } from "components/ProBottomSheet/ProBottomSheet.tsx";
import { useTranslation } from "react-i18next";
import { useAppSelector } from "redux/hooks";
import ProText from "components/ProText";
import ArabicPrice from "components/ArabicPrice";
import styles from "../order.module.css";
import NextIcon from "components/Icons/NextIcon";
import BackIcon from "components/Icons/BackIcon";
interface SplitBillParticipantsBottomSheetProps {
isOpen: boolean;
onClose: () => void;
}
export function SplitBillParticipantsBottomSheet({
isOpen,
onClose,
}: SplitBillParticipantsBottomSheetProps) {
const { t } = useTranslation();
const { isRTL } = useAppSelector((state) => state.locale);
const taxesChargesStyle = {
fontWeight: 400,
fontStyle: "Regular",
fontSize: 12,
lineHeight: "140%",
letterSpacing: "0%",
color: "#777580",
};
return (
<ProBottomSheet
isOpen={isOpen}
onClose={onClose}
title={t("order.whosPaidTheirShareSplitBill")}
showCloseButton={true}
initialSnap={1}
height={285}
snapPoints={[285]}
contentStyle={{
padding: 0,
}}
>
<div
style={{
padding: "20px",
display: "flex",
flexDirection: "column",
gap: 20,
}}
>
<div className={styles.inviteToBill}>
<Button
shape="circle"
iconPlacement="start"
size="small"
className={styles.addButton}
style={{
background: "#F9F9FA",
width: 28,
height: 28,
border: "none",
color: "#FFB700",
}}
>
<ProText style={{ color: "#1F1C2E" }}> 1 </ProText>
</Button>
<div
style={{
display: "flex",
flexDirection: "column",
gap: 4,
width: "100%",
}}
>
<ProText
style={{
fontWeight: 500,
fontStyle: "Medium",
fontSize: 14,
lineHeight: "140%",
letterSpacing: "0%",
color: "#777580",
}}
>
{t("order.personHasPaid")}
</ProText>
</div>
{isRTL ? <BackIcon iconSize={24} /> : <NextIcon iconSize={24} />}
</div>
</div>
<div
style={{
display: "flex",
flexDirection: "column",
backgroundColor: "var(--background)",
padding: "20px",
opacity: 1,
gap: 8,
borderTopLeftRadius: 24,
borderTopRightRadius: 24,
paddingTop: 12,
paddingRight: 24,
paddingBottom: 24,
paddingLeft: 24,
}}
>
<div className={styles.summaryRow}>
<ProText style={taxesChargesStyle}>
{t("splitBill.totalBill")}
</ProText>
<ArabicPrice price={0} textStyle={taxesChargesStyle} />
</div>
<div className={styles.summaryRow}>
<ProText style={taxesChargesStyle}>
{t("splitBill.serviceFee")}
</ProText>
<ArabicPrice price={0} textStyle={taxesChargesStyle} />
</div>
<div className={styles.summaryRow}>
<ProText
style={{
fontWeight: 400,
fontStyle: "Regular",
fontSize: 14,
lineHeight: "140%",
letterSpacing: "0%",
}}
>
{t("splitBill.remainingToPay")}
</ProText>
<ArabicPrice
price={0}
textStyle={taxesChargesStyle}
/>
</div>
<ProText style={taxesChargesStyle}>
{t("splitBill.includesAllOfTaxesCharges")}
</ProText>
</div>
</ProBottomSheet>
);
}

View File

@@ -112,7 +112,17 @@ export default function Stepper({ statuses = [] }: StepperProps) {
{steps.map((step, index) => (
<Fragment key={`label-${step.key}`}>
<Col>
<ProText type={step.isPending ? "secondary" : undefined}>
<ProText
style={{
fontWeight: 400,
fontStyle: "Regular",
fontSize: 14,
lineHeight: "140%",
letterSpacing: "0%",
textAlign: "center",
color: step.isPending ? "#99A2AE" : "#333333",
}}
>
{step.label}
</ProText>
</Col>

View File

@@ -348,3 +348,13 @@
:global(.darkApp) .checkoutButtonContainer {
background-color: #000000 !important;
}
.inviteToBill {
gap: 16px;
opacity: 1;
border-radius: 6px;
display: flex;
flex-direction: row;
justify-content: flex-start;
place-items: center;
}

View File

@@ -37,6 +37,8 @@ import { QRBottomSheet } from "pages/pay/components/splitBill/QRBottomSheet";
import NewRateIcon from "components/Icons/order/NewRateIcon";
import NoteIcon from "components/Icons/NoteIcon";
import SuccessIcon from "components/Icons/SuccessIcon";
import ProInputCard from "components/ProInputCard/ProInputCard";
import { SplitBillParticipantsBottomSheet } from "./components/SplitBillParticipantsBottomSheet";
export default function OrderPage() {
const { t } = useTranslation();
@@ -47,7 +49,7 @@ export default function OrderPage() {
const hasRefetchedRef = useRef(false);
const [isOpen, setIsOpen] = useState(false);
const [isRateOrderOpen, setIsRateOrderOpen] = useState(false);
const [isSplitBillParticipantsBottomSheetOpen, setIsSplitBillParticipantsBottomSheetOpen] = useState(false);
const { data: orderDetails } = useGetOrderDetailsQuery(
{
orderID: orderId || "",
@@ -242,28 +244,31 @@ export default function OrderPage() {
display: "flex",
flexDirection: "row",
gap: "1rem",
backgroundColor: "rgba(255, 183, 0, 0.08)",
backgroundColor: "#f5f5f6",
borderRadius: "12px",
padding: 16,
}}
>
<Button
type="text"
shape="circle"
style={{
backgroundColor: "rgba(255, 183, 0, 0.08)",
}}
>
<Button type="text" shape="circle">
<Image
src={orderDetails?.restaurant_iimage}
className={styles.profileImage}
width={50}
height={50}
width={40}
height={40}
preview={false}
/>
</Button>
<div>
<ProText style={{ fontSize: "1rem" }}>
<ProText
style={{
fontFamily: "Bold/Caption Bold",
fontSize: "12px",
lineHeight: "140%",
letterSpacing: "0%",
fontWeight: "bold",
color: "#434E5C",
}}
>
{t("order.yourOrderFromFascanoRestaurant")}
</ProText>
<br />
@@ -319,27 +324,61 @@ export default function OrderPage() {
</Tooltip>
</Flex>
) : (
<div style={{ margin: "56px 0" }}>
<OrderDishIcon className={styles.orderDishIcon} />
</div>
)}
<div>
<ProTitle
level={5}
style={{
fontWeight: 600,
fontSize: "18px",
fontWeight: 500,
fontStyle: "Medium",
fontSize: 18,
lineHeight: "140%",
letterSpacing: "0%",
marginBottom: "0.75rem",
color: "#333333",
}}
>
{t("order.inProgressOrder")} (1)
</ProTitle>
<div style={{ display: "flex", flexDirection: "row", gap: 8 }}>
<div
style={{
display: "flex",
flexDirection: "row",
gap: 8,
}}
>
<InvoiceIcon className={styles.invoiceIcon} />
<ProText type="secondary" style={{ fontSize: "14px" }}>
<ProText
type="secondary"
style={{
fontWeight: 400,
fontStyle: "Regular",
fontSize: 14,
lineHeight: "140%",
letterSpacing: "0%",
textAlign: "center",
color: "#333333",
}}
>
#{orderDetails?.order.id}
</ProText>
<TimeIcon className={styles.timeIcon} />
<ProText type="secondary" style={{ fontSize: "14px" }}>
<ProText
type="secondary"
style={{
fontWeight: 400,
fontStyle: "Regular",
fontSize: 14,
lineHeight: "140%",
letterSpacing: "0%",
textAlign: "center",
color: "#333333",
}}
>
ordered :- Today -{" "}
{dayjs(orderDetails?.status[0]?.pivot?.created_at).format(
"h:mm A",
@@ -459,31 +498,122 @@ export default function OrderPage() {
<PaymentDetails order={orderDetails?.order} />
<Card
className={styles.inviteToBillCard}
onClick={() => setIsOpen(true)}
>
{/* inviteToBill */}
{!hasClosedStatus && (
<ProInputCard
title={
<>
<div
style={{
display: "flex",
flexDirection: "column",
marginBottom: 9,
gap: 2 ,
}}
>
<ProText
style={{
fontSize: "18px",
fontWeight: 500,
fontStyle: "Medium",
lineHeight: "140%",
letterSpacing: "0%",
color: "#333333",
}}
>
{t("order.whosPaidTheirShareSplitBill")}
</ProText>
<ProText
style={{
fontWeight: 400,
fontStyle: "Regular",
fontSize: 12,
lineHeight: "140%",
letterSpacing: "0%",
color: "#777580",
}}
>
{t("order.seeWhoPaidAndHowMuch")}
</ProText>
</div>
</>
}
>
<div className={styles.inviteToBill}
onClick={() => setIsSplitBillParticipantsBottomSheetOpen(true)}>
<Button
shape="circle"
iconPlacement="start"
size="small"
className={styles.addButton}
style={{
background: "#F9F9FA",
width: 28,
height: 28,
border: "none",
color: "#FFB700",
}}
>
<ProText style={{ color: "#1F1C2E" }}> 1 </ProText>
</Button>
<div
style={{
display: "flex",
flexDirection: "column",
gap: 4,
width: "100%",
}}
>
<ProText
style={{
fontWeight: 500,
fontStyle: "Medium",
fontSize: 14,
lineHeight: "140%",
letterSpacing: "0%",
color: "#777580",
}}
>
{t("order.personHasPaid")}
</ProText>
</div>
{isRTL ? (
<BackIcon iconSize={24} />
) : (
<NextIcon iconSize={24} />
)}
</div>
<Button
type="text"
style={{
height: 48,
width: "100%",
display: "flex",
flexDirection: "row",
justifyContent: "center",
marginTop: 1,
alignItems: "center",
gap: 8,
border: "1px solid #C0BFC4",
borderRadius: 888,
marginTop: 16,
}}
onClick={() => setIsOpen(true)}
>
<div style={{ display: "flex", flexDirection: "row", gap: 10 }}>
<ProTitle
level={5}
<ProText
style={{
marginTop: 1,
fontSize: 14,
fontWeight: 400,
fontStyle: "Regular",
fontSize: 16,
lineHeight: "140%",
letterSpacing: "0%",
color: "#333333",
}}
>
{t("order.inviteToBill")}
</ProTitle>
</div>
</div>
</Card>
{t("order.inviteOthersToBill")}
</ProText>
</Button>
</ProInputCard>
)}
<QRBottomSheet isOpen={isOpen} onClose={() => setIsOpen(false)} />
@@ -532,8 +662,9 @@ export default function OrderPage() {
onClose={() => setIsRateOrderOpen(false)}
/>
<CancelOrderBottomSheet />
{!hasClosedStatus && <CancelOrderBottomSheet />}
</Layout.Content>
{hasClosedStatus && (
<Layout.Footer className={styles.checkoutButtonContainer}>
<Button
type="primary"
@@ -546,7 +677,9 @@ export default function OrderPage() {
{t("order.newOrder")}
</Button>
</Layout.Footer>
)}
</Layout>
<SplitBillParticipantsBottomSheet isOpen={isSplitBillParticipantsBottomSheetOpen} onClose={() => setIsSplitBillParticipantsBottomSheetOpen(false)} />
</>
);
}

1193
yarn.lock

File diff suppressed because it is too large Load Diff