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/profile/[user].js | 496 ------------------------------------------ pages/en/profile/[user].tsx | 509 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 509 insertions(+), 496 deletions(-) delete mode 100644 pages/en/profile/[user].js create mode 100644 pages/en/profile/[user].tsx (limited to 'pages/en/profile') diff --git a/pages/en/profile/[user].js b/pages/en/profile/[user].js deleted file mode 100644 index 7ef5de3..0000000 --- a/pages/en/profile/[user].js +++ /dev/null @@ -1,496 +0,0 @@ -import { getServerSession } from "next-auth"; -import { authOptions } from "../../api/auth/[...nextauth]"; -import Image from "next/image"; -import Link from "next/link"; -import Head from "next/head"; -import { useEffect, useState } from "react"; -import { getUser } from "@/prisma/user"; -import { NewNavbar } from "@/components/shared/NavBar"; -import { toast } from "sonner"; - -export default function MyList({ media, sessions, user, time, userSettings }) { - const [listFilter, setListFilter] = useState("all"); - const [visible, setVisible] = useState(false); - const [useCustomList, setUseCustomList] = useState(true); - - useEffect(() => { - if (userSettings) { - localStorage.setItem("customList", userSettings.CustomLists); - setUseCustomList(userSettings.CustomLists); - } - }, [userSettings]); - - // Function to handle checkbox state changes - const handleCheckboxChange = async () => { - setUseCustomList(!useCustomList); // Toggle the checkbox state - try { - const res = await fetch("/api/user/profile", { - method: "PUT", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: sessions?.user?.name, - settings: { - CustomLists: !useCustomList, - }, - }), - }); - const data = await res.json(); - if (data) { - toast.success(`Custom List is now ${!useCustomList ? "on" : "off"}`); - } - localStorage.setItem("customList", !useCustomList); - } catch (error) { - console.error(error); - } - }; - - const filterMedia = (status) => { - if (status === "all") { - return media; - } - return media.filter((m) => m.name === status); - }; - return ( - <> - - My Lists - - - -
-
-
- user avatar - {user.bannerImage ? ( - image - ) : ( -
- )} -

{user.name}

-
-
-
- Created At : - -
-
- {sessions && user.name === sessions?.user.name ? ( - - - - - Edit Profile - - ) : null} -
-
-
-
- {user.about ? ( -
- ) : ( - "No description created." - )} -
-
- -
-
-

- {user.statistics.anime.episodesWatched} -

-

Total Episodes

-
-
-

- {user.statistics.anime.count} -

-

Total Anime

-
- {time?.days ? ( -
-

{time.days}

-

Days Watched

-
- ) : ( -
-

{time.hours}

-

hours

-
- )} -
- {sessions && user.name === sessions?.user.name && ( -
-

User Settings

-
-

- Custom Lists -

-
- -
-
-
- )} - {media.length !== 0 && ( -
-
-
-

Lists Filter

- - - -
-
setVisible(!visible)} - > - - - -
-
-
    -
  • setListFilter("all")} - className={`p-2 cursor-pointer hover:text-action ${ - listFilter === "all" && "bg-secondary text-action" - }`} - > -

    - Show All -

    -
  • - {media.map((item) => ( -
  • setListFilter(item.name)} - className={`cursor-pointer hover:text-action flex gap-2 p-2 duration-200 ${ - item.name === listFilter && "bg-secondary text-action" - }`} - > -

    {item.name}

    -
    - ({item.entries.length}) -
    -
  • - ))} -
-
- )} -
- -
- {media.length !== 0 ? ( - filterMedia(listFilter).map((item, index) => { - return ( -
-

{item.name}

- - - - - - - - - - {item.entries.map((item) => { - return ( - - - - - - ); - })} - -
- Title - ScoreProgress
-
- {item.media.status === "RELEASING" ? ( - - ) : item.media.status === "NOT_YET_RELEASED" ? ( - - ) : ( - - )} - Cover Image -
- {item.media.id} -
- - {item.media.title.romaji} - -
-
- {item.score === 0 ? null : item.score} - - {item.progress === item.media.episodes - ? item.progress - : item.media.episodes === null - ? item.progress - : `${item.progress}/${item.media.episodes}`} -
-
- ); - }) - ) : ( -
- {user.name === sessions?.user.name ? ( -

- Oops!

Looks like you haven't watch anything yet. -

- ) : ( -

- Oops!

It looks like this user haven't watch anything - yet. -

- )} - - - - - Start Watching - -
- )} -
-
- - ); -} - -export async function getServerSideProps(context) { - const session = await getServerSession(context.req, context.res, authOptions); - const accessToken = session?.user?.token || null; - const query = context.query; - - const response = await fetch("https://graphql.anilist.co/", { - method: "POST", - headers: { - "Content-Type": "application/json", - ...(accessToken && { Authorization: `Bearer ${accessToken}` }), - }, - body: JSON.stringify({ - query: ` - query ($username: String, $status: MediaListStatus) { - MediaListCollection(userName: $username, type: ANIME, status: $status, sort: SCORE_DESC) { - user { - id - name - about (asHtml: true) - createdAt - avatar { - large - } - statistics { - anime { - count - episodesWatched - meanScore - minutesWatched - } - } - bannerImage - mediaListOptions { - animeList { - sectionOrder - } - } - } - lists { - status - name - entries { - id - mediaId - status - progress - score - media { - id - status - title { - english - romaji - } - episodes - coverImage { - large - } - } - } - } - } - } - `, - variables: { - username: query.user, - }, - }), - }); - - const data = await response.json(); - - const get = data.data.MediaListCollection; - const sectionOrder = get?.user.mediaListOptions.animeList.sectionOrder; - - if (!sectionOrder) { - return { - notFound: true, - }; - } - - let userData; - - if (session) { - userData = await getUser(session.user.name, false); - } - - const prog = get.lists; - - function getIndex(status) { - const index = sectionOrder.indexOf(status); - return index === -1 ? sectionOrder.length : index; - } - - prog.sort((a, b) => getIndex(a.name) - getIndex(b.name)); - - const user = get.user; - - const time = convertMinutesToDays(user.statistics.anime.minutesWatched); - - return { - props: { - media: prog, - sessions: session, - user: user, - time: time, - userSettings: userData?.setting || null, - }, - }; -} - -function UnixTimeConverter({ unixTime }) { - const date = new Date(unixTime * 1000); // multiply by 1000 to convert to milliseconds - const formattedDate = date.toISOString().slice(0, 10); // format date to YYYY-MM-DD - - return

{formattedDate}

; -} - -function convertMinutesToDays(minutes) { - const hours = minutes / 60; - const days = hours / 24; - - if (days >= 1) { - return days % 1 === 0 - ? { days: `${parseInt(days)}` } - : { days: `${days.toFixed(1)}` }; - } else { - return hours % 1 === 0 - ? { hours: `${parseInt(hours)}` } - : { hours: `${hours.toFixed(1)}` }; - } -} diff --git a/pages/en/profile/[user].tsx b/pages/en/profile/[user].tsx new file mode 100644 index 0000000..82b88af --- /dev/null +++ b/pages/en/profile/[user].tsx @@ -0,0 +1,509 @@ +import Image from "next/image"; +import Link from "next/link"; +import Head from "next/head"; +import { useEffect, useState } from "react"; +import { getUser } from "@/prisma/user"; +import { toast } from "sonner"; +import { Navbar } from "@/components/shared/NavBar"; +import pls from "@/utils/request"; +import { CurrentMediaTypes } from ".."; + +type MyListProps = { + media: CurrentMediaTypes[]; + sessions: any; + user: any; + time: any; + userSettings: any; +}; + +export default function MyList({ + media, + sessions, + user, + time, + userSettings, +}: MyListProps) { + const [listFilter, setListFilter] = useState("all"); + const [visible, setVisible] = useState(false); + const [useCustomList, setUseCustomList] = useState(true); + + useEffect(() => { + if (userSettings) { + localStorage.setItem("customList", userSettings.CustomLists); + setUseCustomList(userSettings.CustomLists); + } + }, [userSettings]); + + // Function to handle checkbox state changes + const handleCheckboxChange = async () => { + setUseCustomList(!useCustomList); // Toggle the checkbox state + try { + const res = await fetch("/api/user/profile", { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: sessions?.user?.name, + settings: { + CustomLists: !useCustomList, + }, + }), + }); + const data = await res.json(); + if (data) { + toast.success(`Custom List is now ${!useCustomList ? "on" : "off"}`); + } + localStorage.setItem("customList", String(!useCustomList)); + } catch (error) { + console.error(error); + } + }; + + const filterMedia = (status: string) => { + if (status === "all") { + return media; + } + return media.filter((m: { name: string }) => m.name === status); + }; + return ( + <> + + My Lists + + + + +
+
+
+ user avatar + {user.bannerImage ? ( + image + ) : ( +
+ )} +

{user.name}

+
+
+
+ Created At : + +
+
+ {sessions && user.name === sessions?.user.name ? ( + + + + + Edit Profile + + ) : null} +
+
+
+
+ {user.about ? ( +
+ ) : ( + "No description created." + )} +
+
+ +
+
+

+ {user.statistics.anime.episodesWatched} +

+

Total Episodes

+
+
+

+ {user.statistics.anime.count} +

+

Total Anime

+
+ {time?.days ? ( +
+

{time.days}

+

Days Watched

+
+ ) : ( +
+

{time.hours}

+

hours

+
+ )} +
+ {sessions && user.name === sessions?.user.name && ( +
+

User Settings

+
+

+ Custom Lists +

+
+ +
+
+
+ )} + {media.length !== 0 && ( +
+
+
+

Lists Filter

+ + + +
+
setVisible(!visible)} + > + + + +
+
+
    +
  • setListFilter("all")} + className={`p-2 cursor-pointer hover:text-action ${ + listFilter === "all" && "bg-secondary text-action" + }`} + > +

    + Show All +

    +
  • + {media.map((item) => ( +
  • setListFilter(item.name)} + className={`cursor-pointer hover:text-action flex gap-2 p-2 duration-200 ${ + item.name === listFilter && "bg-secondary text-action" + }`} + > +

    {item.name}

    +
    + ({item.entries.length}) +
    +
  • + ))} +
+
+ )} +
+ +
+ {media.length !== 0 ? ( + filterMedia(listFilter).map((item, index) => { + return ( +
+

{item.name}

+ + + + + + + + + + {item.entries.map((item) => { + return ( + + + + + + ); + })} + +
+ Title + ScoreProgress
+
+ {item.media.status === "RELEASING" ? ( + + ) : item.media.status === "NOT_YET_RELEASED" ? ( + + ) : ( + + )} + Cover Image +
+ {String(item.media.id)} +
+ + {item.media.title.romaji} + +
+
+ {item.score === 0 ? null : item.score} + + {item.progress === item.media.episodes + ? item.progress + : item.media.episodes === null + ? item.progress + : `${item.progress}/${item.media.episodes}`} +
+
+ ); + }) + ) : ( +
+ {user.name === sessions?.user.name ? ( +

+ Oops!

Looks like you haven't watch anything yet. +

+ ) : ( +

+ Oops!

It looks like this user haven't watch anything + yet. +

+ )} + + + + + Start Watching + +
+ )} +
+
+ + ); +} + +export async function getServerSideProps(context: any) { + const query = context.query; + + const [data, session] = await pls.post( + "https://graphql.anilist.co/", + { + body: JSON.stringify({ + query: ` + query ($username: String, $status: MediaListStatus) { + MediaListCollection(userName: $username, type: ANIME, status: $status, sort: SCORE_DESC) { + user { + id + name + about (asHtml: true) + createdAt + avatar { + large + } + statistics { + anime { + count + episodesWatched + meanScore + minutesWatched + } + } + bannerImage + mediaListOptions { + animeList { + sectionOrder + } + } + } + lists { + status + name + entries { + id + mediaId + status + progress + score + media { + id + status + title { + english + romaji + } + episodes + coverImage { + large + } + } + } + } + } + } + `, + variables: { + username: query.user, + }, + }), + }, + context + ); + + const get = data?.data?.MediaListCollection; + const sectionOrder = get?.user.mediaListOptions.animeList.sectionOrder; + + if (!sectionOrder) { + return { + notFound: true, + }; + } + + let userData; + + if (session) { + userData = await getUser(session.user.name, false); + } + + const prog = get.lists; + + function getIndex(status: string) { + const index = sectionOrder.indexOf(status); + return index === -1 ? sectionOrder.length : index; + } + + prog.sort( + (a: { name: string }, b: { name: string }) => + getIndex(a.name) - getIndex(b.name) + ); + + const user = get.user; + + const time = convertMinutesToDays(user.statistics.anime.minutesWatched); + + return { + props: { + media: prog, + sessions: session, + user: user, + time: time, + userSettings: userData?.setting || null, + }, + }; +} + +function UnixTimeConverter({ unixTime }: { unixTime: number }) { + const date = new Date(unixTime * 1000); // multiply by 1000 to convert to milliseconds + const formattedDate = date.toISOString().slice(0, 10); // format date to YYYY-MM-DD + + return

{formattedDate}

; +} + +function convertMinutesToDays(minutes: number) { + const hours = minutes / 60; + const days = hours / 24; + + if (days >= 1) { + return days % 1 === 0 + ? { days: `${days}` } + : { days: `${days.toFixed(1)}` }; + } else { + return hours % 1 === 0 + ? { hours: `${hours}` } + : { hours: `${hours.toFixed(1)}` }; + } +} -- cgit v1.2.3