Added releases changed the way apis work underneath to give more room for caching, i.e remove unneeded crap when it is unneeded

This commit is contained in:
2025-01-21 00:43:14 -05:00
parent 9baa792111
commit 52b2301fc1
8 changed files with 343 additions and 59 deletions

View File

@@ -0,0 +1,33 @@
import { fetchAnnouncementById } from "@/lib/api";
import { Announcement } from "@/lib/types";
import { formatDateToMonthDayYear } from "@/lib/utils";
export const metadata = {
title: 'Announcement Detail Page',
description: 'NullTranslationGroup Announcement page',
};
export type paramsType = Promise<{ announcementId: string }>;
export default async function AnnouncementDetailPage(props: {params: paramsType}) {
const { announcementId } = await props.params;
let announcement: Announcement;
try{
announcement = await fetchAnnouncementById(announcementId);
}
catch (error) {
console.error(error);
return (
<div className="prose dark:prose-invert mx-auto p-6 bg-white dark:bg-gray-800 shadow-md rounded-lg mt-4">
<div dangerouslySetInnerHTML={{ __html: '<center><h1> Announcement not found !</h1></center>' }}></div>
</div>
)
}
return (
<div className="prose dark:prose-invert mx-auto p-6 bg-white dark:bg-gray-800 shadow-md rounded-lg mt-4">
<h1>{announcement.title}</h1>
<h2>Release Date: {formatDateToMonthDayYear(new Date(announcement.datetime))}</h2>
<div dangerouslySetInnerHTML={{ __html: announcement.content }}></div>
</div>
)
}

View File

@@ -0,0 +1,38 @@
import { formatDateToMonthDayYear } from "@/lib/utils";
import { Announcement } from "@/lib/types";
import { fetchAnnouncements } from "@/lib/api";
export const metadata = {
title: 'Annoucement page',
description: 'NullTranslationGroup Announcement page',
};
export default async function AnnouncementPage() {
let announcements = [];
try {
announcements = await fetchAnnouncements();
} catch (error) {
console.error(error);
return (
<div className="text-center mt-10 text-red-500">
<p>Failed to load announcements.</p>
</div>
);
}
const sorted_announcements:Announcement[] = announcements.sort((a, b) => new Date(a.datetime).getTime() - new Date(b.datetime).getTime());
return (
<div className="max-w-6xl mx-auto py-10 px-4">
{sorted_announcements.map((announcement) => (
<li key={announcement.id} className="mb-2 list-none">
<div className="text-lg font-semibold">{announcement.title}</div>
<div className="text-sm text-gray-500">{formatDateToMonthDayYear(new Date(announcement.datetime))}</div>
</li>
))}
</div>
);
}

View File

@@ -1,7 +1,7 @@
import React from "react";
import NavigationButtons from "@/components/NavigationButtons";
import { Book, Chapter } from "@/lib/types";
import { fetchBookById } from "@/lib/api";
import { Chapter } from "@/lib/types";
import {fetchChapterByBookId } from "@/lib/api";
export type paramsType = Promise<{ bookId: string; chapterId: string }>;
export const metadata = {
@@ -13,13 +13,12 @@ export const metadata = {
export default async function ChapterPage(props: { params: paramsType}) {
const { bookId, chapterId } = await props.params;
let book: Book;
let chapters: Chapter[];
try{
book = await fetchBookById(bookId);
chapters = await fetchChapterByBookId(bookId, chapterId);
}
catch (error) {
console.error(error);
return (
<div className="prose dark:prose-invert mx-auto p-6 bg-white dark:bg-gray-800 shadow-md rounded-lg mt-4">
<div dangerouslySetInnerHTML={{ __html: '<center><h1> Chapter not found !</h1></center>' }}></div>
@@ -28,11 +27,10 @@ export default async function ChapterPage(props: { params: paramsType}) {
)
}
const chapters :Chapter[] = book.chapters;
const sorted_chapters:Chapter[] = chapters.sort((a, b) => a.number - b.number);
const current_chapter = sorted_chapters.find((chapter) => chapter.documentId === chapterId) || null;
const next_chapter = current_chapter ? sorted_chapters.find((chapter) => chapter.number === current_chapter.number + 1)?.documentId || "" : "";
const prev_chapter = current_chapter ? sorted_chapters.find((chapter) => chapter.number === current_chapter.number - 1)?.documentId || "" : "";
const next_chapter = current_chapter ? sorted_chapters.find((chapter) => chapter.number === current_chapter.number + 1 && new Date(chapter.release_datetime).getTime() <= new Date().getTime())?.documentId || "" : "";
const prev_chapter = current_chapter ? sorted_chapters.find((chapter) => chapter.number === current_chapter.number - 1 && new Date(chapter.release_datetime).getTime() <= new Date().getTime())?.documentId || "" : "";
if(current_chapter === null){
return (

144
src/app/releases/page.tsx Normal file
View File

@@ -0,0 +1,144 @@
import { formatDateToMonthDayYear } from "@/lib/utils";
import { Chapter, Ad } from "@/lib/types";
import { fetchReleases } from "@/lib/api";
import Link from "next/link";
export const metadata = {
title: 'Release page',
description: 'NullTranslationGroup Announcement page',
};
export default async function ReleasePage() {
let current_chapters: Chapter[] = [];
let future_chapters: Chapter[] = [];
try {
const releases = await fetchReleases();
current_chapters = releases.current_chapters
future_chapters = releases.future_chapters
} catch (error) {
console.error(error);
return (
<div className="text-center mt-10 text-red-500">
<p>Failed to load releases.</p>
</div>
);
}
const sorted_current_chapters = current_chapters.sort((a, b) => new Date(a.release_datetime).getTime() - new Date(b.release_datetime).getTime());
const sorted_future_chapters = future_chapters.sort((a, b) => new Date(a.release_datetime).getTime() - new Date(b.release_datetime).getTime());
const groupChaptersByNovel = (chapters: Chapter[]) => {
return chapters.reduce((acc, chapter) => {
const bookTitle = chapter.book?.title || "Unknown Title";
if (!acc[bookTitle]) {
acc[bookTitle] = [];
}
acc[bookTitle].push(chapter);
return acc;
}, {} as Record<string, Chapter[]>);
};
const groupedCurrentChapters = groupChaptersByNovel(sorted_current_chapters)
const groupedFutureChapters = groupChaptersByNovel(sorted_future_chapters);
return (
<div className="mx-auto p-6 bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-gray-100 min-h-screen">
<div className="hidden md:block bg-yellow-500 text-black py-2 px-4 rounded-lg hover:bg-yellow-600 transition duration-200 mb-6">
<a
href={Ad.patreon}
target="_blank"
rel="noopener noreferrer"
className="font-semibold text-center block"
>
WANT TO READ AHEAD OF SCHEDULE ? JOIN OUR PATREON !
</a>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
{/* Current Releases Section */}
<div>
<h2 className="text-2xl font-bold text-yellow-500 mb-6 border-b-2 border-yellow-500 pb-2">
Current Releases
</h2>
{Object.keys(groupedCurrentChapters).length > 0 ? (
Object.entries(groupedCurrentChapters)
.sort(([titleA], [titleB]) => titleA.localeCompare(titleB))
.map(([bookTitle, chapters]) => (
<div key={bookTitle} className="mb-6">
<Link href={`/books/${chapters[0].book?.documentId}`}
className="text-lg font-semibold text-gray-700 dark:text-yellow-300 mb-4 hover:underline">
{bookTitle}
</Link>
<ul className="space-y-4">
{chapters.map((chapter) => (
<li
key={chapter.id}
className="p-4 bg-yellow-100 dark:bg-yellow-800 text-gray-800 dark:text-gray-100 rounded-lg shadow-sm border border-yellow-300 dark:border-yellow-700 transition-transform transform hover:scale-105"
>
<Link href={`books/${chapter.book?.documentId}/chapters/${chapter.documentId}`} className="block">
<h4 className="text-md font-medium">
Chapter {chapter.number}: {chapter.title}
</h4>
<p className="text-sm">
Released on:{" "}
{formatDateToMonthDayYear(
new Date(chapter.release_datetime)
)}
</p>
</Link>
</li>
))}
</ul>
</div>
))
) : (
<p className="text-gray-600 dark:text-gray-400 italic">
No current releases available.
</p>
)}
</div>
{/* Future Releases Section */}
<div>
<h2 className="text-2xl font-bold text-blue-500 mb-6 border-b-2 border-blue-500 pb-2">
Future Releases
</h2>
{Object.keys(groupedFutureChapters).length > 0 ? (
Object.entries(groupedFutureChapters)
.sort(([titleA], [titleB]) => titleA.localeCompare(titleB))
.map(([bookTitle, chapters]) => (
<div key={bookTitle} className="mb-6">
<Link href={`/books/${chapters[0].book?.documentId}`}
className="text-lg font-semibold text-blue-700 dark:text-blue-300 mb-4 hover:underline">
{bookTitle}
</Link>
<ul className="space-y-4">
{chapters.map((chapter) => (
<li
key={chapter.id}
className="p-4 bg-blue-100 dark:bg-blue-800 text-gray-800 dark:text-gray-100 rounded-lg shadow-sm border border-blue-300 dark:border-blue-700 transition-transform transform hover:scale-105"
>
<h4 className="text-md font-medium">
Chapter {chapter.number}: {chapter.title}
</h4>
<p className="text-sm">
Release date:{" "}
{formatDateToMonthDayYear(
new Date(chapter.release_datetime)
)}
</p>
</li>
))}
</ul>
</div>
))
) : (
<p className="text-gray-600 dark:text-gray-400 italic">
No future releases available.
</p>
)}
</div>
</div>
</div>
);
}