aboutsummaryrefslogtreecommitdiff
path: root/pages/en/anime/trending.js
diff options
context:
space:
mode:
authorFactiven <[email protected]>2023-07-20 12:25:11 +0700
committerFactiven <[email protected]>2023-07-20 12:25:11 +0700
commit498a10c96f15381c17bfec293da0208c069d388c (patch)
tree95ce19e383262e54af5fb00ae04ae8783e8cd352 /pages/en/anime/trending.js
parentfix footer layering (diff)
downloadmoopa-498a10c96f15381c17bfec293da0208c069d388c.tar.xz
moopa-498a10c96f15381c17bfec293da0208c069d388c.zip
Update v3.6.6
> Added functionality to see more anime at home page > fixed some bugs
Diffstat (limited to 'pages/en/anime/trending.js')
-rw-r--r--pages/en/anime/trending.js175
1 files changed, 175 insertions, 0 deletions
diff --git a/pages/en/anime/trending.js b/pages/en/anime/trending.js
new file mode 100644
index 0000000..cbc30ab
--- /dev/null
+++ b/pages/en/anime/trending.js
@@ -0,0 +1,175 @@
+import { ChevronLeftIcon } from "@heroicons/react/24/solid";
+import Image from "next/image";
+import Link from "next/link";
+import { useEffect, useState } from "react";
+import Skeleton from "react-loading-skeleton";
+import Navbar from "../../../components/navbar";
+import Footer from "../../../components/footer";
+import { getServerSession } from "next-auth";
+import { authOptions } from "../../api/auth/[...nextauth]";
+import MobileNav from "../../../components/home/mobileNav";
+
+export default function TrendingAnime({ sessions }) {
+ const [data, setData] = useState(null);
+ const [page, setPage] = useState(1);
+ const [nextPage, setNextPage] = useState(true);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ setLoading(true);
+ const fetchData = async () => {
+ const res = await fetch("https://graphql.anilist.co", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Accept: "application/json",
+ },
+ body: JSON.stringify({
+ query: `query ($page: Int, $perPage: Int) {
+ Page (page: $page, perPage: $perPage) {
+ pageInfo {
+ total
+ currentPage
+ lastPage
+ hasNextPage
+ perPage
+ }
+ media (sort: TRENDING_DESC, type: ANIME) {
+ id
+ idMal
+ title {
+ romaji
+ }
+ coverImage {
+ large
+ }
+ averageScore
+ description
+ episodes
+ status
+ }
+ }
+ }
+ `,
+ variables: {
+ page: page,
+ perPage: 20,
+ },
+ }),
+ });
+ const get = await res.json();
+ if (get?.data?.Page?.media?.length === 0) {
+ setNextPage(false);
+ } else if (get !== null && page > 1) {
+ setData((prevData) => {
+ return [...(prevData ?? []), ...get?.data?.Page?.media];
+ });
+ setNextPage(get?.data?.Page?.pageInfo.hasNextPage);
+ } else {
+ setData(get?.data?.Page?.media);
+ }
+ setNextPage(get?.data?.Page?.pageInfo.hasNextPage);
+ setLoading(false);
+ };
+ fetchData();
+ }, [page]);
+
+ useEffect(() => {
+ function handleScroll() {
+ if (page > 5 || !nextPage) {
+ window.removeEventListener("scroll", handleScroll);
+ return;
+ }
+
+ if (
+ window.innerHeight + window.pageYOffset >=
+ document.body.offsetHeight - 3
+ ) {
+ setPage((prevPage) => prevPage + 1);
+ }
+ }
+
+ window.addEventListener("scroll", handleScroll);
+
+ return () => window.removeEventListener("scroll", handleScroll);
+ }, [page, nextPage]);
+
+ return (
+ <>
+ <MobileNav sessions={sessions} />
+ <div className="flex flex-col gap-2 items-center min-h-screen w-screen px-2 relative pb-10">
+ <div className="z-50 bg-primary pt-5 pb-3 shadow-md shadow-primary w-full fixed left-3">
+ <Link href="/en" className="flex gap-2 items-center font-karla">
+ <ChevronLeftIcon className="w-5 h-5" />
+ <h1 className="text-xl">Trending Now</h1>
+ </Link>
+ </div>
+ <div className="grid grid-cols-2 xs:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-6 gap-3 max-w-6xl pt-16">
+ {data?.map((i, index) => (
+ <div
+ key={index}
+ className="flex flex-col items-center w-[150px] lg:w-[180px]"
+ >
+ <Link href={`/en/anime/${i.id}`} className="p-2">
+ <Image
+ src={i.coverImage.large}
+ alt={i.title.romaji}
+ width={500}
+ height={500}
+ className="w-[140px] h-[190px] lg:w-[170px] lg:h-[230px] object-cover rounded hover:scale-105 scale-100 transition-all duration-200 ease-out"
+ />
+ </Link>
+ <Link href={`/en/anime/${i.id}`} className="w-full px-2">
+ <h1 className="font-karla font-bold xl:text-base text-[15px] line-clamp-2">
+ {i.status === "RELEASING" ? (
+ <span className="dots bg-green-500" />
+ ) : i.status === "NOT_YET_RELEASED" ? (
+ <span className="dots bg-red-500" />
+ ) : null}
+ {i.title.romaji}
+ </h1>
+ </Link>
+ </div>
+ ))}
+
+ {loading && (
+ <>
+ {[1, 2, 4, 5, 6, 7, 8].map((item) => (
+ <div
+ key={item}
+ className="flex flex-col items-center w-[150px] lg:w-[180px]"
+ >
+ <div className="w-full p-2">
+ <Skeleton className="w-[140px] h-[190px] lg:w-[170px] lg:h-[230px] rounded" />
+ </div>
+ <div className="w-full px-2">
+ <Skeleton width={80} height={20} />
+ </div>
+ </div>
+ ))}
+ </>
+ )}
+ </div>
+ {!loading && page > 5 && nextPage && (
+ <button
+ onClick={() => setPage((p) => p + 1)}
+ className="bg-secondary xl:w-[30%] w-[80%] h-10 rounded-md mt-5"
+ >
+ Load More
+ </button>
+ )}
+ </div>
+ <Footer />
+ </>
+ );
+}
+
+export async function getServerSideProps(context) {
+ const session = await getServerSession(context.req, context.res, authOptions);
+
+ return {
+ props: {
+ sessions: session,
+ },
+ };
+}