diff options
| author | Factiven <[email protected]> | 2023-12-24 13:03:54 +0700 |
|---|---|---|
| committer | Factiven <[email protected]> | 2023-12-24 13:03:54 +0700 |
| commit | 50a0f0240d7fef133eb5acc1bea2b1168b08e9db (patch) | |
| tree | 307e09e505580415a58d64b5fc3580e9235869f1 /pages/en/search | |
| parent | Update README.md (#104) (diff) | |
| download | moopa-50a0f0240d7fef133eb5acc1bea2b1168b08e9db.tar.xz moopa-50a0f0240d7fef133eb5acc1bea2b1168b08e9db.zip | |
migrate to typescript
Diffstat (limited to 'pages/en/search')
| -rw-r--r-- | pages/en/search/[...param].tsx (renamed from pages/en/search/[...param].js) | 211 |
1 files changed, 119 insertions, 92 deletions
diff --git a/pages/en/search/[...param].js b/pages/en/search/[...param].tsx index c1fd94c..5a34ff5 100644 --- a/pages/en/search/[...param].js +++ b/pages/en/search/[...param].tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from "react"; +import { Key, useEffect, useRef, useState } from "react"; import { motion as m } from "framer-motion"; import Skeleton from "react-loading-skeleton"; import { useRouter } from "next/router"; @@ -23,12 +23,15 @@ import { import InputSelect from "@/components/search/dropdown/inputSelect"; import { Cog6ToothIcon, TrashIcon } from "@heroicons/react/20/solid"; import useDebounce from "@/lib/hooks/useDebounce"; -import { NewNavbar } from "@/components/shared/NavBar"; +import { Navbar } from "@/components/shared/NavBar"; import MobileNav from "@/components/shared/MobileNav"; -import SearchByImage from "@/components/search/searchByImage"; +import SearchByImage, { + TraceMoeResultTypes, +} from "@/components/search/searchByImage"; import { PlayIcon } from "@heroicons/react/24/outline"; +import { StaticImport } from "next/dist/shared/lib/get-img-props"; -export async function getServerSideProps(context) { +export async function getServerSideProps(context: any) { const { param } = context.query; const { search, format, genres, season, year } = context.query; @@ -81,6 +84,15 @@ export async function getServerSideProps(context) { }; } +type CardProps = { + index: number; + query: string; + genres: any; + formats: any; + seasons: any; + years: any; +}; + export default function Card({ index, query, @@ -88,22 +100,25 @@ export default function Card({ formats, seasons, years, -}) { +}: CardProps) { const inputRef = useRef(null); const router = useRouter(); - const [data, setData] = useState(); - const [imageSearch, setImageSearch] = useState(); + const [data, setData] = useState<any>(); + const [imageSearch, setImageSearch] = useState<TraceMoeResultTypes[]>(); const [loading, setLoading] = useState(true); - const [search, setQuery] = useState(query); + const [search, setQuery] = useState<string | null | undefined>(query); const debounceSearch = useDebounce(search, 500); - const [type, setSelectedType] = useState(mediaType[index]); + const [type, setSelectedType] = useState<{ + name: string; + value: string; + } | null>(mediaType[index]); const [year, setYear] = useState(years); const [season, setSeason] = useState(seasons); - const [sort, setSelectedSort] = useState(); + const [sort, setSelectedSort] = useState<{ name: string; value: string }>(); const [genre, setGenre] = useState(genres); const [format, setFormat] = useState(formats); @@ -116,7 +131,7 @@ export default function Card({ setLoading(true); const data = await aniAdvanceSearch({ search: debounceSearch, - type: type?.value, + type: type?.value as "ANIME" | "MANGA" | undefined, genres: genre, page: page, sort: sort?.value, @@ -128,7 +143,7 @@ export default function Card({ setNextPage(false); setLoading(false); } else if (data !== null && page > 1) { - setData((prevData) => { + setData((prevData: any) => { return [...(prevData ?? []), ...data?.media]; }); setNextPage(data?.pageInfo.hasNextPage); @@ -144,7 +159,9 @@ export default function Card({ setData(null); setPage(1); setNextPage(true); - advance(); + if (page === 1) { + advance(); + } // eslint-disable-next-line react-hooks/exhaustive-deps }, [ debounceSearch, @@ -158,7 +175,9 @@ export default function Card({ useEffect(() => { if (imageSearch) return; - advance(); + if (page > 1) { + advance(); + } // eslint-disable-next-line react-hooks/exhaustive-deps }, [page, imageSearch]); @@ -177,21 +196,23 @@ export default function Card({ window.innerHeight + window.pageYOffset >= document.body.offsetHeight - 3 ) { - setPage((prevPage) => prevPage + 1); + if (!loading) { + setPage((prevPage) => prevPage + 1); + } } } window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); - }, [page, nextPage, imageSearch]); + }, [page, nextPage, imageSearch, loading]); - const handleKeyDown = async (event) => { + const handleKeyDown = async (event: any) => { if (event.key === "Enter") { event.preventDefault(); const inputValue = event.target.value; if (inputValue === "") { - setQuery(null); + setQuery(undefined); } else { setQuery(inputValue); } @@ -199,13 +220,13 @@ export default function Card({ }; function trash() { - setImageSearch(); - setQuery(); - setGenre(); - setFormat(); - setSelectedSort(); - setSeason(); - setYear(); + setImageSearch(undefined); + setQuery(undefined); + setGenre(undefined); + setFormat(undefined); + setSelectedSort(undefined); + setSeason(undefined); + setYear(undefined); router.push(`/en/search/${mediaType[index]?.value?.toLowerCase()}`); } @@ -213,8 +234,8 @@ export default function Card({ setIsVisible(!isVisible); } - const handleVideoHover = (hovered, id) => { - const updatedImageSearch = imageSearch?.map((item) => { + const handleVideoHover = (hovered: boolean, id: any) => { + const updatedImageSearch = imageSearch?.map((item: any) => { if (item.filename === id) { return { ...item, hovered }; } @@ -234,7 +255,7 @@ export default function Card({ <link rel="icon" href="/svg/c.svg" /> </Head> - <NewNavbar + <Navbar scrollP={10} withNav={true} shrink={true} @@ -366,7 +387,7 @@ export default function Card({ </div> )} {/* <div> */} - <div className="flex flex-col gap-14 items-center z-30"> + <div className="flex flex-col gap-14 items-center z-30 overflow-x-hidden"> <div key="card-keys" className={`${ @@ -384,69 +405,75 @@ export default function Card({ {data && data?.length > 0 && !imageSearch && - data?.map((anime, index) => { - const anilistId = anime?.mappings?.find( - (x) => x.providerId === "anilist" - )?.id; - return ( - <m.div - initial={{ scale: 0.98 }} - animate={{ scale: 1, transition: { duration: 0.35 } }} - className="w-full" - key={index} - > - <Link - href={ - anime.format === "MANGA" || anime.format === "NOVEL" - ? `/en/manga/${anilistId ? `${anilistId}/` : ""}${ - anime.id - }` - : `/en/anime/${anime.id}` - } - title={anime.title.userPreferred} - className="block relative overflow-hidden bg-secondary hover:scale-[1.03] scale-100 transition-all cursor-pointer duration-200 ease-out rounded" - style={{ - paddingTop: "145%", // 2:3 aspect ratio (3/2 * 100%) - }} - > - <Image - className="object-cover" - src={anime.coverImage.extraLarge} - alt={anime.title.userPreferred} - sizes="(min-width: 808px) 50vw, 100vw" - quality={100} - fill - /> - </Link> - <Link - href={ - anime.format === "MANGA" || anime.format === "NOVEL" - ? `/en/manga/${anilistId ? `${anilistId}/` : ""}${ - anime.id - }` - : `/en/anime/${anime.id}` - } - title={anime.title.userPreferred} + data?.map( + ( + anime: { + format: string; + id: any; + title: { userPreferred: string }; + coverImage: { extraLarge: string | StaticImport }; + status: string; + episodes: any; + chapters: any; + }, + index: Key | null | undefined + ) => { + return ( + <m.div + initial={{ scale: 0.98 }} + animate={{ scale: 1, transition: { duration: 0.35 } }} + className="w-full" + key={index} > - <h1 className="font-outfit font-bold xl:text-base text-[15px] pt-4 line-clamp-2"> - {anime.status === "RELEASING" ? ( - <span className="dots bg-green-500" /> - ) : anime.status === "NOT_YET_RELEASED" ? ( - <span className="dots bg-red-500" /> - ) : null} - {anime.title.userPreferred} - </h1> - </Link> - <h2 className="font-outfit xl:text-[15px] text-[11px] font-light pt-2 text-[#8B8B8B]"> - {anime.format || <p>-</p>} ·{" "} - {anime.status || <p>-</p>} ·{" "} - {anime.episodes - ? `${anime.episodes || "N/A"} Episodes` - : `${anime.chapters || "N/A"} Chapters`} - </h2> - </m.div> - ); - })} + <Link + href={ + anime.format === "MANGA" || anime.format === "NOVEL" + ? `/en/manga/${anime.id}` + : `/en/anime/${anime.id}` + } + title={anime.title.userPreferred} + className="block relative overflow-hidden bg-secondary hover:scale-[1.03] scale-100 transition-all cursor-pointer duration-200 ease-out rounded" + style={{ + paddingTop: "145%", // 2:3 aspect ratio (3/2 * 100%) + }} + > + <Image + className="object-cover" + src={anime.coverImage.extraLarge} + alt={anime.title.userPreferred} + sizes="(min-width: 808px) 50vw, 100vw" + quality={100} + fill + /> + </Link> + <Link + href={ + anime.format === "MANGA" || anime.format === "NOVEL" + ? `/en/manga/${anime.id}` + : `/en/anime/${anime.id}` + } + title={anime.title.userPreferred} + > + <h1 className="font-outfit font-bold xl:text-base text-[15px] pt-4 line-clamp-2"> + {anime.status === "RELEASING" ? ( + <span className="dots bg-green-500" /> + ) : anime.status === "NOT_YET_RELEASED" ? ( + <span className="dots bg-red-500" /> + ) : null} + {anime.title.userPreferred} + </h1> + </Link> + <h2 className="font-outfit xl:text-[15px] text-[11px] font-light pt-2 text-[#8B8B8B]"> + {anime.format || <p>-</p>} ·{" "} + {anime.status || <p>-</p>} ·{" "} + {anime.episodes + ? `${anime.episodes || "N/A"} Episodes` + : `${anime.chapters || "N/A"} Chapters`} + </h2> + </m.div> + ); + } + )} {loading && ( <> @@ -532,7 +559,7 @@ export default function Card({ href={`/en/anime/${a.anilist.id}`} > {/* <h1 className="font-semibold">{a.title}</h1> */} - <p className="flex items-center gap-1 text-sm text-gray-400 w-[320px]"> + <p className="flex items-center gap-1 text-sm text-gray-400 max-w-[320px]"> <span className="text-white max-w-[120px] md:max-w-[200px] lg:max-w-[220px]" style={{ |