Rezepte: listanje po 12 in oglasi med karticami
This commit is contained in:
parent
a039cf48da
commit
8bf90c6942
@ -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>
|
||||
)}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user