diff --git a/app/blog/page.tsx b/app/blog/page.tsx index 45f01e3..20e6279 100644 --- a/app/blog/page.tsx +++ b/app/blog/page.tsx @@ -4,7 +4,7 @@ import Image from "next/image"; import { Reveal, RevealGroup, RevealItem } from "../components/Reveal"; import { Newsletter } from "../components/Newsletter"; import { Footer } from "../components/Footer"; -import { getBlogPosts } from "../lib/payload"; +import { getBlogPosts, getBlogFilterEnabled } from "../lib/payload"; import { formatDate } from "../lib/format"; export const metadata: Metadata = { @@ -41,10 +41,10 @@ export default async function BlogOverviewPage({ }: { searchParams: Promise<{ categories?: string }>; }) { - const allPosts = await getBlogPosts(100); + const [allPosts, blogFilterEnabled] = await Promise.all([getBlogPosts(100), getBlogFilterEnabled()]); const { categories: categoriesParam } = await searchParams; - const activeCategories = categoriesParam ? categoriesParam.split(",").filter(Boolean) : []; - const allCategories = distinctCategories(allPosts); + const activeCategories = blogFilterEnabled && categoriesParam ? categoriesParam.split(",").filter(Boolean) : []; + const allCategories = blogFilterEnabled ? distinctCategories(allPosts) : []; const posts = activeCategories.length === 0 ? allPosts : allPosts.filter((post) => post.categories.some((c) => activeCategories.includes(c))); const [featured, ...rest] = posts; @@ -84,18 +84,31 @@ export default async function BlogOverviewPage({ hit the identical bug and switched to a plain animate — this filter bar doesn't need a scroll-reveal animation at all, so it's simplest to just not wrap it in Reveal in the first place. */} + {/* relative z-20 — the featured-post card right below pulls itself + up by -mt-8 with its own z-10 to overlap the *hero's* bottom + edge (its original, intended design). Inserting this filter + bar between the hero and that card meant the same -mt-8 pull + now overlapped THIS bar instead, and the card's higher/equal + stacking rendered on top of it, visually hiding the chips + behind the card. z-20 keeps this bar above that overlap + regardless. */} {allCategories.length > 1 && ( -
+
{allCategories.map((category) => { const active = activeCategories.includes(category); return ( {category} diff --git a/app/lib/payload.ts b/app/lib/payload.ts index 9ea22e9..6b08013 100644 --- a/app/lib/payload.ts +++ b/app/lib/payload.ts @@ -1039,6 +1039,37 @@ export async function getSearchEnabled(): Promise { return data.docs?.[0]?.searchEnabled ?? false; } +// Same pattern as getWishlistEnabled()/getSearchEnabled() — gates the +// shop overview's price-range filter (ProductGrid.tsx/PriceRangeFilter.tsx). +export async function getShopFilterEnabled(): Promise { + const params = new URLSearchParams({ "where[tenant.slug][equals]": TENANT_SLUG, limit: "1" }); + const res = await fetch(`${PAYLOAD_URL}/api/company-settings?${params}`, { + headers: { "x-order-service-secret": process.env.ORDER_SERVICE_SECRET || "" }, + next: { revalidate: 60 }, + }); + if (!res.ok) { + console.error(`getShopFilterEnabled: Payload returned ${res.status} ${res.statusText}`); + return false; + } + const data: { docs?: { shopFilterEnabled?: boolean }[] } = await res.json(); + return data.docs?.[0]?.shopFilterEnabled ?? false; +} + +// Same pattern — gates the blog overview's category filter (blog/page.tsx). +export async function getBlogFilterEnabled(): Promise { + const params = new URLSearchParams({ "where[tenant.slug][equals]": TENANT_SLUG, limit: "1" }); + const res = await fetch(`${PAYLOAD_URL}/api/company-settings?${params}`, { + headers: { "x-order-service-secret": process.env.ORDER_SERVICE_SECRET || "" }, + next: { revalidate: 60 }, + }); + if (!res.ok) { + console.error(`getBlogFilterEnabled: Payload returned ${res.status} ${res.statusText}`); + return false; + } + const data: { docs?: { blogFilterEnabled?: boolean }[] } = await res.json(); + return data.docs?.[0]?.blogFilterEnabled ?? false; +} + export type SeoSettings = { defaultTitle: string | null; titleTemplate: string | null; diff --git a/app/shop/components/ProductGrid.tsx b/app/shop/components/ProductGrid.tsx index 8878aa7..e39084c 100644 --- a/app/shop/components/ProductGrid.tsx +++ b/app/shop/components/ProductGrid.tsx @@ -1,6 +1,6 @@ import Link from "next/link"; import Image from "next/image"; -import { getProducts, getShippingSettings, getDefaultTaxRatePercent, getKleinunternehmer, getWishlistEnabled } from "../../lib/payload"; +import { getProducts, getShippingSettings, getDefaultTaxRatePercent, getKleinunternehmer, getWishlistEnabled, getShopFilterEnabled } from "../../lib/payload"; import { effectiveTaxRate } from "../../lib/cartTotals"; import { formatPrice, discountPercent } from "../../lib/format"; import { RevealGroup, RevealItem } from "../../components/Reveal"; @@ -21,12 +21,13 @@ import { PriceRangeFilter } from "./PriceRangeFilter"; // buckets — tried buckets-as-toggle-chips first, reverted 2026-07-30 // ("keine toggle badges"). export async function ProductGrid({ searchParams }: { searchParams?: { minPrice?: string; maxPrice?: string } }) { - const [allProducts, shipping, defaultTaxRate, kleinunternehmer, wishlistEnabled] = await Promise.all([ + const [allProducts, shipping, defaultTaxRate, kleinunternehmer, wishlistEnabled, shopFilterEnabled] = await Promise.all([ getProducts(), getShippingSettings(), getDefaultTaxRatePercent(), getKleinunternehmer(), getWishlistEnabled(), + getShopFilterEnabled(), ]); const allActiveProducts = allProducts.filter((p) => p.active); @@ -41,13 +42,13 @@ export async function ProductGrid({ searchParams }: { searchParams?: { minPrice? const catalogPrices = allActiveProducts.map((p) => p.price); const catalogMin = Math.min(...catalogPrices); const catalogMax = Math.max(...catalogPrices); - const minPrice = searchParams?.minPrice ? Number(searchParams.minPrice) : null; - const maxPrice = searchParams?.maxPrice ? Number(searchParams.maxPrice) : null; + const minPrice = shopFilterEnabled && searchParams?.minPrice ? Number(searchParams.minPrice) : null; + const maxPrice = shopFilterEnabled && searchParams?.maxPrice ? Number(searchParams.maxPrice) : null; const products = allActiveProducts.filter((p) => (minPrice === null || p.price >= minPrice) && (maxPrice === null || p.price <= maxPrice)); return (
- {catalogMin !== catalogMax && } + {shopFilterEnabled && catalogMin !== catalogMax && } {products.length === 0 &&

Keine Produkte in dieser Preisspanne gefunden.

}