Files
bookshelf/books/App.tsx
Yuriy Panov 3004f712f3 initial
2026-02-02 17:12:25 +06:00

133 lines
4.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;