menu: on click on prduct open details as BS, also add redirect button to detials page if user click on redirect button
This commit is contained in:
68
src/pages/product/components/ProductBottomSheet.tsx
Normal file
68
src/pages/product/components/ProductBottomSheet.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import { ProBottomSheet } from "components/ProBottomSheet/ProBottomSheet.tsx";
|
||||
import ProductDetailPage from "../page";
|
||||
import { Button } from "antd";
|
||||
import { UploadOutlined } from "@ant-design/icons";
|
||||
import { useAppSelector } from "redux/hooks";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
interface ProductBottomSheetProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export function ProductBottomSheet({
|
||||
isOpen,
|
||||
onClose,
|
||||
}: ProductBottomSheetProps) {
|
||||
const { themeName } = useAppSelector((state) => state.theme);
|
||||
const { isRTL } = useAppSelector((state) => state.locale);
|
||||
const { subdomain } = useParams();
|
||||
const closeButtonStyle: React.CSSProperties = {
|
||||
color: themeName === "dark" ? "#ffffff" : "#4D5154",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
padding: 8,
|
||||
borderRadius: "50%",
|
||||
backgroundColor: themeName === "dark" ? "rgba(54, 54, 54, 0.8)" : "#EDEEEE",
|
||||
border: `1px solid ${themeName === "dark" ? "#424242" : "transparent"}`,
|
||||
transition: "all 0.3s ease",
|
||||
cursor: "pointer",
|
||||
width: 30,
|
||||
height: 30,
|
||||
position: "absolute",
|
||||
top: 40,
|
||||
[isRTL ? "right" : "left"]: 16,
|
||||
zIndex: 1000,
|
||||
};
|
||||
|
||||
const navigate = useNavigate();
|
||||
const productId = localStorage.getItem("productId");
|
||||
|
||||
const redirectToProductPage = () => {
|
||||
if (productId) {
|
||||
navigate(`/${subdomain}/product/${productId}`);
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ProBottomSheet
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
showCloseButton={true}
|
||||
initialSnap={1}
|
||||
height={"90vh"}
|
||||
snapPoints={["90vh"]}
|
||||
contentStyle={{ padding: 0 }}
|
||||
>
|
||||
<Button
|
||||
type="text"
|
||||
icon={<UploadOutlined />}
|
||||
onClick={redirectToProductPage}
|
||||
style={closeButtonStyle}
|
||||
/>
|
||||
<ProductDetailPage onClose={onClose} />
|
||||
</ProBottomSheet>
|
||||
);
|
||||
}
|
||||
@@ -55,6 +55,9 @@ export default function ProductFooter({
|
||||
product.extras.length,
|
||||
product?.theExtrasGroups?.length,
|
||||
]);
|
||||
const isBottomSheetView = useMemo(() => {
|
||||
return window.location.href.includes("menu");
|
||||
}, []);
|
||||
|
||||
const handleAddToCart = () => {
|
||||
if (restaurant && !restaurant.isOpened) {
|
||||
@@ -114,7 +117,7 @@ export default function ProductFooter({
|
||||
}),
|
||||
);
|
||||
// Navigate back to menu - scroll position will be restored automatically
|
||||
if (!isDesktop) window.history.back();
|
||||
if (!isDesktop && !isBottomSheetView ) window.history.back();
|
||||
else {
|
||||
onClose?.();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ export default function ProductDetailPage({
|
||||
onClose?: () => void;
|
||||
}) {
|
||||
const { productId } = useParams();
|
||||
|
||||
const { isRTL } = useAppSelector((state) => state.locale);
|
||||
const { restaurant } = useAppSelector((state) => state.order);
|
||||
const { isDesktop, isTablet } = useBreakPoint();
|
||||
@@ -33,6 +32,14 @@ export default function ProductDetailPage({
|
||||
const [viewportHeight, setViewportHeight] = useState<number>(
|
||||
typeof window !== "undefined" ? window.innerHeight : 0,
|
||||
);
|
||||
const isBottomSheetView = useMemo(() => {
|
||||
return window.location.href.includes("menu");
|
||||
}, []);
|
||||
|
||||
const currenctProductId = useMemo(() => {
|
||||
// in case the prduct viewing from the bottom sheet, the product id is not passed in the url
|
||||
return productId || localStorage.getItem("productId");
|
||||
}, [localStorage.getItem("productId")]);
|
||||
|
||||
// Update viewport height when browser UI changes (mobile address bar, etc.)
|
||||
useEffect(() => {
|
||||
@@ -55,7 +62,10 @@ export default function ProductDetailPage({
|
||||
window.removeEventListener("resize", updateViewportHeight);
|
||||
window.removeEventListener("orientationchange", updateViewportHeight);
|
||||
if (window.visualViewport) {
|
||||
window.visualViewport.removeEventListener("resize", updateViewportHeight);
|
||||
window.visualViewport.removeEventListener(
|
||||
"resize",
|
||||
updateViewportHeight,
|
||||
);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
@@ -71,14 +81,15 @@ export default function ProductDetailPage({
|
||||
// because in desktop we open the product dialog from the menu list
|
||||
// and the product id is not passed in the url
|
||||
const productIdLocalStorage = localStorage.getItem("productId");
|
||||
if (!menuData?.products || (!productId && !productIdLocalStorage))
|
||||
if (!menuData?.products || (!currenctProductId && !productIdLocalStorage))
|
||||
return null;
|
||||
|
||||
// Find the product with matching IDs
|
||||
return menuData.products.find(
|
||||
(p: Product) => p.id.toString() === (productId || productIdLocalStorage),
|
||||
(p: Product) =>
|
||||
p.id.toString() === (currenctProductId || productIdLocalStorage),
|
||||
);
|
||||
}, [menuData, productId]);
|
||||
}, [menuData, currenctProductId]);
|
||||
|
||||
// State for variant selections
|
||||
const [selectedVariants, setSelectedVariants] = useState<
|
||||
@@ -205,14 +216,15 @@ export default function ProductDetailPage({
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
height: viewportHeight > 0
|
||||
? `${viewportHeight - 195}px`
|
||||
: "calc(100dvh - 195px)",
|
||||
height:
|
||||
viewportHeight > 0
|
||||
? `${viewportHeight - 195}px`
|
||||
: "calc(100dvh - 195px)",
|
||||
overflow: "auto",
|
||||
scrollbarWidth: "none",
|
||||
}}
|
||||
>
|
||||
{!isDesktop && (
|
||||
{!isDesktop && !isBottomSheetView && (
|
||||
<div className={styles.backButtonContainer}>
|
||||
<BackButton />
|
||||
</div>
|
||||
@@ -371,6 +383,7 @@ export default function ProductDetailPage({
|
||||
selectedGroups={selectedExtrasByGroup}
|
||||
quantity={quantity}
|
||||
setQuantity={(quantity: number) => setQuantity(quantity)}
|
||||
onClose={onClose}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -315,6 +315,11 @@
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
:global(.ant-app-rtl) .backButtonContainer {
|
||||
left: auto;
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
:global(.darkApp) .itemDescriptionIcons path {
|
||||
fill: #ffffff !important;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user