@@ -23,4 +25,4 @@ const LoadingComponent = () => {
);
};
-export default LoadingComponent;
+export default memo(LoadingComponent);
diff --git a/src/components/loading/LoadingSkeleton.jsx b/src/components/loading/LoadingSkeleton.jsx
index 9a964dc..1043f90 100644
--- a/src/components/loading/LoadingSkeleton.jsx
+++ b/src/components/loading/LoadingSkeleton.jsx
@@ -1,3 +1,5 @@
+import { memo } from "react";
+
const LoadingSkeleton = ({ className, width, height, radius }) => {
return (
{
);
};
-export default LoadingSkeleton;
+export default memo(LoadingSkeleton);
diff --git a/src/components/search/SearchContainer.jsx b/src/components/search/SearchContainer.jsx
deleted file mode 100644
index 83b48bc..0000000
--- a/src/components/search/SearchContainer.jsx
+++ /dev/null
@@ -1,107 +0,0 @@
-import AnimeItem from "../anime/AnimeItem";
-import { useEffect, useRef, useState } from "react";
-import CharacterItem from "../character/CharacterItem";
-import AnimeItemSkeleton from "../anime/AnimeItemSkeleton";
-import { search } from "../../apis/apis";
-import { toast } from "react-toastify";
-import { useNavigate } from "react-router-dom";
-import { v4 } from "uuid";
-import { useInfiniteQuery } from "@tanstack/react-query";
-import InfiniteScroll from "react-infinite-scroller";
-
-const SearchContainer = ({ type }) => {
- const navigate = useNavigate();
- const [query, setQuery] = useState("naruto");
- const inputRef = useRef(null);
- const searchBtnRef = useRef(null);
-
- const url = `https://api.jikan.moe/v4/${type}?q=${query}`;
-
- const { data, hasNextPage, fetchNextPage, isError, isLoading } =
- useInfiniteQuery(
- [`search-${type}`, query],
- ({ pageParam = url }) => search(pageParam),
- {
- getNextPageParam: (lastPage, allPages) =>
- lastPage.pagination.has_next_page
- ? `${url}&page=${lastPage.pagination.current_page + 1}`
- : undefined,
- }
- );
-
- if (isLoading) {
- toast.info("Loading...");
- }
-
- if (isError) {
- toast.error("Something went wrong! Please try again!");
- return navigate("/");
- }
-
- useEffect(() => {
- const handlerEnterKeyPress = (e) => {
- if (e.code === "Enter") {
- setQuery(inputRef.current.value);
- }
- };
-
- document.addEventListener("keyup", handlerEnterKeyPress);
-
- return () => {
- document.removeEventListener("keyup", handlerEnterKeyPress);
- };
- }, []);
-
- console.log(data);
-
- return (
-
-
-
-
-
-
-
-
- {isLoading && (
-
- {new Array(4).fill(0).map(() => (
-
- ))}
-
- )}
-
-
- {!isLoading &&
- data.pages.map((pageData) =>
- pageData.data.map((item) => (
- <>
- {type === "anime" ? (
-
- ) : (
-
- )}
- >
- ))
- )}
-
-
-
-
-
- );
-};
-
-export default SearchContainer;
diff --git a/src/main.jsx b/src/main.jsx
index 49b4372..a5a0c05 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -1,7 +1,7 @@
import { render } from "react-dom";
import { lazy, Suspense } from "react";
+import { ToastContainer } from "react-toastify";
import { BrowserRouter, Route, Routes } from "react-router-dom";
-
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import LoadingComponent from "./components/loading/LoadingComponent";
@@ -11,14 +11,12 @@ const HomePage = lazy(() => import("./page/HomePage"));
const AnimePage = lazy(() => import("./page/AnimePage"));
const SearchPage = lazy(() => import("./page/SearchPage"));
const AnimeDetailPage = lazy(() => import("./page/AnimeDetailPage"));
-const CharacterPage = lazy(() => import("./page/CharacterPage"));
const CharacterDetailPage = lazy(() => import("./page/CharacterDetailPage"));
const Error404Page = lazy(() => import("./page/Error404Page"));
import "swiper/css";
import "react-toastify/dist/ReactToastify.css";
import "./index.scss";
-import { ToastContainer } from "react-toastify";
const queryClient = new QueryClient();
@@ -31,12 +29,15 @@ render(
} />
} />
} />
-
} />
+
}
+ />
}
/>
-
} />
+
} />
} />
diff --git a/src/page/AnimeDetailPage.jsx b/src/page/AnimeDetailPage.jsx
index d36d5bb..3fb749b 100644
--- a/src/page/AnimeDetailPage.jsx
+++ b/src/page/AnimeDetailPage.jsx
@@ -1,17 +1,18 @@
import { useNavigate, useParams } from "react-router-dom";
-import DetailStatus from "../components/anime-details/DetailStatus";
-import IconStar from "../components/icons/IconStar";
-import IconUserGroup from "../components/icons/IconUserGroup";
-import IconFavorite from "../components/icons/IconFavorite";
-import IconRank from "../components/icons/IconRank";
-
import { getRating } from "../utils/getRating";
-import DetailListItem from "../components/anime-details/DetailListItem";
-import LoadingComponent from "../components/loading/LoadingComponent";
import { useQuery } from "@tanstack/react-query";
import { getAnimeDetail } from "../apis/apis";
import { toast } from "react-toastify";
+import {
+ DetailListItem,
+ DetailStatus,
+ IconFavorite,
+ IconRank,
+ IconStar,
+ IconUserGroup,
+ LoadingComponent,
+} from "../components";
const AnimeDetailPage = () => {
const { animeID } = useParams();
diff --git a/src/page/AnimePage.jsx b/src/page/AnimePage.jsx
index 3a1f268..9882118 100644
--- a/src/page/AnimePage.jsx
+++ b/src/page/AnimePage.jsx
@@ -1,4 +1,4 @@
-import AnimeList from "../components/anime/AnimeList";
+import { AnimeList } from "../components";
const AnimePage = () => {
return (
diff --git a/src/page/CharacterDetailPage.jsx b/src/page/CharacterDetailPage.jsx
index 36c81e5..71d782c 100644
--- a/src/page/CharacterDetailPage.jsx
+++ b/src/page/CharacterDetailPage.jsx
@@ -1,11 +1,9 @@
import { useNavigate, useParams } from "react-router-dom";
import { useQuery } from "@tanstack/react-query";
+import { toast } from "react-toastify";
-import IconFavorite from "../components/icons/IconFavorite";
-import IconEmail from "../components/icons/IconEmail";
-import LoadingComponent from "../components/loading/LoadingComponent";
import { getCharacterDetail } from "../apis/apis";
-import { toast } from "react-toastify";
+import { IconEmail, IconFavorite, LoadingComponent } from "../components";
const CharacterDetailPage = () => {
const navigate = useNavigate();
diff --git a/src/page/CharacterPage.jsx b/src/page/CharacterPage.jsx
deleted file mode 100644
index 595751e..0000000
--- a/src/page/CharacterPage.jsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import SearchContainer from "../components/search/SearchContainer";
-
-const CharacterPage = () => {
- return
;
-};
-
-export default CharacterPage;
diff --git a/src/page/Error404Page.jsx b/src/page/Error404Page.jsx
index 5fac6bb..fb99ea5 100644
--- a/src/page/Error404Page.jsx
+++ b/src/page/Error404Page.jsx
@@ -1,6 +1,7 @@
import { useNavigate } from "react-router-dom";
-import Button from "../components/buttons/Button";
+
import errorImg from "../images/404.png";
+import { Button } from "../components";
const Error404Page = () => {
const navigate = useNavigate();
diff --git a/src/page/SearchPage.jsx b/src/page/SearchPage.jsx
index d602476..57d6053 100644
--- a/src/page/SearchPage.jsx
+++ b/src/page/SearchPage.jsx
@@ -1,7 +1,113 @@
-import SearchContainer from "../components/search/SearchContainer";
+import { v4 } from "uuid";
+import { toast } from "react-toastify";
+import { useNavigate } from "react-router-dom";
+import { useEffect, useRef, useState } from "react";
+import InfiniteScroll from "react-infinite-scroller";
+import { useInfiniteQuery } from "@tanstack/react-query";
-const SearchPage = () => {
- return
;
+import { search } from "../apis/apis";
+import { AnimeItem, AnimeItemSkeleton, CharacterItem } from "../components";
+
+const SearchPage = ({ type }) => {
+ const navigate = useNavigate();
+ const [query, setQuery] = useState("naruto");
+ const inputRef = useRef(null);
+ const searchBtnRef = useRef(null);
+
+ const url = `https://api.jikan.moe/v4/${type}?q=${query}`;
+
+ const {
+ data,
+ hasNextPage,
+ fetchNextPage,
+ isError,
+ isLoading,
+ isFetchingNextPage,
+ } = useInfiniteQuery(
+ [`search-${type}`, query],
+ ({ pageParam = url }) => search(pageParam),
+ {
+ getNextPageParam: (lastPage, _) =>
+ lastPage.pagination.has_next_page
+ ? `${url}&page=${lastPage.pagination.current_page + 1}`
+ : undefined,
+ }
+ );
+
+ if (isError) {
+ toast.error("Something went wrong! Please try again!");
+ return navigate("/");
+ }
+
+ useEffect(() => {
+ const handlerEnterKeyPress = (e) => {
+ if (e.code === "Enter") {
+ setQuery(inputRef.current.value);
+ }
+ };
+
+ document.addEventListener("keyup", handlerEnterKeyPress);
+
+ return () => {
+ document.removeEventListener("keyup", handlerEnterKeyPress);
+ };
+ }, []);
+
+ return (
+
+
+
+
+
+
+
+
+ {isLoading && (
+
+ {new Array(4).fill(0).map(() => (
+
+ ))}
+
+ )}
+
+
+ {!isLoading &&
+ data.pages.map((pageData) =>
+ pageData.data.map((item) => (
+ <>
+ {type === "anime" ? (
+
+ ) : (
+
+ )}
+ >
+ ))
+ )}
+ {isFetchingNextPage && (
+ <>
+ {new Array(4).fill(0).map(() => (
+
+ ))}
+ >
+ )}
+
+
+
+
+
+ );
};
export default SearchPage;
diff --git a/src/utils/fetcher.jsx b/src/utils/fetcher.jsx
deleted file mode 100644
index 3c44991..0000000
--- a/src/utils/fetcher.jsx
+++ /dev/null
@@ -1 +0,0 @@
-export const fetcher = (...args) => fetch(...args).then((res) => res.json());
diff --git a/src/utils/request.jsx b/src/utils/request.jsx
deleted file mode 100644
index e69de29..0000000