aboutsummaryrefslogtreecommitdiff
path: root/src/app
diff options
context:
space:
mode:
authorreal-zephex <[email protected]>2024-04-06 15:38:39 +0530
committerGitHub <[email protected]>2024-04-06 15:38:39 +0530
commit99e977342c2bc4aa3f6b930dfab80a7dc9f5eee3 (patch)
treee5ea8e64e27778ce468431138775bf9f6dc3874b /src/app
parentUI Upgrades for anime section. (diff)
parentadded search functionality (diff)
downloaddramalama-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/app')
-rw-r--r--src/app/anime/[id]/[...animeId]/page.jsx13
-rw-r--r--src/app/anime/[id]/[...animeId]/video.module.css7
-rw-r--r--src/app/anime/recent/recent.module.css5
-rw-r--r--src/app/anime/top-airing/trending.module.css5
-rw-r--r--src/app/components/header/header.jsx10
-rw-r--r--src/app/components/header/header.module.css3
-rw-r--r--src/app/globals.css3
-rw-r--r--src/app/globals.module.css2
-rw-r--r--src/app/kdrama/[id]/buttons.jsx59
-rw-r--r--src/app/kdrama/[id]/page.jsx70
-rw-r--r--src/app/kdrama/api/fetchAnime.js28
-rw-r--r--src/app/kdrama/components/cacher.js15
-rw-r--r--src/app/kdrama/components/popular.jsx42
-rw-r--r--src/app/kdrama/components/recent.jsx42
-rw-r--r--src/app/kdrama/components/search.jsx56
-rw-r--r--src/app/kdrama/components/searchQuery.js8
-rw-r--r--src/app/kdrama/components/videoLink.js11
-rw-r--r--src/app/kdrama/kdrama.css232
-rw-r--r--src/app/kdrama/page.jsx169
-rw-r--r--src/app/kdrama/styles/info.module.css113
-rw-r--r--src/app/kdrama/styles/kdrama.module.css4
-rw-r--r--src/app/kdrama/styles/popular.module.css52
-rw-r--r--src/app/kdrama/styles/search.module.css77
-rw-r--r--src/app/manga/[title]/[id]/page.jsx3
-rw-r--r--src/app/manga/manga.module.css61
-rw-r--r--src/app/manga/page.jsx39
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>
);