aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorreal-zephex <[email protected]>2024-05-29 01:04:20 +0530
committerGitHub <[email protected]>2024-05-29 01:04:20 +0530
commite28fba92670b5c2775a512511346136991698cbc (patch)
tree5d40f1b802af30859b06e4c7f577fd50f3cc74cb
parentMerge pull request #39 from real-zephex/homepage-redesign (diff)
parent✨ feat(series): rewrite series page and drop manga support (diff)
downloaddramalama-e28fba92670b5c2775a512511346136991698cbc.tar.xz
dramalama-e28fba92670b5c2775a512511346136991698cbc.zip
Merge pull request #41 from real-zephex/series-overhaul
✨ feat(series): rewrite series page and drop manga support
-rw-r--r--src/app/components/header/header.jsx18
-rw-r--r--src/app/page.jsx41
-rw-r--r--src/app/page.module.css9
-rw-r--r--src/app/web-series/[id]/page.jsx144
-rw-r--r--src/app/web-series/components/HomePageModules.jsx56
-rw-r--r--src/app/web-series/components/descriptionTabs.jsx129
-rw-r--r--src/app/web-series/components/search.jsx57
-rw-r--r--src/app/web-series/components/searchBar.jsx49
-rw-r--r--src/app/web-series/components/searchResults.jsx35
-rw-r--r--src/app/web-series/components/seriesSearchFormatter.jsx49
-rw-r--r--src/app/web-series/components/videoPlayer.jsx100
-rw-r--r--src/app/web-series/page.jsx107
-rw-r--r--src/app/web-series/styles/info.module.css170
-rw-r--r--src/app/web-series/styles/pages.module.css49
-rw-r--r--src/app/web-series/styles/search.module.css80
-rw-r--r--src/app/web-series/styles/videoPlayer.module.css76
-rw-r--r--src/app/web-series/styles/web-series.module.css4
-rw-r--r--utils/movie_urls.js1
18 files changed, 445 insertions, 729 deletions
diff --git a/src/app/components/header/header.jsx b/src/app/components/header/header.jsx
index c420888..104911b 100644
--- a/src/app/components/header/header.jsx
+++ b/src/app/components/header/header.jsx
@@ -8,33 +8,23 @@ export default async function Header() {
<h4 className="text-teal-400 text-2xl p-2">
<Link href={"/"}>Dramalama</Link>
</h4>
- <div
+ {/* <div
className={`mx-2 flex items-center overflow-auto ${styles.ScrollBarAdjuster}`}
>
- <ThemeSwitcher />
-
<Link href={"/anime"} className="mx-2 hover:text-sky-400">
<p>Anime</p>
</Link>
<Link href={"/kdrama"} className="mx-2 hover:text-sky-400">
<p>Kdrama</p>
</Link>
- <Link
- href={"/components/workInProgress/"}
- className="mx-2 hover:text-sky-400"
- >
- <p>Manga</p>
- </Link>
- <Link
- href={"/components/workInProgress/"}
- className="mx-2 hover:text-sky-400"
- >
+ <Link href={"/series"} className="mx-2 hover:text-sky-400">
<p>Series</p>
</Link>
<Link href={"/movies"} className="mx-2 hover:text-sky-400">
<p>Movies</p>
</Link>
- </div>
+ </div> */}
+ <ThemeSwitcher />
</div>
);
}
diff --git a/src/app/page.jsx b/src/app/page.jsx
index b6fdd75..9565872 100644
--- a/src/app/page.jsx
+++ b/src/app/page.jsx
@@ -2,7 +2,7 @@ import { Card, CardHeader, CardBody, Divider, Link } from "@nextui-org/react";
import Image from "next/image";
export default async function Home() {
- const homePageCards = (title, message, url) => {
+ const homePageCards = (title) => {
return (
// <Link href={`/${title}`} className="my-1">
// <Card className="max-w-[400px] border-1 border-gray-500">
@@ -27,41 +27,22 @@ export default async function Home() {
// </CardBody>
// </Card>
// </Link>
- <Link
- href={`/${title}`}
- className="flex mb-2 lg:mx-2 text-center transition ease-in delay-50 hover:scale-105 text-inherit bg-gray-200 dark:bg-[#1f1f1f] p-1 rounded-lg"
- >
- <section>
- <Image
- src={url}
- height={100}
- width={100}
- alt="section image"
- className="rounded-full overflow-visible"
- ></Image>
- <p className="uppercase font-xl">{title}</p>
- </section>
+ <Link href={`/${title}`} className="mb-2 lg:mx-1">
+ <Card isPressable shadow="lg">
+ <CardBody>
+ <p className="text-xl lg:text-2xl">{title}</p>
+ </CardBody>
+ </Card>
</Link>
);
};
return (
<section className="h-screen w-screen flex flex-col items-center justify-center lg:flex-row ">
- {homePageCards(
- "anime",
- "Gravity of anime constant state of falling into the depths of happiness and joy",
- "https://cdn3.iconfinder.com/data/icons/letters-and-numbers-1/32/letter_A_red-256.png"
- )}
- {homePageCards(
- "kdrama",
- "Infinity loop I'll watch just one k-drama, ok one more, ok wait...",
- "https://cdn3.iconfinder.com/data/icons/letters-and-numbers-1/32/letter_K_red-512.png"
- )}
- {homePageCards(
- "movies",
- "Dive into a world of thrilling adventure and heart-pounding suspense",
- "https://cdn3.iconfinder.com/data/icons/letters-and-numbers-1/32/letter_M_red-512.png"
- )}
+ {homePageCards("anime")}
+ {homePageCards("movies")}
+ {homePageCards("kdrama")}
+ {homePageCards("web-series")}
</section>
);
}
diff --git a/src/app/page.module.css b/src/app/page.module.css
index 6620bc9..4c14adf 100644
--- a/src/app/page.module.css
+++ b/src/app/page.module.css
@@ -5,4 +5,13 @@
.ScrollBarAdjuster::-webkit-scrollbar-thumb {
background-color: rgb(95, 95, 95);
border-radius: 1rem;
+}
+
+.ScrollBarAdjuster2::-webkit-scrollbar {
+ height: 0.1rem;
+}
+
+.ScrollBarAdjuster2::-webkit-scrollbar-thumb {
+ background-color: rgb(95, 95, 95);
+ border-radius: 1rem;
} \ No newline at end of file
diff --git a/src/app/web-series/[id]/page.jsx b/src/app/web-series/[id]/page.jsx
index 3d36883..06902b1 100644
--- a/src/app/web-series/[id]/page.jsx
+++ b/src/app/web-series/[id]/page.jsx
@@ -1,111 +1,63 @@
-import Image from "next/image";
-import { SERIES_INFO, CREW_DETAILS } from "../components/data-fetch";
-import styles from "../styles/info.module.css";
-import { BiSolidUpvote } from "react-icons/bi";
-import { LiaStarSolid } from "react-icons/lia";
-import SeriesPlayer from "../components/videoPlayer";
+import { Image, Chip } from "@nextui-org/react";
+
+import { SERIES_INFO } from "../components/data-fetch";
+import Questions from "@/app/movies/components/faqs";
+import SeriesDescriptionTabs from "../components/descriptionTabs";
+import SeriesVideoPlayer from "../components/videoPlayer";
const SeriesInfoPage = async ({ params }) => {
- const id = params.id;
- const data = await FetchSeriesInfo(id);
- const crew_data = await CREW_DETAILS(id);
+ const { id } = params;
+
+ const data = await SERIES_INFO(id);
+
return (
- <main
+ <section
style={{
- // backgroundImage: `url(https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${data.backdrop_path})`,
- background: `linear-gradient(to bottom, rgba(0, 0, 0, 0) 70%, #121212 100%),
- url(https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${data.backdrop_path}) no-repeat center center fixed`,
- backgroundSize: "cover",
+ backgroundImage: `radial-gradient(gray 1px, transparent 1px)`,
+ backgroundSize: "40px 40px",
}}
- className={styles.Main}
+ className="h-screen bg-white dark:bg-black"
>
- <div className={styles.AnimeInfo}>
- <section className={styles.AnimeInfoContainer}>
- <div className={styles.TitleContainer}>
+ <section className="absolute inset-0 bg-gradient-to-b from-transparent to-white-400 dark:to-black">
+ <section className="pt-12 m-auto w-full lg:w-9/12">
+ <SeriesVideoPlayer id={data.id} />
+ <div className="flex items-center">
<Image
+ isBlurred
+ shadow="lg"
src={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${data.poster_path}`}
- width={190}
- height={290}
- alt="Series Poster"
- priority
- />
- <section className={styles.SideTitleContainer}>
- <h2 className={styles.title}>{data.name}</h2>
- <p className={styles.secondTitle}>
- {data.original_name}
- </p>
- <p className={styles.tagline}>
- <span>{data.tagline || "not found"}</span>
- </p>
- <p className={styles.description}>
- {" "}
- {data.overview}
- </p>
- <hr />
- <p className={styles.genres}>
- Genres:{" "}
- {data.genres.map((item, index) => (
- <span key={index}>
- {item.name}
- {index !== data.genres.length - 1 &&
- ", "}
- </span>
- ))}
- </p>
- <p className={styles.epiInfo}>
- Seasons: <span>{data.number_of_seasons}</span>
- </p>
- <p className={styles.epiInfo}>
- Episodes: <span>{data.number_of_episodes}</span>
- </p>
- <div className={styles.votes}>
- <section className={styles.vote}>
- <BiSolidUpvote color="var(--nord-green)" />{" "}
- <p>{data.vote_count}</p>
- </section>
- <section className={styles.vote}>
- <LiaStarSolid color="var(--nord-green)" />{" "}
- <p>{data.vote_average}</p>
- </section>
+ width={180}
+ height={300}
+ alt="Anime Title Poster"
+ className="m-2"
+ ></Image>
+ <div className="mx-5">
+ <h4 className={`text-2xl`}>
+ <strong>{data.name}</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.name}
+ </p>
+ </Chip>
+ ))}
</div>
- </section>
- </div>
- <section className={styles.CrewContainer}>
- <h2>Crew</h2>
- <div className={styles.CrewEntry}>
- {crew_data &&
- crew_data.cast.map((item, index) => (
- <div
- key={index}
- className={styles.CastEntry}
- >
- <Image
- src={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${item.profile_path}`}
- width={140}
- height={190}
- alt="Crew Poster"
- />
- <p>{item.name}</p>
- <p style={{ fontSize: 11 }}>
- {item.character}
- </p>
- </div>
- ))}
</div>
- </section>
-
- <section className={styles.VideoContainer}>
- <SeriesPlayer id={data.id} />
- </section>
+ </div>
+ <SeriesDescriptionTabs data={data} />
+ <Questions />
</section>
- </div>
- </main>
+ </section>
+ </section>
);
};
-const FetchSeriesInfo = async (id) => {
- const data = SERIES_INFO(id);
- return data;
-};
-
export default SeriesInfoPage;
diff --git a/src/app/web-series/components/HomePageModules.jsx b/src/app/web-series/components/HomePageModules.jsx
deleted file mode 100644
index 91d90bf..0000000
--- a/src/app/web-series/components/HomePageModules.jsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { POPULAR_SHOWS, TRENDING_SHOWS, TOP_SHOWS } from "./data-fetch";
-import styles from "../styles/pages.module.css";
-import Image from "next/image";
-import Link from "next/link";
-import PreFecthSeriesInfo from "./cacher";
-
-const HomepageUtils = async (type) => {
- const fetchFunctions = {
- popular: POPULAR_SHOWS,
- trending: TRENDING_SHOWS,
- top: TOP_SHOWS,
- };
-
- const fetchData = fetchFunctions[type];
-
- if (fetchData) {
- return await fetchData();
- } else {
- return;
- }
-};
-
-const Pages = async ({ type: type }) => {
- const data = await HomepageUtils(type);
- PreFecthSeriesInfo(data);
- return (
- <main className={styles.main}>
- <h2>{type} series</h2>
- <section className={styles.SeriesContainer}>
- {data &&
- data.results.length > 0 &&
- data.results.map((item, index) => (
- <Link
- key={index}
- href={`/web-series/${item.id}`}
- style={{ textDecoration: "none", color: "white" }}
- title={item.name}
- >
- <section className={styles.SeriesEntry}>
- <Image
- src={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${item.poster_path}`}
- width={180}
- height={300}
- alt="Series Poster"
- priority
- />
- <p>{item.name || "Not sure"}</p>
- </section>
- </Link>
- ))}
- </section>
- </main>
- );
-};
-
-export default Pages;
diff --git a/src/app/web-series/components/descriptionTabs.jsx b/src/app/web-series/components/descriptionTabs.jsx
new file mode 100644
index 0000000..ec6a78b
--- /dev/null
+++ b/src/app/web-series/components/descriptionTabs.jsx
@@ -0,0 +1,129 @@
+"use client";
+
+import {
+ Tabs,
+ Tab,
+ Card,
+ CardBody,
+ Link,
+ Image,
+ Chip,
+} from "@nextui-org/react";
+import { FiThumbsUp } from "react-icons/fi";
+import { TiStarFullOutline } from "react-icons/ti";
+
+import { lexend, atkinson } from "../../../../config/fonts";
+
+export default function SeriesDescriptionTabs({ 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.overview || "No description found"}
+ </CardBody>
+ </Card>
+ </Tab>
+ <Tab key="episodes" title="Details">
+ <Card>
+ <CardBody className={lexend.className}>
+ <h4>
+ <strong>Tagline</strong>:{" "}
+ <span>{data.tagline || "not sure"}</span>
+ </h4>
+ <h4>
+ <strong>Homepage</strong>:{" "}
+ <span>
+ <Link
+ color="warning"
+ isExternal
+ href={data.homepage || ""}
+ >
+ {data.homepage || "not sure"}
+ </Link>
+ </span>
+ </h4>
+ <h4>
+ <strong className="text-success">
+ Episodes:
+ </strong>{" "}
+ <span>
+ {data.number_of_episodes || "not sure"}
+ </span>
+ </h4>
+ <h4>
+ <strong className="text-secondary">
+ Seasons:
+ </strong>{" "}
+ <span>
+ {data.number_of_seasons || "not sure"}
+ </span>
+ </h4>
+ <h4>
+ <strong>Status</strong>:{" "}
+ <span>{data.status || "not sure"}</span>
+ </h4>
+ <h4>
+ <strong>Released on</strong>:{" "}
+ <span>{data.first_air_date || "not sure"}</span>
+ </h4>
+ <h4 className="flex items-center">
+ <strong>
+ <FiThumbsUp />
+ </strong>
+ <span className="ml-2">
+ {data.vote_count || "not sure"}
+ </span>
+ <strong className="ml-3">
+ <TiStarFullOutline />
+ </strong>
+ <span className="ml-2">
+ {data.vote_average || "not sure"}
+ </span>
+ </h4>
+ </CardBody>
+ </Card>
+ </Tab>
+ <Tab key="seasons" title="Seasons">
+ <Card>
+ <CardBody>
+ {data.seasons &&
+ data.seasons.map((item, index) => (
+ <Card
+ key={index}
+ className="flex flex-row items-center mb-1"
+ isPressable
+ shadow="lg"
+ >
+ <Image
+ src={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${item.poster_path}`}
+ width={100}
+ isBlurred
+ shadow="lg"
+ className="p-1"
+ ></Image>
+ <CardBody className="ml-1">
+ <p className="text-sky-400">
+ {item.name}
+ </p>
+ <Chip
+ color="warning"
+ size="sm"
+ variant="faded"
+ className="mt-1"
+ >
+ {item.air_date
+ ? item.air_date
+ : "TBD "}
+ </Chip>
+ </CardBody>
+ </Card>
+ ))}
+ </CardBody>
+ </Card>
+ </Tab>
+ </Tabs>
+ </div>
+ );
+}
diff --git a/src/app/web-series/components/search.jsx b/src/app/web-series/components/search.jsx
new file mode 100644
index 0000000..ecf392c
--- /dev/null
+++ b/src/app/web-series/components/search.jsx
@@ -0,0 +1,57 @@
+"use client";
+
+import { useState } from "react";
+import { Input, Progress } from "@nextui-org/react";
+
+import { SEARCH_TV } from "./data-fetch";
+import SeriesSearchFormatter from "./seriesSearchFormatter";
+import PreFecthSeriesInfo from "./cacher";
+// import { SearchMovie } from "./requestsHandler";
+// import MovieSearchFormatter from "./searchFormatter";
+
+const SeriesSearchBar = () => {
+ const [seriesTitle, setSeriesTitle] = useState("");
+ const [loading, setLoading] = useState(<></>);
+ const [seriesResults, setSeriesResults] = useState(<></>);
+
+ async function handleInputChange() {
+ setLoading(
+ <Progress
+ size="sm"
+ isIndeterminate
+ aria-label="Loading..."
+ className="w-full"
+ />
+ );
+ const data = await SEARCH_TV(seriesTitle);
+ PreFecthSeriesInfo(data);
+ setLoading(<></>);
+ setSeriesResults(await SeriesSearchFormatter(data));
+ }
+
+ return (
+ <section>
+ <div className="flex flex-col w-full md:flex-nowrap gap-2 lg:w-1/2">
+ <Input
+ type="text"
+ label="Search for series"
+ placeholder="Enter series title"
+ onChange={(event) => {
+ if (event.target.value.trim() !== "") {
+ setSeriesTitle(event.target.value);
+ }
+ }}
+ onKeyDown={async (event) => {
+ if (event.key === "Enter" || event.code === "Enter") {
+ await handleInputChange();
+ }
+ }}
+ />
+ {loading}
+ </div>
+ <div className="mt-2">{seriesResults}</div>
+ </section>
+ );
+};
+
+export default SeriesSearchBar;
diff --git a/src/app/web-series/components/searchBar.jsx b/src/app/web-series/components/searchBar.jsx
deleted file mode 100644
index 42531bc..0000000
--- a/src/app/web-series/components/searchBar.jsx
+++ /dev/null
@@ -1,49 +0,0 @@
-"use client";
-import styles from "../styles/search.module.css";
-import { FaSearch } from "react-icons/fa";
-import { useState } from "react";
-
-import { SEARCH_TV } from "./data-fetch";
-import SearchResults from "./searchResults";
-
-const SearchBar = () => {
- const [title, setTitle] = useState("");
- const [result, setResults] = useState(null);
- const [loading, setloading] = useState(false);
-
- const fetch_results = async (title) => {
- setloading(true);
- setResults(await SearchResults(await SEARCH_TV(title)));
- setloading(false);
- };
-
- return (
- <main className={styles.Main}>
- <section className={styles.InputContainer}>
- <FaSearch
- color="white"
- className={styles.SearchIcon}
- size={22}
- />
- <input
- placeholder="Enter series title here"
- onChange={(event) => setTitle(event.target.value)}
- onKeyDown={async (e) => {
- if ((e.key === "Enter" || e.code === 13) && title) {
- await fetch_results(e.target.value);
- }
- }}
- ></input>
- </section>
-
- {loading && (
- <p style={{ color: "white", textAlign: "center" }}>
- Please wait while we crunch up all the data
- </p>
- )}
- <section className={styles.SearchResults}>{result}</section>
- </main>
- );
-};
-
-export default SearchBar;
diff --git a/src/app/web-series/components/searchResults.jsx b/src/app/web-series/components/searchResults.jsx
deleted file mode 100644
index d1564e0..0000000
--- a/src/app/web-series/components/searchResults.jsx
+++ /dev/null
@@ -1,35 +0,0 @@
-"use server";
-
-import Link from "next/link";
-import Image from "next/image";
-import styles from "../styles/search.module.css";
-import PreFecthSeriesInfo from "./cacher";
-
-const SearchResults = async (data) => {
- PreFecthSeriesInfo(data);
- return (
- <div className={styles.SearchedSeriesContainer}>
- {data &&
- data.results.map((item, index) => (
- <Link
- key={index}
- style={{ color: "white", textDecoration: "none" }}
- href={`/web-series/${item.id}`}
- title={item.name}
- >
- <div className={styles.SearchedSeriesEntry}>
- <Image
- src={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${item.poster_path}`}
- width={160}
- height={247}
- alt="Searched Series Poster"
- />
- <p>{item.name}</p>
- </div>
- </Link>
- ))}
- </div>
- );
-};
-
-export default SearchResults;
diff --git a/src/app/web-series/components/seriesSearchFormatter.jsx b/src/app/web-series/components/seriesSearchFormatter.jsx
new file mode 100644
index 0000000..408e7c0
--- /dev/null
+++ b/src/app/web-series/components/seriesSearchFormatter.jsx
@@ -0,0 +1,49 @@
+import { Card, CardHeader, CardBody } from "@nextui-org/react";
+import Link from "next/link";
+import Image from "next/image";
+
+import styles from "../../page.module.css";
+
+const SeriesSearchFormatter = async (data) => {
+ return (
+ <section
+ className={`flex items-center overflow-auto pb-2 mb-2 ${styles.ScrollBarAdjuster}`}
+ >
+ {data &&
+ data.results.map((item, index) => {
+ if (item.poster_path) {
+ return (
+ <Link
+ key={index}
+ href={`/web-series/${item.id}`}
+ aria-label="anime redirection links"
+ className="flex flex-col items-center mx-1 "
+ >
+ <Card className="overflow-hidden" isPressable>
+ <CardBody>
+ <Image
+ alt="Searched Movie Poster"
+ src={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${item.poster_path}`}
+ width={190}
+ height={120}
+ className="rounded-md h-64"
+ priority
+ />
+ </CardBody>
+ <CardHeader>
+ <h4
+ className={`antialiased text-small text-center uppercase w-44 overflow-hidden whitespace-nowrap text-ellipsis `}
+ >
+ {item.name}
+ </h4>
+ </CardHeader>
+ </Card>
+ </Link>
+ );
+ }
+ })}
+ </section>
+ );
+};
+
+export default SeriesSearchFormatter;
diff --git a/src/app/web-series/components/videoPlayer.jsx b/src/app/web-series/components/videoPlayer.jsx
index cc8feb3..50a703d 100644
--- a/src/app/web-series/components/videoPlayer.jsx
+++ b/src/app/web-series/components/videoPlayer.jsx
@@ -1,66 +1,76 @@
"use client";
-import { useState } from "react";
-import styles from "../styles/videoPlayer.module.css";
+import { useEffect, useState } from "react";
-const SeriesPlayer = ({ id: id }) => {
- const [iframe, iframeContent] = useState(null);
- const [episode, setEpisode] = useState("");
- const [season, setSeason] = useState("");
+import { Input } from "@nextui-org/react";
- async function VideoPlayerInitialize() {
- if (!episode || !season) {
- alert("Please provide the required episode and season number.");
+const SeriesVideoPlayer = ({ id: id }) => {
+ const [seasonNumber, setSeasonNumber] = useState("");
+ const [episodeNumber, setEpisodeNumber] = useState("");
+ const [videoFrame, setVideoFrame] = useState(<></>);
+
+ useEffect(() => {
+ setVideoFrame(VideoFrameGenerator(1, 1));
+ }, []);
+
+ const VideoFrameGenerator = (sea, epi) => {
+ return (
+ <iframe
+ src={`https://vidsrc.pro/embed/tv/${id}/${sea}/${epi}`}
+ allowFullScreen
+ referrerPolicy="origin"
+ height={720}
+ className="w-full h-[240px] lg:h-[720px]"
+ ></iframe>
+ );
+ };
+
+ function renderVideoFrame() {
+ if (seasonNumber === "" || episodeNumber === "") {
+ alert(
+ "Make sure that you have entered the episode number and the season number."
+ );
return;
}
- iframeContent(await iframeGenerator(id, season, episode));
- document.getElementById("video-player").style.display = "none";
+
+ setVideoFrame(VideoFrameGenerator(seasonNumber, episodeNumber));
}
return (
- <main className={styles.Main}>
- <div className={styles.EpisodeSeasonInput}>
- <input
- name="Season"
+ <div>
+ {videoFrame}
+ <div className="flex w-full items-center md:flex-nowrap gap-2 mt-2">
+ <Input
type="number"
+ label="Season"
placeholder="Season Number"
- onChange={(e) => {
- if (Number(e.target.value) > 0) {
- setSeason(e.target.value);
+ isRequired
+ onChange={(event) => {
+ setSeasonNumber(event.target.value);
+ }}
+ onKeyDown={(event) => {
+ if (event.key === "Enter" || event.code === "Enter") {
+ renderVideoFrame();
}
}}
- ></input>
- <input
- name="Episode"
+ />
+ <Input
type="number"
+ label="Episode"
placeholder="Episode Number"
- onChange={(e) => {
- if (Number(e.target.value) > 0) {
- setEpisode(e.target.value);
+ isRequired
+ onChange={(event) => {
+ setEpisodeNumber(event.target.value);
+ }}
+ onKeyDown={(event) => {
+ if (event.key === "Enter" || event.code === "Enter") {
+ renderVideoFrame();
}
}}
- ></input>
-
- <button onClick={() => VideoPlayerInitialize(id)}>
- Search
- </button>
- </div>
-
- <div className={styles.VideoPlayer}>
- {iframe}
- <p id="video-player">
- Please use adblockers to prevent ads and redirects. We have
- no control over the amount of ads or the type of ads which
- you might encounter.
- </p>
+ />
</div>
- </main>
+ </div>
);
};
-const iframeGenerator = async (id, seasonNumber, episodeNumber) => {
- const url = `https://vidsrc.pro/embed/tv/${id}/${seasonNumber}/${episodeNumber}`;
- return <iframe src={url} allowFullScreen referrerPolicy="origin"></iframe>;
-};
-
-export default SeriesPlayer;
+export default SeriesVideoPlayer;
diff --git a/src/app/web-series/page.jsx b/src/app/web-series/page.jsx
index 63fcd05..1adac80 100644
--- a/src/app/web-series/page.jsx
+++ b/src/app/web-series/page.jsx
@@ -1,28 +1,85 @@
-import styles from "./styles/web-series.module.css";
-import Pages from "./components/HomePageModules";
-import SearchBar from "./components/searchBar";
+import { Card, CardHeader, CardBody } from "@nextui-org/react";
+import Image from "next/image";
+import Link from "next/link";
+
+import {
+ TOP_SHOWS,
+ TRENDING_SHOWS,
+ POPULAR_SHOWS,
+} from "./components/data-fetch";
+import PreFecthSeriesInfo from "./components/cacher";
+import SeriesSearchBar from "./components/search";
+import styles from "../page.module.css";
+
+const SeriesHomepage = async () => {
+ const top_data = await TOP_SHOWS();
+ const trending_data = await TRENDING_SHOWS();
+ const popular_data = await POPULAR_SHOWS();
+
+ const dataToBeLoaded = [top_data, trending_data, popular_data];
+
+ for (let item of dataToBeLoaded) {
+ PreFecthSeriesInfo(item);
+ }
+
+ const HomepageDataFormatter = (title, data) => {
+ return (
+ <section className="flex flex-col">
+ <p className="text-sky-400 text-2xl font-bold">{title}</p>
+
+ <div
+ className={`flex items-center overflow-auto pb-2 mt-1 ${styles.ScrollBarAdjuster}`}
+ >
+ {data &&
+ data.results.map((item, index) => (
+ <Link
+ key={index}
+ href={`/web-series/${item.id}`}
+ aria-label="anime redirection links"
+ className="flex flex-col items-center mx-1 "
+ >
+ <Card className="overflow-visible " isPressable>
+ <CardBody>
+ <Image
+ alt="Movie Poster"
+ src={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${item.poster_path}`}
+ width={270}
+ height={180}
+ className="h-64 rounded-md overflow-hidden"
+ priority
+ />
+ </CardBody>
+ <CardHeader>
+ <h4
+ className={`antialiased text-small text-center uppercase w-44 overflow-hidden whitespace-nowrap text-ellipsis `}
+ >
+ {item.name}
+ </h4>
+ </CardHeader>
+ </Card>
+ </Link>
+ ))}
+ </div>
+ </section>
+ );
+ };
-export default async function SeriesHomepage() {
return (
- <main className={styles.main}>
- <SearchBar />
- <Pages type={"popular"} />
- <hr
- style={{
- borderColor: "grey",
- marginTop: 15,
- marginBottom: -15,
- }}
- />
- <Pages type={"trending"} />
- <hr
- style={{
- borderColor: "grey",
- marginTop: 15,
- marginBottom: -15,
- }}
- />
- <Pages type={"top"} />
- </main>
+ <section className="pt-12">
+ <div className="lg:ml-1">
+ <SeriesSearchBar />
+ </div>
+ <div className="lg:ml-1">
+ {HomepageDataFormatter("Popular Series", popular_data)}
+ <div className="mt-2">
+ {HomepageDataFormatter("Trending Series", trending_data)}
+ </div>
+ <div className="mt-2">
+ {HomepageDataFormatter("Top Rated Series", top_data)}
+ </div>
+ </div>
+ </section>
);
-}
+};
+
+export default SeriesHomepage;
diff --git a/src/app/web-series/styles/info.module.css b/src/app/web-series/styles/info.module.css
deleted file mode 100644
index d60023d..0000000
--- a/src/app/web-series/styles/info.module.css
+++ /dev/null
@@ -1,170 +0,0 @@
-.Main {
- margin-top: 60px;
-
-}
-
-.Main::-webkit-scrollbar {
- width: 0;
-}
-
-.AnimeInfo {
- backdrop-filter: blur(10px);
- background-color: #1f1f1fcb;
-
-}
-
-.AnimeInfoContainer {
- width: 50%;
- height: 100vh;
- margin: 0px auto;
-}
-
-.TitleContainer {
- display: flex;
- align-items: center;
-}
-
-.TitleContainer img {
- border-radius: 0.8rem;
- padding: 0.5rem;
-}
-
-.SideTitleContainer {
- margin: 0.4rem;
- color: white;
-}
-
-.title {
- margin: 0;
-}
-
-.secondTitle {
- margin: 0;
- font-size: small;
-}
-
-.tagline {
- margin: 0;
-}
-
-.tagline span {
- background-color: #121212b7;
- padding: 0.2rem;
- border-radius: 0.5rem;
- font-size: 12px;
-}
-
-.description {
- margin: 0.2rem 0 0 0;
- height: auto;
- max-height: 100px;
- overflow: auto;
-}
-
-.description::-webkit-scrollbar {
- width: 3px;
-}
-
-.description::-webkit-scrollbar-thumb {
- background-color: var(--neon-yellow);
- border-radius: 1rem;
-}
-
-
-.genres {
- margin: 0;
- color: var(--nord-yellow);
-}
-
-.genres span {
- color: white;
-}
-
-.epiInfo {
- margin: 0;
- color: var(--nord-yellow);
-}
-
-.epiInfo span {
- color: white;
-}
-
-.votes {
- display: flex;
-}
-
-.votes p {
- margin: 0 0 0 0;
-}
-
-.vote {
- display: flex;
- align-items: center;
- margin: 0 0.2rem 0 0;
-}
-
-.CrewContainer {
- color: white;
- margin-top: -1rem;
-}
-
-.CrewEntry {
- display: flex;
- align-items: center;
- overflow: auto;
-}
-
-.CrewEntry h2 {
- margin: 0;
- color: white;
-}
-
-.CastEntry {
- display: flex;
- flex-direction: column;
- align-items: center;
- margin: 0 0 0 0.4rem;
-}
-
-.CastEntry img {
- border-radius: 0.5rem;
-}
-
-.CastEntry p {
- margin: 0;
- width: 140px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- text-align: center;
-}
-
-.CrewEntry::-webkit-scrollbar {
- height: 3px;
-}
-
-.CrewEntry::-webkit-scrollbar-thumb {
- background-color: var(--neon-yellow);
- border-radius: 1rem;
-}
-
-
-@media screen and (max-width: 1024px) {
- .AnimeInfoContainer {
- width: 100%;
- }
-
- .title {
- font-size: 20px;
- }
-
- .description {
- font-size: 14px;
- max-height: 100px;
- overflow: auto;
- }
-
- .SideTitleContainer {
- font-size: 14px;
- }
-} \ No newline at end of file
diff --git a/src/app/web-series/styles/pages.module.css b/src/app/web-series/styles/pages.module.css
deleted file mode 100644
index 8f15de2..0000000
--- a/src/app/web-series/styles/pages.module.css
+++ /dev/null
@@ -1,49 +0,0 @@
-.main h2 {
- color: white;
- /* margin: 0.4rem 0 0 0; */
- text-transform: uppercase;
- font-size: 30px;
-}
-
-.SeriesContainer {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
- grid-gap: 0.5rem;
- align-items: center;
- margin: -1rem 0 0 0;
-}
-
-.SeriesEntry {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- background-color: #1f1f1fce;
- border-radius: 0.5rem;
- padding: 0.4rem;
- color: white;
- cursor: pointer;
-}
-
-.SeriesEntry p {
- width: 170px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- text-align: center;
- margin: 0.3rem 0 0 0;
- font-family: "Lexend Deca", serif;
-}
-
-.SeriesEntry img {
- border-radius: 0.5rem;
-}
-
-@media screen and (max-width: 768px) {
- .SeriesContainer {
- display: flex;
- align-items: center;
- overflow-x: auto;
- overflow-y: hidden;
- }
-} \ No newline at end of file
diff --git a/src/app/web-series/styles/search.module.css b/src/app/web-series/styles/search.module.css
deleted file mode 100644
index fdf46e3..0000000
--- a/src/app/web-series/styles/search.module.css
+++ /dev/null
@@ -1,80 +0,0 @@
-.InputContainer {
- display: flex;
- align-items: center;
- background-color: #1f1f1f;
- width: 40vw;
- border-radius: 0.5rem;
- padding: 0.4rem;
-}
-
-.SearchIcon {
- margin-left: 0.4rem;
-}
-
-.InputContainer input {
- background-color: transparent;
- outline: none;
- border: none;
- padding: 0.4rem;
- font-family: "Lexend Deca", serif;
- font-size: 20px;
- margin-left: 0.2rem;
- font-size: large;
- color: white;
- width: 100%;
-}
-
-.SearchedSeriesContainer {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
- grid-gap: 0.7rem;
- align-items: center;
- margin-top: 0.8rem;
-}
-
-.SearchedSeriesEntry {
- display: flex;
- align-items: center;
- flex-direction: column;
- background-color: #1f1f1f;
- border-radius: 0.5rem;
- padding: 0.2rem;
- transition: opacity 200ms ease;
-
-}
-
-.SearchedSeriesContainer:hover .SearchedSeriesEntry {
- opacity: 0.5;
-}
-
-.SearchedSeriesContainer .SearchedSeriesEntry:hover {
- opacity: 1;
-}
-
-.SearchedSeriesEntry p {
- width: 150px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- text-align: center;
- margin: 0.2rem 0 0.2rem 0;
-}
-
-.SearchedSeriesEntry img {
- border-radius: 0.5rem;
- padding: 0.2rem 0.2rem 0 0.2rem;
-}
-
-@media screen and (max-width: 768px) {
-
- .InputContainer {
- width: 100%;
- }
-
- .SearchedSeriesContainer {
- display: flex;
- overflow: auto;
- }
-
-
-} \ No newline at end of file
diff --git a/src/app/web-series/styles/videoPlayer.module.css b/src/app/web-series/styles/videoPlayer.module.css
deleted file mode 100644
index f44776f..0000000
--- a/src/app/web-series/styles/videoPlayer.module.css
+++ /dev/null
@@ -1,76 +0,0 @@
-.Main {
- margin: 1.5rem 0 0 0;
-}
-
-.EpisodeSeasonInput {
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.EpisodeSeasonInput input {
- padding: 0.6rem;
- margin: 0 0.2rem 0 0.2rem;
- border: none;
- outline: none;
- background-color: #121212a6;
- border-radius: 0.5rem;
- font-family: "Lexend Deca", serif;
- color: white;
-}
-
-.EpisodeSeasonInput button {
- padding: 0.5rem;
- border: none;
- outline: none;
- border-radius: 0.5rem;
- background-color: #121212a6;
- color: white;
- cursor: pointer;
- font-family: "Atkinson Hyperlegible", serif;
-}
-
-
-.EpisodeSeasonInput input::placeholder {
- color: gray;
-}
-
-.VideoPlayer iframe {
- margin: 1rem 0 2.5rem 0;
- width: 100%;
- height: 400px;
- border-radius: 0.5rem;
- border: none;
- outline: none;
-}
-
-.VideoPlayer p {
- color: white;
- margin: 0.5rem 0 0 0;
- text-align: center;
- font-size: 12px;
-}
-
-@media screen and (max-width: 768px) {
-
- .EpisodeSeasonInput {
- width: 80%;
- margin: 0px auto;
- }
-
- .VideoPlayer iframe {
- width: 100%;
- height: 300px;
- margin-bottom: 50px;
- }
-
- .EpisodeSeasonInput input {
- padding: 0.4rem;
- }
-
- .EpisodeSeasonInput button {
- padding: 0.3rem 0.4rem 0.3rem 0.4rem;
- font-size: 14px;
- }
-
-} \ No newline at end of file
diff --git a/src/app/web-series/styles/web-series.module.css b/src/app/web-series/styles/web-series.module.css
deleted file mode 100644
index 849fed9..0000000
--- a/src/app/web-series/styles/web-series.module.css
+++ /dev/null
@@ -1,4 +0,0 @@
-.main {
- margin: 65px auto;
- width: 99%;
-} \ No newline at end of file
diff --git a/utils/movie_urls.js b/utils/movie_urls.js
index b99675a..e8707c4 100644
--- a/utils/movie_urls.js
+++ b/utils/movie_urls.js
@@ -18,3 +18,4 @@ export const TOP_RATED = `${PROXY}https://api.themoviedb.org/3/movie/top_rated?a
export const UPCOMING_MOVIES = `${PROXY}https://api.themoviedb.org/3/movie/upcoming?api_key=${API_KEY}`;
export const NOW_IN_THEATERS = `${PROXY}https://api.themoviedb.org/3/movie/now_playing?api_key=${API_KEY}`;
+