diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml
new file mode 100644
index 0000000..2765c9f
--- /dev/null
+++ b/.github/workflows/links.yml
@@ -0,0 +1,16 @@
+name: Links (Fail Fast)
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ linkChecker:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Link Checker
+ uses: lycheeverse/lychee-action@v1.8.0
+ with:
+ fail: true
diff --git a/src/components/RelatedPost.tsx b/src/components/RelatedPost.tsx
deleted file mode 100644
index 2379f15..0000000
--- a/src/components/RelatedPost.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import React from 'react';
-import { Flex, useColorModeValue } from '@chakra-ui/react';
-
-import { RelatedCard } from '../components/cards/RelatedCard';
-import { CardType, ReleatedBooksType } from '../components/types';
-import { useMoreBooks } from '../hooks/querys';
-
-export default function RelatedPost({ currentBookId }: ReleatedBooksType) {
- const colorCard = useColorModeValue('gray.900', 'gray.100');
- const { data, refetch } = useMoreBooks();
-
- // Filtrar el ID que coincide con el libro que se esta viendo para evitar ver el mismo en los relacionados,
- // si eso pasa se hace un refetch() a la api para mostrar otros libros,
- // si no hay coincidencias no se hace una actualizaciĆ³n.
-
- const relatedBooks = data.filter((book: any) => {
- if (book.pathUrl === currentBookId) {
- refetch();
- }
-
- return book.pathUrl !== currentBookId;
- });
-
- return (
- <>
-
- {relatedBooks.map(
- ({ id, title, synopsis, authors, category, pathUrl }: CardType) => (
-
-
-
- ),
- )}
-
- >
- );
-}
diff --git a/src/components/cards/Card.tsx b/src/components/cards/Card.tsx
index b5e41f6..5dcb416 100644
--- a/src/components/cards/Card.tsx
+++ b/src/components/cards/Card.tsx
@@ -66,7 +66,7 @@ export function Card({
bg='green.50'
color='green.900'
icon={BsTag}
- name={category[0]}
+ name={category && category[0]}
size='md'
isFocused={false}
tabIndex={-1}
diff --git a/src/components/cards/ContainerRCard.tsx b/src/components/cards/ContainerRCard.tsx
new file mode 100644
index 0000000..ddef073
--- /dev/null
+++ b/src/components/cards/ContainerRCard.tsx
@@ -0,0 +1,14 @@
+import React from 'react';
+import { Flex, useColorModeValue } from '@chakra-ui/react';
+
+export function ContainerRCard({ children }: { children: React.ReactNode }) {
+ const colorCard = useColorModeValue('gray.900', 'gray.100');
+
+ return (
+ <>
+
+ {children}
+
+ >
+ );
+}
diff --git a/src/components/cards/MoreBooks.tsx b/src/components/cards/MoreBooks.tsx
new file mode 100644
index 0000000..53c654b
--- /dev/null
+++ b/src/components/cards/MoreBooks.tsx
@@ -0,0 +1,38 @@
+import React from 'react';
+
+import { RelatedCard } from './RelatedCard';
+import { ContainerRCard } from './ContainerRCard';
+import { CardType, ReleatedBooksType } from '../types';
+import { useMoreBooks } from '../../hooks/querys';
+import { useRefetchLocation } from '../../hooks/useRefetchLocation';
+
+export default function MoreBooks({ currentBookId }: ReleatedBooksType) {
+ const { data, refetch } = useMoreBooks();
+ const moreBooks = useRefetchLocation(currentBookId, data, refetch);
+
+ // const moreBooks = data.filter((book: any) => {
+ // if (book.pathUrl === currentBookId) {
+ // refetch();
+ // }
+
+ // return book.pathUrl !== currentBookId;
+ // });
+
+ return (
+ <>
+
+ {moreBooks.map(({ id, title, authors, pathUrl }: CardType) => (
+
+
+
+ ))}
+
+ >
+ );
+}
diff --git a/src/components/cards/RelatedBooks.tsx b/src/components/cards/RelatedBooks.tsx
new file mode 100644
index 0000000..45e9331
--- /dev/null
+++ b/src/components/cards/RelatedBooks.tsx
@@ -0,0 +1,30 @@
+import React from 'react';
+
+import { RelatedCard } from './RelatedCard';
+import { ContainerRCard } from './ContainerRCard';
+import { CardType, ReleatedBooksType } from '../types';
+import { useRelatedBooks } from '../../hooks/querys';
+import { useRefetchLocation } from '../../hooks/useRefetchLocation';
+
+export default function RelatedBooks({ currentBookId, id }: ReleatedBooksType) {
+ const { data, refetch } = useRelatedBooks(id);
+ const relatedBooks = useRefetchLocation(currentBookId, data, refetch);
+
+ return (
+ <>
+
+ {relatedBooks.map(({ id, title, authors, pathUrl }: CardType) => (
+
+
+
+ ))}
+
+ >
+ );
+}
diff --git a/src/components/types.d.ts b/src/components/types.d.ts
index 2d52ba6..7c75dc7 100644
--- a/src/components/types.d.ts
+++ b/src/components/types.d.ts
@@ -24,7 +24,7 @@ interface CardType {
title: string;
synopsis?: string;
authors: string[];
- category: string[];
+ category?: string[];
year?: number;
language?: number;
sourceLink?: string;
@@ -92,7 +92,8 @@ interface ModalType extends DisclosureType {
}
interface ReleatedBooksType {
- currentBookId: string | undefined;
+ id?: string;
+ currentBookId?: string | undefined;
}
interface SelectType extends Omit {
diff --git a/src/hooks/querys.ts b/src/hooks/querys.ts
index 0b12e9c..8f6b4c2 100644
--- a/src/hooks/querys.ts
+++ b/src/hooks/querys.ts
@@ -13,6 +13,7 @@ import {
getBook,
getBooksFilter,
getMoreBooks,
+ getRelatedBooks,
postBook,
} from '../services/api';
import { keys } from '../utils/utils';
@@ -113,6 +114,17 @@ function useMoreBooks() {
});
}
+function useRelatedBooks(id: string | undefined) {
+ return useQuery({
+ queryKey: [keys.relatedBooks],
+ queryFn: () => getRelatedBooks(id),
+ suspense: true,
+ refetchOnWindowFocus: false,
+ cacheTime: 3000,
+ staleTime: 60000,
+ });
+}
+
function useBook(pathUrl: string | undefined) {
return useQuery({
queryKey: [keys.one, pathUrl],
@@ -132,4 +144,5 @@ export {
useBook,
useFilter,
useMoreBooks,
+ useRelatedBooks,
};
diff --git a/src/hooks/useRefetchLocation.tsx b/src/hooks/useRefetchLocation.tsx
new file mode 100644
index 0000000..013a4ff
--- /dev/null
+++ b/src/hooks/useRefetchLocation.tsx
@@ -0,0 +1,23 @@
+import { useState, useEffect } from 'react';
+import { useLocation } from 'react-router-dom';
+
+export function useRefetchLocation(currentBookId, data, refetch) {
+ const location = useLocation();
+ const [previousPathname, setPreviousPathname] = useState(location.pathname);
+ const [relatedBooks, setRelatedBooks] = useState([]);
+
+ useEffect(() => {
+ const filteredBooks = data.filter((book) => {
+ return book.pathUrl !== currentBookId;
+ });
+
+ setRelatedBooks(filteredBooks);
+
+ if (location.pathname !== previousPathname) {
+ refetch();
+ setPreviousPathname(location.pathname);
+ }
+ }, [data, currentBookId, location.pathname, refetch, previousPathname]);
+
+ return relatedBooks;
+}
diff --git a/src/pages/Book.tsx b/src/pages/Book.tsx
index c9030f1..971f1ac 100644
--- a/src/pages/Book.tsx
+++ b/src/pages/Book.tsx
@@ -25,7 +25,8 @@ import { ModalShare } from '../components/ModalShare';
import { MyLink } from '../components/MyLink';
const Categories = lazy(() => import('../components/Categories'));
-const RelatedPost = lazy(() => import('../components/RelatedPost'));
+const RelatedBooks = lazy(() => import('../components/cards/RelatedBooks'));
+const MoreBooks = lazy(() => import('../components/cards/MoreBooks'));
export default function Book() {
const shareUrl = window.location.href;
@@ -114,7 +115,7 @@ export default function Book() {
w='full'
maxW='1300px'
m='auto'
- mb='25'
+ mb={{ base: 25, md: 32 }}
align='flex-start'
direction={{ base: 'column', lg: 'row-reverse' }}
>
@@ -314,6 +315,34 @@ export default function Book() {
+
+
+ Libros relacionados con{' '}
+
+ {data.category[0]}
+
+
+
+
+
+ }
+ >
+
+
+
+
+
+
+
+
-
+
diff --git a/src/services/api.ts b/src/services/api.ts
index 536a21b..4f3cbd2 100644
--- a/src/services/api.ts
+++ b/src/services/api.ts
@@ -50,6 +50,12 @@ async function getMoreBooks() {
return data;
}
+async function getRelatedBooks(id: string | undefined) {
+ const data = await fetchData(`${API_URL}/books/related-books/${id}`);
+
+ return data;
+}
+
async function getAllFilterOptions() {
const data = await fetchData(`${API_URL}/books/options`);
@@ -72,6 +78,7 @@ export {
getBooksFilter,
getAllFilterOptions,
getMoreBooks,
+ getRelatedBooks,
postBook,
deleteBook,
};
diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index c576625..76238c4 100644
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -11,6 +11,7 @@ const keys = {
paginate: 'BookPaginate',
filter: 'BooksFilter',
random: 'BooksRandom',
+ relatedBooks: 'RelatedBooks',
};
function handleImageLoad(e: React.SyntheticEvent) {