Interleave banners between carousels, real "view all" links, bigger desktop logo

- StoreSpecialCarousels now inserts one of the two banner sections
  (TwoBanners/ThreeBanners, cycling) between every pair of carousels
  instead of stacking all carousels together with the banners fixed
  elsewhere on the page — works for any number of dynamic carousels.
- SectionTitle's action button is a real link now (actionHref), not an
  inert <button>. Each carousel's "مشاهده همه" goes to
  /products?specialId={group.id}, which renders that exact
  admin-curated group in the full product grid — store-specials groups
  have no pagination, so this is genuinely the complete set, not a
  truncated preview. Also fixed BlogCarousel's dead "وبلاگ" button the
  same way, now linking to /blog.
- Reduced FeaturedCategories' vertical padding (py-10/14 -> py-4/6).
- Desktop header logo was smaller than the mobile one (36px vs 46px) —
  bumped to 40/48px so it reads properly at desktop width.
- CONTEXT.md: document the banner-interleaving and specialId patterns.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
amirhosein.ashourloo
2026-09-15 17:57:01 +03:30
co-authored by Claude Sonnet 5
parent bc6cafaffa
commit 7c04316f3a
8 changed files with 134 additions and 44 deletions
+50 -24
View File
@@ -1,7 +1,10 @@
import { Fragment } from "react";
import { Carousel } from "@/components/ui/Carousel";
import { ProductCard } from "@/components/ui/ProductCard";
import { SectionTitle } from "@/components/ui/SectionTitle";
import { productHref, type ProductGroup } from "@/lib/meshkee";
import { TwoBanners } from "@/components/home/TwoBanners";
import { ThreeBanners } from "@/components/home/ThreeBanners";
import { productHref, type ProductGroup, type StaticImageWithUrl } from "@/lib/meshkee";
// Renders every admin-managed carousel from GET /store-specials — whatever
// groups exist there, in their configured order. Nothing here is keyed off
@@ -9,40 +12,63 @@ import { productHref, type ProductGroup } from "@/lib/meshkee";
// dashboard (any name) shows up on the homepage automatically, with no code
// change. Groups with no items are skipped (honest empty state — no heading
// over nothing).
//
// One of the two banner sections is inserted between every pair of
// carousels (never before the first or after the last), cycling if there
// end up being more than two carousels.
export function StoreSpecialCarousels({
groups,
contactPhone,
twoBannerImages,
twoBannerAspectRatio,
threeBannerImages,
threeBannerAspectRatio,
}: {
groups: ProductGroup[];
contactPhone?: string;
twoBannerImages?: StaticImageWithUrl[];
twoBannerAspectRatio?: string;
threeBannerImages?: StaticImageWithUrl[];
threeBannerAspectRatio?: string;
}) {
const visibleGroups = groups.filter((group) => group.items.length > 0);
const banners = [
<TwoBanners key="two" images={twoBannerImages} aspectRatio={twoBannerAspectRatio} />,
<ThreeBanners key="three" images={threeBannerImages} aspectRatio={threeBannerAspectRatio} />,
];
return (
<>
{visibleGroups.map((group) => (
<section key={group.id} className="py-10 md:py-14">
<div className="mx-auto max-w-7xl px-4">
<SectionTitle title={group.title} />
<Carousel ariaLabel={`کاروسل ${group.title}`}>
{group.items.map((product) => (
<ProductCard
key={product.id}
name={product.name}
brand={product.brand ?? ""}
price={product.price}
oldPrice={product.oldPrice}
discount={product.discount}
image={product.image ?? "/images/placeholder.svg"}
href={productHref(product)}
contactPhone={contactPhone}
variantId={product.variantId}
slug={product.slug}
/>
))}
</Carousel>
</div>
</section>
{visibleGroups.map((group, i) => (
<Fragment key={group.id}>
{i > 0 && banners[(i - 1) % banners.length]}
<section className="py-10 md:py-14">
<div className="mx-auto max-w-7xl px-4">
<SectionTitle
title={group.title}
action="مشاهده همه"
actionHref={`/products?specialId=${group.id}`}
/>
<Carousel ariaLabel={`کاروسل ${group.title}`}>
{group.items.map((product) => (
<ProductCard
key={product.id}
name={product.name}
brand={product.brand ?? ""}
price={product.price}
oldPrice={product.oldPrice}
discount={product.discount}
image={product.image ?? "/images/placeholder.svg"}
href={productHref(product)}
contactPhone={contactPhone}
variantId={product.variantId}
slug={product.slug}
/>
))}
</Carousel>
</div>
</section>
</Fragment>
))}
</>
);