Full push for initial version of NullTranslationGroup website.
This commit is contained in:
46
src/app/books/[bookId]/chapters/[chapterId]/page.tsx
Normal file
46
src/app/books/[bookId]/chapters/[chapterId]/page.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import React from "react";
|
||||
import NavigationButtons from "@/components/NavigationButtons";
|
||||
import { Chapter } from "@/lib/types";
|
||||
import { fetchBookById } from "@/lib/api";
|
||||
|
||||
export type paramsType = Promise<{ bookId: string; chapterId: string }>;
|
||||
|
||||
// Dynamic page component
|
||||
export default async function ChapterPage(props: { params: paramsType}) {
|
||||
const { bookId, chapterId } = await props.params;
|
||||
|
||||
const book = await fetchBookById(bookId);
|
||||
|
||||
const chapters :Chapter[] = book.chapters;
|
||||
const sorted_chapters:Chapter[] = chapters.sort((a, b) => a.Chapter_Number - b.Chapter_Number);
|
||||
const current_chapter = sorted_chapters.find((chapter) => chapter.documentId === chapterId) || undefined;
|
||||
const next_chapter = current_chapter ? sorted_chapters.find((chapter) => chapter.Chapter_Number === current_chapter.Chapter_Number + 1)?.documentId || "" : "";
|
||||
const prev_chapter = current_chapter ? sorted_chapters.find((chapter) => chapter.Chapter_Number === current_chapter.Chapter_Number - 1)?.documentId || "" : "";
|
||||
// Fetch chapter data
|
||||
|
||||
if (current_chapter === undefined) {
|
||||
return (
|
||||
<div className="relative bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-gray-100 min-h-screen">
|
||||
<div className="prose dark:prose-invert mx-auto p-6 bg-white dark:bg-gray-800 shadow-md rounded-lg">
|
||||
<div dangerouslySetInnerHTML={{ __html: '<center><h1> Chapter not found !</h1></center>' }}></div>
|
||||
|
||||
{/* Client component for navigation */}
|
||||
<NavigationButtons bookId={bookId} documentId={chapterId} prevChapter={prev_chapter} nextChapter={next_chapter} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="prose dark:prose-invert mx-auto p-6 bg-white dark:bg-gray-800 shadow-md rounded-lg">
|
||||
<NavigationButtons bookId={bookId} documentId={chapterId} prevChapter={prev_chapter} nextChapter={next_chapter} />
|
||||
|
||||
<div className="pt-4" dangerouslySetInnerHTML={{ __html: current_chapter.Content }}></div>
|
||||
|
||||
{/* Client component for navigation */}
|
||||
<NavigationButtons bookId={bookId} documentId={chapterId} prevChapter={prev_chapter} nextChapter={next_chapter}/>
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
88
src/app/books/[bookId]/page.tsx
Normal file
88
src/app/books/[bookId]/page.tsx
Normal file
@@ -0,0 +1,88 @@
|
||||
import { fetchBookChapterLinks } from "@/lib/api";
|
||||
import { Book } from "@/lib/types";
|
||||
import { formatDateToMonthDayYear } from "@/lib/utils";
|
||||
import ChapterDropdown from "@/components/ChapterDropdown";
|
||||
|
||||
export type paramsType = Promise<{ bookId: string}>;
|
||||
|
||||
|
||||
export default async function BookPage(props: { params: paramsType }) {
|
||||
const { bookId } = await props.params;
|
||||
|
||||
let book: Book;
|
||||
try {
|
||||
book = await fetchBookChapterLinks(bookId);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return (
|
||||
<div className="text-center mt-10 text-red-500">
|
||||
Error fetching book data. Please try again later.
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const { Name, Author, Description, chapters } = book;
|
||||
const recentChapters = chapters.length > 6 ? chapters.slice(chapters.length - 6, chapters.length) : chapters;
|
||||
return (
|
||||
<div className="max-w-6xl mx-auto py-10 px-4">
|
||||
<div className="flex items-center justify-between mb-4 pt-4">
|
||||
{/* Book Title */}
|
||||
<h1 className="text-5xl font-bold">{Name}</h1>
|
||||
|
||||
{/* Patreon Button */}
|
||||
<a
|
||||
href="https://www.patreon.com/c/nulltranslationgroup/membership?view_as=patron" // Replace with your Patreon URL
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="ml-4 bg-yellow-500 text-white font-semibold py-2 px-4 rounded hover:bg-yellow-600 transition duration-200"
|
||||
>
|
||||
Join Our Patreon for Unreleased Chapters
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p className="text-lg text-gray-600 dark:text-gray-400 mb-4">
|
||||
<strong>Author:</strong> {Author}
|
||||
<br></br>
|
||||
<strong>Translator:</strong> Null Translation Group
|
||||
</p>
|
||||
<p className="mb-6">{Description}</p>
|
||||
|
||||
<h2 className="text-3xl font-semibold mb-4">Recent Chapters</h2>
|
||||
<ul className="grid gap-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
|
||||
{recentChapters.map((chapter) => (
|
||||
<li key={chapter.id}>
|
||||
<a
|
||||
href={`/books/${bookId}/chapters/${chapter.documentId}`}
|
||||
className="block bg-white dark:bg-gray-800 rounded-lg shadow p-4 hover:shadow-lg transition duration-200"
|
||||
>
|
||||
<h3 className="text-xl font-medium">
|
||||
Chapter {chapter.Chapter_Number}: {chapter.Name}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 mt-2">
|
||||
<strong>Release Date:</strong> {formatDateToMonthDayYear(new Date(chapter.ReleaseDate))}
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="flex items-center justify-between mb-4 pt-4">
|
||||
<h2 className="text-3xl font-semibold">All Chapters</h2>
|
||||
<ChapterDropdown chapters={chapters} bookId={bookId} />
|
||||
</div>
|
||||
{chapters.map((chapter) => (
|
||||
<li key={chapter.id} className="mb-2 list-none">
|
||||
<a
|
||||
href={`/books/${bookId}/chapters/${chapter.documentId}`}
|
||||
className="block bg-white dark:bg-gray-800 rounded-lg shadow p-4 hover:shadow-lg transition duration-200"
|
||||
>
|
||||
<h3 className="text-xl font-medium">
|
||||
Chapter {chapter.Chapter_Number}: {chapter.Name}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 mt-2">
|
||||
<strong>Release Date:</strong> {formatDateToMonthDayYear(new Date(chapter.ReleaseDate))}
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</div>);
|
||||
}
|
||||
Reference in New Issue
Block a user