Add EPUB upload + DB integration

Add server-side EPUB import and integrate Prisma + Mongo for novels/chapters. Introduces a new moderator API route (app/api/mod/epub/route.ts) that parses .epub files, creates a novel record in Prisma, and inserts chapter documents into MongoDB via the Chapter Mongoose model. Frontend: novel management UI now supports EPUB upload (app/mod/truyen/novel-client.tsx) with progress/toasts and preserves the manual 'Add novel' dialog. Convert app pages to fetch real data from Prisma and Mongo (app/page.tsx, app/truyen/[slug]/page.tsx, app/truyen/[slug]/[chapterId]/page.tsx), adapt types/props to use authorName, and adjust chapter/comment IDs to use Mongo _id strings. Minor fixes: TTS player logs playback errors, UI text fixes (e.g. "Chương"), and novel-card/other components updated for authorName. package.json updated with epub2, html-to-text and types; pnpm lock updated. Adds tsconfig.tsbuildinfo.
This commit is contained in:
2026-03-05 18:02:11 +07:00
parent 112e8604e2
commit ce805adb08
13 changed files with 582 additions and 138 deletions
+13 -13
View File
@@ -20,7 +20,7 @@ export const novels: Novel[] = [
id: "1",
title: "Phàm Nhân Tu Tiên",
slug: "pham-nhan-tu-tien",
author: "Vong Ngữ",
authorName: "Vong Ngữ",
coverColor: "from-amber-500 to-orange-600",
description: "Hàn Lập, một thiếu niên nghèo khó từ một ngôi làng nhỏ, tình cờ bước vào con đường tu tiên. Không có thiên phú xuất chúng, không có bối cảnh gia thế, chỉ bằng sự kiên trì và trí tuệ phi thường, hắn từng bước vượt qua muôn vàn khó khăn, chiến đấu với yêu ma quỷ quái, đối đầu với các thế lực lớn trong tu chân giới. Từ một phàm nhân bình thường, Hàn Lập dần dần khám phá ra bí mật của thiên địa, tìm kiếm con đường trường sinh bất lão.",
genres: ["tien-hiep", "huyen-huyen"],
@@ -37,7 +37,7 @@ export const novels: Novel[] = [
id: "2",
title: "Đấu Phá Thương Khung",
slug: "dau-pha-thuong-khung",
author: "Thiên Tằm Thổ Đậu",
authorName: "Thiên Tằm Thổ Đậu",
coverColor: "from-blue-500 to-indigo-600",
description: "Tiêu Viêm, từng là thiên tài trẻ tuổi nhất Ô Thản thành, bỗng nhiên mất đi toàn bộ đấu khí vào năm 11 tuổi. Ba năm sau, cậu tình cờ khám phá ra bí mật ẩn giấu trong chiếc nhẫn truyền gia, từ đó bắt đầu hành trình tu luyện phi thường. Với sự giúp đỡ của Dược Lão, Tiêu Viêm quyết tâm lấy lại vinh quang đã mất và chinh phục đỉnh cao của thế giới đấu khí.",
genres: ["huyen-huyen", "tien-hiep"],
@@ -54,7 +54,7 @@ export const novels: Novel[] = [
id: "3",
title: "Hoa Thiên Cốt",
slug: "hoa-thien-cot",
author: "Fresh Quả Quả",
authorName: "Fresh Quả Quả",
coverColor: "from-pink-400 to-rose-500",
description: "Hoa Thiên Cốt kể về câu chuyện tình yêu xuyên suốt ba kiếp giữa Hoa Thiên Cốt và Bạch Tử Họa. Nàng là đệ tử của Trường Lưu môn, chàng là chưởng môn Trường Lưu - sư phụ của nàng. Mối tình cấm đoán giữa sư đồ, những hiểu lầm, hy sinh và sự kiên trung trong tình yêu khiến độc giả không khỏi xúc động.",
genres: ["ngon-tinh", "tien-hiep"],
@@ -71,7 +71,7 @@ export const novels: Novel[] = [
id: "4",
title: "Anh Hùng Xạ Điêu",
slug: "anh-hung-xa-dieu",
author: "Kim Dung",
authorName: "Kim Dung",
coverColor: "from-emerald-500 to-teal-600",
description: "Câu chuyện về Quách Tĩnh, một chàng trai chất phác nhưng kiên trì, cùng Hoàng Dung, cô gái thông minh tuyệt đỉnh. Giữa bối cảnh đất nước bị xâm lăng, hai người cùng nhau trải qua bao sóng gió giang hồ, học được những tuyệt kỹ võ công, và cuối cùng trở thành anh hùng dân tộc.",
genres: ["kiem-hiep", "lich-su"],
@@ -88,7 +88,7 @@ export const novels: Novel[] = [
id: "5",
title: "Toàn Chức Cao Thủ",
slug: "toan-chuc-cao-thu",
author: "Hồ Điệp Lam",
authorName: "Hồ Điệp Lam",
coverColor: "from-cyan-500 to-blue-600",
description: "Diệp Tu, đỉnh cao của giới game Glory, bị buộc phải rời đội tuyển chuyên nghiệp. Nhưng với mười năm kinh nghiệm và kỹ thuật vô song, anh bắt đầu lại từ đầu tại một quán net nhỏ. Với tài khoản mới và quyết tâm mãnh liệt, Diệp Tu từng bước quay trở lại đỉnh cao vinh quang.",
genres: ["do-thi", "hai-huoc"],
@@ -105,7 +105,7 @@ export const novels: Novel[] = [
id: "6",
title: "Thôn Phệ Tinh Không",
slug: "thon-phe-tinh-khong",
author: "Thần Đông",
authorName: "Thần Đông",
coverColor: "from-violet-500 to-purple-600",
description: "Trong tương lai, khi Trái Đất trải qua biến cố lớn, con người phát hiện ra năng lực chiến đấu tiềm ẩn. La Phong, một thanh niên bình thường, tình cờ gặp được một sinh vật ngoài hành tinh đặc biệt, từ đó bắt đầu hành trình chinh phục vũ trụ bao la. Từ Trái Đất đến các vì sao, La Phong dần trở thành chiến sĩ mạnh nhất thiên hà.",
genres: ["khoa-huyen", "huyen-huyen"],
@@ -122,7 +122,7 @@ export const novels: Novel[] = [
id: "7",
title: "Khánh Dư Niên",
slug: "khanh-du-nien",
author: "Miêu Nị",
authorName: "Miêu Nị",
coverColor: "from-yellow-500 to-amber-600",
description: "Phạm Nhàn, một thanh niên từ thế giới hiện đại, xuyên không đến một thế giới cổ đại với ký ức về một nền văn minh đã mất. Với kiến thức từ kiếp trước, hắn dần vượt qua các âm mưu cung đình, chiến đấu với các thế lực ngầm, và khám phá ra bí mật kinh thiên về nguồn gốc của thế giới này.",
genres: ["lich-su", "huyen-huyen"],
@@ -139,7 +139,7 @@ export const novels: Novel[] = [
id: "8",
title: "Yêu Thần Ký",
slug: "yeu-than-ky",
author: "Phát Tiêu Đích Mao Nhi",
authorName: "Phát Tiêu Đích Mao Nhi",
coverColor: "from-red-500 to-rose-600",
description: "Nhiếp Ly, vị Yêu Thần hùng mạnh nhất, bị phản bội và hy sinh trong trận chiến cuối cùng. Nhưng khi tỉnh dậy, hắn phát hiện mình đã quay trở lại thời niên thiếu. Với kinh nghiệm và kiến thức từ kiếp trước, Nhiếp Ly quyết tâm thay đổi vận mệnh, cứu lấy những người thân yêu và ngăn chặn thảm họa sắp xảy đến.",
genres: ["huyen-huyen", "tien-hiep"],
@@ -156,7 +156,7 @@ export const novels: Novel[] = [
id: "9",
title: "Thiên Quan Tứ Phúc",
slug: "thien-quan-tu-phuc",
author: "Mặc Hương Đồng Khứu",
authorName: "Mặc Hương Đồng Khứu",
coverColor: "from-sky-400 to-indigo-500",
description: "Tạ Liên, thái tử triều đại Tiên Lạc, ba lần phi thăng thành thiên quan và ba lần bị đánh rơi. Tám trăm năm sau, ngài lại một lần nữa phi thăng, nhưng lần này không ai chào đón. Trong hành trình thu thập công đức, Tạ Liên gặp lại Hoa Thành - một Quỷ vương bí ẩn có mối quan hệ sâu xa với ngài từ tám trăm năm trước.",
genres: ["ngon-tinh", "huyen-huyen"],
@@ -173,7 +173,7 @@ export const novels: Novel[] = [
id: "10",
title: "Thám Tử Lừng Danh",
slug: "tham-tu-lung-danh",
author: "Linh Vũ",
authorName: "Linh Vũ",
coverColor: "from-slate-500 to-zinc-700",
description: "Lâm Phong, một thanh tra cảnh sát trẻ tuổi với khả năng quan sát phi thường, liên tiếp phá giải những vụ án bí ẩn nhất thành phố. Mỗi vụ án đều ẩn chứa những bí mật đen tối, và càng đi sâu, Lâm Phong càng phát hiện ra một tổ chức tội phạm khổng lồ đang ẩn nấp trong bóng tối.",
genres: ["trinh-tham", "do-thi"],
@@ -190,7 +190,7 @@ export const novels: Novel[] = [
id: "11",
title: "Đại Quân Sư",
slug: "dai-quan-su",
author: "Trần Phong",
authorName: "Trần Phong",
coverColor: "from-green-600 to-emerald-700",
description: "Trương Lương, một thiên tài quân sự thời hiện đại, xuyên không về thời Tam Quốc. Với kiến thức chiến thuật vượt thời đại, hắn trở thành quân sư cho một thế lực nhỏ và từng bước thay đổi cục diện thiên hạ. Những trận chiến sử thi, những mưu kế thâm sâu, tất cả đều được tái hiện qua góc nhìn của một người hiện đại.",
genres: ["quan-su", "lich-su"],
@@ -207,7 +207,7 @@ export const novels: Novel[] = [
id: "12",
title: "Vạn Giới Thần Chủ",
slug: "van-gioi-than-chu",
author: "Nhất Niệm Vĩnh Hằng",
authorName: "Nhất Niệm Vĩnh Hằng",
coverColor: "from-orange-500 to-red-600",
description: "Lâm Phàm tình cờ có được một mảnh ngọc bội cổ xưa có thể mở cánh cửa đến vạn giới. Mỗi thế giới đều có quy tắc riêng, sức mạnh riêng, và nguy hiểm riêng. Lâm Phàm phải chinh phục từng thế giới, thu thập sức mạnh và trí tuệ, để cuối cùng trở thành bá chủ vạn giới.",
genres: ["tien-hiep", "huyen-huyen"],
@@ -355,7 +355,7 @@ export function searchNovels(query: string): Novel[] {
return novels.filter(
(n) =>
n.title.toLowerCase().includes(q) ||
n.author.toLowerCase().includes(q) ||
n.authorName.toLowerCase().includes(q) ||
n.description.toLowerCase().includes(q)
)
}
+1 -1
View File
@@ -10,7 +10,7 @@ export interface Novel {
id: string
title: string
slug: string
author: string
authorName: string
coverColor: string
description: string
genres: string[]