Compare commits
3 Commits
1c5c212574
...
102415fe8b
| Author | SHA1 | Date | |
|---|---|---|---|
| 102415fe8b | |||
| f294138d30 | |||
| 13cce2f12f |
@@ -83,7 +83,7 @@
|
|||||||
color: var(--secondary-background);
|
color: var(--secondary-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.minusIcon{
|
.minusIcon {
|
||||||
color: var(--secondary-foreground);
|
color: var(--secondary-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -134,9 +134,10 @@ export default function CartActionsButtons({ item }: { item: CartItem }) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
disabled={item.quantity >= 99}
|
||||||
className={styles.addButton}
|
className={styles.addButton}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: colors.primary,
|
backgroundColor: "#FFC600",
|
||||||
width: 28,
|
width: 28,
|
||||||
height: 28,
|
height: 28,
|
||||||
border: "none",
|
border: "none",
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ interface PlusIconType {
|
|||||||
className?: string;
|
className?: string;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
dimesion?: string
|
dimesion?: string
|
||||||
|
color?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const PlusIcon = ({ className, onClick, dimesion }: PlusIconType) => {
|
const PlusIcon = ({ className, onClick, dimesion, color }: PlusIconType) => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
width={dimesion || "16"}
|
width={dimesion || "16"}
|
||||||
@@ -17,7 +18,7 @@ const PlusIcon = ({ className, onClick, dimesion }: PlusIconType) => {
|
|||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
d="M7.99992 3.3335V12.6668M3.33325 8.00016H12.6666"
|
d="M7.99992 3.3335V12.6668M3.33325 8.00016H12.6666"
|
||||||
stroke="#FFD633"
|
stroke={color || "#FFD633"}
|
||||||
strokeWidth="1.5"
|
strokeWidth="1.5"
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
|
|||||||
29
src/components/Icons/RefershIcon.tsx
Normal file
29
src/components/Icons/RefershIcon.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
interface RefershIconType {
|
||||||
|
className?: string;
|
||||||
|
onClick?: () => void;
|
||||||
|
dimension?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RefershIcon = ({ className, onClick, dimension }: RefershIconType) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
width={dimension || "18"}
|
||||||
|
height={dimension || "18"}
|
||||||
|
viewBox="0 0 18 18"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className={className}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M1.5 7.5C1.5 7.5 1.59099 6.86307 4.22703 4.22703C6.86307 1.59099 11.1369 1.59099 13.773 4.22703C14.7069 5.16099 15.31 6.30054 15.5821 7.5M1.5 7.5V3M1.5 7.5H6M16.5 10.5C16.5 10.5 16.409 11.1369 13.773 13.773C11.1369 16.409 6.86307 16.409 4.22703 13.773C3.29307 12.839 2.69002 11.6995 2.41787 10.5M16.5 10.5V15M16.5 10.5H12"
|
||||||
|
stroke="#5F6C7B"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RefershIcon;
|
||||||
@@ -3,16 +3,25 @@
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
gap: 10px;
|
gap: 8px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50px;
|
top: 50px;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
|
right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-app-rtl) .languageSwitch {
|
:global(.ant-app-rtl) .languageSwitch {
|
||||||
left: 0;
|
left: 0;
|
||||||
|
right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-app-ltr) .languageSwitch {
|
.refreshIcon {
|
||||||
right: 0;
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.ant-app-rtl) .refreshIcon {
|
||||||
|
margin-left: 3px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { useDispatch } from "react-redux";
|
|||||||
import { useAppSelector } from "redux/hooks";
|
import { useAppSelector } from "redux/hooks";
|
||||||
import ProText from "../ProText";
|
import ProText from "../ProText";
|
||||||
import styles from "./LanguageSwitch.module.css";
|
import styles from "./LanguageSwitch.module.css";
|
||||||
|
import RefershIcon from "components/Icons/RefershIcon";
|
||||||
|
|
||||||
export function LanguageSwitch() {
|
export function LanguageSwitch() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@@ -23,11 +24,15 @@ export function LanguageSwitch() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const refreshPage = () => {
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.languageSwitch}>
|
<div className={styles.languageSwitch}>
|
||||||
<GlobalOutlined
|
<GlobalOutlined
|
||||||
style={{
|
style={{
|
||||||
color: themeName === "dark" ? "#fff" : "#434E5C",
|
color: themeName === "dark" ? "#fff" : "#333333",
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
marginRight: 3,
|
marginRight: 3,
|
||||||
cursor: isPending ? "wait" : "pointer",
|
cursor: isPending ? "wait" : "pointer",
|
||||||
@@ -37,23 +42,19 @@ export function LanguageSwitch() {
|
|||||||
/>
|
/>
|
||||||
<ProText
|
<ProText
|
||||||
style={{
|
style={{
|
||||||
color: themeName === "dark" ? "#fff" : "#434E5C",
|
color: themeName === "dark" ? "#fff" : "#333333",
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
marginRight: 3,
|
marginRight: 3,
|
||||||
opacity: isPending ? 0.7 : 1,
|
opacity: isPending ? 0.7 : 1,
|
||||||
[isRTL ? "marginLeft" : "marginRight"]: 3,
|
[isRTL ? "marginLeft" : "marginRight"]: 3,
|
||||||
}}
|
}}
|
||||||
|
onClick={changeLanguage}
|
||||||
>
|
>
|
||||||
{isPending ? "..." : isRTL ? "English" : "Arabic"}
|
{isPending ? "..." : isRTL ? "English" : "Arabic"}
|
||||||
</ProText>
|
</ProText>
|
||||||
<ShakeOutlined
|
<div onClick={refreshPage}>
|
||||||
style={{
|
<RefershIcon dimension={18} className={styles.refreshIcon} />
|
||||||
color: themeName === "dark" ? "#fff" : "#434E5C",
|
</div>
|
||||||
fontSize: 15,
|
|
||||||
marginRight: 3,
|
|
||||||
[isRTL ? "marginLeft" : "marginRight"]: 3,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,12 +42,22 @@ export function ScrollHandlerProvider({ children }: { children: ReactNode }) {
|
|||||||
const scrollToCategory = useCallback((categoryId: number) => {
|
const scrollToCategory = useCallback((categoryId: number) => {
|
||||||
const categoryRef = categoryRefs.current?.[categoryId];
|
const categoryRef = categoryRefs.current?.[categoryId];
|
||||||
if (categoryRef) {
|
if (categoryRef) {
|
||||||
categoryRef.scrollIntoView({
|
// Get the sticky header height (70px when sticky, 0 when not)
|
||||||
|
const stickyHeaderHeight = isCategoriesSticky && categoriesContainerRef.current
|
||||||
|
? categoriesContainerRef.current.offsetHeight
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
// Calculate the position of the category element
|
||||||
|
const elementPosition = categoryRef.getBoundingClientRect().top;
|
||||||
|
const offsetPosition = elementPosition + window.pageYOffset - stickyHeaderHeight;
|
||||||
|
|
||||||
|
// Scroll to the exact position, accounting for sticky header
|
||||||
|
window.scrollTo({
|
||||||
|
top: offsetPosition,
|
||||||
behavior: "smooth",
|
behavior: "smooth",
|
||||||
block: "start",
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, []);
|
}, [isCategoriesSticky, categoriesContainerRef]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollHandlerContext.Provider
|
<ScrollHandlerContext.Provider
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ export const CART_STORAGE_KEYS = {
|
|||||||
HIDDEN_SERVICES: "fascano_hidden_services",
|
HIDDEN_SERVICES: "fascano_hidden_services",
|
||||||
VISIBLE_SERVICES: "fascano_visible_services",
|
VISIBLE_SERVICES: "fascano_visible_services",
|
||||||
ESTIMATE_WAY: "fascano_estimate_way",
|
ESTIMATE_WAY: "fascano_estimate_way",
|
||||||
|
CUSTOMER_NAME: "fascano_customer_name",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// Utility functions for localStorage
|
// Utility functions for localStorage
|
||||||
@@ -201,7 +202,7 @@ const initialState: CartState = {
|
|||||||
estimateWay: getFromLocalStorage(CART_STORAGE_KEYS.ESTIMATE_WAY, ""),
|
estimateWay: getFromLocalStorage(CART_STORAGE_KEYS.ESTIMATE_WAY, ""),
|
||||||
order: getFromLocalStorage(CART_STORAGE_KEYS.ORDER, null),
|
order: getFromLocalStorage(CART_STORAGE_KEYS.ORDER, null),
|
||||||
splitBillAmount: 0,
|
splitBillAmount: 0,
|
||||||
customerName: "",
|
customerName: getFromLocalStorage(CART_STORAGE_KEYS.CUSTOMER_NAME, ""),
|
||||||
totalServices: 8,
|
totalServices: 8,
|
||||||
hiddenServices: 0,
|
hiddenServices: 0,
|
||||||
visibleServices: 0,
|
visibleServices: 0,
|
||||||
@@ -363,6 +364,19 @@ const orderSlice = createSlice({
|
|||||||
state.collectionMethod = "";
|
state.collectionMethod = "";
|
||||||
state.paymentMethod = "";
|
state.paymentMethod = "";
|
||||||
state.loyaltyValidationError = null;
|
state.loyaltyValidationError = null;
|
||||||
|
state.discount = {
|
||||||
|
value: 0,
|
||||||
|
isGift: false,
|
||||||
|
isDiscount: false,
|
||||||
|
};
|
||||||
|
state.plateCar = "";
|
||||||
|
state.pickupDate = "";
|
||||||
|
state.pickupTime = "";
|
||||||
|
state.pickupType = "";
|
||||||
|
state.estimateWay = "";
|
||||||
|
state.order = null;
|
||||||
|
state.splitBillAmount = 0;
|
||||||
|
state.customerName = "";
|
||||||
// Clear all cart data from localStorage
|
// Clear all cart data from localStorage
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
Object.values(CART_STORAGE_KEYS)
|
Object.values(CART_STORAGE_KEYS)
|
||||||
@@ -701,6 +715,12 @@ const orderSlice = createSlice({
|
|||||||
},
|
},
|
||||||
updateCustomerName(state, action: PayloadAction<string>) {
|
updateCustomerName(state, action: PayloadAction<string>) {
|
||||||
state.customerName = action.payload;
|
state.customerName = action.payload;
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
localStorage.setItem(
|
||||||
|
CART_STORAGE_KEYS.CUSTOMER_NAME,
|
||||||
|
JSON.stringify(state.customerName),
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import ProInputCard from "components/ProInputCard/ProInputCard.tsx";
|
import ProInputCard from "components/ProInputCard/ProInputCard.tsx";
|
||||||
import ProPhoneInput from "components/ProPhoneInput";
|
import ProPhoneInput from "components/ProPhoneInput";
|
||||||
import { selectCart, updateCustomerName } from "features/order/orderSlice";
|
import {
|
||||||
|
selectCart,
|
||||||
|
updateCustomerName,
|
||||||
|
updatePhone,
|
||||||
|
} from "features/order/orderSlice";
|
||||||
import { OrderType } from "pages/checkout/hooks/types.ts";
|
import { OrderType } from "pages/checkout/hooks/types.ts";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useAppDispatch, useAppSelector } from "redux/hooks";
|
import { useAppDispatch, useAppSelector } from "redux/hooks";
|
||||||
@@ -9,9 +13,12 @@ import styles from "./CustomerInformationCard.module.css";
|
|||||||
|
|
||||||
export default function CustomerInformationCard() {
|
export default function CustomerInformationCard() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { orderType } = useAppSelector(selectCart);
|
const { orderType, customerName, phone } = useAppSelector(selectCart);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const customerName = useAppSelector((state) => state.order.customerName);
|
|
||||||
|
const setPhone = (value: string) => {
|
||||||
|
dispatch(updatePhone(value));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
orderType !== OrderType.Gift && (
|
orderType !== OrderType.Gift && (
|
||||||
@@ -30,7 +37,7 @@ export default function CustomerInformationCard() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<ProPhoneInput propName="phone" />
|
<ProPhoneInput propName="phone" value={phone} onChange={setPhone} />
|
||||||
</div>
|
</div>
|
||||||
</ProInputCard>
|
</ProInputCard>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -24,13 +24,13 @@ import { useEffect } from "react";
|
|||||||
export default function CheckoutPage() {
|
export default function CheckoutPage() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const { phone, order, orderType, collectionMethod, coupon } =
|
const { phone, order, orderType, collectionMethod, coupon, customerName } =
|
||||||
useAppSelector(selectCart);
|
useAppSelector(selectCart);
|
||||||
const { token } = useAppSelector((state) => state.auth);
|
const { token } = useAppSelector((state) => state.auth);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
form.setFieldsValue({ coupon, collectionMethod });
|
form.setFieldsValue({ coupon, collectionMethod, phone, customerName });
|
||||||
}, [form, phone]);
|
}, [form, phone, coupon, collectionMethod, customerName]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,25 +1,93 @@
|
|||||||
.plusIcon {
|
.quantityControls {
|
||||||
position: relative;
|
display: flex;
|
||||||
top: -1px;
|
align-items: center;
|
||||||
|
background-color: var(--background);
|
||||||
|
border-radius: 888px;
|
||||||
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addButton {
|
.quantityLabel {
|
||||||
position: absolute;
|
font-size: 14px;
|
||||||
z-index: 1;
|
color: var(--secondary-color);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantityInputContainer {
|
||||||
|
display: flex;
|
||||||
|
padding: 0 1px;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 888px;
|
||||||
|
width: 90px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantityButton {
|
||||||
|
padding: 0;
|
||||||
|
width: 28px !important;
|
||||||
|
height: 28px !important;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--secondary-background);
|
||||||
|
background-color: var(--primary);
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantityInput {
|
||||||
|
text-align: center;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
border: 0;
|
padding: 0;
|
||||||
color: #fff;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.actionRect {
|
.removeButton {
|
||||||
fill: var(--background) !important;
|
padding: 4px 0;
|
||||||
|
height: 32px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
width: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addButton svg rect {
|
.deleteButtonContainer {
|
||||||
fill: var(--background) !important;
|
position: absolute;
|
||||||
|
top: 12px;
|
||||||
|
right: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
padding: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.darkApp) .addButton rect {
|
.deleteIcon {
|
||||||
fill: var(--background) !important;
|
font-size: 18px;
|
||||||
|
color: var(--secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cartItemActions :global(.ant-input-number-outlined) {
|
||||||
|
border: none;
|
||||||
|
width: 40px;
|
||||||
|
background-color: inherit;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cartItemActions :global(.ant-input-number-input) {
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plusIcon {
|
||||||
|
margin-bottom: 1px;
|
||||||
|
color: var(--secondary-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.minusIcon {
|
||||||
|
color: var(--secondary-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
.deleteIcon {
|
||||||
|
position: relative;
|
||||||
|
right: 1px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { MinusOutlined, PlusOutlined } from "@ant-design/icons";
|
import { MinusOutlined, PlusOutlined } from "@ant-design/icons";
|
||||||
import { Button, message } from "antd";
|
import { Button, InputNumber, message } from "antd";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import { useGetRestaurantDetailsQuery } from "redux/api/others";
|
import { useGetRestaurantDetailsQuery } from "redux/api/others";
|
||||||
@@ -8,7 +8,7 @@ import { useAppSelector, useAppDispatch } from "redux/hooks";
|
|||||||
import { Product } from "utils/types/appTypes";
|
import { Product } from "utils/types/appTypes";
|
||||||
import NextIcon from "components/Icons/NextIcon";
|
import NextIcon from "components/Icons/NextIcon";
|
||||||
import { addItem, removeItem, updateQuantity } from "features/order/orderSlice";
|
import { addItem, removeItem, updateQuantity } from "features/order/orderSlice";
|
||||||
import ProText from "components/ProText";
|
import PlusIcon from "components/Icons/PlusIcon";
|
||||||
|
|
||||||
export function AddToCartButton({ item }: { item: Product }) {
|
export function AddToCartButton({ item }: { item: Product }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -158,24 +158,24 @@ export function AddToCartButton({ item }: { item: Product }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return isInCart && !hasOptions ? (
|
return (
|
||||||
<>
|
|
||||||
<div
|
<div
|
||||||
className={styles.addButton}
|
className={styles.cartItemActions}
|
||||||
style={{
|
onClick={(e) => {
|
||||||
width: 90,
|
e.stopPropagation();
|
||||||
height: 30,
|
e.preventDefault;
|
||||||
position: "absolute",
|
|
||||||
bottom: 3,
|
|
||||||
[isRTL ? "left" : "right"]: 1,
|
|
||||||
background: "#FAFAFA",
|
|
||||||
borderRadius: 888,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
{isInCart && !hasOptions ? (
|
||||||
|
<>
|
||||||
|
<div className={styles.quantityControls}>
|
||||||
|
<div className={styles.quantityInputContainer}>
|
||||||
<Button
|
<Button
|
||||||
shape="circle"
|
shape="circle"
|
||||||
iconPlacement="start"
|
iconPlacement="start"
|
||||||
icon={<MinusOutlined title="minus" style={{ color: "black" }} />}
|
icon={
|
||||||
|
<MinusOutlined title="minus" style={{ color: "black" }} />
|
||||||
|
}
|
||||||
size="small"
|
size="small"
|
||||||
onClick={handleMinusClick}
|
onClick={handleMinusClick}
|
||||||
className={styles.addButton}
|
className={styles.addButton}
|
||||||
@@ -183,57 +183,49 @@ export function AddToCartButton({ item }: { item: Product }) {
|
|||||||
backgroundColor: "white",
|
backgroundColor: "white",
|
||||||
width: 28,
|
width: 28,
|
||||||
height: 28,
|
height: 28,
|
||||||
position: "absolute",
|
|
||||||
bottom: 1,
|
|
||||||
[isRTL ? "left" : "right"]: 60,
|
|
||||||
minWidth: 28,
|
|
||||||
border: "none",
|
border: "none",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<ProText
|
<InputNumber
|
||||||
style={{
|
min={1}
|
||||||
position: "absolute",
|
max={99}
|
||||||
bottom: 7,
|
value={totalQuantity}
|
||||||
[isRTL ? "left" : "right"]: 45,
|
onClick={(e) => {
|
||||||
fontSize: 14,
|
e.stopPropagation();
|
||||||
fontWeight: 700,
|
e.preventDefault;
|
||||||
fontStyle: "Bold",
|
|
||||||
lineHeight: "100%",
|
|
||||||
letterSpacing: "0.06px",
|
|
||||||
textAlign: "center",
|
|
||||||
verticalAlign: "middle",
|
|
||||||
}}
|
}}
|
||||||
>
|
onChange={(value: number | null) =>
|
||||||
{totalQuantity}
|
dispatch(
|
||||||
</ProText>
|
updateQuantity({
|
||||||
|
id: item.id,
|
||||||
|
uniqueId: basicCartItem?.uniqueId || "",
|
||||||
|
quantity: value || 1,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
size="small"
|
||||||
|
controls={false}
|
||||||
|
className={styles.quantityInput}
|
||||||
|
name="id"
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
shape="circle"
|
shape="circle"
|
||||||
iconPlacement="start"
|
iconPlacement="start"
|
||||||
icon={<PlusOutlined title="plus" />}
|
icon={<PlusIcon color="#FFF" />}
|
||||||
size="small"
|
size="small"
|
||||||
onClick={handlePlusClick}
|
onClick={handlePlusClick}
|
||||||
|
disabled={totalQuantity >= 99}
|
||||||
className={styles.addButton}
|
className={styles.addButton}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: "#FFC600",
|
backgroundColor: "#FFC600",
|
||||||
width: 28,
|
width: 28,
|
||||||
height: 28,
|
height: 28,
|
||||||
position: "absolute",
|
|
||||||
bottom: 1,
|
|
||||||
[isRTL ? "left" : "right"]: 2,
|
|
||||||
minWidth: 28,
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
bottom: -11,
|
|
||||||
[isRTL ? "left" : "right"]: -2,
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Button
|
<Button
|
||||||
shape="circle"
|
shape="circle"
|
||||||
iconPlacement="start"
|
iconPlacement="start"
|
||||||
@@ -246,6 +238,7 @@ export function AddToCartButton({ item }: { item: Product }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
|
disabled={!hasOptions && totalQuantity >= 99}
|
||||||
className={styles.addButton}
|
className={styles.addButton}
|
||||||
style={{
|
style={{
|
||||||
color: "#302E3E",
|
color: "#302E3E",
|
||||||
@@ -253,13 +246,14 @@ export function AddToCartButton({ item }: { item: Product }) {
|
|||||||
width: 28,
|
width: 28,
|
||||||
height: 28,
|
height: 28,
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
bottom: 16,
|
[isRTL ? "left" : "right"]: -87,
|
||||||
[isRTL ? "left" : "right"]: 7,
|
bottom: 3,
|
||||||
minWidth: 28,
|
minWidth: 28,
|
||||||
boxShadow:
|
boxShadow:
|
||||||
"0px 1px 2px 0px #8585851A, 0px 3px 3px 0px #85858517, -1px 7px 4px 0px #8585850D, -1px 13px 5px 0px #85858503, -2px 20px 6px 0px #85858500",
|
"0px 1px 2px 0px #8585851A, 0px 3px 3px 0px #85858517, -1px 7px 4px 0px #8585850D, -1px 13px 5px 0px #85858503, -2px 20px 6px 0px #85858500",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import styles from "pages/menu/components/MenuList/ProductCard.module.css";
|
|||||||
import { Card, Badge } from "antd";
|
import { Card, Badge } from "antd";
|
||||||
import ProText from "components/ProText.tsx";
|
import ProText from "components/ProText.tsx";
|
||||||
import ArabicPrice from "components/ArabicPrice";
|
import ArabicPrice from "components/ArabicPrice";
|
||||||
import { colors } from "ThemeConstants.ts";
|
|
||||||
import { ItemDescriptionIcons } from "components/ItemDescriptionIcons/ItemDescriptionIcons.tsx";
|
import { ItemDescriptionIcons } from "components/ItemDescriptionIcons/ItemDescriptionIcons.tsx";
|
||||||
import ImageWithFallback from "components/ImageWithFallback";
|
import ImageWithFallback from "components/ImageWithFallback";
|
||||||
import { Product } from "utils/types/appTypes.ts";
|
import { Product } from "utils/types/appTypes.ts";
|
||||||
@@ -207,7 +206,14 @@ export default function ProductCard({ item, setIsBottomSheetOpen }: Props) {
|
|||||||
width={91}
|
width={91}
|
||||||
height={96}
|
height={96}
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
bottom: 3,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<AddToCartButton item={item} />
|
<AddToCartButton item={item} />
|
||||||
|
</div>
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -171,7 +171,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.headerContainer {
|
.headerContainer {
|
||||||
margin: 5px 0px;
|
margin: 5px 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enhanced responsive item description */
|
/* Enhanced responsive item description */
|
||||||
|
|||||||
@@ -51,7 +51,21 @@ export function SplitBillParticipantsBottomSheet({
|
|||||||
gap: 20,
|
gap: 20,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={styles.inviteToBill}>
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
placeItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
placeItems: "center",
|
||||||
|
gap: 10,
|
||||||
|
}}>
|
||||||
<Button
|
<Button
|
||||||
shape="circle"
|
shape="circle"
|
||||||
iconPlacement="start"
|
iconPlacement="start"
|
||||||
@@ -67,14 +81,7 @@ export function SplitBillParticipantsBottomSheet({
|
|||||||
>
|
>
|
||||||
<ProText style={{ color: "#1F1C2E" }}> 1 </ProText>
|
<ProText style={{ color: "#1F1C2E" }}> 1 </ProText>
|
||||||
</Button>
|
</Button>
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
gap: 4,
|
|
||||||
width: "100%",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ProText
|
<ProText
|
||||||
style={{
|
style={{
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
@@ -88,7 +95,18 @@ export function SplitBillParticipantsBottomSheet({
|
|||||||
{t("order.personHasPaid")}
|
{t("order.personHasPaid")}
|
||||||
</ProText>
|
</ProText>
|
||||||
</div>
|
</div>
|
||||||
{isRTL ? <BackIcon iconSize={24} /> : <NextIcon iconSize={24} />}
|
|
||||||
|
<ArabicPrice
|
||||||
|
price={0}
|
||||||
|
textStyle={{
|
||||||
|
fontWeight: 400,
|
||||||
|
fontStyle: "Regular",
|
||||||
|
fontSize: 12,
|
||||||
|
lineHeight: "140%",
|
||||||
|
letterSpacing: "0%",
|
||||||
|
color: "#3D3B4A",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -132,10 +150,7 @@ export function SplitBillParticipantsBottomSheet({
|
|||||||
>
|
>
|
||||||
{t("splitBill.remainingToPay")}
|
{t("splitBill.remainingToPay")}
|
||||||
</ProText>
|
</ProText>
|
||||||
<ArabicPrice
|
<ArabicPrice price={0} textStyle={taxesChargesStyle} />
|
||||||
price={0}
|
|
||||||
textStyle={taxesChargesStyle}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<ProText style={taxesChargesStyle}>
|
<ProText style={taxesChargesStyle}>
|
||||||
{t("splitBill.includesAllOfTaxesCharges")}
|
{t("splitBill.includesAllOfTaxesCharges")}
|
||||||
|
|||||||
Reference in New Issue
Block a user