Vitron-Front/app/components/cart/CartHeader.tsx
Arda Samadi b4d5f8d8db fix(ios): respect safe-area insets so chrome clears the notch/home bar
Content was drawing under the iOS status bar and home indicator because
the app uses viewport-fit=cover + black-translucent but the fixed/sticky
chrome didn't reserve the safe areas.

- bottom nav (MyLayout): move the 50px row into an inner box and let the
  bar extend by env(safe-area-inset-bottom) so icons sit above the home
  indicator (previously the fixed height clipped the inset padding).
- top headers gain env(safe-area-inset-top): HomePageTopBar, ExploreTopBar,
  SearchTopBar, CartHeader, ChatHeader, and wrapper-padded HeaderWithSupport
  / ProfilePagesHeader (so their absolutely-positioned buttons shift too).
- chat input pads bottom by the inset; chat scroll area height accounts for
  the taller header/input.
- _index.tsx no longer overrides the viewport meta (it was dropping
  viewport-fit=cover on the home page); the global one in root.tsx wins.

env(safe-area-inset-*) is 0 on non-notch devices, so desktop/Android render
identically — only iOS gains the padding.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 13:42:51 +03:30

75 lines
2.2 KiB
TypeScript

import { ArrowRight } from "lucide-react";
import { CartDetail } from "src/api/types";
import SellerLogo from "../SellerLogo";
import { useNavigate } from "@remix-run/react";
import { safeGoBack } from "~/utils/helpers";
interface CartHeaderProps {
cart: CartDetail | null | undefined;
step: number;
setStep: React.Dispatch<React.SetStateAction<number>>;
}
export const CartHeader = ({ cart, step, setStep }: CartHeaderProps) => {
const navigate = useNavigate();
return (
<div
className={`flex flex-col gap-3 pt-[calc(1rem_+_env(safe-area-inset-top))] sticky top-0 z-30 bg-WHITE w-full items-center justify-center ${step !== 0 ? "pb-4" : ""}`}
>
<p className={"text-B16 font-bold px-4"}>
{step === 0
? "سبد خرید"
: step === 1
? "اطلاعات ارسال"
: "اطلاعات تحویل گیرنده وپرداخت"}
</p>
<ArrowRight
onClick={() => {
if (step > 0) setStep((p) => p - 1);
else safeGoBack(navigate);
}}
className="absolute top-[calc(1rem_+_env(safe-area-inset-top))] right-4"
/>
{cart && cart.items && cart.items.length > 0 && (
<>
<StepIndicator currentStep={step} />
{step === 0 && (
<a
href={`/seller/${cart.seller?.username}`}
className="flex px-4 gap-2 h-[65px] border-b w-full justify-center items-center"
>
<SellerLogo
size="sm"
src={cart.seller?.logo}
alt={"seller-image"}
/>
<div className="flex flex-col items-center justify-center">
<p className="text-B12 font-bold text-overflow-ellipsis overflow-hidden whitespace-nowrap">
{cart.seller?.name}
</p>
</div>
</a>
)}
</>
)}
</div>
);
};
// Step Indicator Component
const StepIndicator = ({ currentStep }: { currentStep: number }) => (
<div className="w-full px-4 gap-4 flex pt-2">
{Array(3)
.fill(0)
.map((_, index) => (
<div
key={index}
className={`w-full h-[6px] rounded-md ${
currentStep >= index ? "bg-BLACK" : "bg-GRAY2"
}`}
/>
))}
</div>
);