aboutsummaryrefslogtreecommitdiff
path: root/pages/en/search
diff options
context:
space:
mode:
authorFactiven <[email protected]>2023-12-24 13:03:54 +0700
committerFactiven <[email protected]>2023-12-24 13:03:54 +0700
commit50a0f0240d7fef133eb5acc1bea2b1168b08e9db (patch)
tree307e09e505580415a58d64b5fc3580e9235869f1 /pages/en/search
parentUpdate README.md (#104) (diff)
downloadmoopa-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>} &#183;{" "}
- {anime.status || <p>-</p>} &#183;{" "}
- {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>} &#183;{" "}
+ {anime.status || <p>-</p>} &#183;{" "}
+ {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={{