"use client" import { useState, useEffect } from "react" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Textarea } from "@/components/ui/textarea" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog" import { BookOpen, Loader2, Plus, Upload } from "lucide-react" import { toast } from "sonner" import Link from "next/link" interface Novel { id: string title: string slug: string authorName: string status: string totalChapters: number } export function NovelClient() { const [novels, setNovels] = useState([]) const [loading, setLoading] = useState(true) const [openAdd, setOpenAdd] = useState(false) const [submitting, setSubmitting] = useState(false) const [uploadingEpub, setUploadingEpub] = useState(false) // Form states const [title, setTitle] = useState("") const [authorName, setAuthorName] = useState("") const [description, setDescription] = useState("") const fetchNovels = async () => { try { const res = await fetch("/api/mod/truyen") if (!res.ok) throw new Error("Lấy danh sách lỗi") const data = await res.json() setNovels(data) } catch { toast.error("Không thể tải danh sách truyện") } finally { setLoading(false) } } useEffect(() => { fetchNovels() }, []) const handleAddSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!title || !authorName || !description) { toast.error("Vui lòng điền đầy đủ thông tin") return } setSubmitting(true) try { const res = await fetch("/api/mod/truyen", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ title, authorName, description }), }) if (!res.ok) throw new Error("Thêm mới thất bại") toast.success("Đã thêm truyện thành công!") setOpenAdd(false) setTitle("") setAuthorName("") setDescription("") fetchNovels() } catch { toast.error("Lỗi khi thêm truyện mới") } finally { setSubmitting(false) } } const handleEpubUpload = async (e: React.ChangeEvent) => { const file = e.target.files?.[0] if (!file) return if (!file.name.endsWith('.epub')) { toast.error("Vui lòng chọn file định dạng .epub") e.target.value = "" // Reset input return } setUploadingEpub(true) const formData = new FormData() formData.append("file", file) try { const res = await fetch("/api/mod/epub", { method: "POST", body: formData, }) if (!res.ok) { const data = await res.json() throw new Error(data.error || "Lỗi khi tải lên EPUB") } toast.success("Phân tích và xuất bản EPUB thành công!") fetchNovels() } catch (err: any) { toast.error(err.message || "Có lỗi xảy ra khi xử lý file EPUB") } finally { setUploadingEpub(false) e.target.value = "" // Reset input } } return (

Quản lý truyện

Thêm Truyện Mới Nhập thông tin cơ bản cho đầu truyện mới của bạn.
setTitle(e.target.value)} placeholder="Ví dụ: Phàm Nhân Tu Tiên" autoFocus />
setAuthorName(e.target.value)} placeholder="Ví dụ: Vong Ngữ" />