diff options
| author | Factiven <[email protected]> | 2023-04-14 00:07:02 +0700 |
|---|---|---|
| committer | Factiven <[email protected]> | 2023-04-14 00:07:02 +0700 |
| commit | 482b1c8db5cfeaa20d75ce92fcb10f3ca8433633 (patch) | |
| tree | f0c12d3acb6bd8ce43e63e01527c97a62dba7e9c /pages/components/hero | |
| parent | Update index.js (diff) | |
| download | moopa-482b1c8db5cfeaa20d75ce92fcb10f3ca8433633.tar.xz moopa-482b1c8db5cfeaa20d75ce92fcb10f3ca8433633.zip | |
Update 5th
Diffstat (limited to 'pages/components/hero')
| -rw-r--r-- | pages/components/hero/content.js | 90 | ||||
| -rw-r--r-- | pages/components/hero/searchAni.js | 64 | ||||
| -rw-r--r-- | pages/components/hero/trending.js | 120 |
3 files changed, 274 insertions, 0 deletions
diff --git a/pages/components/hero/content.js b/pages/components/hero/content.js new file mode 100644 index 0000000..b7515d2 --- /dev/null +++ b/pages/components/hero/content.js @@ -0,0 +1,90 @@ +import Link from "next/link"; +import React, { useState } from "react"; +import Image from "next/image"; +import { MdChevronLeft, MdChevronRight } from "react-icons/md"; + +export default function Content({ ids, section, data }) { + const [scrollLeft, setScrollLeft] = useState(false); + const [scrollRight, setScrollRight] = useState(true); + + const slideLeft = () => { + var slider = document.getElementById(ids); + slider.scrollLeft = slider.scrollLeft - 500; + }; + const slideRight = () => { + var slider = document.getElementById(ids); + slider.scrollLeft = slider.scrollLeft + 500; + }; + + const handleScroll = (e) => { + const scrollLeft = e.target.scrollLeft > 31; + const scrollRight = + e.target.scrollLeft < e.target.scrollWidth - e.target.clientWidth; + setScrollLeft(scrollLeft); + setScrollRight(scrollRight); + }; + + // console.log({ left: scrollLeft, right: scrollRight }); + + const array = data; + let filteredData = array.filter((item) => item.status !== "Unknown"); + return ( + <div> + <h1 className="px-5 font-karla text-[20px] font-bold">{section}</h1> + <div className="relative flex items-center lg:gap-2"> + <MdChevronLeft + onClick={slideLeft} + size={35} + className={`mb-5 cursor-pointer absolute left-0 bg-gradient-to-r from-[#141519] z-40 h-full hover:opacity-100 ${ + scrollLeft ? "visible" : "hidden" + }`} + /> + <div + id={ids} + className="scroll flex h-full w-full items-center select-none overflow-x-scroll scroll-smooth whitespace-nowrap overflow-y-hidden scrollbar-hide lg:gap-8 gap-5 p-10 z-30 " + onScroll={handleScroll} + > + {filteredData.map((anime) => { + return ( + <div + key={anime.id} + className="flex shrink-0 cursor-pointer items-center" + > + <Link + href={`/anime/${anime.id}`} + className="hover:scale-105 duration-300 ease-in-out" + > + <Image + draggable={false} + src={ + anime.image || + anime.coverImage?.extraLarge || + "https://cdn.discordapp.com/attachments/986579286397964290/1058415946945003611/gray_pfp.png" + } + alt={anime.title.romaji || anime.title.english} + width={209} + height={300} + placeholder="blur" + blurDataURL={ + anime.image || + anime.coverImage?.extraLarge || + "https://cdn.discordapp.com/attachments/986579286397964290/1058415946945003611/gray_pfp.png" + } + className="z-20 h-[192px] w-[135px] object-cover lg:h-[265px] lg:w-[185px] rounded-md" + /> + </Link> + </div> + ); + })} + </div> + <MdChevronRight + onClick={slideRight} + size={30} + className={`mb-5 cursor-pointer absolute right-0 bg-gradient-to-l from-[#141519] z-40 h-full hover:opacity-100 hover:bg-gradient-to-l ${ + scrollRight ? "visible" : "hidden" + }`} + /> + </div> + </div> + ); +} diff --git a/pages/components/hero/searchAni.js b/pages/components/hero/searchAni.js new file mode 100644 index 0000000..390165a --- /dev/null +++ b/pages/components/hero/searchAni.js @@ -0,0 +1,64 @@ +import React from "react"; +import { useQuery, gql } from "@apollo/client"; +import Link from "next/link"; + +const SearchAni = ({ searchQuery }) => { + const ANIME_QUERY = gql` + query ( + $id: Int + $page: Int + $perPage: Int + $search: String + $sort: [MediaSort] + ) { + Page(page: $page, perPage: $perPage) { + pageInfo { + total + currentPage + lastPage + hasNextPage + perPage + } + media(id: $id, search: $search, sort: $sort, type: ANIME) { + id + idMal + title { + romaji + english + } + coverImage { + large + } + } + } + } + `; + + // use useQuery hook to execute query and get data + const { loading, error, data } = useQuery(ANIME_QUERY, { + variables: { + search: searchQuery, + page: 1, + perPage: 5, + sort: "TRENDING_DESC", + }, + }); + + // render component + if (loading) return <p>Loading...</p>; + if (error) return <p>Error :(</p>; + + const { media } = data.Page; + + // const cleanDescription = description.replace(/<br>/g, '').replace(/\n/g, ' '); + + return ( + <main className="flex flex-col"> + <div className="my-10 mx-[1rem] flex flex-col gap-10 md:mx-auto md:w-full"> + {media.map((anime) => {})} + </div> + </main> + ); +}; + +export default SearchAni; diff --git a/pages/components/hero/trending.js b/pages/components/hero/trending.js new file mode 100644 index 0000000..24a6804 --- /dev/null +++ b/pages/components/hero/trending.js @@ -0,0 +1,120 @@ +import React from "react"; +import { useQuery, gql } from "@apollo/client"; +import { MdChevronLeft, MdChevronRight } from "react-icons/md"; +import Link from "next/link"; +import Image from "next/image"; + +const Trending = () => { + const ANIME_QUERY = gql` + query ( + $id: Int + $page: Int + $perPage: Int + $search: String + $sort: [MediaSort] + ) { + Page(page: $page, perPage: $perPage) { + pageInfo { + total + currentPage + lastPage + hasNextPage + perPage + } + media(id: $id, search: $search, sort: $sort, type: ANIME) { + id + idMal + title { + romaji + english + } + coverImage { + large + } + description + bannerImage + type + popularity + averageScore + } + } + } + `; + + // use useQuery hook to execute query and get data + const { loading, error, data } = useQuery(ANIME_QUERY, { + variables: { + page: 1, + perPage: 15, + sort: "TRENDING_DESC", + }, + }); + + // render component + if (loading) return <p></p>; + if (error) return <p>Error :(</p>; + + const { media } = data.Page; + + const slideLeft = () => { + var slider = document.getElementById("slider"); + slider.scrollLeft = slider.scrollLeft - 500; + }; + const slideRight = () => { + var slider = document.getElementById("slider"); + slider.scrollLeft = slider.scrollLeft + 500; + }; + + return ( + <div className="relative flex items-center gap-0 lg:gap-2"> + <MdChevronLeft + onClick={slideLeft} + size={40} + className="mb-5 cursor-pointer opacity-50 hover:opacity-100" + /> + <div + id="slider" + className="scroll flex h-full w-full items-center overflow-x-scroll scroll-smooth whitespace-nowrap overflow-y-hidden scrollbar-hide lg:gap-5 " + > + {media.map((anime) => { + const url = encodeURIComponent( + anime.title.english || anime.title.romaji + ); + + return ( + <div + key={anime.id} + className="flex shrink-0 cursor-pointer lg:items-center " + > + <Link href={`/anime/${anime.id}`}> + <Image + src={anime.coverImage.large} + alt={anime.title.romaji || anime.title.english} + width={209} + height={300} + skeleton={ + <div + style={{ + backgroundColor: "lightgray", + width: 209, + height: 300, + }} + /> + } + className="z-20 h-[230px] w-[168px] object-cover p-2 duration-300 ease-in-out hover:scale-105 lg:h-[290px] lg:w-[209px]" + /> + </Link> + </div> + ); + })} + </div> + <MdChevronRight + onClick={slideRight} + size={40} + className="mb-5 cursor-pointer opacity-50 hover:opacity-100" + /> + </div> + ); +}; + +export default Trending; |