Skip to content

Commit

Permalink
fat: add react-router
Browse files Browse the repository at this point in the history
  • Loading branch information
juanpabotero committed Sep 5, 2023
1 parent e8d3560 commit fb16b0e
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 72 deletions.
63 changes: 62 additions & 1 deletion pruebas/01-reading-list/juanpabotero/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pruebas/01-reading-list/juanpabotero/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-router-dom": "^6.15.0"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.17.0",
Expand Down
44 changes: 10 additions & 34 deletions pruebas/01-reading-list/juanpabotero/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,23 @@
import { useState } from 'react';
import { Books } from './components/Books';
import { Route, Routes } from 'react-router-dom';
import { Home } from './Home';
import { Book } from './components/Book';
import { Header } from './components/Header';
import { Tabs } from './components/Tabs';
import { useFilters } from './hooks/useFilters';
import { useReadingList } from './hooks/useReadingList';
import { library as initialBooks } from './mocks/books.json';

function App() {
const { filterBooks } = useFilters();
const [isReadingListActive, setIsReadingListActive] = useState(false);
const { readingList, clearReadingList } = useReadingList();

const filteredBooks = filterBooks(initialBooks);
const filteredBooksMapped = filteredBooks.map(({ book }) => book);

return (
<>
<div className="max-w-5xl mx-auto px-4">
<Header />
<Tabs
{...{
isReadingListActive,
setIsReadingListActive,
readingList,
clearReadingList,
filteredBooksMapped
}}
/>
<main className="grid mb-8">
<div className={`${isReadingListActive ? 'hidden' : ''}`}>
<Books
books={filteredBooksMapped}
isReadingListActive={isReadingListActive}
/>
</div>
<div className={`${isReadingListActive ? '' : 'hidden'}`}>
<Books
books={readingList}
isReadingListActive={isReadingListActive}
/>
</div>
</main>
</div>
<div className="max-w-5xl mx-auto pt-20 pb-14 px-4">
<Routes>
<Route path="/" element={<Home />} />
<Route path="header" element={<Header />} />
<Route path="book/:id" element={<Book books={filteredBooksMapped} />} />
</Routes>
<div
className="fixed -z-10 h-[134px] w-[134px] lg:w-[300px] lg:h-[300px] rounded-full
bg-red-600 blur-[150px] lg:blur-[350px] opacity-50 left-0 top-0"
Expand All @@ -50,7 +26,7 @@ function App() {
className="fixed -z-10 h-[134px] w-[134px] lg:w-[300px] lg:h-[300px] rounded-full
bg-amber-600 blur-[150px] lg:blur-[350px] opacity-50 right-0 bottom-0"
></div>
</>
</div>
);
}

Expand Down
45 changes: 45 additions & 0 deletions pruebas/01-reading-list/juanpabotero/src/Home.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useState } from 'react';
import { Books } from './components/Books';
import { Header } from './components/Header';
import { Tabs } from './components/Tabs';
import { useFilters } from './hooks/useFilters';
import { useReadingList } from './hooks/useReadingList';
import { library as initialBooks } from './mocks/books.json';

export function Home() {
const { filterBooks } = useFilters();
const [isReadingListActive, setIsReadingListActive] = useState(false);
const { readingList, clearReadingList } = useReadingList();

const filteredBooks = filterBooks(initialBooks);
const filteredBooksMapped = filteredBooks.map(({ book }) => book);

return (
<>
<Header />
<Tabs
{...{
isReadingListActive,
setIsReadingListActive,
readingList,
clearReadingList,
filteredBooksMapped
}}
/>
<main className="grid">
<div className={`${isReadingListActive ? 'hidden' : ''}`}>
<Books
books={filteredBooksMapped}
isReadingListActive={isReadingListActive}
/>
</div>
<div className={`${isReadingListActive ? '' : 'hidden'}`}>
<Books
books={readingList}
isReadingListActive={isReadingListActive}
/>
</div>
</main>
</>
);
}
41 changes: 41 additions & 0 deletions pruebas/01-reading-list/juanpabotero/src/components/Book.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useParams } from 'react-router-dom';

export function Book({ books }) {
const { id } = useParams();
const book = books.find((book) => String(book.id) === id);
return (
<article className="flex flex-col gap-4 items-center border rounded-lg shadow md:flex-row md:max-w-2xl border-gray-700 bg-gray-800 mx-auto p-4">
<img
className="object-contain w-full rounded-t-lg h-96 md:h-auto md:w-48 md:rounded-none"
src={book.cover}
alt={book.title}
/>
<div className="flex flex-col justify-between leading-normal">
<h5 className="mb-1 text-2xl md:text-3xl font-bold tracking-tight text-white">
{book.title}
</h5>
<p className="mb-6 text-gray-400">
<span className="font-bold">Por:</span> {book.author.name}
</p>
<p className="mb-6 text-white text-lg leading-snug">{book.synopsis}</p>
<p className="text-gray-400">
<span className="font-bold">Género:</span> {book.genre}
</p>
<p className="text-gray-400">
<span className="font-bold">No. de páginas:</span> {book.pages}
</p>
<p className="mb-6 text-gray-400">
<span className="font-bold">Año:</span> {book.year}
</p>
<p className="text-gray-400">
<span className="font-bold">Más libros de {book.author.name}:</span>
</p>
<p className="text-gray-400">
{book.author.otherBooks.map((otherBook) => (
<span key={book.id}>{otherBook}, </span>
))}
</p>
</div>
</article>
);
}
48 changes: 23 additions & 25 deletions pruebas/01-reading-list/juanpabotero/src/components/Books.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
SadFaceIcon
} from './Icons';
import '../styles/Books.css';
import { Link } from 'react-router-dom';

export function Books({ books, isReadingListActive }) {
const { addToReadingList, removeFromReadingList, readingList } =
Expand Down Expand Up @@ -38,19 +39,18 @@ export function Books({ books, isReadingListActive }) {
return (
<article
key={book.id}
className="grid relative content-start max-w-[160px] sm:max-w-[178px]"
className="grid relative content-start max-w-[160px] sm:max-w-[178px]
border rounded-lg shadow bg-gray-800 border-gray-700"
>
<button
className={`add-book-button absolute -top-2 -right-1 rounded-full p-1 bg-gray-900
hover:scale-110 transition-all duration-200 z-20
${
isReadingListActive ? (
'text-red-600'
) : isBookInReadingList ? (
'text-lime-400'
) : (
'text-yellow-400'
)
isReadingListActive
? 'text-red-600'
: isBookInReadingList
? 'text-lime-400'
: 'text-yellow-400'
}`}
aria-label="addBookButton"
onClick={() => {
Expand All @@ -67,24 +67,22 @@ export function Books({ books, isReadingListActive }) {
<AddBookIcon />
)}
</button>
<img
className="book-cover h-56 sm:h-64 aspect-auto mb-2 rounded-md"
src={book.cover}
alt={`Portada de ${book.title}`}
/>
<div
className="book-synopsis absolute top-0 left-0 h-56 sm:h-64 bg-gray-950/90
rounded-md place-content-center hidden transition-all duration-500 z-10 hover:grid"
>
<p className="text-sm sm:text-base px-4 py-2 text-gray-50 overflow-hidden">
{book.synopsis}
</p>
<Link to={`/book/${book.id}`}>
<img
className="book-cover h-56 sm:h-64 w-full aspect-auto mb-2 rounded-md"
src={book.cover}
alt={`Portada de ${book.title}`}
/>
</Link>
<div className="p-2 sm:p-3">
<Link to={`/book/${book.id}`}>
<h2 className="text-lg font-bold text-white mb-1">
{book.title}
</h2>
</Link>
<p className="text-gray-400">{book.author.name}</p>
<p className="text-gray-400 text-sm">{book.genre}</p>
</div>
<h2 className="text-lg font-bold text-white mb-1">
{book.title}
</h2>
<p className="text-gray-400">{book.author.name}</p>
<p className="text-gray-400 text-sm">{book.genre}</p>
</article>
);
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Filters } from './Filters';

export function Header() {
return (
<header className="grid gap-8 mt-14 my-16">
<header className="grid gap-8 mb-16">
<h1 className="text-3xl text-gray-50 font-bold flex gap-3 mb-2">
Mi Librería
</h1>
Expand Down
8 changes: 4 additions & 4 deletions pruebas/01-reading-list/juanpabotero/src/components/Tabs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ export function Tabs({
justify-start gap-8 mb-10"
>
<button
className={`font-bold text-white pb-1 ${
isReadingListActive ? '' : 'border-b'
className={`font-bold text-white pb-1 border-b ${
isReadingListActive ? 'border-b-transparent' : ''
}`}
onClick={() => setIsReadingListActive(false)}
>
Libros disponibles ({filteredBooksMapped.length})
</button>
<button
className={`font-bold text-white pb-1 ${
isReadingListActive ? 'border-b' : ''
className={`font-bold text-white pb-1 border-b ${
isReadingListActive ? '' : 'border-b-transparent'
}`}
onClick={() => setIsReadingListActive(true)}
>
Expand Down
15 changes: 9 additions & 6 deletions pruebas/01-reading-list/juanpabotero/src/main.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App.jsx';
import { FiltersProvider } from './context/filters.jsx';
import './index.css';
import { ReadingListProvider } from './context/reading-list.jsx';
import './index.css';

ReactDOM.createRoot(document.getElementById('root')).render(
<FiltersProvider>
<ReadingListProvider>
<App />
</ReadingListProvider>
</FiltersProvider>
<BrowserRouter>
<FiltersProvider>
<ReadingListProvider>
<App />
</ReadingListProvider>
</FiltersProvider>
</BrowserRouter>
);

0 comments on commit fb16b0e

Please sign in to comment.