This commit is contained in:
Yuriy Panov
2026-02-02 17:12:25 +06:00
commit 3004f712f3
19 changed files with 1157 additions and 0 deletions

108
books/screens/Library.tsx Normal file
View File

@@ -0,0 +1,108 @@
import React, { useState } from 'react';
import { Book, AppScreen } from '../types';
interface LibraryProps {
books: Book[];
onBookClick: (book: Book) => void;
onAddClick: () => void;
}
export const Library: React.FC<LibraryProps> = ({ books, onBookClick, onAddClick }) => {
const [search, setSearch] = useState('');
const filteredBooks = books.filter(b =>
b.title.toLowerCase().includes(search.toLowerCase()) ||
b.author.toLowerCase().includes(search.toLowerCase())
);
return (
<div className="flex flex-col h-full bg-background-dark">
<header className="sticky top-0 z-30 bg-background-dark/95 backdrop-blur-md border-b border-white/5 pb-2 pt-4">
<div className="flex items-center px-4 py-3 justify-between">
<div className="w-10"></div>
<h2 className="text-xl font-bold leading-tight tracking-tight flex-1 text-center">Книжная полка</h2>
<div className="w-10 flex justify-end">
<button className="text-white hover:text-primary transition-colors">
<span className="material-symbols-outlined">notifications</span>
</button>
</div>
</div>
<div className="px-4 pb-2">
<div className="flex w-full items-stretch rounded-xl h-12 bg-surface-highlight shadow-sm ring-1 ring-white/5 focus-within:ring-2 focus-within:ring-primary transition-all">
<div className="text-text-muted flex items-center justify-center pl-4 pr-2">
<span className="material-symbols-outlined text-[20px]">search</span>
</div>
<input
className="flex w-full min-w-0 flex-1 bg-transparent text-white focus:outline-none placeholder:text-text-muted text-base font-normal"
placeholder="Поиск по названию или автору..."
value={search}
onChange={(e) => setSearch(e.target.value)}
/>
</div>
</div>
</header>
<div className="px-4 pt-2 pb-24 flex-1">
<div className="flex flex-col gap-4 mb-6">
<div className="flex h-10 w-full items-center justify-center rounded-lg bg-surface-highlight p-1">
<button className="flex-1 h-full rounded-md bg-background-dark shadow-sm text-sm font-medium text-white">Все книги</button>
<button className="flex-1 h-full text-sm font-medium text-text-muted">Категории</button>
</div>
<div className="flex gap-3 overflow-x-auto no-scrollbar pb-1">
<button className="flex h-9 items-center justify-center gap-x-2 rounded-full bg-surface-highlight border border-white/5 px-4">
<span className="material-symbols-outlined text-[18px]">sort</span>
<span className="text-white text-sm font-medium">Сортировка</span>
</button>
<button className="flex h-9 items-center justify-center gap-x-2 rounded-full bg-surface-highlight border border-white/5 px-4">
<span className="material-symbols-outlined text-[18px]">filter_list</span>
<span className="text-white text-sm font-medium">Фильтр</span>
</button>
<button className="flex h-9 items-center justify-center gap-x-2 rounded-full bg-surface-highlight border border-white/5 px-4 whitespace-nowrap">
<span className="text-white text-sm font-medium">Непрочитанные</span>
</button>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
{filteredBooks.map((book) => (
<div key={book.id} className="flex flex-col gap-2 group cursor-pointer" onClick={() => onBookClick(book)}>
<div className="relative w-full aspect-[2/3] rounded-lg overflow-hidden shadow-md group-hover:shadow-xl transition-all duration-300 bg-surface-dark">
<img src={book.coverUrl || 'https://picsum.photos/seed/placeholder/400/600'} className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105" alt={book.title} />
{book.status === 'reading' && (
<div className="absolute bottom-0 left-0 right-0 h-1 bg-black/50">
<div className="h-full bg-primary" style={{ width: `${book.progress || 0}%` }}></div>
</div>
)}
{book.status === 'done' && (
<div className="absolute top-2 left-2 bg-primary/90 text-white text-[10px] font-bold px-2 py-0.5 rounded-full backdrop-blur-sm">DONE</div>
)}
{book.isFavorite && (
<div className="absolute top-2 right-2 bg-black/60 backdrop-blur-sm rounded-full p-1">
<span className="material-symbols-outlined text-white text-[14px] fill-current">favorite</span>
</div>
)}
</div>
<div>
<h3 className="text-white text-base font-semibold leading-tight line-clamp-1">{book.title}</h3>
<p className="text-text-muted text-sm font-normal leading-normal line-clamp-1">{book.author}</p>
</div>
</div>
))}
</div>
</div>
<button
onClick={onAddClick}
className="fixed bottom-24 right-5 z-40 bg-primary text-white w-14 h-14 rounded-full shadow-lg shadow-primary/40 flex items-center justify-center hover:scale-110 active:scale-95 transition-all"
>
<span className="material-symbols-outlined text-[28px]">add</span>
</button>
</div>
);
};