Refactoring LibraryPage to separate directory
This commit is contained in:
@@ -1,48 +0,0 @@
|
|||||||
.libraryContainer {
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.viewToggle {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.viewToggle button {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
padding: 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.viewToggle button.active {
|
|
||||||
color: blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
gap: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bookCard {
|
|
||||||
text-align: center;
|
|
||||||
border: 1px solid #eaeaea;
|
|
||||||
padding: 16px;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bookCard img {
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bookCard h3 {
|
|
||||||
margin-top: 12px;
|
|
||||||
}
|
|
||||||
+2
-2
@@ -2,7 +2,7 @@ import * as React from 'react';
|
|||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
import { Book, BooksGroup } from '../types/book';
|
import { Book, BooksGroup } from '@/types/book';
|
||||||
import { FaPlus } from 'react-icons/fa';
|
import { FaPlus } from 'react-icons/fa';
|
||||||
|
|
||||||
type BookshelfItem = Book | BooksGroup;
|
type BookshelfItem = Book | BooksGroup;
|
||||||
@@ -59,7 +59,7 @@ const Bookshelf: React.FC<BookshelfProps> = ({ libraryBooks, onImportBooks }) =>
|
|||||||
{/* Books Grid */}
|
{/* Books Grid */}
|
||||||
<div className='grid grid-cols-3 gap-6 sm:grid-cols-4 md:grid-cols-6 lg:grid-cols-8'>
|
<div className='grid grid-cols-3 gap-6 sm:grid-cols-4 md:grid-cols-6 lg:grid-cols-8'>
|
||||||
{bookshelfItems.map((item, index) => (
|
{bookshelfItems.map((item, index) => (
|
||||||
<div key={`library-item-${index}`} className='flex h-full flex-col'>
|
<div key={`library-item-${index}`} className='hover:bg-base-200 flex h-full flex-col'>
|
||||||
<div className='flex-grow'>
|
<div className='flex-grow'>
|
||||||
{'format' in item ? (
|
{'format' in item ? (
|
||||||
<div className='bookItem cursor-pointer' onClick={() => handleBookClick(item.hash)}>
|
<div className='bookItem cursor-pointer' onClick={() => handleBookClick(item.hash)}>
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import { useState, useRef } from 'react';
|
||||||
|
|
||||||
|
import { useEnv } from '@/context/EnvContext';
|
||||||
|
import { useReaderStore } from '@/store/readerStore';
|
||||||
|
|
||||||
|
import Spinner from '@/components/Spinner';
|
||||||
|
import SearchBar from '@/app/library/components/SearchBar';
|
||||||
|
import Bookshelf from '@/app/library/components/Bookshelf';
|
||||||
|
|
||||||
|
const LibraryPage = () => {
|
||||||
|
const { envConfig, appService, getAppService } = useEnv();
|
||||||
|
const { library: libraryBooks, setLibrary } = useReaderStore();
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const isInitiating = useRef(false);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isInitiating.current) return;
|
||||||
|
isInitiating.current = true;
|
||||||
|
setLoading(true);
|
||||||
|
getAppService(envConfig).then(async (appService) => {
|
||||||
|
console.log('Loading library books...');
|
||||||
|
setLibrary(await appService.loadLibraryBooks());
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const importBooks = async (files: [string | File]) => {
|
||||||
|
setLoading(true);
|
||||||
|
for (const file of files) {
|
||||||
|
await appService?.importBook(file, libraryBooks);
|
||||||
|
setLibrary(libraryBooks);
|
||||||
|
}
|
||||||
|
appService?.saveLibraryBooks(libraryBooks);
|
||||||
|
setLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectFilesTauri = async () => {
|
||||||
|
return appService?.selectFiles('Select Books', ['epub', 'pdf']);
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectFilesWeb = () => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const fileInput = document.createElement('input');
|
||||||
|
fileInput.type = 'file';
|
||||||
|
fileInput.accept = '.epub, .pdf';
|
||||||
|
fileInput.multiple = true;
|
||||||
|
fileInput.click();
|
||||||
|
|
||||||
|
fileInput.onchange = () => {
|
||||||
|
resolve(fileInput.files);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleImportBooks = async () => {
|
||||||
|
console.log('Importing books...');
|
||||||
|
const { type } = await import('@tauri-apps/plugin-os');
|
||||||
|
let files;
|
||||||
|
if (['android', 'ios'].includes(type())) {
|
||||||
|
files = (await selectFilesWeb()) as [File];
|
||||||
|
} else {
|
||||||
|
files = (await selectFilesTauri()) as [string];
|
||||||
|
}
|
||||||
|
importBooks(files);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='min-h-screen bg-gray-100'>
|
||||||
|
<SearchBar onImportBooks={handleImportBooks} />
|
||||||
|
<div className='min-h-screen p-2 pt-16'>
|
||||||
|
<div className='hero-content'>
|
||||||
|
<Spinner loading={loading} />
|
||||||
|
<Bookshelf libraryBooks={libraryBooks} onImportBooks={handleImportBooks} />
|
||||||
|
</div>
|
||||||
|
{!loading && libraryBooks.length === 0 && (
|
||||||
|
<div className='hero min-h-screen'>
|
||||||
|
<div className='hero-content text-neutral-content text-center'>
|
||||||
|
<div className='max-w-md'>
|
||||||
|
<h1 className='mb-5 text-5xl font-bold'>Your Library</h1>
|
||||||
|
<p className='mb-5'>
|
||||||
|
Welcome to your library. You can upload your books here and read them anytime.
|
||||||
|
</p>
|
||||||
|
<button className='btn btn-primary' onClick={handleImportBooks}>
|
||||||
|
Upload Books
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LibraryPage;
|
||||||
@@ -1,98 +1,18 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import * as React from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useState, useRef } from 'react';
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
import { useEnv } from '@/context/EnvContext';
|
|
||||||
import { useReaderStore } from '@/store/readerStore';
|
|
||||||
|
|
||||||
import SearchBar from '@/components/SearchBar';
|
|
||||||
import Spinner from '@/components/Spinner';
|
import Spinner from '@/components/Spinner';
|
||||||
import Bookshelf from '@/components/Bookshelf';
|
|
||||||
|
|
||||||
const LibraryPage = () => {
|
const HomePage = () => {
|
||||||
const { envConfig, appService, getAppService } = useEnv();
|
const router = useRouter();
|
||||||
const { library: libraryBooks, setLibrary } = useReaderStore();
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const isInitiating = useRef(false);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
useEffect(() => {
|
||||||
if (isInitiating.current) return;
|
router.push('/library');
|
||||||
isInitiating.current = true;
|
}, [router]);
|
||||||
setLoading(true);
|
|
||||||
getAppService(envConfig).then(async (appService) => {
|
|
||||||
console.log('Loading library books...');
|
|
||||||
setLibrary(await appService.loadLibraryBooks());
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const importBooks = async (files: [string | File]) => {
|
return <Spinner loading={true} />;
|
||||||
setLoading(true);
|
|
||||||
for (const file of files) {
|
|
||||||
await appService?.importBook(file, libraryBooks);
|
|
||||||
setLibrary(libraryBooks);
|
|
||||||
}
|
|
||||||
appService?.saveLibraryBooks(libraryBooks);
|
|
||||||
setLoading(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const selectFilesTauri = async () => {
|
|
||||||
return appService?.selectFiles('Select Books', ['epub', 'pdf']);
|
|
||||||
};
|
|
||||||
|
|
||||||
const selectFilesWeb = () => {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const fileInput = document.createElement('input');
|
|
||||||
fileInput.type = 'file';
|
|
||||||
fileInput.accept = '.epub, .pdf';
|
|
||||||
fileInput.multiple = true;
|
|
||||||
fileInput.click();
|
|
||||||
|
|
||||||
fileInput.onchange = () => {
|
|
||||||
resolve(fileInput.files);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleImportBooks = async () => {
|
|
||||||
console.log('Importing books...');
|
|
||||||
const { type } = await import('@tauri-apps/plugin-os');
|
|
||||||
let files;
|
|
||||||
if (['android', 'ios'].includes(type())) {
|
|
||||||
files = (await selectFilesWeb()) as [File];
|
|
||||||
} else {
|
|
||||||
files = (await selectFilesTauri()) as [string];
|
|
||||||
}
|
|
||||||
importBooks(files);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='min-h-screen bg-gray-100'>
|
|
||||||
<SearchBar onImportBooks={handleImportBooks} />
|
|
||||||
<div className='min-h-screen p-2 pt-16'>
|
|
||||||
<div className='hero-content'>
|
|
||||||
<Spinner loading={loading} />
|
|
||||||
<Bookshelf libraryBooks={libraryBooks} onImportBooks={handleImportBooks} />
|
|
||||||
</div>
|
|
||||||
{!loading && libraryBooks.length === 0 && (
|
|
||||||
<div className='hero min-h-screen'>
|
|
||||||
<div className='hero-content text-neutral-content text-center'>
|
|
||||||
<div className='max-w-md'>
|
|
||||||
<h1 className='mb-5 text-5xl font-bold'>Your Library</h1>
|
|
||||||
<p className='mb-5'>
|
|
||||||
Welcome to your library. You can upload your books here and read them anytime.
|
|
||||||
</p>
|
|
||||||
<button className='btn btn-primary' onClick={handleImportBooks}>
|
|
||||||
Upload Books
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LibraryPage;
|
export default HomePage;
|
||||||
|
|||||||
Reference in New Issue
Block a user