initial
This commit is contained in:
108
books/screens/Library.tsx
Normal file
108
books/screens/Library.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user