MyLayout only pads the bottom inset globally; each top bar must add its own top inset. Several inline page headers omitted it, so their content slid under the notch in the iOS standalone PWA (home was fine — its bar has it). Wrap the back-button headers the same way ProfilePagesHeader already does (outer sticky element carries pt-[env(safe-area-inset-top)]; inner relative bar holds the content) so the absolute back arrow stays out of the notch. Fixed: /profile hub, /discounts, /collections, /collection/:id, /sellers, seller store index, and financial transactions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
105 lines
3.9 KiB
TypeScript
105 lines
3.9 KiB
TypeScript
import { MetaFunction } from "@remix-run/node";
|
||
import { useNavigate } from "@remix-run/react";
|
||
import { ArrowRight, Tag } from "lucide-react";
|
||
import { safeGoBack } from "~/utils/helpers";
|
||
import { useGetHomeDiscounts } from "~/requestHandler/use-home-hooks";
|
||
import MondrianProductList from "~/components/MondrianProductList";
|
||
|
||
export default function Discounts() {
|
||
const navigate = useNavigate();
|
||
const {
|
||
data,
|
||
isLoading,
|
||
isError,
|
||
refetch,
|
||
fetchNextPage,
|
||
hasNextPage,
|
||
isFetchingNextPage,
|
||
} = useGetHomeDiscounts();
|
||
|
||
const products =
|
||
data?.pages.flatMap((page) => (page?.results as unknown[]) || []) || [];
|
||
|
||
const handleBack = () => safeGoBack(navigate);
|
||
|
||
return (
|
||
<div className="flex flex-col bg-WHITE pb-20">
|
||
{/* Header (mobile) */}
|
||
<div className="lg:hidden sticky top-0 z-30 bg-WHITE pt-[env(safe-area-inset-top)]">
|
||
<div className="relative flex flex-row h-[65px] w-full items-center justify-center border-b border-inner-border">
|
||
<ArrowRight
|
||
onClick={handleBack}
|
||
className="absolute top-5 right-5 cursor-pointer"
|
||
/>
|
||
<p className="text-B16 font-bold">تخفیفها</p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Content */}
|
||
<div className="flex flex-col py-6 lg:max-w-[1320px] lg:mx-auto lg:w-full lg:px-8">
|
||
<div className="hidden lg:block mb-6 px-4 lg:px-0">
|
||
<h1 className="text-[28px] font-extrabold">تخفیفها</h1>
|
||
<p className="text-R16 text-GRAY mt-1">
|
||
فرصتهایی محدود برای انتخابهای هوشمندانه
|
||
</p>
|
||
</div>
|
||
|
||
<MondrianProductList
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||
products={(products as any[]).map((product) => ({
|
||
id: product?.id || "",
|
||
title: product?.title || "",
|
||
images: Array.isArray(product?.imageUrls) ? product.imageUrls : [],
|
||
basePrice: product?.basePrice || 0,
|
||
discountPercent: product?.discountPercent || 0,
|
||
discountPrice: product?.discountPrice || 0,
|
||
sellerName: product?.sellerName,
|
||
sellerLogo: product?.sellerLogo,
|
||
sellerUsername: product?.sellerUsername,
|
||
}))}
|
||
fetchNextPage={fetchNextPage}
|
||
hasNextPage={!!hasNextPage}
|
||
isFetchingNextPage={isFetchingNextPage}
|
||
isLoading={isLoading}
|
||
isError={isError}
|
||
refetch={refetch}
|
||
emptyState={{
|
||
image: <Tag size={80} />,
|
||
title: "در حال حاضر تخفیفی موجود نیست",
|
||
description: "به زودی پیشنهادهای ویژهای اضافه خواهد شد",
|
||
}}
|
||
/>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export const meta: MetaFunction = () => {
|
||
const title = "تخفیفها | پیشنهادهای ویژه ویترون";
|
||
const description =
|
||
"جدیدترین محصولات تخفیفدار ویترون. خرید با بهترین قیمت از فروشگاههای معتبر.";
|
||
const imageUrl =
|
||
"https://vitrownstatics.s3.ir-thr-at1.arvanstorage.ir/SVG-06.svg?versionId=";
|
||
|
||
return [
|
||
{ title },
|
||
{ name: "description", content: description },
|
||
{
|
||
name: "keywords",
|
||
content: "تخفیف، حراج، فروش ویژه، خرید ارزان، ویترون",
|
||
},
|
||
{ name: "robots", content: "index, follow" },
|
||
|
||
{ property: "og:type", content: "website" },
|
||
{ property: "og:title", content: title },
|
||
{ property: "og:description", content: description },
|
||
{ property: "og:image", content: imageUrl },
|
||
{ property: "og:site_name", content: "ویترون" },
|
||
{ property: "og:locale", content: "fa_IR" },
|
||
|
||
{ name: "twitter:card", content: "summary_large_image" },
|
||
{ name: "twitter:title", content: title },
|
||
{ name: "twitter:description", content: description },
|
||
];
|
||
};
|