Rezepte: listanje po 12 in oglasi med karticami

This commit is contained in:
sebastjan 2026-08-15 17:53:42 +02:00
parent a039cf48da
commit 8bf90c6942

View File

@ -1,4 +1,4 @@
import { useState } from "react";
import { useState, Fragment } from "react";
import { useQuery } from "@tanstack/react-query";
import { ChefHat, X, Calendar } from "lucide-react";
import { usePageMeta } from "@/hooks/use-page-meta";
@ -43,6 +43,8 @@ export default function RecipesPage() {
"Das Rezept des Tages und alle bisherigen Rezepte aus der Alpenküche bei FOLX TV — österreichische, bayerische und schweizer Hausmannskost."
);
const [selected, setSelected] = useState<DailyRecipe | null>(null);
const [page, setPage] = useState(0);
const PAGE_SIZE = 12;
const { data = [], isLoading } = useQuery<DailyRecipe[]>({
queryKey: ["/api/recipes"],
@ -51,6 +53,13 @@ export default function RecipesPage() {
const today = data[0];
const rest = data.slice(1);
const totalPages = Math.max(1, Math.ceil(rest.length / PAGE_SIZE));
const pageItems = rest.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE);
const goPage = (p: number) => {
setPage(Math.max(0, Math.min(totalPages - 1, p)));
document.getElementById("rezept-archiv")?.scrollIntoView({ behavior: "smooth", block: "start" });
};
return (
<div className="min-h-screen bg-background">
@ -96,16 +105,24 @@ export default function RecipesPage() {
<InArticleAd />
{rest.length > 0 && (
<section data-testid="section-recipe-archive">
<section data-testid="section-recipe-archive" id="rezept-archiv">
<div className="flex items-center gap-3 mb-4 mt-8">
<div className="h-px flex-1 bg-card-border" />
<h2 className="text-lg font-bold text-foreground px-3">Alle Rezepte</h2>
<div className="h-px flex-1 bg-card-border" />
</div>
<p className="text-xs text-muted-foreground mb-4">
{rest.length} Rezepte · Seite {page + 1} von {totalPages}
</p>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-5">
{rest.map((r) => (
{pageItems.map((r, idx) => (
<Fragment key={r.id}>
{idx > 0 && idx % 4 === 0 && (
<div key={`ad-${idx}`} className="sm:col-span-2 lg:col-span-3 xl:col-span-4">
<InArticleAd />
</div>
)}
<button
key={r.id}
onClick={() => setSelected(r)}
className="bg-card rounded-xl border border-card-border overflow-hidden text-left group hover:border-primary/50 transition-all hover:shadow-lg hover:shadow-primary/5"
data-testid={`card-recipe-${r.id}`}
@ -128,8 +145,41 @@ export default function RecipesPage() {
)}
</div>
</button>
</Fragment>
))}
</div>
{totalPages > 1 && (
<div className="flex flex-wrap items-center justify-center gap-2 mt-8" data-testid="recipe-pagination">
<button
onClick={() => goPage(page - 1)}
disabled={page === 0}
className="px-3 py-2 text-sm rounded-lg border border-card-border bg-card text-foreground disabled:opacity-40 hover:border-primary/50 transition-colors"
>
Zurück
</button>
{Array.from({ length: totalPages }).map((_, i) => (
<button
key={i}
onClick={() => goPage(i)}
className={`w-9 h-9 text-sm rounded-lg border transition-colors ${
i === page
? "bg-primary text-white border-primary"
: "bg-card text-foreground border-card-border hover:border-primary/50"
}`}
>
{i + 1}
</button>
))}
<button
onClick={() => goPage(page + 1)}
disabled={page === totalPages - 1}
className="px-3 py-2 text-sm rounded-lg border border-card-border bg-card text-foreground disabled:opacity-40 hover:border-primary/50 transition-colors"
>
Weiter
</button>
</div>
)}
</section>
)}