141 lines
3.9 KiB
TypeScript
141 lines
3.9 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import Link from "next/link";
|
|
|
|
type PageData = {
|
|
number: number;
|
|
imageUrl: string;
|
|
};
|
|
|
|
type PageReaderProps = {
|
|
pages: PageData[];
|
|
mangaSlug: string;
|
|
mangaTitle: string;
|
|
chapterNumber: number;
|
|
chapterTitle: string;
|
|
prevChapter: number | null;
|
|
nextChapter: number | null;
|
|
};
|
|
|
|
export function PageReader({
|
|
pages,
|
|
mangaSlug,
|
|
mangaTitle,
|
|
chapterNumber,
|
|
chapterTitle,
|
|
prevChapter,
|
|
nextChapter,
|
|
}: PageReaderProps) {
|
|
const [showUI, setShowUI] = useState(true);
|
|
|
|
return (
|
|
<div className="min-h-screen bg-black relative">
|
|
{/* Top bar */}
|
|
<div
|
|
className={`fixed top-0 left-0 right-0 z-50 bg-black/90 backdrop-blur-sm transition-transform duration-300 ${
|
|
showUI ? "translate-y-0" : "-translate-y-full"
|
|
}`}
|
|
>
|
|
<div className="flex items-center gap-3 px-4 h-12 max-w-4xl mx-auto">
|
|
<Link
|
|
href={`/manga/${mangaSlug}`}
|
|
className="text-white/80 hover:text-white transition-colors"
|
|
>
|
|
<svg
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth={2}
|
|
className="w-6 h-6"
|
|
>
|
|
<polyline points="15 18 9 12 15 6" />
|
|
</svg>
|
|
</Link>
|
|
<div className="min-w-0 flex-1">
|
|
<p className="text-white text-sm font-medium truncate">
|
|
{mangaTitle}
|
|
</p>
|
|
<p className="text-white/50 text-xs truncate">
|
|
Ch. {chapterNumber} — {chapterTitle}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Pages - vertical scroll (webtoon style, best for mobile) */}
|
|
<div
|
|
className="max-w-4xl mx-auto"
|
|
onClick={() => setShowUI(!showUI)}
|
|
>
|
|
{pages.map((page) => (
|
|
<div key={page.number} className="relative">
|
|
<img
|
|
src={page.imageUrl}
|
|
alt={`Page ${page.number}`}
|
|
className="w-full h-auto block"
|
|
loading={page.number <= 3 ? "eager" : "lazy"}
|
|
/>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Bottom navigation */}
|
|
<div
|
|
className={`fixed bottom-0 left-0 right-0 z-50 bg-black/90 backdrop-blur-sm transition-transform duration-300 pb-safe ${
|
|
showUI ? "translate-y-0" : "translate-y-full"
|
|
}`}
|
|
>
|
|
<div className="flex items-center justify-between px-4 h-14 max-w-4xl mx-auto">
|
|
{prevChapter ? (
|
|
<Link
|
|
href={`/manga/${mangaSlug}/${prevChapter}`}
|
|
className="flex items-center gap-1 text-white/80 hover:text-white text-sm transition-colors"
|
|
>
|
|
<svg
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth={2}
|
|
className="w-5 h-5"
|
|
>
|
|
<polyline points="15 18 9 12 15 6" />
|
|
</svg>
|
|
Prev
|
|
</Link>
|
|
) : (
|
|
<div />
|
|
)}
|
|
<span className="text-white/50 text-xs">
|
|
{pages.length} pages
|
|
</span>
|
|
{nextChapter ? (
|
|
<Link
|
|
href={`/manga/${mangaSlug}/${nextChapter}`}
|
|
className="flex items-center gap-1 text-white/80 hover:text-white text-sm transition-colors"
|
|
>
|
|
Next
|
|
<svg
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth={2}
|
|
className="w-5 h-5"
|
|
>
|
|
<polyline points="9 18 15 12 9 6" />
|
|
</svg>
|
|
</Link>
|
|
) : (
|
|
<Link
|
|
href={`/manga/${mangaSlug}`}
|
|
className="text-accent text-sm font-medium"
|
|
>
|
|
Done
|
|
</Link>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|