'use client'; import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { Search, Eye, Star, BookOpen } from 'lucide-react'; import Link from 'next/link'; import Image from 'next/image'; import { Book, BookSearchFilters } from '@/lib/types'; async function fetchBooks(filters: BookSearchFilters & { page: number; pageSize: number }) { const params = new URLSearchParams(); Object.entries(filters).forEach(([key, value]) => { if (value !== undefined && value !== '') { params.append(key, value.toString()); } }); const response = await fetch(`/api/books?${params}`); if (!response.ok) { throw new Error('Failed to fetch books'); } return response.json(); } export default function BooksPage() { const [searchFilters, setSearchFilters] = useState({}); const [page, setPage] = useState(1); const pageSize = 12; const { data, isLoading, error } = useQuery({ queryKey: ['books', searchFilters, page, pageSize], queryFn: () => fetchBooks({ ...searchFilters, page, pageSize }), }); const handleSearch = (e: React.FormEvent) => { e.preventDefault(); setPage(1); }; const handleInputChange = (field: keyof BookSearchFilters, value: string) => { setSearchFilters(prev => ({ ...prev, [field]: value || undefined, })); }; return (
{/* Header */}

图书检索

搜索和浏览图书馆藏书

{/* Search Filters */}
handleInputChange('title', e.target.value)} />
handleInputChange('author', e.target.value)} />
handleInputChange('isbn', e.target.value)} />
handleInputChange('classificationNo', e.target.value)} />
handleInputChange('available', e.target.checked ? 'true' : '')} />
{/* Results */} {isLoading ? (

加载中...

) : error ? (

加载失败,请重试

) : ( <> {/* Results Header */}

找到 {data?.data?.total || 0} 本图书

{/* Books Grid */}
{data?.data?.data?.map((book: Book) => (
{book.coverUrl ? ( {book.title} ) : ( )}

{book.title}

作者: {book.authors?.join(', ')}

出版社: {book.publisher}

可借: {book.availableCopies}/{book.totalCopies} {book.status === 'normal' ? '正常' : book.status === 'damaged' ? '损坏' : '下架'}
4.5
详情
))}
{/* Pagination */} {data?.data?.totalPages > 1 && (
{page > 1 && ( )} {[...Array(Math.min(5, data.data.totalPages))].map((_, i) => { const pageNum = i + 1; return ( ); })} {page < data.data.totalPages && ( )}
)} )}
); }