aboutsummaryrefslogtreecommitdiff
path: root/src/app/kdrama
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/kdrama')
-rw-r--r--src/app/kdrama/[id]/buttons.jsx86
-rw-r--r--src/app/kdrama/[id]/page.jsx92
-rw-r--r--src/app/kdrama/components/cacher.js17
-rw-r--r--src/app/kdrama/components/episodesContainer.jsx83
-rw-r--r--src/app/kdrama/components/infoTabs.jsx51
-rw-r--r--src/app/kdrama/components/popular.jsx47
-rw-r--r--src/app/kdrama/components/recent.jsx46
-rw-r--r--src/app/kdrama/components/requests.js44
-rw-r--r--src/app/kdrama/components/search.jsx65
-rw-r--r--src/app/kdrama/components/searchBar.jsx57
-rw-r--r--src/app/kdrama/components/searchFormatter.jsx46
-rw-r--r--src/app/kdrama/components/searchQuery.js10
-rw-r--r--src/app/kdrama/components/videoLink.js11
-rw-r--r--src/app/kdrama/loading.jsx9
-rw-r--r--src/app/kdrama/page.jsx104
-rw-r--r--src/app/kdrama/styles/info.module.css173
-rw-r--r--src/app/kdrama/styles/kdrama.module.css4
-rw-r--r--src/app/kdrama/styles/loading.module.css21
-rw-r--r--src/app/kdrama/styles/popular.module.css73
-rw-r--r--src/app/kdrama/styles/search.module.css84
20 files changed, 410 insertions, 713 deletions
diff --git a/src/app/kdrama/[id]/buttons.jsx b/src/app/kdrama/[id]/buttons.jsx
deleted file mode 100644
index 66292e7..0000000
--- a/src/app/kdrama/[id]/buttons.jsx
+++ /dev/null
@@ -1,86 +0,0 @@
-"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/default/theme.css";
-import "@vidstack/react/player/styles/default/layouts/video.css";
-import {
- defaultLayoutIcons,
- DefaultVideoLayout,
-} from "@vidstack/react/player/layouts/default";
-
-export default function EpisodesButtons({ data: episodeData, id: dramaId }) {
- const [videoLink, setVideoLink] = useState(null);
-
- async function test(a, b) {
- let link = await getVideoLink(a, b);
- setVideoLink(link);
- }
-
- return (
- <div>
- <div className={styles.EpisodesContainer}>
- <h2>Episodes</h2>
- <div className={styles.EpisodeButtons}>
- {episodeData && episodeData.length > 0 ? (
- episodeData.map((item, index) => (
- <button
- title={item.title}
- key={index}
- onClick={(event) => {
- test(item.id, dramaId, item.title);
- event.currentTarget.style.backgroundColor =
- "var(--soft-purple)";
- }}
- >
- <p>{item.title}</p>
- </button>
- ))
- ) : (
- <p style={{ color: "white" }}>
- No episodes are available at the moment but they
- will be made available soon. Thank you for your
- patience.
- </p>
- )}
- </div>
- </div>
-
- {videoLink && (
- <div
- className={styles.videoPopUp}
- id="popup"
- onKeyDown={(event) => {
- if (event.code === "Escape") {
- setVideoLink("");
- }
- }}
- >
- <div className={styles.video}>
- <MediaPlayer
- title="dramaPlayer"
- src={videoLink}
- load="eager"
- className={styles.VideoPlayer}
- playsInline
- id="videoPlayer"
- volume={0.8}
- >
- <MediaProvider />
- <DefaultVideoLayout icons={defaultLayoutIcons} />
- </MediaPlayer>
- <button
- className={styles.closeButton}
- onClick={() => {
- setVideoLink("");
- }}
- >
- Close
- </button>
- </div>
- </div>
- )}
- </div>
- );
-}
diff --git a/src/app/kdrama/[id]/page.jsx b/src/app/kdrama/[id]/page.jsx
index 9cb3cd8..d94810e 100644
--- a/src/app/kdrama/[id]/page.jsx
+++ b/src/app/kdrama/[id]/page.jsx
@@ -1,66 +1,46 @@
-import styles from "../styles/info.module.css";
-import Image from "next/image";
-import EpisodesButtons from "./buttons";
-import { PreFetchVideoLinks } from "../components/cacher";
+import { Chip, Image } from "@nextui-org/react";
+import DescriptionTabs from "../components/infoTabs";
+import { dramaInfo } from "../components/requests";
+import EpisodesContainer from "../components/episodesContainer";
export default async function DramaInfo({ params }) {
const id = decodeURIComponent(params.id);
- const info = await getDramaInfo(id);
-
- PreFetchVideoLinks(info.episodes, id);
+ const data = await dramaInfo(id);
return (
- <div className={styles.Main}>
- {info && (
- <div className={styles.DramaInfoContainer}>
- <div className={styles.TitleContainer}>
- <p>{info.title}</p>
- <Image
- src={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=${info.image}`}
- width={175}
- height={256}
- 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) => (
- <p key={index}>{item}</p>
- ))}
- </div>
-
- {/* Other names */}
- <div className={styles.DramaGenre}>
- <span className={styles.genreMain}>AKA: </span>
- {info.otherNames &&
- info.otherNames.map((item, index) => (
- <p key={index}>{item}</p>
+ <section className="pt-12 lg:w-9/12 m-auto">
+ <div className="flex items-center justify-center lg:justify-start md:justify-start">
+ <Image
+ isBlurred
+ width={190}
+ src={data.image.toString()}
+ alt="Anime Title Poster"
+ className="m-2"
+ />
+ <div className="mx-5">
+ <h4 className={`text-2xl`}>
+ <strong>{data.title}</strong>
+ </h4>
+ <div className="mt-1">
+ {data.genres &&
+ data.genres.map((item, index) => (
+ <Chip
+ key={index}
+ color="warning"
+ variant="faded"
+ className="mr-1 mb-1"
+ >
+ <p className="text-xs">{item}</p>
+ </Chip>
))}
</div>
-
- {/* Episodes Buttons */}
- <EpisodesButtons data={info.episodes} id={id} />
</div>
- )}
- </div>
- );
-}
-
-async function getDramaInfo(id) {
- const res = await fetch(
- `https://consumet-jade.vercel.app/movies/dramacool/info?id=${id}`,
- { next: { revalidate: 21600 } }
+ </div>
+ <DescriptionTabs data={data} />
+ <EpisodesContainer data={data} />
+ <br />
+ <br />
+ <br />
+ </section>
);
- const data = await res.json();
- return data;
}
diff --git a/src/app/kdrama/components/cacher.js b/src/app/kdrama/components/cacher.js
index 860cdca..fdfa272 100644
--- a/src/app/kdrama/components/cacher.js
+++ b/src/app/kdrama/components/cacher.js
@@ -1,21 +1,6 @@
-// This function pre-fetches all the video links for a drama in the background
"use server";
-export async function PreFetchVideoLinks(data, dramaId) {
- try {
- const fetchPromises = data.map(async (element) => {
- const link = `https://consumet-jade.vercel.app/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);
- }
-}
-
-export async function PreFetchAnimeInfo(data) {
+export async function PreFetchKdramaInfo(data) {
try {
const fetchPromises = data.results.map(async (element) => {
const link = `https://consumet-jade.vercel.app/movies/dramacool/info?id=${element.id}`;
diff --git a/src/app/kdrama/components/episodesContainer.jsx b/src/app/kdrama/components/episodesContainer.jsx
new file mode 100644
index 0000000..984ece5
--- /dev/null
+++ b/src/app/kdrama/components/episodesContainer.jsx
@@ -0,0 +1,83 @@
+"use client";
+
+import { MediaPlayer, MediaProvider } from "@vidstack/react";
+import "@vidstack/react/player/styles/default/theme.css";
+import "@vidstack/react/player/styles/default/layouts/video.css";
+import {
+ defaultLayoutIcons,
+ DefaultVideoLayout,
+} from "@vidstack/react/player/layouts/default";
+import { Select, SelectItem, Button, Skeleton } from "@nextui-org/react";
+import { useState, useEffect } from "react";
+
+import { lexend } from "../../../../config/fonts";
+import { videoLink } from "./requests";
+
+const EpisodesContainer = ({ data: data }) => {
+ const [videolink, setVideoLink] = useState("");
+ const [loading, setLoading] = useState(<></>);
+
+ async function handleSelectChange(episodeId) {
+ setVideoLink("");
+ setLoading(
+ <div className="w-full flex items-center gap-3">
+ <div className="w-full flex flex-col gap-2">
+ <Skeleton className="h-44 rounded-lg lg:h-96" />
+ </div>
+ </div>
+ );
+ const videoURL = await videoLink(episodeId, data.id);
+ setLoading(<></>);
+ setVideoLink(videoURL);
+ }
+
+ return (
+ <section>
+ <div className="flex w-full flex-wrap md:flex-nowrap gap-4 my-2">
+ <Select
+ label="Select Episode"
+ className={`${lexend.className} max-w-xs`}
+ >
+ {data.episodes && data.episodes.length > 0 ? (
+ data.episodes.map((item, index) => (
+ <SelectItem
+ key={index}
+ textValue={item.episode}
+ onClick={async () =>
+ await handleSelectChange(item.id)
+ }
+ className={lexend.className}
+ >
+ {item.episode}
+ </SelectItem>
+ ))
+ ) : (
+ <SelectItem disabled className={lexend.className}>
+ No episodes available right now
+ </SelectItem>
+ )}
+ </Select>
+ </div>
+
+ {loading}
+ {videolink && (
+ <div>
+ <MediaPlayer
+ title={data.title}
+ src={videolink}
+ aspectRatio="16/9"
+ load="eager"
+ playsInline
+ volume={0.8}
+ autoPlay
+ >
+ <MediaProvider />
+ <DefaultVideoLayout icons={defaultLayoutIcons} />
+ </MediaPlayer>
+ </div>
+ )}
+ </section>
+ );
+};
+
+export default EpisodesContainer;
diff --git a/src/app/kdrama/components/infoTabs.jsx b/src/app/kdrama/components/infoTabs.jsx
new file mode 100644
index 0000000..54c05ba
--- /dev/null
+++ b/src/app/kdrama/components/infoTabs.jsx
@@ -0,0 +1,51 @@
+"use client";
+
+import { Tabs, Tab, Card, CardBody } from "@nextui-org/react";
+
+import { lexend, atkinson } from "../../../../config/fonts";
+
+export default function DescriptionTabs({ data: data }) {
+ return (
+ <div className="flex w-full flex-col">
+ <Tabs aria-label="Options" className={lexend.className}>
+ <Tab key="description" title="Description">
+ <Card>
+ <CardBody className={atkinson.className}>
+ {data.description || "No description found"}
+ </CardBody>
+ </Card>
+ </Tab>
+ <Tab key="episodes" title="Details">
+ <Card>
+ <CardBody className={atkinson.className}>
+ <h4>
+ <strong>Episodes</strong>:{" "}
+ <span>{data.episodes.length}</span>
+ </h4>
+ <h4>
+ <strong>Duration</strong>:{" "}
+ <span>{data.duration || "not found"}</span>
+ </h4>
+ <h4>
+ <strong>Release Year</strong>:{" "}
+ <span>{data.releaseDate}</span>
+ </h4>
+ <h4>
+ <strong>Other Names</strong>:{" "}
+ {data.otherNames &&
+ data.otherNames.map((item, index) => (
+ <span key={index}>
+ {item}
+ {index <
+ data.otherNames.length - 1 &&
+ ", "}
+ </span>
+ ))}
+ </h4>
+ </CardBody>
+ </Card>
+ </Tab>
+ </Tabs>
+ </div>
+ );
+}
diff --git a/src/app/kdrama/components/popular.jsx b/src/app/kdrama/components/popular.jsx
deleted file mode 100644
index 21d8cc3..0000000
--- a/src/app/kdrama/components/popular.jsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import styles from "../styles/popular.module.css";
-import Image from "next/image";
-import Link from "next/link";
-import { PreFetchAnimeInfo } from "./cacher";
-
-export default async function PopularDramas() {
- const popular = await getPopular();
- PreFetchAnimeInfo(popular);
-
- return (
- <div className={styles.Main}>
- <h2 className={styles.popDramasText}>Trending Dramas</h2>
-
- <div className={styles.AnimeContainer}>
- {popular &&
- popular.results.slice(0, 24).map((item, index) => (
- <Link
- href={`/kdrama/${encodeURIComponent(item.id)}`}
- key={index}
- style={{ textDecoration: "none" }}
- >
- <div
- className={styles.AnimeEntry}
- title={item.title}
- >
- <Image
- src={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=${item.image}`}
- width={167}
- height={267}
- 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: 21600 },
- });
- const data = await res.json();
- return data;
-}
diff --git a/src/app/kdrama/components/recent.jsx b/src/app/kdrama/components/recent.jsx
deleted file mode 100644
index 2b883d6..0000000
--- a/src/app/kdrama/components/recent.jsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import styles from "../styles/popular.module.css";
-import Image from "next/image";
-import Link from "next/link";
-import { PreFetchAnimeInfo } from "./cacher";
-
-export default async function RecentDramas() {
- const popular = await getPopular();
- PreFetchAnimeInfo(popular);
- return (
- <div className={styles.Main}>
- <h2 className={styles.popDramasText}>Recent Releases</h2>
-
- <div className={styles.AnimeContainer}>
- {popular &&
- popular.results.slice(0, 24).map((item, index) => (
- <Link
- href={`/kdrama/${encodeURIComponent(item.id)}`}
- key={index}
- style={{ textDecoration: "none" }}
- >
- <div
- className={styles.AnimeEntry}
- title={item.title}
- >
- <Image
- src={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=${item.image}`}
- width={167}
- height={267}
- 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: 21600 },
- });
- const data = await res.json();
- return data;
-}
diff --git a/src/app/kdrama/components/requests.js b/src/app/kdrama/components/requests.js
new file mode 100644
index 0000000..5609d79
--- /dev/null
+++ b/src/app/kdrama/components/requests.js
@@ -0,0 +1,44 @@
+"use server";
+
+import {
+ popular_dramas_url,
+ recent_drama_url,
+ search_drama_url,
+ drama_info_url,
+ videoURL,
+} from "../../../../utils/kdrama_urls";
+
+export const DramaDataFetcher = async (type) => {
+ const options = {
+ popular: popular_dramas_url,
+ recent: recent_drama_url,
+ };
+ const res = await fetch(options[type], { next: { revalidate: 21600 } });
+ const data = await res.json();
+ return data;
+};
+
+export const SearchedDramaData = async (title) => {
+ const res = await fetch(search_drama_url(title), {
+ next: { revalidate: 21600 },
+ });
+ const data = await res.json();
+ return data;
+};
+
+export const dramaInfo = async (id) => {
+ const res = await fetch(drama_info_url(id), {
+ next: { revalidate: 21600 },
+ });
+ const data = await res.json();
+ return data;
+};
+
+export const videoLink = async (epiId, mediaId) => {
+ const res = await fetch(videoURL(epiId, mediaId), {
+ next: { revalidate: 21600 },
+ });
+ const data = await res.json();
+ const videoLink = data.sources[0].url;
+ return videoLink;
+};
diff --git a/src/app/kdrama/components/search.jsx b/src/app/kdrama/components/search.jsx
deleted file mode 100644
index f44e4bb..0000000
--- a/src/app/kdrama/components/search.jsx
+++ /dev/null
@@ -1,65 +0,0 @@
-"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";
-import { PreFetchAnimeInfo } from "./cacher";
-
-export default function DramaSearch() {
- const [title, setTitle] = useState("");
- const [infoTitle, setInfoTitle] = useState(null);
- const [loadingText, setLoadingText] = useState(null);
-
- const handleSearch = async (title) => {
- setLoadingText(true);
- const data = await FetchSearchTitle(title);
- PreFetchAnimeInfo(data);
- setLoadingText(false);
- 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 handleSearch(e.target.value);
- }
- }}
- ></input>
- </div>
-
- {loadingText && (
- <p className={styles.LoadingText}>Wait a moment...</p>
- )}
-
- <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={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=${item.image}`}
- width={140}
- height={210}
- alt="Drama Poster"
- />
- </div>
- </Link>
- ))}
- </div>
- </div>
- );
-}
diff --git a/src/app/kdrama/components/searchBar.jsx b/src/app/kdrama/components/searchBar.jsx
new file mode 100644
index 0000000..5f5d89e
--- /dev/null
+++ b/src/app/kdrama/components/searchBar.jsx
@@ -0,0 +1,57 @@
+"use client";
+
+import React from "react";
+import { useState } from "react";
+import { Input, Progress } from "@nextui-org/react";
+
+import { SearchedDramaData } from "./requests";
+import SearchedDataFormatter from "./searchFormatter";
+import { PreFetchKdramaInfo } from "./cacher";
+
+export const Searchbar = () => {
+ const [loading, setLoading] = useState(<></>);
+ const [searchData, setSearchData] = useState(null);
+ const [searchTitle, setSearchTitle] = useState("");
+
+ async function handleSearchInput() {
+ setSearchData(null);
+ setLoading(
+ <Progress
+ size="sm"
+ isIndeterminate
+ aria-label="Loading..."
+ className="w-full"
+ />
+ );
+ const data = await SearchedDramaData(searchTitle);
+ PreFetchKdramaInfo(data);
+ const format = await SearchedDataFormatter(data);
+ setSearchData(format);
+ setLoading(<></>);
+ }
+
+ return (
+ <div>
+ <div className="flex w-full flex-wrap flex-col mt-2 md:flex-nowrap md:mx-2 gap-4 lg:w-1/2 lg:mx-2">
+ <Input
+ type="text"
+ label="Search for k-dramas here"
+ placeholder="Enter k-drama title"
+ color="default"
+ onChange={(event) => {
+ if (event.target.value.trim() !== "") {
+ setSearchTitle(event.target.value);
+ }
+ }}
+ onKeyDown={async (event) => {
+ if (event.key === "Enter" || event.code === "Enter") {
+ await handleSearchInput();
+ }
+ }}
+ />
+ {loading}
+ </div>
+ <div className="w-full mt-2">{searchData}</div>
+ </div>
+ );
+};
diff --git a/src/app/kdrama/components/searchFormatter.jsx b/src/app/kdrama/components/searchFormatter.jsx
new file mode 100644
index 0000000..bac2549
--- /dev/null
+++ b/src/app/kdrama/components/searchFormatter.jsx
@@ -0,0 +1,46 @@
+import { Card, CardHeader, CardBody, Image, Link } from "@nextui-org/react";
+import NextImage from "next/image";
+
+import styles from "../../page.module.css";
+
+const SearchedDataFormatter = async (data) => {
+ return (
+ <section
+ className={`flex items-center overflow-auto pb-2 ${styles.ScrollBarAdjuster}`}
+ >
+ {data &&
+ data.results.length > 0 &&
+ data.results.map((item, index) => (
+ <Link
+ key={index}
+ href={`/kdrama/${encodeURIComponent(item.id)}`}
+ aria-label="anime redirection links"
+ className="flex flex-col items-center mx-1"
+ >
+ <Card className="overflow-hidden" isPressable>
+ <CardBody>
+ <Image
+ as={NextImage}
+ isBlurred
+ alt="Anime Poster"
+ src={item.image}
+ width={185}
+ height={120}
+ shadow="lg"
+ className="h-64"
+ priority
+ />
+ </CardBody>
+ <CardHeader>
+ <h4 className="antialiased text-small text-center uppercase w-44 overflow-hidden whitespace-nowrap text-ellipsis ">
+ {item.title}
+ </h4>
+ </CardHeader>
+ </Card>
+ </Link>
+ ))}
+ </section>
+ );
+};
+
+export default SearchedDataFormatter;
diff --git a/src/app/kdrama/components/searchQuery.js b/src/app/kdrama/components/searchQuery.js
deleted file mode 100644
index 18c06a9..0000000
--- a/src/app/kdrama/components/searchQuery.js
+++ /dev/null
@@ -1,10 +0,0 @@
-"use server";
-
-export default async function FetchSearchTitle(title) {
- const res = await fetch(
- `https://consumet-jade.vercel.app/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
deleted file mode 100644
index e49ca18..0000000
--- a/src/app/kdrama/components/videoLink.js
+++ /dev/null
@@ -1,11 +0,0 @@
-"use server";
-export default async function getVideoLink(epiId, mediaId) {
- let videoLink;
- const res = await fetch(
- `https://consumet-jade.vercel.app/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/loading.jsx b/src/app/kdrama/loading.jsx
deleted file mode 100644
index 4d5e9bd..0000000
--- a/src/app/kdrama/loading.jsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import styles from "./styles/loading.module.css";
-
-export default async function Loading() {
- return (
- <div className={styles.Main}>
- <div className={styles.LoadingContainer}></div>
- </div>
- );
-}
diff --git a/src/app/kdrama/page.jsx b/src/app/kdrama/page.jsx
index b9cdb69..d5e2855 100644
--- a/src/app/kdrama/page.jsx
+++ b/src/app/kdrama/page.jsx
@@ -1,15 +1,95 @@
-import styles from "./styles/kdrama.module.css";
-import PopularDramas from "./components/popular";
-import RecentDramas from "./components/recent";
-import DramaSearch from "./components/search";
+import { Card, CardHeader, CardBody, Image, Link } from "@nextui-org/react";
+import NextImage from "next/image";
+
+import { DramaDataFetcher } from "./components/requests";
+import styles from "../page.module.css";
+import { Searchbar } from "./components/searchBar";
+import { PreFetchKdramaInfo } from "./components/cacher";
+
+const KdramaHomepage = async () => {
+ const recent_data = await DramaDataFetcher("recent");
+ const popular_data = await DramaDataFetcher("popular");
+
+ const dataToBeLoaded = [recent_data, popular_data];
+
+ for (let item of dataToBeLoaded) {
+ PreFetchKdramaInfo(item);
+ }
+
+ const header = (title) => (
+ <>
+ <p className="antialiased font-bold text-sky-400 text-2xl my-1">
+ {title}
+ </p>
+ </>
+ );
+
+ const format = (data) => (
+ <>
+ {data &&
+ data.results.map((item, index) => (
+ <Link
+ key={index}
+ href={`/kdrama/${encodeURIComponent(item.id)}`}
+ aria-label="anime redirection links"
+ className="flex flex-col items-center mx-1"
+ >
+ <Card className="overflow-visible " isPressable>
+ <CardBody>
+ <Image
+ as={NextImage}
+ isBlurred
+ alt="Anime Poster"
+ src={item.image}
+ width={270}
+ height={160}
+ className="h-60 overflow-hidden"
+ shadow="lg"
+ priority
+ />
+ </CardBody>
+ <CardHeader>
+ <h4
+ className={`antialiased text-small text-center uppercase w-44 overflow-hidden whitespace-nowrap text-ellipsis `}
+ >
+ {item.title}
+ </h4>
+ </CardHeader>
+ </Card>
+ </Link>
+ ))}
+ </>
+ );
-export default async function Kdrama() {
return (
- <div className={styles.Main}>
- <DramaSearch />
- <PopularDramas />
- <hr style={{ marginTop: 15, borderColor: "gray" }} />
- <RecentDramas />
- </div>
+ <section className="pt-12">
+ <div>
+ <Searchbar />
+ </div>
+ <div className="mx-2">
+ {header("Popular K-dramas")}
+ <div
+ className={`flex overflow-auto overflow-y-hidden pb-3 ${styles.ScrollBarAdjuster}`}
+ >
+ {format(popular_data)}
+ </div>
+ </div>
+ <div className="mx-2">
+ {header("Recent Releases")}
+ <div
+ className={`flex overflow-auto overflow-y-hidden pb-3 ${styles.ScrollBarAdjuster}`}
+ >
+ {format(recent_data)}
+ </div>
+ </div>
+
+ <br />
+ <br />
+ <br />
+ <br />
+ <br />
+ </section>
);
-}
+};
+
+export default KdramaHomepage;
diff --git a/src/app/kdrama/styles/info.module.css b/src/app/kdrama/styles/info.module.css
deleted file mode 100644
index 3b60fd2..0000000
--- a/src/app/kdrama/styles/info.module.css
+++ /dev/null
@@ -1,173 +0,0 @@
-.Main {
- max-width: 98%;
- margin: 60px auto;
-}
-
-.TitleContainer {
- display: flex;
- align-items: center;
- justify-content: space-between;
-}
-
-.TitleContainer p {
- color: white;
- font-size: 34px;
- font-weight: 500;
- color: var(--neon-green);
- margin: 0;
-}
-
-.TitleContainer img {
- border-radius: 0.4rem;
-}
-
-.DramaDescription h2 {
- color: gray;
-}
-
-.DramaDescription p {
- color: white;
- margin-top: -10px;
- color: rgba(255, 255, 255, 0.637);
-}
-
-.DramaGenre {
- display: flex;
- align-items: center;
- overflow-x: auto;
- color: white;
- margin-top: 1rem;
-}
-.DramaGenre p {
- background-color: #1f1f1f;
- margin: 0rem 0rem 0rem 0.4rem;
- padding: 0.4rem;
- border-radius: 0.2rem;
-}
-
-.DramaGenre::-webkit-scrollbar {
- height: 2px;
-}
-
-.DramaGenre::-webkit-scrollbar-thumb {
- background-color: var(--light-green);
- border-radius: 1rem;
-}
-
-.genreMain {
- color: var(--neon-green);
- font-size: 18px;
-}
-
-.EpisodesContainer {
- margin-top: -10px;
-}
-
-.EpisodesContainer h2 {
- color: gray;
-}
-
-.EpisodeButtons {
- margin: -10px 5px;
-}
-
-.EpisodeButtons button {
- margin: 3px;
- padding: 5px;
- border: none;
- outline: none;
- border-radius: 5px;
- background-color: #3d3d3d;
- transition: background-color 0.2s linear;
- color: white;
- cursor: pointer;
- width: 100px;
-}
-
-.EpisodeButtons button p {
- text-align: center;
- font-family: "Lexend Deca", serif;
- margin: 0;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
-}
-
-.EpisodeButtons button:hover {
- background-color: #1f1f1f;
- transition: background-color 0.2s linear;
-}
-
-.videoPopUp {
- height: 100dvh;
- width: 100dvw;
- background-color: #141414ea;
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- z-index: 1;
- overflow-y: auto;
-}
-
-.closeButton {
- font-family: "Lexend Deca", serif;
- font-size: 16px;
- background-color: var(--pastel-red);
- padding: 0.5rem 1.5rem;
- border: 0;
- outline: 0;
- border-radius: 0.5rem;
- cursor: pointer;
- margin: 5px;
-}
-
-.video {
- width: 60vw;
-}
-
-.VideoPlayer {
- width: 100%;
- height: auto;
-}
-
-@media screen and (max-width: 768px) {
- .video {
- width: 100%;
- }
-
- .EpisodeButtons button {
- font-size: 14px;
- width: 80px;
- }
-
- .TitleContainer {
- flex-direction: column;
- }
-
- .TitleContainer img {
- width: auto;
- height: auto;
- border-radius: 0.2rem;
- background-color: #121212;
- padding: 0.2rem;
- }
-
- .TitleContainer p {
- font-size: 30px;
- font-weight: 400;
- margin: 0 0 0.25rem 0
- }
-
- .EpisodesContainer {
- text-align: center;
- }
-
- .EpisodeButtons button {
- width: 90px;
- }
-}
diff --git a/src/app/kdrama/styles/kdrama.module.css b/src/app/kdrama/styles/kdrama.module.css
deleted file mode 100644
index deb3860..0000000
--- a/src/app/kdrama/styles/kdrama.module.css
+++ /dev/null
@@ -1,4 +0,0 @@
-.Main {
- margin: 80px auto;
- width: 99%;
-}
diff --git a/src/app/kdrama/styles/loading.module.css b/src/app/kdrama/styles/loading.module.css
deleted file mode 100644
index 825c247..0000000
--- a/src/app/kdrama/styles/loading.module.css
+++ /dev/null
@@ -1,21 +0,0 @@
-.Main {
- height: 100dvh;
- display: flex;
- justify-content: center;
- align-items: center;
-}
-
-.LoadingContainer {
- width: 50px;
- height: 50px;
- border-radius: 50%;
- border: 8px solid;
- border-color: #f4f4f4 #0000;
- animation: s1 1s infinite;
-}
-
-@keyframes s1 {
- to {
- transform: rotate(0.5turn);
- }
-}
diff --git a/src/app/kdrama/styles/popular.module.css b/src/app/kdrama/styles/popular.module.css
deleted file mode 100644
index ec76fb3..0000000
--- a/src/app/kdrama/styles/popular.module.css
+++ /dev/null
@@ -1,73 +0,0 @@
-.popDramasText {
- color: white;
- margin: 0 0 0.2rem 0;
-}
-
-.AnimeContainer {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
- grid-gap: 0.7rem;
- align-items: center;
-}
-
-.AnimeContainer::-webkit-scrollbar {
- height: 0px;
-}
-
-.AnimeContainer:hover .AnimeEntry {
- opacity: 0.5;
-}
-
-.AnimeContainer:hover .AnimeEntry:hover {
- opacity: 1;
- transform: scale(1.018);
- background-color: #272727;
-}
-
-.AnimeEntry {
- display: flex;
- flex-direction: column;
- align-items: center;
- background-color: #1f1f1fbb;
- padding: 0.5rem;
- transition: opacity 200ms ease, transform 200ms ease,
- background-color 200ms ease;
- cursor: grab;
- border-radius: 0.4rem;
- overflow: hidden;
-}
-
-.AnimeEntry img {
- border-radius: 0.4rem;
- box-shadow: 0 0 10px 5px rgba(18, 18, 18, 0.863);
-}
-
-.AnimeEntry p {
- text-align: center;
- color: white;
- width: auto;
- max-width: 160px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- margin: 0.5rem 0rem 0rem 0rem;
-}
-
-@media screen and (max-width: 768px) {
- .popDramasText {
- text-align: start;
- font-size: 26px;
- margin: 1rem 0 1rem 0;
- }
-
- .AnimeContainer {
- display: flex;
- overflow-x: auto;
- overflow-y: hidden;
- margin-top: -8px;
- }
-
- .AnimeEntry img {
- width: auto;
- }
-}
diff --git a/src/app/kdrama/styles/search.module.css b/src/app/kdrama/styles/search.module.css
deleted file mode 100644
index d7d28b2..0000000
--- a/src/app/kdrama/styles/search.module.css
+++ /dev/null
@@ -1,84 +0,0 @@
-
-.LoadingText {
- color: white;
- text-align: center;
- font-size: 18px;
-}
-
-.Search {
- padding: 5px;
- background-color: #121212;
- display: flex;
- align-items: center;
- max-width: 30%;
- border-radius: 0.5rem;
-}
-
-.SearchContainer input {
- margin-left: 5px;
- padding: 5px;
- border: none;
- outline: none;
- background-color: #121212;
- font-size: 16px;
- color: white;
- width: 100%;
- font-family: "Lexend Deca";
-}
-
-.SearchResults {
- display: flex;
- margin: 10px 0 10px 0;
- 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: 0.5rem;
- cursor: pointer;
- transition: opacity 200ms linear, background-color 200ms linear;
-}
-
-.SearchResults .SearchEntry {
- opacity: 0.5;
-}
-
-.SearchResults .SearchEntry:hover {
- opacity: 1;
- background-color: #333333c9;
-}
-
-.SearchEntry p {
- color: white;
- font-size: 18px;
- width: 45vh;
-}
-
-.SearchEntry img {
- border-radius: 0.5rem;
-}
-
-@media screen and (max-width: 768px) {
- .Search {
- max-width: 100%;
- }
-}