From 473e849dfac3262a2e76d2d830514f389ab27915 Mon Sep 17 00:00:00 2001 From: Froidefond Julien Date: Mon, 9 Mar 2026 22:18:47 +0100 Subject: [PATCH] feat(backoffice): add page preview carousel on book detail page Shows 5 pages at a time in a full-width grid with prev/next navigation. Pages are fetched via the existing proxy route with webp format. Co-Authored-By: Claude Sonnet 4.6 --- apps/backoffice/app/books/[id]/page.tsx | 7 +++ .../backoffice/app/components/BookPreview.tsx | 60 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 apps/backoffice/app/components/BookPreview.tsx diff --git a/apps/backoffice/app/books/[id]/page.tsx b/apps/backoffice/app/books/[id]/page.tsx index be817f4..4c5d06a 100644 --- a/apps/backoffice/app/books/[id]/page.tsx +++ b/apps/backoffice/app/books/[id]/page.tsx @@ -1,4 +1,5 @@ import { fetchLibraries, getBookCoverUrl, BookDto, apiFetch } from "../../../lib/api"; +import { BookPreview } from "../../components/BookPreview"; import Image from "next/image"; import Link from "next/link"; import { notFound } from "next/navigation"; @@ -157,6 +158,12 @@ export default async function BookDetailPage({ + + {book.page_count && book.page_count > 0 && ( +
+ +
+ )} ); } diff --git a/apps/backoffice/app/components/BookPreview.tsx b/apps/backoffice/app/components/BookPreview.tsx new file mode 100644 index 0000000..e329bd9 --- /dev/null +++ b/apps/backoffice/app/components/BookPreview.tsx @@ -0,0 +1,60 @@ +"use client"; + +import { useState } from "react"; +import Image from "next/image"; + +const PAGE_SIZE = 5; + +export function BookPreview({ bookId, pageCount }: { bookId: string; pageCount: number }) { + const [offset, setOffset] = useState(0); + + const pages = Array.from({ length: PAGE_SIZE }, (_, i) => offset + i + 1).filter( + (p) => p <= pageCount + ); + + return ( +
+
+

+ Preview + + pages {offset + 1}–{Math.min(offset + PAGE_SIZE, pageCount)} / {pageCount} + +

+
+ + +
+
+ +
+ {pages.map((pageNum) => ( +
+
+ {`Page +
+ {pageNum} +
+ ))} +
+
+ ); +}