133 lines
4.3 KiB
TypeScript
133 lines
4.3 KiB
TypeScript
|
||
import React, { useState } from 'react';
|
||
import { AppScreen, Book } from './types';
|
||
import { INITIAL_BOOKS } from './constants';
|
||
import { Layout } from './components/Layout';
|
||
import { Library } from './screens/Library';
|
||
import { Categories } from './screens/Categories';
|
||
import { BookDetails } from './screens/BookDetails';
|
||
import { AddBook } from './screens/AddBook';
|
||
import { Scanner } from './screens/Scanner';
|
||
|
||
const App: React.FC = () => {
|
||
const [currentScreen, setCurrentScreen] = useState<AppScreen>(AppScreen.LIBRARY);
|
||
const [books, setBooks] = useState<Book[]>(INITIAL_BOOKS);
|
||
const [selectedBook, setSelectedBook] = useState<Book | null>(null);
|
||
const [prefilledData, setPrefilledData] = useState<Partial<Book> | null>(null);
|
||
|
||
const handleBookClick = (book: Book) => {
|
||
setSelectedBook(book);
|
||
setCurrentScreen(AppScreen.DETAILS);
|
||
};
|
||
|
||
const handleAddClick = () => {
|
||
setPrefilledData(null);
|
||
setCurrentScreen(AppScreen.ADD_BOOK);
|
||
};
|
||
|
||
const handleSaveBook = (bookData: Partial<Book>) => {
|
||
if (selectedBook) {
|
||
// Edit existing
|
||
setBooks(prev => prev.map(b => b.id === selectedBook.id ? { ...b, ...bookData } as Book : b));
|
||
} else {
|
||
// Add new
|
||
const newBook: Book = {
|
||
id: Math.random().toString(36).substr(2, 9),
|
||
title: bookData.title || 'Unknown',
|
||
author: bookData.author || 'Unknown',
|
||
genre: bookData.genre || 'Unknown',
|
||
annotation: bookData.annotation || '',
|
||
coverUrl: bookData.coverUrl || 'https://picsum.photos/seed/new/400/600',
|
||
status: 'want_to_read',
|
||
...bookData
|
||
} as Book;
|
||
setBooks(prev => [...prev, newBook]);
|
||
}
|
||
setCurrentScreen(AppScreen.LIBRARY);
|
||
setSelectedBook(null);
|
||
setPrefilledData(null);
|
||
};
|
||
|
||
const handleDeleteBook = (id: string) => {
|
||
setBooks(prev => prev.filter(b => b.id !== id));
|
||
setCurrentScreen(AppScreen.LIBRARY);
|
||
};
|
||
|
||
const handleDetected = (data: Partial<Book>) => {
|
||
setPrefilledData(data);
|
||
setCurrentScreen(AppScreen.ADD_BOOK);
|
||
};
|
||
|
||
const renderScreen = () => {
|
||
switch (currentScreen) {
|
||
case AppScreen.LIBRARY:
|
||
return (
|
||
<Library
|
||
books={books}
|
||
onBookClick={handleBookClick}
|
||
onAddClick={handleAddClick}
|
||
/>
|
||
);
|
||
case AppScreen.CATEGORIES:
|
||
return <Categories />;
|
||
case AppScreen.DETAILS:
|
||
return selectedBook ? (
|
||
<BookDetails
|
||
book={selectedBook}
|
||
onBack={() => setCurrentScreen(AppScreen.LIBRARY)}
|
||
onDelete={handleDeleteBook}
|
||
onEdit={(b) => {
|
||
setSelectedBook(b);
|
||
setCurrentScreen(AppScreen.ADD_BOOK);
|
||
}}
|
||
/>
|
||
) : null;
|
||
case AppScreen.ADD_BOOK:
|
||
return (
|
||
<AddBook
|
||
initialData={selectedBook || prefilledData || {}}
|
||
onSave={handleSaveBook}
|
||
onCancel={() => {
|
||
setCurrentScreen(selectedBook ? AppScreen.DETAILS : AppScreen.LIBRARY);
|
||
setPrefilledData(null);
|
||
}}
|
||
onScanClick={() => setCurrentScreen(AppScreen.SCANNER)}
|
||
/>
|
||
);
|
||
case AppScreen.SCANNER:
|
||
return (
|
||
<Scanner
|
||
onCancel={() => setCurrentScreen(AppScreen.ADD_BOOK)}
|
||
onDetected={handleDetected}
|
||
/>
|
||
);
|
||
case AppScreen.WISHLIST:
|
||
return (
|
||
<div className="p-10 text-center">
|
||
<h2 className="text-xl font-bold">Вишлист</h2>
|
||
<p className="text-text-muted mt-2">Здесь будут книги, которые вы хотите прочитать.</p>
|
||
</div>
|
||
);
|
||
case AppScreen.SETTINGS:
|
||
return (
|
||
<div className="p-10 text-center">
|
||
<h2 className="text-xl font-bold">Настройки</h2>
|
||
<p className="text-text-muted mt-2">Персонализируйте ваше приложение.</p>
|
||
</div>
|
||
);
|
||
default:
|
||
return <Library books={books} onBookClick={handleBookClick} onAddClick={handleAddClick} />;
|
||
}
|
||
};
|
||
|
||
const hideNav = [AppScreen.SCANNER, AppScreen.DETAILS, AppScreen.ADD_BOOK].includes(currentScreen);
|
||
|
||
return (
|
||
<Layout currentScreen={currentScreen} setScreen={setCurrentScreen} hideNav={hideNav}>
|
||
{renderScreen()}
|
||
</Layout>
|
||
);
|
||
};
|
||
|
||
export default App;
|