- apply fixed height for footer buttons over app
- add floating cart button in cart page in desktop size
This commit is contained in:
2025-10-07 05:01:24 +03:00
parent 3485c073a3
commit 03a945c929
16 changed files with 127 additions and 66 deletions

View File

@@ -165,7 +165,7 @@
position: fixed;
bottom: 0;
left: 0;
height: 10vh;
height: 80px;
display: flex;
flex-direction: row;
justify-content: space-around;

View File

@@ -1,17 +1,15 @@
import { colors } from "ThemeConstants.ts";
import { Link, useParams } from "react-router-dom";
import { Button } from "antd";
import { useAppSelector } from "redux/hooks.ts";
import useBreakPoint from "hooks/useBreakPoint.ts";
import { useTranslation } from "react-i18next";
import { selectCart } from "features/order/orderSlice.ts";
import { useTranslation } from "react-i18next";
import { Link, useParams } from "react-router-dom";
import { useAppSelector } from "redux/hooks.ts";
import styles from "./footer.module.css";
export default function CartFooter() {
const { t } = useTranslation();
const { items } = useAppSelector(selectCart);
const { id } = useParams();
const { isMobile, isTablet } = useBreakPoint();
const orderType = localStorage.getItem("orderType");
return (
@@ -25,7 +23,7 @@ export default function CartFooter() {
<Button
style={{
borderRadius: 100,
height: isMobile ? 48 : isTablet ? 56 : 64,
height: 50,
borderColor: "black",
width: "100%",
fontSize: 16,
@@ -45,7 +43,7 @@ export default function CartFooter() {
style={{
backgroundColor: colors.primary,
borderRadius: 100,
height: isMobile ? 48 : isTablet ? 56 : 64,
height: 50,
borderColor: "#F2F2F2",
fontSize: 16,
color: "white",

View File

@@ -4,12 +4,12 @@
position: fixed;
bottom: 0;
left: 0;
height: 10vh;
height: 80px;
display: flex;
flex-direction: row;
justify-content: space-around;
gap: 1rem;
background-color: var(--background);
background-color: var(--primary-light);
box-shadow: none;
}
/* :global(.darkApp) .cartFooter {

View File

@@ -0,0 +1,23 @@
/* Scroll to Top Button */
.scrollToTopButton {
animation: fadeInUp 0.3s ease-out;
transition: all 0.3s ease;
}
.scrollToTopButton:hover {
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2) !important;
}
/* Dark theme scroll to top button */
:global(.darkApp) .scrollToTopButton {
background-color: var(--primary) !important;
border-color: var(--primary) !important;
color: #000000 !important;
}
:global(.darkApp) .scrollToTopButton:hover {
background-color: #ffd633 !important;
border-color: #ffd633 !important;
box-shadow: 0 6px 16px rgba(255, 198, 0, 0.3) !important;
}

View File

@@ -0,0 +1,60 @@
import { Badge, Button } from "antd";
import CartIcon from "components/Icons/cart/CartIcon";
import { selectCartItems } from "features/order/orderSlice";
import useBreakPoint from "hooks/useBreakPoint";
import { useCallback } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { useAppSelector } from "redux/hooks";
import { colors } from "ThemeConstants";
import styles from "./CartButton.module.css";
export function CartButton() {
const { isRTL } = useAppSelector((state) => state.locale);
const { themeName } = useAppSelector((state) => state.theme);
const { isMobile, isTablet } = useBreakPoint();
const { id } = useParams();
const navigate = useNavigate();
const items = useAppSelector(selectCartItems);
const onCartClick = useCallback(() => {
navigate(`/${id}/cart`);
}, [navigate, id]);
const totalItems = items.reduce((sum, item) => sum + item.quantity, 0);
return (
<>
<Button
type="primary"
shape="circle"
size={"large"}
icon={
<div style={{ position: "relative", left: 4, top: 2 }}>
<CartIcon />
</div>
}
onClick={onCartClick}
className={`${styles.scrollToTopButton}`}
style={{
position: "fixed",
bottom: isMobile ? "100px" : isTablet ? "120px" : "25px",
right: !isRTL ? "auto" : isMobile ? "20px" : "32px",
left: !isRTL ? (isMobile ? "20px" : "32px") : "auto",
zIndex: 1000,
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
backgroundColor:
themeName === "dark" ? colors.primary : colors.primary,
borderColor: themeName === "dark" ? colors.primary : colors.primary,
width: isMobile ? 48 : 56,
height: isMobile ? 48 : 56,
}}
>
<Badge
count={totalItems}
size="default"
style={{ position: "absolute", top: -35, right: -18 }}
/>
</Button>
</>
);
}

View File

@@ -1,21 +1,18 @@
import { Badge, Button, Grid } from "antd";
import { Badge, Button } from "antd";
import CartIcon from "components/Icons/cart/CartIcon";
import ProText from "components/ProText";
import { selectCartItems } from "features/order/orderSlice";
import useBreakPoint from "hooks/useBreakPoint";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { useAppSelector } from "redux/hooks";
import { colors, ProBlack2 } from "ThemeConstants";
const { useBreakpoint } = Grid;
export function MenuFooter() {
const items = useAppSelector(selectCartItems);
const restaurantName = localStorage.getItem("restaurantName");
const { themeName } = useAppSelector((state) => state.theme);
const { xs, sm } = useBreakpoint();
const isMobile = xs;
const isTablet = sm && !xs;
const { isMobile, isTablet } = useBreakPoint();
const { t } = useTranslation();
const totalItems = items.reduce((sum, item) => sum + item.quantity, 0);
@@ -30,7 +27,7 @@ export function MenuFooter() {
position: "fixed",
bottom: 0,
left: 0,
height: "10vh",
height: "80px",
display: "flex",
flexDirection: "row",
justifyContent: "space-around",
@@ -51,8 +48,7 @@ export function MenuFooter() {
shape="round"
style={{
width: "100%",
height: 48,
marginBottom: 16,
height: 50,
boxShadow: "none",
}}
>

View File

@@ -157,7 +157,7 @@ export function MenuList({ data, categoryRefs }: MenuListProps) {
style={{
margin: 0,
display: "inline-block",
fontSize: xs ? "1rem" : 18,
fontSize: "1rem" ,
fontWeight: 600,
letterSpacing: "-0.01em",
lineHeight: 1.2,
@@ -194,7 +194,7 @@ export function MenuList({ data, categoryRefs }: MenuListProps) {
price={item.original_price}
strong
style={{
fontSize: xs ? "1rem" : 22,
fontSize: "1rem",
fontWeight: 700,
color: colors.primary,
textDecoration: "line-through",
@@ -207,7 +207,7 @@ export function MenuList({ data, categoryRefs }: MenuListProps) {
price={item.price}
strong
style={{
fontSize: xs ? "1rem" : 22,
fontSize: "1rem",
fontWeight: 700,
color: colors.primary,
}}

View File

@@ -212,6 +212,7 @@ const MenuSkeleton = ({
width: "32px",
height: "32px",
borderRadius: "50%",
overflow: "hidden",
}}
/>
))}

View File

@@ -449,7 +449,6 @@
}
.contentWrapper {
max-width: 800px;
margin: 0px auto;
padding: 0 1rem;
}
@@ -546,12 +545,12 @@
}
.leftShape {
top: 170px;
top: 171px;
left: -3px;
}
.rightShape {
top: 170px;
top: 171px;
left: 116px;
}
@@ -615,12 +614,12 @@
}
.leftShape {
top: 170px;
top: 171px;
left: -10px;
}
.rightShape {
top: 170px;
top: 171px;
left: 179px;
}
}

View File

@@ -1,11 +1,12 @@
import { StarFilled } from "@ant-design/icons";
import { Grid, Image, Space } from "antd";
import { Image, Space } from "antd";
import { FloatingButton } from "components/FloatingButton/FloatingButton";
import ImageWithFallback from "components/ImageWithFallback";
import LoyaltyCard from "components/LoyaltyCard/LoyaltyCard";
import ProText from "components/ProText";
import ProTitle from "components/ProTitle";
import { useScrollHandler } from "contexts/ScrollHandlerContext";
import useBreakPoint from "hooks/useBreakPoint";
import { useTranslation } from "react-i18next";
import { useParams, useSearchParams } from "react-router-dom";
import {
@@ -15,6 +16,7 @@ import {
import { useAppSelector } from "redux/hooks";
import { default_image } from "utils/constants";
import BackButton from "./components/BackButton";
import { CartButton } from "./components/CartButton/CartButton";
import { CategoriesList } from "./components/CategoriesList/CategoriesList";
import LocalStorageHandler from "./components/LocalStorageHandler";
import { MenuFooter } from "./components/MenuFooter/MenuFooter";
@@ -24,8 +26,6 @@ import ScrollEventHandler from "./components/ScrollEventHandler";
import SearchButton from "./components/SearchButton";
import styles from "./menu.module.css";
const { useBreakpoint } = Grid;
function MenuPage() {
const { id } = useParams();
const [searchParams] = useSearchParams();
@@ -44,8 +44,7 @@ function MenuPage() {
},
);
const { categoryRefs } = useScrollHandler();
const { xs, md } = useBreakpoint();
const isTablet = !xs && !md;
const { isMobile, isTablet, isDesktop } = useBreakPoint();
const isLoading = isLoadingRestaurant || isLoadingMenu;
@@ -68,7 +67,7 @@ function MenuPage() {
alt={t("menu.restaurantCover")}
className={styles.cover}
width={"100%"}
height={xs ? 182 : isTablet ? 200 : 220}
height={isMobile ? 182 : isTablet ? 200 : 220}
preview={false}
loadingContainerStyle={{
width: "100vw",
@@ -122,23 +121,8 @@ function MenuPage() {
</div>
</div>
<div
className={`${styles.pageContainer}`}
// style={{
// maxWidth: isDesktop ? "1200px" : "100%",
// margin: isDesktop ? "0 auto" : "0",
// }}
>
<Space
direction="vertical"
// size={isMobile ? "middle" : isTablet ? "large" : "large"}
style={{ width: "100%", gap: 16 }}
>
{/* Placeholder to prevent content jumping when categories become sticky */}
{/* {isCategoriesSticky && (
<div style={{ height: xs ? 95 : md ? 160 : 180 }} />
)} */}
<div className={`${styles.pageContainer}`}>
<Space direction="vertical" style={{ width: "100%", gap: 16 }}>
<div>
<LoyaltyCard />
<CategoriesList categories={menuData?.categories || []} />
@@ -156,6 +140,7 @@ function MenuPage() {
<ScrollEventHandler />
<FloatingButton />
{isDesktop && <CartButton />}
</div>
)}
</>

View File

@@ -120,7 +120,7 @@ export default function SplitBillPage() {
position: "fixed",
bottom: 0,
left: 0,
height: "10vh",
height: "80px",
display: "flex",
flexDirection: "row",
justifyContent: "space-around",