diff options
| author | real-zephex <[email protected]> | 2024-04-06 15:38:39 +0530 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-04-06 15:38:39 +0530 |
| commit | 99e977342c2bc4aa3f6b930dfab80a7dc9f5eee3 (patch) | |
| tree | e5ea8e64e27778ce468431138775bf9f6dc3874b /src | |
| parent | UI Upgrades for anime section. (diff) | |
| parent | added search functionality (diff) | |
| download | dramalama-99e977342c2bc4aa3f6b930dfab80a7dc9f5eee3.tar.xz dramalama-99e977342c2bc4aa3f6b930dfab80a7dc9f5eee3.zip | |
Merge pull request #2 from real-zephex/kdrama-section-rewrite
The kdrama section underwent a complete rewrite.
Diffstat (limited to 'src')
26 files changed, 621 insertions, 508 deletions
diff --git a/src/app/anime/[id]/[...animeId]/page.jsx b/src/app/anime/[id]/[...animeId]/page.jsx index 966f212..950f618 100644 --- a/src/app/anime/[id]/[...animeId]/page.jsx +++ b/src/app/anime/[id]/[...animeId]/page.jsx @@ -10,6 +10,7 @@ import { redirect } from "next/navigation"; import Link from "next/link"; export default async function Video({ params }) { + let link; const id = params.animeId[0]; const series = params.animeId[1]; @@ -25,7 +26,16 @@ export default async function Video({ params }) { redirect("/404"); } - const link = data.sources[4].url; + try { + link = data.sources[4].url; + } catch (error) { + try { + link = data.sources[3].url; + } catch (error) { + console.log("Episode not found."); + redirect("/404"); + } + } return ( <div className={styles.VideoMain}> @@ -37,7 +47,6 @@ export default async function Video({ params }) { <MediaPlayer title={words} src={link} - playsInline aspectRatio="16/9" load="eager" className={styles.VideoPlayer} diff --git a/src/app/anime/[id]/[...animeId]/video.module.css b/src/app/anime/[id]/[...animeId]/video.module.css index d947fc3..0214e60 100644 --- a/src/app/anime/[id]/[...animeId]/video.module.css +++ b/src/app/anime/[id]/[...animeId]/video.module.css @@ -1,8 +1,3 @@ -.VideoMain { - max-width: 98%; - margin: 0px auto; -} - .Video { display: flex; justify-content: center; @@ -11,7 +6,7 @@ .VideoPlayer { border-radius: 10px; - width: 75%; + width: 70%; height: auto; } diff --git a/src/app/anime/recent/recent.module.css b/src/app/anime/recent/recent.module.css index 20c5e1b..ab9d98d 100644 --- a/src/app/anime/recent/recent.module.css +++ b/src/app/anime/recent/recent.module.css @@ -1,5 +1,4 @@ .RecentText { - color: #FFB996; display: flex; align-items: center; } @@ -7,7 +6,8 @@ .RecentText p { font-size: 26px; margin: 5px; - font-family: "Quicksand"; + color: var(--soft-purple); + font-family: "Poppins"; } .RecentText span { @@ -42,6 +42,7 @@ text-align: center; margin: 5px auto; width: 140px; + font-family: "Atkinson Hyperlegible"; } .RecentEntries p::-webkit-scrollbar { diff --git a/src/app/anime/top-airing/trending.module.css b/src/app/anime/top-airing/trending.module.css index 1dcfb9d..3aa1ee7 100644 --- a/src/app/anime/top-airing/trending.module.css +++ b/src/app/anime/top-airing/trending.module.css @@ -1,5 +1,4 @@ .TrendingText { - color: #FFB996; display: flex; align-items: center; } @@ -7,7 +6,8 @@ .TrendingText p { font-size: 26px; margin: 5px; - font-family: "Quicksand"; + color: var(--soft-purple); + font-family: "Poppins"; } .TrendingText span { @@ -42,6 +42,7 @@ text-align: center; margin: 5px auto; width: 140px; + font-family: "Atkinson Hyperlegible"; } .trendingEntries p::-webkit-scrollbar { diff --git a/src/app/components/header/header.jsx b/src/app/components/header/header.jsx index 286aed6..b105bb6 100644 --- a/src/app/components/header/header.jsx +++ b/src/app/components/header/header.jsx @@ -16,14 +16,14 @@ export default function Header() { </Link> <div className={styles.rightNav}> <Link href="/anime"> - <p>Anime</p> + <p>anime</p> </Link> <Link href="/manga"> - <p>Manga</p> + <p>manga</p> + </Link> + <Link href="/kdrama"> + <p>kdrama</p> </Link> - {/* <Link href="/kdrama"> - <p>Kdrama</p> - </Link> */} </div> </div> <hr style={{ marginTop: "-3px" }} /> diff --git a/src/app/components/header/header.module.css b/src/app/components/header/header.module.css index ce855ed..5ff32fd 100644 --- a/src/app/components/header/header.module.css +++ b/src/app/components/header/header.module.css @@ -5,7 +5,7 @@ align-items: center; max-width: 95%; margin: -10px auto; - font-family: "Quicksand"; + font-family: "Poppins"; } .rightNav { @@ -16,6 +16,7 @@ .rightNav a { text-decoration: underline; + font-family: "Atkinson Hyperlegible"; color: var(--light-green); font-size: 18px; } diff --git a/src/app/globals.css b/src/app/globals.css index 8690bc9..36616bb 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,3 +1,6 @@ +@import url('https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible:ital,wght@0,400;0,700;1,400;1,700&family=Kanit:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&family=Open+Sans:ital@0;1&family=Quicksand&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); + :root { --neon-green: #45FFCA; --neon-yellow: #FEFFAC; diff --git a/src/app/globals.module.css b/src/app/globals.module.css index e57a44b..983f1dd 100644 --- a/src/app/globals.module.css +++ b/src/app/globals.module.css @@ -1,5 +1,3 @@ -@import url('https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible:ital,wght@0,400;0,700;1,400;1,700&family=Kanit:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&family=Open+Sans:ital@0;1&family=Quicksand&display=swap'); - .ErrorContainer { display: flex; justify-content: center; diff --git a/src/app/kdrama/[id]/buttons.jsx b/src/app/kdrama/[id]/buttons.jsx new file mode 100644 index 0000000..8ec633f --- /dev/null +++ b/src/app/kdrama/[id]/buttons.jsx @@ -0,0 +1,59 @@ +"use client"; +import styles from "../styles/info.module.css"; +import getVideoLink from "../components/videoLink"; +import React, { useState } from "react"; +import { MediaPlayer, MediaProvider } from "@vidstack/react"; +import "@vidstack/react/player/styles/base.css"; +import "@vidstack/react/player/styles/plyr/theme.css"; +import { + PlyrLayout, + plyrLayoutIcons, +} from "@vidstack/react/player/layouts/plyr"; + +export default function EpisodesButtons({ data: episodeData, id: dramaId }) { + const [videoLink, setVideoLink] = useState(null); + const [episode, setEpisode] = useState(""); + + async function test(a, b, episodeText) { + let link = await getVideoLink(a, b); + setVideoLink(link); + setEpisode(episodeText); + } + + return ( + <div> + <div className={styles.EpisodesContainer}> + <h2>Episodes</h2> + <div className={styles.EpisodeButtons}> + {episodeData && + episodeData.map((item, index) => ( + <button + key={index} + onClick={() => + test(item.id, dramaId, item.title) + } + > + {item.title} + </button> + ))} + </div> + </div> + {videoLink && ( + <div className={styles.VideoContainer}> + <MediaPlayer + title="dramaPlayer" + src={videoLink} + aspectRatio="16/9" + load="eager" + className={styles.VideoPlayer} + playsInline + > + <MediaProvider /> + <PlyrLayout icons={plyrLayoutIcons} /> + </MediaPlayer> + <p>{episode.toUpperCase()}</p> + </div> + )} + </div> + ); +} diff --git a/src/app/kdrama/[id]/page.jsx b/src/app/kdrama/[id]/page.jsx new file mode 100644 index 0000000..baaf24e --- /dev/null +++ b/src/app/kdrama/[id]/page.jsx @@ -0,0 +1,70 @@ +import styles from "../styles/info.module.css"; +import Image from "next/image"; +import EpisodesButtons from "./buttons"; +import PreFetchVideoLinks from "../components/cacher"; + +export default async function DramaInfo({ params }) { + const id = decodeURIComponent(params.id); + const info = await getDramaInfo(id); + + PreFetchVideoLinks(info.episodes, id); + + return ( + <div className={styles.Main}> + {info && ( + <div className={styles.DramaInfoContainer}> + <div className={styles.TitleContainer}> + <p>{info.title}</p> + <Image + src={info.image} + width={160} + height={240} + alt="Drama Poster" + priority + /> + </div> + + {/* Drama description */} + <div className={styles.DramaDescription}> + <h2>Description</h2> + <p>{info.description}</p> + </div> + + {/* Genres */} + <div className={styles.DramaGenre}> + <span className={styles.genreMain}>Genres: </span> + {info.genres && + info.genres.map((item, index) => ( + <span key={index} className={styles.genreEntry}> + {item} + </span> + ))} + </div> + + {/* Other names */} + <div className={styles.DramaGenre}> + <span className={styles.genreMain}>AKA: </span> + {info.otherNames && + info.otherNames.map((item, index) => ( + <span key={index} className={styles.genreEntry}> + {item} + </span> + ))} + </div> + + {/* Episodes Buttons */} + <EpisodesButtons data={info.episodes} id={id} /> + </div> + )} + </div> + ); +} + +async function getDramaInfo(id) { + const res = await fetch( + `https://consumet-api-di2e.onrender.com/movies/dramacool/info?id=${id}`, + { next: { revalidate: 86400 } } + ); + const data = await res.json(); + return data; +} diff --git a/src/app/kdrama/api/fetchAnime.js b/src/app/kdrama/api/fetchAnime.js deleted file mode 100644 index ae0c5a9..0000000 --- a/src/app/kdrama/api/fetchAnime.js +++ /dev/null @@ -1,28 +0,0 @@ -export async function fetchAnimeInfo(title) { - const res = await fetch( - "https://consumet-api-di2e.onrender.com/movies/dramacool/" + title, - { cache: "force-cache" } - ); - const data = await res.json(); - return data; -} - -export async function fetchDramaInfo(id) { - const res = ( - await fetch( - `https://consumet-api-di2e.onrender.com/movies/dramacool/info?id=${id}`, - { cache: "force-cache" } - ) - ).json(); - return res; -} - -export async function fetchVideoLinks(drama_id, episode_id) { - const res = ( - await fetch( - `https://consumet-api-di2e.onrender.com/movies/dramacool/watch?episodeId=${episode_id}&mediaId=${drama_id}`, - { cache: "force-cache" } - ) - ).json(); - return res; -} diff --git a/src/app/kdrama/components/cacher.js b/src/app/kdrama/components/cacher.js new file mode 100644 index 0000000..b04c932 --- /dev/null +++ b/src/app/kdrama/components/cacher.js @@ -0,0 +1,15 @@ +// This function pre-fetches all the video links for a drama in the background + +export default async function PreFetchVideoLinks(data, dramaId) { + try { + const fetchPromises = data.map(async (element) => { + const link = `https://consumet-api-di2e.onrender.com/movies/dramacool/watch?episodeId=${element.id}&mediaId=${dramaId}`; + await fetch(link, { cache: "force-cache" }); + }); + + await Promise.all(fetchPromises); + console.log("Video links pre-fetched successfully!"); + } catch (error) { + console.error("Error occurred while pre-fetching video links:", error); + } +} diff --git a/src/app/kdrama/components/popular.jsx b/src/app/kdrama/components/popular.jsx new file mode 100644 index 0000000..d9126ec --- /dev/null +++ b/src/app/kdrama/components/popular.jsx @@ -0,0 +1,42 @@ +import styles from "../styles/popular.module.css"; +import Image from "next/image"; +import Link from "next/link"; + +export default async function PopularDramas() { + const popular = await getPopular(); + + return ( + <div className={styles.Main}> + <p className={styles.popDramasText}>Popular Dramas</p> + + <div className={styles.AnimeContainer}> + {popular && + popular.results.map((item, index) => ( + <Link + href={`/kdrama/${encodeURIComponent(item.id)}`} + key={index} + style={{ textDecoration: "none" }} + > + <div className={styles.AnimeEntry}> + <Image + src={item.image} + width={160} + height={240} + alt="Drama Poster" + /> + <p>{item.title}</p> + </div> + </Link> + ))} + </div> + </div> + ); +} + +async function getPopular() { + const res = await fetch("https://dramacool-scraper.vercel.app/popular", { + next: { revalidate: 86400 }, + }); + const data = await res.json(); + return data; +} diff --git a/src/app/kdrama/components/recent.jsx b/src/app/kdrama/components/recent.jsx new file mode 100644 index 0000000..759e179 --- /dev/null +++ b/src/app/kdrama/components/recent.jsx @@ -0,0 +1,42 @@ +import styles from "../styles/popular.module.css"; +import Image from "next/image"; +import Link from "next/link"; + +export default async function RecentDramas() { + const popular = await getPopular(); + + return ( + <div className={styles.Main}> + <p className={styles.popDramasText}>Recently Released</p> + + <div className={styles.AnimeContainer}> + {popular && + popular.results.map((item, index) => ( + <Link + href={`/kdrama/${encodeURIComponent(item.id)}`} + key={index} + style={{ textDecoration: "none" }} + > + <div className={styles.AnimeEntry}> + <Image + src={item.image} + width={160} + height={240} + alt="Drama Poster" + /> + <p>{item.title}</p> + </div> + </Link> + ))} + </div> + </div> + ); +} + +async function getPopular() { + const res = await fetch("https://dramacool-scraper.vercel.app/recent", { + next: { revalidate: 86400 }, + }); + const data = await res.json(); + return data; +} diff --git a/src/app/kdrama/components/search.jsx b/src/app/kdrama/components/search.jsx new file mode 100644 index 0000000..4c9d00c --- /dev/null +++ b/src/app/kdrama/components/search.jsx @@ -0,0 +1,56 @@ +"use client"; + +import styles from "../styles/search.module.css"; +import { useState } from "react"; +import { FaSearch } from "react-icons/fa"; +import FetchSearchTitle from "./searchQuery"; +import Image from "next/image"; +import Link from "next/link"; + +export default function DramaSearch() { + const [title, setTitle] = useState(""); + const [infoTitle, setInfoTitle] = useState(null); + + async function getSearchResults(title) { + const data = await FetchSearchTitle(title); + setInfoTitle(data); + } + + return ( + <div className={styles.SearchContainer}> + <div className={styles.Search}> + <FaSearch color="white" size={16} /> + <input + placeholder="Search for drama" + onChange={(event) => setTitle(event.target.value)} + onKeyDown={async (e) => { + if ((e.key === "Enter" || e.code === 13) && title) { + await getSearchResults(e.target.value); + } + }} + ></input> + </div> + + <div className={styles.SearchResults}> + {infoTitle && + infoTitle.results.map((item, index) => ( + <Link + href={`/kdrama/${encodeURIComponent(item.id)}`} + style={{ textDecoration: "none" }} + key={index} + > + <div className={styles.SearchEntry}> + <p>{item.title}</p> + <Image + src={item.image} + width={110} + height={180} + alt="Drama Poster" + /> + </div> + </Link> + ))} + </div> + </div> + ); +} diff --git a/src/app/kdrama/components/searchQuery.js b/src/app/kdrama/components/searchQuery.js new file mode 100644 index 0000000..64e428b --- /dev/null +++ b/src/app/kdrama/components/searchQuery.js @@ -0,0 +1,8 @@ +export default async function FetchSearchTitle(title) { + const res = await fetch( + `https://consumet-api-di2e.onrender.com/movies/dramacool/${title}`, + { cache: "force-cache" } + ); + const data = await res.json(); + return data; +} diff --git a/src/app/kdrama/components/videoLink.js b/src/app/kdrama/components/videoLink.js new file mode 100644 index 0000000..fec016d --- /dev/null +++ b/src/app/kdrama/components/videoLink.js @@ -0,0 +1,11 @@ +"use server"; +export default async function getVideoLink(epiId, mediaId) { + let videoLink; + const res = await fetch( + `https://consumet-api-di2e.onrender.com/movies/dramacool/watch?episodeId=${epiId}&mediaId=${mediaId}`, + { cache: "force-cache" } + ); + const data = await res.json(); + videoLink = data.sources[0].url; + return videoLink; +} diff --git a/src/app/kdrama/kdrama.css b/src/app/kdrama/kdrama.css deleted file mode 100644 index 0e96be7..0000000 --- a/src/app/kdrama/kdrama.css +++ /dev/null @@ -1,232 +0,0 @@ -.sC { - display: flex; - align-items: center; - margin: 30px auto; - background-color: #2c2c2c; - padding: 8px; - border-radius: 5px; - width: 20%; -} - -.sC input { - border: none; - border-radius: 5px; - color: white; - outline: none; - background: none; - width: 100%; - font-family: "Lato"; - font-size: 16px; -} - - -.searchIcon { - color: white; - margin-right: 5px; -} - - -.intro { - display: flex; - color: white; - justify-content: center; - align-items: center; - height: 60vh; - width: 100%; - margin: 0px auto; - flex-direction: column; -} - -.introText { - font-size: 22px; - font-family: "Quicksand"; - color: var(--softer-purple) -} - -.introText2 { - font-family: "Quicksand"; - color: white; -} - -.popup { - z-index: 1; - display: none; - position: fixed; - top: 0; - align-items: center; - height: 100%; - justify-content: center; - width: 100%; - background-color: #141414ad; -} - - -.popupEntries { - border-radius: 5px; - display: flex; - flex-direction: column; - height: 60%; - overflow-y: auto; -} - -.popupEntries::-webkit-scrollbar { - width: 5px; - height: 5px; -} - -.popupEntry { - background: #272727b4; - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - border-radius: 10px; - width: 800px; - margin: 5px auto; - padding: 3px; - border-color: var(--soft-purple); - cursor: pointer; -} - - - -.popupEntry img { - width: auto; - height: auto; - padding: 5px; - border-radius: 10px; - -} - -.popupEntry p { - color: #8CABFF; - font-size: 20px; - margin-left: 10px; -} - -.closeButton { - position: absolute; - bottom: 0; - left: 0; - margin: 10px; -} - -.closeButton button { - padding: 12px; - background-color: var(--pastel-red); - font-family: "Quicksand"; - font-size: 18px; - border-radius: 5px; - border: none; - cursor: pointer; -} - -.videoContainer { - display: none; - max-width: 60%; - margin: 10px auto; - justify-content: center; - border-style: dotted; - border-color: rgba(97, 97, 97, 0.575); - border-radius: 20px; - border-width: 4px; - padding: 10px; -} - -.titleContainer2 { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - margin: 0px auto; - width: 100%; -} - -.dramaTitle { - color: var(--neon-green); - font-family: "Kanit"; - font-size: 30px; -} - -.dramaImage { - width: auto; - height: auto; - border-radius: 10px; -} - -.dramaDescription { - color: var(--softer-purple); - font-family: "Atkinson Hyperlegible"; - text-align: center; - max-width: 95%; -} - -.episodesButtonsContainer { - max-width: 80%; - margin: 0px auto; - max-height: 200px; - overflow-y: auto; - text-align: center; -} - -.episodeButton { - background-color: var(--light-green); - border: none; - border-radius: 5px; - padding: 8px; - margin: 5px; - width: 50px; - font-family: "Atkinson Hyperlegible"; - font-size: 16px; - cursor: pointer; -} - -.episodeButton:hover { - background-color: var(--soft-purple); -} - -.episodeButton:focus { - background-color: var(--pastel-red); - transition: padding 0.2s ease; - padding: 5px; -} - -.videoPlayer { - display: flex; - justify-content: center; -} - -.videoPlayer video { - border-radius: 10px; -} - -@media screen and (max-width: 1440px) { - .videoContainer { - max-width: 70%; - } - -} - -@media screen and (max-width: 1024px) { - .videoContainer { - max-width: 95%; - } -} - -@media screen and (max-width: 768px) { - .videoContainer { - max-width: 95%; - } - - .titleContainer { - width: 100%; - } - - .popupEntry { - width: 90%; - } - - .sC { - width: 70%; - } -}
\ No newline at end of file diff --git a/src/app/kdrama/page.jsx b/src/app/kdrama/page.jsx index 4426a2b..44f8eb9 100644 --- a/src/app/kdrama/page.jsx +++ b/src/app/kdrama/page.jsx @@ -1,163 +1,14 @@ -"use client"; - -import "./kdrama.css"; - -import { useState } from "react"; -import ReactPlayer from "react-player"; -import Image from "next/image"; -import { FaSearch } from "react-icons/fa"; // Import the search icon from react-icons library - -import { - fetchAnimeInfo, - fetchDramaInfo, - fetchVideoLinks, -} from "./api/fetchAnime.js"; - -export default function Kdrama() { - const [searchTitle, setSearchTitle] = useState(""); - const [searchedDrama, setSearchedDrama] = useState(null); - async function handleKeyPresses(event) { - if ( - (event.code === "Enter" || - event.code === 13 || - event.key === "Enter") && - searchTitle != "" - ) { - const info = await fetchAnimeInfo(searchTitle); - setSearchedDrama(info); - document.getElementById("popup").style.display = "flex"; - } - } - - const [details, setDetails] = useState(null); - async function handleDramaSearch(input) { - setVideoLink(null); - setEpisodeNo(""); - const drama_info = await fetchDramaInfo(input); - setDetails(drama_info); - document.getElementById("intro").style.display = "none"; - document.getElementById("videoContainer").style.display = "flex"; - } - - const [videoLink, setVideoLink] = useState(null); - const [episodeNo, setEpisodeNo] = useState(""); - async function get_video_link(ep_id, drama_id, episode) { - const link = await fetchVideoLinks(drama_id, ep_id); - const video_link = link.sources[0].url; - setVideoLink(video_link); - setEpisodeNo(episode); - } +import styles from "./styles/kdrama.module.css"; +import PopularDramas from "./components/popular"; +import RecentDramas from "./components/recent"; +import DramaSearch from "./components/search"; +export default async function Kdrama() { return ( - <main className="main"> - <div className="sC"> - <FaSearch className="searchIcon" /> - <input - placeholder="Enter drama title" - onChange={(event) => setSearchTitle(event.target.value)} - onKeyDown={(event) => handleKeyPresses(event)} - /> - </div> - - <div className="intro" id="intro"> - <p className="introText">Start by searching for some dramas</p> - <p className="introText2">Look for the search box above.</p> - </div> - - <div className="videoContainer" id="videoContainer"> - <div className="dramaInfoContainer"> - {videoLink && ( - <div className="videoPlayer"> - <ReactPlayer - url={videoLink} - controls - playsinline - width={"100%"} - height={"auto"} - id="thing" - /> - </div> - )} - {episodeNo && ( - <p - style={{ - color: "white", - fontFamily: "Atkinson Hyperlegible", - color: "#FF6868", - textAlign: "center", - }} - > - Episode {episodeNo} - </p> - )} - - {details && ( - <div className="dramaInfo2"> - <div className="titleContainer2"> - <p className="dramaTitle">{details.title}</p> - <Image - className="dramaImage" - src={details.image} - width={"120"} - height={"240"} - alt="Drama" - /> - </div> - <div className="dramaDescription"> - <p>{details.description}</p> - </div> - <div className="episodesButtonsContainer"> - {details.episodes.map((eps, index) => ( - <button - key={index} - className="episodeButton" - onClick={() => - get_video_link( - eps.id, - details.id, - eps.episode - ) - } - > - {eps.episode} - </button> - ))} - </div> - </div> - )} - </div> - </div> - - <div className="popup" id="popup"> - <div className="popupEntries"> - {searchedDrama && - searchedDrama.results.map((item, index) => ( - <div - className="popupEntry" - key={index} - onClick={() => handleDramaSearch(item.id)} - > - <p>{item.title}</p> - <Image - src={item.image} - alt={item.title} - width={"120"} - height={"190"} - /> - </div> - ))} - </div> - - <div - className="closeButton" - onClick={() => - (document.getElementById("popup").style.display = - "none") - } - > - <button>Close</button> - </div> - </div> - </main> + <div className={styles.Main}> + <DramaSearch /> + <PopularDramas /> + <RecentDramas /> + </div> ); } diff --git a/src/app/kdrama/styles/info.module.css b/src/app/kdrama/styles/info.module.css new file mode 100644 index 0000000..90a33b5 --- /dev/null +++ b/src/app/kdrama/styles/info.module.css @@ -0,0 +1,113 @@ +.Main { + max-width: 95%; + margin: 0px auto; +} + +.TitleContainer { + display: flex; + align-items: center; + justify-content: space-between; +} + +.TitleContainer p { + color: white; + font-family: "Poppins"; + font-size: 32px; +} + +.TitleContainer img { + height: auto; + width: auto; + border-radius: 10px; +} + +.DramaDescription h2 { + color: gray; + font-family: "Poppins"; +} + +.DramaDescription p { + font-family: "Atkinson Hyperlegible"; + color: white; + margin-top: -10px; +} + +.DramaGenre { + display: flex; + align-items: center; + overflow-x: auto; +} + +.genreMain { + font-family: "Poppins"; + color: var(--neon-green); + font-size: 18px; +} + +.genreEntry { + background-color: #31313141; + color: white; + padding: 5px; + margin: 3px; + border-radius: 5px; + font-family: "Atkinson Hyperlegible"; + cursor: crosshair; +} + +.EpisodesContainer { + margin-top: -10px; +} + +.EpisodesContainer h2 { + color: gray; + font-family: "Poppins"; +} + +.EpisodeButtons { + margin: -10px 5px; +} + +.EpisodeButtons button { + margin: 3px; + padding: 5px; + border: none; + outline: none; + font-family: "Atkinson Hyperlegible"; + font-size: 16px; + border-radius: 5px; + background-color: #3d3d3d; + transition: background-color 0.2s linear; + color: white; + cursor: pointer; + width: 100px; +} + +.EpisodeButtons button:hover { + background-color: #1f1f1f; + transition: background-color 0.2s linear +} + +.VideoContainer { + margin-top: 20px; + display: flex; + align-items: center; + flex-direction: column; +} + +.VideoContainer p { + color: white; + font-family: "Atkinson Hyperlegible"; + color: var(--neon-green); +} + +.VideoPlayer { + width: 70%; + height: auto; + margin: 0px auto; +} + +@media screen and (max-width: 768px) { + .VideoPlayer { + width: 100%; + } +}
\ No newline at end of file diff --git a/src/app/kdrama/styles/kdrama.module.css b/src/app/kdrama/styles/kdrama.module.css new file mode 100644 index 0000000..3e84530 --- /dev/null +++ b/src/app/kdrama/styles/kdrama.module.css @@ -0,0 +1,4 @@ +.Main { + max-width: 95%; + margin: 0px auto; +}
\ No newline at end of file diff --git a/src/app/kdrama/styles/popular.module.css b/src/app/kdrama/styles/popular.module.css new file mode 100644 index 0000000..eafe792 --- /dev/null +++ b/src/app/kdrama/styles/popular.module.css @@ -0,0 +1,52 @@ +.popDramasText { + color: var(--soft-purple); + font-family: "Poppins"; + font-size: 28px; + margin-bottom: 10px; +} + +.AnimeContainer { + display: flex; + overflow-x: auto; +} + +.AnimeContainer::-webkit-scrollbar { + height: 5px; +} + +.AnimeContainer::-webkit-scrollbar-track { + background-color: #3333339d; + border-radius: 5px; +} + +.AnimeContainer::-webkit-scrollbar-thumb { + background-color: rgb(68, 68, 68); + border-radius: 5px; +} + +/* Format the scrollbar later */ + +.AnimeEntry { + display: flex; + flex-direction: column; + align-items: center; + margin: 7px; + transition: transform 0.2s linear; + cursor: grab; +} + +.AnimeEntry:hover { + transition: transform 0.2s linear; + transform: scale(0.97); +} + +.AnimeEntry img { + border-radius: 5px; +} + + +.AnimeEntry p { + text-align: center; + color: white; + font-family: "Atkinson Hyperlegible"; +}
\ No newline at end of file diff --git a/src/app/kdrama/styles/search.module.css b/src/app/kdrama/styles/search.module.css new file mode 100644 index 0000000..5f61c23 --- /dev/null +++ b/src/app/kdrama/styles/search.module.css @@ -0,0 +1,77 @@ +.SearchContainer { + margin: 20px 0px -20px 0px; +} + +.Search { + padding: 5px; + background-color: #121212; + display: flex; + align-items: center; + max-width: 30%; + border-radius: 10px; +} + +.SearchContainer input { + margin-left: 5px; + padding: 5px; + border: none; + outline: none; + background-color: #121212; + font-size: 16px; + font-family: "Atkinson Hyperlegible"; + color: white; + width: 100%; +} + +.SearchResults { + display: flex; + margin-top: 10px; + overflow-x: auto; +} + +.SearchResults::-webkit-scrollbar { + height: 5px; +} + +.SearchResults::-webkit-scrollbar-track { + background-color: #3333339d; + border-radius: 5px; +} + +.SearchResults::-webkit-scrollbar-thumb { + background-color: rgb(68, 68, 68); + border-radius: 5px; +} + +.SearchEntry { + display: flex; + align-items: center; + justify-content: space-between; + margin: 5px; + padding: 6px; + background-color: #2e2e2eab; + border-radius: 10px; + cursor: pointer; + transition: transform 0.2s linear; +} + +.SearchEntry:hover { + transition: transform 0.2s linear; + transform: scale(1.01); +} + +.SearchEntry p { + color: white; + font-family: "Atkinson Hyperlegible"; + width: 40vh; +} + +.SearchEntry img { + border-radius: 10px; +} + +@media screen and (max-width: 768px) { + .Search { + max-width: 100%; + } +}
\ No newline at end of file diff --git a/src/app/manga/[title]/[id]/page.jsx b/src/app/manga/[title]/[id]/page.jsx index 5b54e23..1e4a26f 100644 --- a/src/app/manga/[title]/[id]/page.jsx +++ b/src/app/manga/[title]/[id]/page.jsx @@ -119,7 +119,8 @@ export default async function MangaInfo({ params }) { async function getMangaInfo(id) { const res = await fetch( - `https://consumet-api-di2e.onrender.com/meta/anilist-manga/info/${id}?provider=mangadex` + `https://consumet-api-di2e.onrender.com/meta/anilist-manga/info/${id}?provider=mangadex`, + { next: { revalidate: 86400 } } ); const data = await res.json(); return data; diff --git a/src/app/manga/manga.module.css b/src/app/manga/manga.module.css index a1bf84f..6091f6d 100644 --- a/src/app/manga/manga.module.css +++ b/src/app/manga/manga.module.css @@ -1,7 +1,5 @@ -@import url('https://fonts.googleapis.com/css2?family=Glass+Antiqua&family=Inter&display=swap'); - .Main { - max-width: 90%; + max-width: 95%; margin: 10px auto; } @@ -14,18 +12,12 @@ .ImageContainer { display: flex; flex-direction: column; + max-width: auto; } .ImageContainer img { margin: 0px 4px 4px 4px; border-radius: 8px; - animation: zoomer 1s alternate-reverse infinite ease; -} - -@keyframes zoomer { - to { - transform: scale(1.01); - } } .WelcomeContainer button { @@ -41,42 +33,26 @@ } .WelcomeText { - font-family: "Kanit"; + font-family: "Poppins"; color: white; - font-size: 50px; - text-shadow: #FC0 2px 2px 50px; + font-size: 48px; + text-shadow: rgb(0, 183, 255) 2px 2px 50px; margin-right: 10px; } - .SelfPromoContainer { display: flex; - justify-content: space-around; - font-family: "Lato"; + justify-content: center; + flex-direction: column; color: white; - /* margin-top: 20px; */ } .SelfPromoContainer p { - font-family: "Quicksand"; + font-family: "Atkinson Hyperlegible"; color: white; text-align: center; } - -@media screen and (max-width: 1024px) { - - .HorizontalImageContainer img { - width: auto; - height: auto; - } - - .VerticalImageContainer img { - width: 265px; - } -} - - .SearchBar { display: flex; align-items: center; @@ -110,20 +86,6 @@ @media screen and (max-width: 768px) { - .HorizontalImageContainer img { - width: 95%; - height: auto; - } - - .VerticalImageContainer img { - width: 46.5%; - height: 300px; - } -} - - -@media screen and (max-width: 425px) { - .Hero { flex-direction: column; } @@ -132,17 +94,19 @@ display: flex; align-items: center; flex-direction: column; + justify-content: center; margin-bottom: 10px; } .WelcomeText { - font-size: 32px; + font-size: 30px; } .HorizontalImageContainer img { - margin-top: 20px; width: 100%; + border-radius: 5px; height: auto; + margin: 10px auto; } .VerticalImageContainer img { @@ -151,5 +115,6 @@ .SearchBar { width: 80%; + margin: 0px auto; } }
\ No newline at end of file diff --git a/src/app/manga/page.jsx b/src/app/manga/page.jsx index 7f1f9cb..e6ad898 100644 --- a/src/app/manga/page.jsx +++ b/src/app/manga/page.jsx @@ -16,20 +16,20 @@ export default async function Manga() { <div className={styles.HorizontalImageContainer}> <Image src="/image.png" - width={480} + width={487} height={260} alt="Haikyu" /> </div> <div className={styles.VerticalImageContainer}> <Image - src="/haikyu1.jpg" + src="/image.webp" width={240} height={360} alt="Haikyu" /> <Image - src="/solo_levelling.png" + src="/solo_poster.png" width={240} height={360} alt="Haikyu" @@ -39,23 +39,22 @@ export default async function Manga() { </div> <div className={styles.SelfPromoContainer}> - <div className={styles.Welcome1}> - <p - style={{ - textAlign: "center", - fontSize: 32, - color: "var(--soft-purple)", - }} - > - Welcome to Dramalama Manga - </p> - <p> - Dive into a world where action jumps off the page and - pictures paint a thousand words. Dramalama Manga is a - site that will immerse you in stunning illustrations and - compel you to lose yourself in thrilling narratives. - </p> - </div> + <p + style={{ + textAlign: "center", + fontSize: 32, + color: "var(--soft-purple)", + fontFamily: "Poppins", + }} + > + Welcome to Dramalama Manga + </p> + <p style={{ marginTop: -10 }}> + Dive into a world where action jumps off the page and + pictures paint a thousand words. Dramalama Manga is a site + that will immerse you in stunning illustrations and compel + you to lose yourself in thrilling narratives. + </p> </div> </div> ); |