From 50a0f0240d7fef133eb5acc1bea2b1168b08e9db Mon Sep 17 00:00:00 2001 From: Factiven Date: Sun, 24 Dec 2023 13:03:54 +0700 Subject: migrate to typescript --- pages/en/index.tsx | 712 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 712 insertions(+) create mode 100644 pages/en/index.tsx (limited to 'pages/en/index.tsx') diff --git a/pages/en/index.tsx b/pages/en/index.tsx new file mode 100644 index 0000000..4141015 --- /dev/null +++ b/pages/en/index.tsx @@ -0,0 +1,712 @@ +import { aniListData } from "@/lib/anilist/AniList"; +import { useState, useEffect, Fragment } from "react"; +import Head from "next/head"; +import Link from "next/link"; +import Footer from "@/components/shared/footer"; +import Image from "next/image"; +import Content from "@/components/home/content"; + +import { motion } from "framer-motion"; + +import { signOut, useSession } from "next-auth/react"; +import Genres from "@/components/home/genres"; +import Schedule from "@/components/home/schedule"; +import getUpcomingAnime from "@/lib/anilist/getUpcomingAnime"; + +import GetMedia from "@/lib/anilist/getMedia"; +import MobileNav from "@/components/shared/MobileNav"; +import { getGreetings } from "@/utils/getGreetings"; +import { redis } from "@/lib/redis"; +import { Navbar } from "@/components/shared/NavBar"; +import UserRecommendation from "@/components/home/recommendation"; + +export async function getServerSideProps() { + let cachedData; + + if (redis) { + cachedData = await redis.get("index_server"); + } + + if (cachedData) { + const { genre, detail, populars } = JSON.parse(cachedData); + const upComing = await getUpcomingAnime(); + return { + props: { + genre, + detail, + populars, + upComing, + }, + }; + } else { + const trendingDetail = await aniListData({ + sort: "TRENDING_DESC", + page: 1, + }); + const popularDetail = await aniListData({ + sort: "POPULARITY_DESC", + page: 1, + }); + const genreDetail = await aniListData({ sort: "TYPE", page: 1 }); + + if (redis) { + await redis.set( + "index_server", + JSON.stringify({ + genre: genreDetail.props, + detail: trendingDetail.props, + populars: popularDetail.props, + }), // set cache for 2 hours + "EX", + 60 * 60 * 2 + ); + } + + const upComing = await getUpcomingAnime(); + + return { + props: { + genre: genreDetail.props, + detail: trendingDetail.props, + populars: popularDetail.props, + upComing, + }, + }; + } +} + +type HomeProps = { + genre: any; + detail: any; + populars: any; + upComing: any; +}; + +export interface SessionTypes { + name: string; + picture: Picture; + sub: string; + token: string; + id: number; + image: Image; + list: string[]; + version: string; + iat: number; + exp: number; + jti: string; +} + +interface Picture { + large: string; + medium: string; +} + +interface Image { + large: string; + medium: string; +} + +export default function Home({ detail, populars, upComing }: HomeProps) { + const { data: sessions }: any = useSession(); + const userSession: SessionTypes = sessions?.user; + + const { + anime: currentAnime, + manga: currentManga, + recommendations, + }: { + anime: CurrentMediaTypes[]; + manga: CurrentMediaTypes[]; + recommendations: CurrentMediaTypes[]; + } = GetMedia(sessions, { + stats: "CURRENT", + }); + const { anime: plan }: { anime: CurrentMediaTypes[] } = GetMedia(sessions, { + stats: "PLANNING", + }); + const { anime: release } = GetMedia(sessions); + + const [schedules, setSchedules] = useState(null); + const [anime, setAnime] = useState([]); + + const [recentAdded, setRecentAdded] = useState([]); + + async function getRecent() { + const data = await fetch(`/api/v2/etc/recent/1`) + .then((res) => res.json()) + .catch((err) => console.log(err)); + + setRecentAdded(data?.results); + } + + useEffect(() => { + if (userSession?.version) { + if (userSession?.version !== "1.0.1") { + signOut({ redirect: true }); + } + } + }, [userSession?.version]); + + useEffect(() => { + getRecent(); + }, []); + + const update = () => { + setAnime((prevAnime) => prevAnime.slice(1)); + }; + + useEffect(() => { + if (upComing && upComing.length > 0) { + setAnime(upComing); + } + }, [upComing]); + + const [releaseData, setReleaseData] = useState([]); + + useEffect(() => { + function getRelease() { + let releasingAnime: any[] = []; + let progress: any[] = []; + let seenIds = new Set(); // Create a Set to store the IDs of seen anime + (release as any[]).forEach((list: any) => { + list.entries.forEach((entry: any) => { + if ( + entry.media.status === "RELEASING" && + !seenIds.has(entry.media.id) + ) { + releasingAnime.push(entry.media); + seenIds.add(entry.media.id); // Add the ID to the Set + } + progress.push(entry); + }); + }); + setReleaseData(releasingAnime); + if (progress.length > 0) setProg(progress); + } + getRelease(); + }, [release]); + + const [listAnime, setListAnime] = useState(); + const [listManga, setListManga] = useState(null); + const [planned, setPlanned] = useState(null); + const [user, setUser] = useState(null); + const [removed, setRemoved] = useState(); + + const [prog, setProg] = useState(); + + const popular = populars?.data; + const data = detail.data[0]; + + useEffect(() => { + async function userData() { + try { + if (userSession?.name) { + await fetch(`/api/user/profile`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: sessions.user.name, + }), + }); + } + } catch (error) { + console.log(error); + } + let data: UserDataType | null = null; + try { + if (userSession?.name) { + const res = await fetch( + `/api/user/profile?name=${sessions.user.name}` + ); + if (!res.ok) { + switch (res.status) { + case 404: { + console.log("user not found"); + break; + } + case 500: { + console.log("server error"); + break; + } + default: { + console.log("unknown error"); + break; + } + } + } else { + data = await res.json(); + // Do something with the data + } + } + } catch (error) { + console.error(error); + // Handle the error here + } + if (!data) { + const dat: any = localStorage.getItem("artplayer_settings"); + if (dat) { + const arr = Object.keys(dat).map((key: string) => dat[key] as any); + const newFirst = arr?.sort((a: any, b: any) => { + return ( + new Date(b?.createdAt).getTime() - + new Date(a?.createdAt).getTime() + ); + }); + + const uniqueTitles = new Set(); + + // Filter out duplicates and store unique entries + const filteredData = newFirst.filter((entry: any) => { + if (uniqueTitles.has(entry.aniTitle)) { + return false; + } + uniqueTitles.add(entry.aniTitle); + return true; + }); + + if (filteredData) { + setUser(filteredData); + } + } + } else { + // Create a Set to store unique aniTitles + const uniqueTitles = new Set(); + + // Filter out duplicates and store unique entries + const filteredData = data?.WatchListEpisode.filter((entry) => { + if (uniqueTitles.has(entry.aniTitle)) { + return false; + } + uniqueTitles.add(entry.aniTitle); + return true; + }); + setUser(filteredData); + } + // const data = await res.json(); + } + userData(); + }, [userSession?.name, removed]); + + useEffect(() => { + async function userData() { + if (!userSession?.name) return; + + const getMedia = + currentAnime.find((item) => item.status === "CURRENT") || null; + const listAnime = getMedia?.entries + .map(({ media }) => media) + .filter((media) => media); + + const getManga = + currentManga?.find((item) => item.status === "CURRENT") || null; + const listManga = getManga?.entries + .map(({ media }) => media) + .filter((media) => media); + + const planned = plan?.[0]?.entries + .map(({ media }) => media) + .filter((media) => media); + + if (listManga) { + setListManga(listManga); + } + if (listAnime) { + setListAnime(listAnime); + } + if (planned) { + setPlanned(planned); + } + } + userData(); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [userSession?.name, currentAnime, plan]); + + return ( + + + Moopa + + + + + + + + + + + + + + + + + + + + + + +
+ {/* PC / TABLET */} +
+
+
+

+ {data.title.english || data.title.romaji || data.title.native} +

+

+ +

+ + START WATCHING + +
+
+
+
+
+ + {`cover +
+
+
+
+ {/*
+