'use client';
import {
BookOpen,
CheckCircle2,
Compass,
Library,
Search,
Sparkles,
XCircle,
} from 'lucide-react';
import Link from 'next/link';
import { useEffect, useMemo, useState } from 'react';
import { BookSource } from '@/lib/book.types';
function BooksHomeSkeleton() {
return (
{Array.from({ length: 6 }).map((_, index) => (
))}
);
}
function CapabilityPill({
enabled,
children,
}: {
enabled?: boolean;
children: React.ReactNode;
}) {
const Icon = enabled ? CheckCircle2 : XCircle;
return (
{children}
);
}
export default function BooksHomePage() {
const [sources, setSources] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
if (
typeof window !== 'undefined' &&
!(window as Window & { RUNTIME_CONFIG?: { BOOKS_ENABLED?: boolean } })
.RUNTIME_CONFIG?.BOOKS_ENABLED
) {
window.location.href = '/';
return;
}
fetch('/api/books/sources')
.then((res) => res.json())
.then((data) => setSources(data.sources || []))
.catch((err) => setError(err.message || '加载书源失败'))
.finally(() => setLoading(false));
}, []);
const stats = useMemo(() => {
const catalogCount = sources.filter(
(source) => source.capabilities?.catalogSupported
).length;
const searchCount = sources.filter(
(source) => source.capabilities?.searchSupported
).length;
return [
{ label: '可用书源', value: sources.length },
{ label: '支持目录', value: catalogCount },
{ label: '支持搜索', value: searchCount },
];
}, [sources]);
return (
MoonTVPlus Reading Library
电子书馆
搜索书籍
我的书架
{stats.map((stat) => (
{stat.value}
{stat.label}
))}
{loading ?
: null}
{error ? (
{error}
) : null}
{sources.map((source) => (
{source.name}
{source.type === 'legado' ? 'Legado' : 'OPDS'}
分类{source.capabilities?.catalogSupported ? '可用' : '不可用'}
搜索{source.capabilities?.searchSupported ? '可用' : '不可用'}
{source.capabilities?.catalogSupported && (
浏览目录
)}
{source.capabilities?.searchSupported && (
搜索书籍
)}
))}
{!loading && !error && sources.length === 0 ? (
暂无可用书源
) : null}
);
}