Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import type { Category } from "@spree/sdk";
import { cacheLife, cacheTag } from "next/cache";
import Link from "next/link";
import { Breadcrumbs } from "@/components/navigation/Breadcrumbs";

interface CategoryBannerProps {
category: Category;
basePath: string;
locale: string;
}

export async function CategoryBanner({
category,
basePath,
locale,
}: CategoryBannerProps) {
"use cache: remote";
cacheLife("minutes");
cacheTag("category-banner");

return (
<>
<div
className="flex flex-col justify-end min-h-[350px] bg-gray-50 bg-cover bg-center"
style={
category.image_url
? { backgroundImage: `url(${category.image_url})` }
: undefined
}
>
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
<Breadcrumbs
category={category}
basePath={basePath}
locale={locale}
/>

<div className="mb-4">
<h1 className="text-4xl font-bold text-gray-900">
{category.name}
</h1>
</div>

{/* Description */}
{category.description && (
<p className="mb-4 text-gray-600">{category.description}</p>
)}
</div>
</div>

{/* Subcategories */}
{category.children && category.children.length > 0 && (
<div className="container mx-auto px-4 sm:px-6 lg:px-8 mt-4">
<div className="flex flex-wrap gap-2 items-center border-b border-gray-100 pb-4">
{category.children.map((child) => (
<Link
key={child.id}
href={`${basePath}/c/${child.permalink}`}
className="px-1.5 py-1 hover:bg-gray-100 rounded-lg text-gray-700 transition-colors"
>
{child.name}
</Link>
))}
</div>
</div>
)}
</>
);
}
46 changes: 2 additions & 44 deletions src/app/[country]/[locale]/(storefront)/c/[...permalink]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getCategory } from "@/lib/data/categories";
import { generateCategoryMetadata } from "@/lib/metadata/category";
import { buildBreadcrumbJsonLd } from "@/lib/seo";
import { getStoreUrl } from "@/lib/store";
import { CategoryBanner } from "./CategoryBanner";
import { CategoryProductsContent } from "./CategoryProductsContent";

interface CategoryPageProps {
Expand Down Expand Up @@ -51,50 +52,7 @@ export default async function CategoryPage({ params }: CategoryPageProps) {
<JsonLd data={buildBreadcrumbJsonLd(category, basePath, storeUrl)} />
)}

<div
className="flex flex-col justify-end min-h-[350px] bg-gray-50 bg-cover bg-center"
style={
category.image_url
? { backgroundImage: `url(${category.image_url})` }
: undefined
}
>
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
<Breadcrumbs
category={category}
basePath={basePath}
locale={locale}
/>

<div className="mb-4">
<h1 className="text-4xl font-bold text-gray-900">
{category.name}
</h1>
</div>

{/* Description */}
{category.description && (
<p className="mb-4 text-gray-600">{category.description}</p>
)}
</div>
</div>

{/* Subcategories */}
{category.children && category.children.length > 0 && (
<div className="container mx-auto px-4 sm:px-6 lg:px-8 mt-4">
<div className="flex flex-wrap gap-2 items-center border-b border-gray-100 pb-4">
{category.children.map((child) => (
<Link
key={child.id}
href={`${basePath}/c/${child.permalink}`}
className="px-1.5 py-1 hover:bg-gray-100 rounded-lg text-gray-700 transition-colors"
>
{child.name}
</Link>
))}
</div>
</div>
)}
<CategoryBanner category={category} basePath={basePath} locale={locale} />

<div className="container mx-auto px-4 sm:px-6 lg:px-8 pt-4">
{/* Products */}
Expand Down
15 changes: 13 additions & 2 deletions src/lib/data/categories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,23 @@ export async function getCategories(params?: CategoryListParams) {
return cachedListCategories(params, options);
}

async function cachedGetCategory(
idOrPermalink: string,
params: { expand?: string[] } | undefined,
options: { locale?: string; country?: string },
) {
"use cache: remote";
cacheLife("minutes");
cacheTag("category");
return getClient().categories.get(idOrPermalink, params, options);
}

export async function getCategory(
idOrPermalink: string,
params?: CategoryListParams,
params?: { expand?: string[] },
) {
const options = await getLocaleOptions();
return getClient().categories.get(idOrPermalink, params, options);
return cachedGetCategory(idOrPermalink, params, options);
}

export async function getCategoryProducts(
Expand Down
Loading