106 lines
5.9 KiB
TypeScript
106 lines
5.9 KiB
TypeScript
|
|
import React from 'react';
|
|
import { Book, AppScreen } from '../types';
|
|
|
|
interface BookDetailsProps {
|
|
book: Book;
|
|
onBack: () => void;
|
|
onDelete: (id: string) => void;
|
|
onEdit: (book: Book) => void;
|
|
}
|
|
|
|
export const BookDetails: React.FC<BookDetailsProps> = ({ book, onBack, onDelete, onEdit }) => {
|
|
return (
|
|
<div className="relative flex flex-col h-full bg-background-dark overflow-y-auto no-scrollbar">
|
|
<div className="absolute top-0 left-0 right-0 z-50 p-4 pt-6 flex items-center justify-between">
|
|
<button onClick={onBack} className="size-10 flex items-center justify-center rounded-full bg-black/20 hover:bg-black/40 text-white backdrop-blur-md border border-white/10">
|
|
<span className="material-symbols-outlined">arrow_back_ios_new</span>
|
|
</button>
|
|
<button className="size-10 flex items-center justify-center rounded-full bg-black/20 hover:bg-black/40 text-white backdrop-blur-md border border-white/10">
|
|
<span className="material-symbols-outlined">more_horiz</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div className="relative w-full h-[460px] flex flex-col items-center justify-end pb-8 overflow-hidden shrink-0">
|
|
<div className="absolute inset-0 z-0">
|
|
<div
|
|
className="absolute inset-0 bg-cover bg-center blur-2xl opacity-40 scale-125 saturate-150"
|
|
style={{ backgroundImage: `url(${book.coverUrl})` }}
|
|
/>
|
|
<div className="absolute inset-0 bg-gradient-to-t from-background-dark via-background-dark/80 to-transparent"></div>
|
|
</div>
|
|
|
|
<div className="relative z-10 mb-4 transform transition-transform duration-500 hover:scale-105">
|
|
<div className="w-44 h-64 rounded-lg shadow-2xl bg-gray-800 relative overflow-hidden shadow-black/50">
|
|
<img src={book.coverUrl} className="absolute inset-0 w-full h-full object-cover" alt={book.title} />
|
|
<div className="absolute inset-0 bg-gradient-to-tr from-black/40 via-transparent to-white/10 pointer-events-none"></div>
|
|
<div className="absolute left-0 top-0 bottom-0 w-[2px] bg-white/20 blur-[1px]"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="relative z-20 mb-2">
|
|
<div className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-black/40 border border-white/10 backdrop-blur-md">
|
|
<span className="relative flex h-2 w-2">
|
|
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75"></span>
|
|
<span className="relative inline-flex rounded-full h-2 w-2 bg-primary"></span>
|
|
</span>
|
|
<span className="text-primary text-xs font-bold tracking-wide uppercase">
|
|
{book.status === 'reading' ? 'Reading Now' : book.status === 'done' ? 'Completed' : 'Wishlist'}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="relative z-20 px-6 -mt-2 space-y-8 pb-10">
|
|
<div className="text-center space-y-1">
|
|
<h1 className="text-white text-[28px] font-bold leading-tight tracking-tight">{book.title}</h1>
|
|
<p className="text-gray-400 text-lg font-medium">{book.author}</p>
|
|
</div>
|
|
|
|
<div className="flex flex-wrap justify-center gap-2">
|
|
{book.genre.split(',').map((g, i) => (
|
|
<div key={i} className="px-4 py-2 rounded-lg bg-[#244730] border border-[#386e4b]/50">
|
|
<p className="text-white text-xs font-semibold uppercase tracking-wider">{g.trim()}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div className="grid grid-cols-2 gap-3 pt-2">
|
|
<button onClick={() => onEdit(book)} className="group flex items-center justify-center gap-2 h-12 bg-primary hover:bg-[#15bd4d] text-background-dark font-bold rounded-xl transition-all active:scale-95 shadow-[0_4px_20px_-5px_rgba(23,207,84,0.4)]">
|
|
<span className="material-symbols-outlined text-[20px]">edit_square</span>
|
|
Edit Details
|
|
</button>
|
|
<button onClick={() => onDelete(book.id)} className="group flex items-center justify-center gap-2 h-12 bg-white/5 hover:bg-red-500/10 text-gray-300 hover:text-red-400 border border-white/10 hover:border-red-500/30 font-semibold rounded-xl transition-all active:scale-95">
|
|
<span className="material-symbols-outlined text-[20px]">delete</span>
|
|
Delete
|
|
</button>
|
|
</div>
|
|
|
|
<div className="space-y-3 pt-2">
|
|
<h3 className="text-white text-lg font-bold">About</h3>
|
|
<div className="relative bg-white/5 rounded-2xl p-4 border border-white/5">
|
|
<p className="text-gray-300 leading-relaxed text-[15px] font-light">{book.annotation}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-2 gap-3 pt-4">
|
|
{[
|
|
{ label: 'Pages', val: book.pages || 'N/A', icon: 'menu_book', color: 'text-blue-400', bg: 'bg-blue-500/20' },
|
|
{ label: 'Language', val: book.language || 'Russian', icon: 'language', color: 'text-purple-400', bg: 'bg-purple-500/20' },
|
|
{ label: 'Published', val: book.publishedYear || 'N/A', icon: 'calendar_month', color: 'text-orange-400', bg: 'bg-orange-500/20' },
|
|
{ label: 'Rating', val: `${book.rating || '0'}/5`, icon: 'star', color: 'text-yellow-400', bg: 'bg-yellow-500/20' },
|
|
].map((item, idx) => (
|
|
<div key={idx} className="glass-panel p-3.5 rounded-xl border border-white/5 flex flex-col gap-1 items-start bg-white/5">
|
|
<div className={`p-1.5 rounded-md ${item.bg} ${item.color} mb-1`}>
|
|
<span className="material-symbols-outlined text-[18px]">{item.icon}</span>
|
|
</div>
|
|
<span className="text-gray-500 text-[11px] uppercase font-bold tracking-wider">{item.label}</span>
|
|
<span className="text-white font-semibold text-base">{item.val}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|