responsive
This commit is contained in:
@@ -5,7 +5,7 @@ import { BREADCRUMB_ITEMS } from "../constants";
|
||||
|
||||
const ProductBreadcrumb: FC = () => {
|
||||
return (
|
||||
<nav aria-label="مسیر صفحه" className="flex items-center justify-start gap-2 bg-secondary px-4 py-3 text-sm text-[#3F4D5A] sm:px-8 lg:px-30">
|
||||
<nav aria-label="مسیر صفحه" className="flex items-center justify-start gap-2 overflow-x-auto bg-secondary px-4 py-3 text-sm whitespace-nowrap text-[#3F4D5A] sm:px-8 lg:px-30">
|
||||
{BREADCRUMB_ITEMS.map((item, index) => (
|
||||
<Fragment key={item.label}>
|
||||
{index > 0 && <ArrowLeft2 size={14} color="currentColor" className="shrink-0" />}
|
||||
|
||||
@@ -17,19 +17,21 @@ const ProductDetail: FC = () => {
|
||||
<>
|
||||
<ProductBreadcrumb />
|
||||
|
||||
<div className="px-4 py-6 sm:px-8 sm:py-8 lg:px-30">
|
||||
<div className="flex flex-col items-start gap-8 lg:flex-row lg:items-start lg:gap-10">
|
||||
<ProductGallery images={PRODUCT_GALLERY_IMAGES} alt={PRODUCT_TITLE} />
|
||||
<div className="flex w-full min-w-0 flex-1 flex-col items-end">
|
||||
<ProductPurchaseOptions selectedTier={selectedTier} onSelectTier={setSelectedTier} />
|
||||
<ProductOrderActions selectedTier={selectedTier} />
|
||||
<div className="pb-28 lg:pb-0">
|
||||
<div className="px-4 py-6 sm:px-8 sm:py-8 lg:px-30">
|
||||
<div className="flex flex-col items-start gap-6 sm:gap-8 lg:flex-row lg:items-start lg:gap-10">
|
||||
<ProductGallery images={PRODUCT_GALLERY_IMAGES} alt={PRODUCT_TITLE} />
|
||||
<div className="flex w-full min-w-0 flex-1 flex-col">
|
||||
<ProductPurchaseOptions selectedTier={selectedTier} onSelectTier={setSelectedTier} />
|
||||
<ProductOrderActions selectedTier={selectedTier} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ProductTabs />
|
||||
<ProductRelated />
|
||||
<ContactCtaSection />
|
||||
<ProductTabs />
|
||||
<ProductRelated />
|
||||
<ContactCtaSection />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,12 +13,12 @@ const ProductGallery: FC<ProductGalleryProps> = ({ images, alt }) => {
|
||||
const [activeIndex, setActiveIndex] = useState(0);
|
||||
|
||||
return (
|
||||
<div className="flex w-full shrink-0 flex-col gap-3 lg:w-[45%] lg:max-w-120">
|
||||
<div className="relative aspect-square w-full overflow-hidden rounded-2xl bg-[#F7FAFC]">
|
||||
<div className="flex w-full shrink-0 flex-col gap-3 sm:gap-4 lg:w-[45%] lg:max-w-120">
|
||||
<div className="relative aspect-square w-full overflow-hidden rounded-xl bg-[#F7FAFC] sm:rounded-2xl">
|
||||
<Image src={images[activeIndex]} alt={alt} fill priority className="object-contain p-4" sizes="(max-width: 1024px) 100vw, 480px" />
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-4 gap-2.5">
|
||||
<div className="grid grid-cols-4 gap-2 sm:gap-2.5">
|
||||
{images.slice(0, 4).map((image, index) => (
|
||||
<button
|
||||
key={index}
|
||||
|
||||
@@ -10,18 +10,18 @@ type ProductOrderActionsProps = {
|
||||
|
||||
const ProductOrderActions = ({ selectedTier }: ProductOrderActionsProps) => {
|
||||
return (
|
||||
<div className="mt-5 flex w-full flex-col gap-3 self-end rounded-t-2xl bg-white px-4 py-4 shadow-[0px_-4px_34px_0px_#1A456C14] sm:flex-row sm:items-center sm:justify-between sm:gap-5 sm:px-5 sm:py-4">
|
||||
<div className="fixed inset-x-0 bottom-0 z-40 flex w-full flex-col gap-3 rounded-t-2xl bg-white px-4 py-3 shadow-[0px_-4px_34px_0px_#1A456C14] sm:flex-row sm:items-center sm:justify-between sm:gap-4 sm:px-8 sm:py-4 lg:relative lg:inset-auto lg:mt-5 lg:gap-5 lg:rounded-t-2xl lg:px-5 lg:shadow-[0px_-4px_34px_0px_#1A456C14]">
|
||||
<div className="space-y-1 text-right">
|
||||
<p className="text-base font-bold text-[#0A1B2C] sm:text-lg">{formatPrice(selectedTier.totalPrice)}﷼</p>
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
<div className="flex flex-wrap items-center justify-end gap-2">
|
||||
<span className="text-xs text-[#0A1B2C] sm:text-sm">{formatPrice(selectedTier.unitPrice)} ﷼ به ازای هر عدد</span>
|
||||
<span className="rounded-lg bg-[#00893E] px-2 py-0.5 text-[10px] font-medium text-white sm:text-xs">{PRODUCT_PROFIT_PERCENT}٪ سود</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="hidden h-16 w-0 shrink-0 border-s-2 border-primary sm:block" />
|
||||
<div className="hidden h-16 w-0 shrink-0 border-s-2 border-primary lg:block" />
|
||||
|
||||
<div className="flex flex-col gap-2 sm:flex-row sm:items-end sm:gap-5">
|
||||
<div className="flex flex-col gap-2 sm:flex-row sm:items-end sm:gap-4 lg:gap-5">
|
||||
<div className="w-full space-y-1 sm:w-32">
|
||||
<span className="block text-right text-xs font-medium text-[#0A1B2C]">تعداد</span>
|
||||
<Select options={[...STICKY_QUANTITY_OPTIONS]} defaultValue="1000" className="h-10 rounded-xl border-[#E9EEF2] text-sm" />
|
||||
|
||||
@@ -14,11 +14,11 @@ type ProductPurchaseOptionsProps = {
|
||||
|
||||
const ProductPurchaseOptions: FC<ProductPurchaseOptionsProps> = ({ selectedTier, onSelectTier }) => {
|
||||
return (
|
||||
<div className="flex w-full min-w-0 flex-1 flex-col items-end gap-4">
|
||||
<div className="flex w-full min-w-0 flex-1 flex-col gap-4">
|
||||
<div className="w-full space-y-2 text-right">
|
||||
<h1 className="text-xl font-bold text-[#0A1B2C] sm:text-2xl">{PRODUCT_TITLE}</h1>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
<Rating initialValue={PRODUCT_RATING} size={16} readonly rtl allowFraction SVGstyle={{ display: "inline-block" }} />
|
||||
<span className="text-sm font-medium text-[#0A1B2C]">{PRODUCT_RATING}</span>
|
||||
</div>
|
||||
@@ -55,17 +55,19 @@ const ProductPurchaseOptions: FC<ProductPurchaseOptionsProps> = ({ selectedTier,
|
||||
type="button"
|
||||
onClick={() => onSelectTier(tier)}
|
||||
className={cn(
|
||||
"flex h-10 w-full items-center justify-between gap-2 rounded-xl border border-[#E9EEF2] px-3 transition-colors",
|
||||
"flex min-h-10 w-full items-center justify-between gap-1.5 rounded-xl border border-[#E9EEF2] px-2.5 transition-colors sm:gap-2 sm:px-3",
|
||||
isSelected ? "bg-secondary" : "bg-white hover:bg-secondary/50",
|
||||
)}
|
||||
>
|
||||
<span className="w-6 shrink-0 text-end text-xs font-medium text-[#0A1B2C]">{tier.quantity}</span>
|
||||
<span className="hidden w-6 shrink-0 text-end text-xs font-medium text-[#0A1B2C] sm:inline">{tier.quantity}</span>
|
||||
|
||||
<div className="flex min-w-0 flex-1 items-center justify-center gap-2">
|
||||
<span className="text-[11px] text-[#0A1B2C] sm:text-xs">{formatPrice(tier.unitPrice)}﷼ / هر عدد</span>
|
||||
<span className="text-xs font-medium text-[#0A1B2C]">{formatPrice(tier.totalPrice)}﷼</span>
|
||||
<div className="flex min-w-0 flex-1 items-center justify-between gap-1.5 sm:justify-center sm:gap-2">
|
||||
<span className="text-[10px] text-[#0A1B2C] sm:text-xs">{formatPrice(tier.unitPrice)}﷼ / هر عدد</span>
|
||||
<span className="text-[11px] font-medium text-[#0A1B2C] sm:text-xs">{formatPrice(tier.totalPrice)}﷼</span>
|
||||
</div>
|
||||
<span className={cn("w-6 shrink-0 text-start text-xs font-medium", tier.discount ? "text-[#DC0000]" : "text-[#0A1B2C]")}>{tier.discount ? `-${tier.discount}%` : tier.quantity}</span>
|
||||
<span className={cn("w-8 shrink-0 text-start text-[10px] font-medium sm:w-6 sm:text-xs", tier.discount ? "text-[#DC0000]" : "text-[#0A1B2C]")}>
|
||||
{tier.discount ? `-${tier.discount}%` : tier.quantity}
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { RELATED_PRODUCTS } from "../constants";
|
||||
|
||||
const ProductRelated: FC = () => {
|
||||
return (
|
||||
<section className="mt-10 px-4 sm:mt-12 sm:px-8 lg:px-30">
|
||||
<section className="mt-8 px-4 sm:mt-10 sm:px-8 lg:mt-12 lg:px-30">
|
||||
<Carousel slidesPerView={{ base: 1.4, md: 3, lg: 5 }} gap={{ base: 12, md: 16, lg: 24 }}>
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<h2 className="text-lg font-bold text-[#0A1B2C] sm:text-xl">محصولات مرتبط</h2>
|
||||
|
||||
Reference in New Issue
Block a user