initial
This commit is contained in:
136
books/screens/AddBook.tsx
Normal file
136
books/screens/AddBook.tsx
Normal file
@@ -0,0 +1,136 @@
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Book, AppScreen } from '../types';
|
||||
|
||||
interface AddBookProps {
|
||||
initialData?: Partial<Book>;
|
||||
onSave: (book: Partial<Book>) => void;
|
||||
onCancel: () => void;
|
||||
onScanClick: () => void;
|
||||
}
|
||||
|
||||
export const AddBook: React.FC<AddBookProps> = ({ initialData, onSave, onCancel, onScanClick }) => {
|
||||
const [formData, setFormData] = useState<Partial<Book>>({
|
||||
title: '',
|
||||
author: '',
|
||||
genre: '',
|
||||
annotation: '',
|
||||
status: 'want_to_read',
|
||||
pages: 0,
|
||||
language: 'Russian',
|
||||
publishedYear: new Date().getFullYear(),
|
||||
rating: 5,
|
||||
coverUrl: 'https://picsum.photos/seed/newbook/400/600',
|
||||
...initialData
|
||||
});
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
|
||||
const { id, value } = e.target;
|
||||
setFormData(prev => ({ ...prev, [id]: value }));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full bg-background-dark">
|
||||
<header className="sticky top-0 z-50 flex items-center justify-between px-4 py-3 bg-background-dark/90 backdrop-blur-md border-b border-white/5">
|
||||
<button onClick={onCancel} className="flex items-center justify-center size-10 rounded-full hover:bg-surface-dark transition-colors text-gray-300">
|
||||
<span className="material-symbols-outlined">arrow_back_ios_new</span>
|
||||
</button>
|
||||
<h1 className="text-lg font-bold tracking-tight text-center flex-1 pr-10">Добавить книгу</h1>
|
||||
</header>
|
||||
|
||||
<main className="flex-1 flex flex-col p-5 gap-6 overflow-y-auto no-scrollbar pb-32">
|
||||
<div className="flex justify-center w-full">
|
||||
<div
|
||||
onClick={onScanClick}
|
||||
className="group relative flex flex-col items-center justify-center w-40 h-60 rounded-lg border-2 border-dashed border-border-dark bg-surface-dark transition-all hover:border-primary cursor-pointer overflow-hidden shadow-sm"
|
||||
>
|
||||
{formData.coverUrl && !formData.coverUrl.includes('picsum') ? (
|
||||
<img src={formData.coverUrl} className="absolute inset-0 w-full h-full object-cover" alt="Preview" />
|
||||
) : (
|
||||
<div className="flex flex-col items-center gap-3 p-4 text-center z-10 transition-transform group-hover:scale-105">
|
||||
<div className="size-12 rounded-full bg-primary/10 flex items-center justify-center text-primary">
|
||||
<span className="material-symbols-outlined text-[28px]">add_a_photo</span>
|
||||
</div>
|
||||
<p className="text-xs font-medium text-gray-400 group-hover:text-primary transition-colors">Загрузить или отсканировать</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form className="flex flex-col gap-5">
|
||||
<div className="flex flex-col gap-2">
|
||||
<label className="text-sm font-semibold text-gray-200 ml-1" htmlFor="title">Название</label>
|
||||
<input
|
||||
id="title"
|
||||
className="w-full rounded-xl border-border-dark bg-surface-dark px-4 py-3.5 text-base text-white placeholder-gray-500 focus:border-primary focus:ring-1 focus:ring-primary transition-shadow shadow-sm"
|
||||
placeholder="Введите название книги"
|
||||
value={formData.title}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
<label className="text-sm font-semibold text-gray-200 ml-1" htmlFor="author">Автор</label>
|
||||
<input
|
||||
id="author"
|
||||
className="w-full rounded-xl border-border-dark bg-surface-dark px-4 py-3.5 text-base text-white placeholder-gray-500 focus:border-primary focus:ring-1 focus:ring-primary transition-shadow shadow-sm"
|
||||
placeholder="Имя автора"
|
||||
value={formData.author}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
<label className="text-sm font-semibold text-gray-200 ml-1" htmlFor="genre">Жанр</label>
|
||||
<div className="relative">
|
||||
<select
|
||||
id="genre"
|
||||
className="w-full appearance-none rounded-xl border-border-dark bg-surface-dark px-4 py-3.5 text-base text-white focus:border-primary focus:ring-1 focus:ring-primary transition-shadow shadow-sm pr-10 cursor-pointer"
|
||||
value={formData.genre}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<option disabled value="">Выберите жанр</option>
|
||||
<option value="fiction">Фантастика</option>
|
||||
<option value="fantasy">Фэнтези</option>
|
||||
<option value="science">Научпоп</option>
|
||||
<option value="biography">Биография</option>
|
||||
<option value="detective">Детектив</option>
|
||||
<option value="other">Другое</option>
|
||||
</select>
|
||||
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-4 text-gray-400">
|
||||
<span className="material-symbols-outlined">expand_more</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
<label className="text-sm font-semibold text-gray-200 ml-1" htmlFor="annotation">Аннотация</label>
|
||||
<textarea
|
||||
id="annotation"
|
||||
rows={4}
|
||||
className="w-full rounded-xl border-border-dark bg-surface-dark px-4 py-3.5 text-base text-white placeholder-gray-500 focus:border-primary focus:ring-1 focus:ring-primary transition-shadow shadow-sm resize-none"
|
||||
placeholder="О чем эта книга? Краткое описание или заметки..."
|
||||
value={formData.annotation}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
<div className="fixed bottom-0 left-0 right-0 max-w-md mx-auto p-4 bg-background-dark/95 backdrop-blur-sm border-t border-white/5 z-40">
|
||||
<div className="flex gap-3">
|
||||
<button onClick={onCancel} className="flex-1 py-3.5 px-4 rounded-xl font-semibold text-gray-300 bg-surface-dark hover:bg-[#25422e] transition-colors">
|
||||
Отмена
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onSave(formData)}
|
||||
className="flex-[2] py-3.5 px-4 rounded-xl font-bold text-white bg-primary hover:bg-[#14b047] shadow-lg shadow-primary/20 transition-all active:scale-[0.98] flex items-center justify-center gap-2"
|
||||
>
|
||||
<span className="material-symbols-outlined text-[20px]">save</span>
|
||||
Сохранить
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user