diff --git a/public/pictures/hammer.png b/public/pictures/hammer.png
new file mode 100644
index 0000000..227d5c9
Binary files /dev/null and b/public/pictures/hammer.png differ
diff --git a/src/components/loader.jsx b/src/components/loader.jsx
new file mode 100644
index 0000000..112cbaf
--- /dev/null
+++ b/src/components/loader.jsx
@@ -0,0 +1,9 @@
+import '../style/loader.scss';
+
+export default function Loader() {
+ return (
+
+
Loading.....
+
+ );
+}
diff --git a/src/components/marvel-characters.jsx b/src/components/marvel-characters.jsx
index 7dbb5d6..9708628 100644
--- a/src/components/marvel-characters.jsx
+++ b/src/components/marvel-characters.jsx
@@ -3,6 +3,7 @@ import { useEffect, useState } from 'react';
import Card from '../components/card';
import Modal from '../components/modal';
import Profile from '../components/profile';
+import Loader from './loader';
const publicKey = import.meta.env.VITE_PUBLIC_KEY;
@@ -12,10 +13,12 @@ export default function MarvelCharacters({ addToFavorites }) {
const [isModalOpen, setIsModalOpen] = useState(false);
const [comics, setComics] = useState([]);
const [currentPage, setCurrentPage] = useState(0);
- const charactersPerPage = 20;
+ const [loading, setLoading] = useState(true);
+ const [err, setError] = useState(null);
+ const charactersPerPage = 15;
useEffect(() => {
- const apiComics = `https://gateway.marvel.com/v1/public/characters?apikey=${publicKey}&limit=100`;
+ const apiComics = `https://gateway.marvel.com/v1/public/characters?apikey=${publicKey}&limit=40`;
fetch(apiComics)
.then((res) => {
@@ -23,14 +26,29 @@ export default function MarvelCharacters({ addToFavorites }) {
return res.json();
})
.then((data) => {
- const randomCharacters = data.data.results.sort(() => Math.random() - 1);
- setMarvelCharacter(randomCharacters);
+ const filteredCharacters = data.data.results.filter(
+ (marvel) =>
+ marvel.thumbnail &&
+ marvel.thumbnail.path &&
+ marvel.thumbnail.extension &&
+ !marvel.thumbnail.path.includes('image_not_available'),
+ );
+ setLoading(false);
+ setMarvelCharacter(filteredCharacters);
})
- // eslint-disable-next-line no-console
- .catch((err) => console.error(err));
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [MarvelCharacters]);
+ .catch((err) => {
+ setError(err);
+ setLoading(false);
+ });
+ }, []);
+
+ if (loading)
+ return (
+
+
+
+ );
const handleAddToFavorites = (character) => {
addToFavorites(character);
};
@@ -84,6 +102,8 @@ export default function MarvelCharacters({ addToFavorites }) {
)
.slice(currentPage * charactersPerPage, (currentPage + 1) * charactersPerPage);
+ if (err) return Error: {err.message}
;
+
return (
diff --git a/src/style/loader.scss b/src/style/loader.scss
new file mode 100644
index 0000000..50cae57
--- /dev/null
+++ b/src/style/loader.scss
@@ -0,0 +1,29 @@
+@use 'settings' as *;
+
+@keyframes spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+.load {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ p {
+ padding-bottom: 20px;
+ color: white;
+ font-size: 50px;
+
+ font-family: $font-family;
+ }
+ img {
+ width: 150px;
+ animation: spin 1s linear infinite;
+ padding-top: 20px;
+ }
+}