aboutsummaryrefslogtreecommitdiff
path: root/src/app/web-series/components
diff options
context:
space:
mode:
authorreal-zephex <[email protected]>2024-05-19 08:08:57 +0530
committerGitHub <[email protected]>2024-05-19 08:08:57 +0530
commita8e9ca0c14bcd6a8b2aa8cfe5b95a4e98dbcebfe (patch)
tree98fa3f6cbdd690648c7d31a79c7d381624f38530 /src/app/web-series/components
parentminor changes to the manga page (diff)
parentadded series support (diff)
downloaddramalama-a8e9ca0c14bcd6a8b2aa8cfe5b95a4e98dbcebfe.tar.xz
dramalama-a8e9ca0c14bcd6a8b2aa8cfe5b95a4e98dbcebfe.zip
Merge pull request #28 from real-zephex/improvement-2
added series support
Diffstat (limited to 'src/app/web-series/components')
-rw-r--r--src/app/web-series/components/HomePageModules.jsx56
-rw-r--r--src/app/web-series/components/cacher.js19
-rw-r--r--src/app/web-series/components/data-fetch.js87
-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/videoPlayer.jsx66
6 files changed, 312 insertions, 0 deletions
diff --git a/src/app/web-series/components/HomePageModules.jsx b/src/app/web-series/components/HomePageModules.jsx
new file mode 100644
index 0000000..90af2f8
--- /dev/null
+++ b/src/app/web-series/components/HomePageModules.jsx
@@ -0,0 +1,56 @@
+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={167}
+ height={267}
+ 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/cacher.js b/src/app/web-series/components/cacher.js
new file mode 100644
index 0000000..3e2a197
--- /dev/null
+++ b/src/app/web-series/components/cacher.js
@@ -0,0 +1,19 @@
+import { SERIES_INFO } from "./data-fetch";
+
+const PreFecthSeriesInfo = async (data) => {
+ try {
+ const fetchPromises = data.results.map(async (element) => {
+ await SERIES_INFO(element.id);
+ });
+
+ await Promise.all(fetchPromises);
+ console.log("Series info pre-fetched successfully!");
+ } catch (error) {
+ console.error(
+ "Error occurred while pre-fetching series info page:",
+ error
+ );
+ }
+};
+
+export default PreFecthSeriesInfo;
diff --git a/src/app/web-series/components/data-fetch.js b/src/app/web-series/components/data-fetch.js
new file mode 100644
index 0000000..e0feca5
--- /dev/null
+++ b/src/app/web-series/components/data-fetch.js
@@ -0,0 +1,87 @@
+"use server";
+
+import {
+ popular_tv_shows,
+ trending_tv_shows,
+ top_rated_shows,
+ recommended_shows,
+ crew_details,
+ tv_info,
+ search_tv,
+} from "../../../../utils/series_urls";
+
+export const POPULAR_SHOWS = async () => {
+ try {
+ const res = await fetch(popular_tv_shows(), {
+ next: {
+ revalidate: 21600,
+ },
+ });
+ const data = await res.json();
+ return data;
+ } catch (error) {
+ throw new Error(error.message);
+ }
+};
+
+export const TRENDING_SHOWS = async () => {
+ try {
+ const res = await fetch(trending_tv_shows(), {
+ next: {
+ revalidate: 21600,
+ },
+ });
+ const data = await res.json();
+ return data;
+ } catch (error) {
+ throw new Error(error.message);
+ }
+};
+
+export const TOP_SHOWS = async () => {
+ try {
+ const res = await fetch(top_rated_shows(), {
+ next: {
+ revalidate: 21600,
+ },
+ });
+ const data = await res.json();
+ return data;
+ } catch (error) {
+ throw new Error(error.message);
+ }
+};
+
+export const SERIES_INFO = async (id) => {
+ try {
+ const res = await fetch(tv_info(id), { next: { revalidate: 21600 } });
+ const data = await res.json();
+ return data;
+ } catch (error) {
+ throw new Error(error.message);
+ }
+};
+
+export const CREW_DETAILS = async (id) => {
+ try {
+ const res = await fetch(crew_details(id), {
+ next: { revalidate: 21600 },
+ });
+ const data = await res.json();
+ return data;
+ } catch (error) {
+ throw new Error(error.message);
+ }
+};
+
+export const SEARCH_TV = async (title) => {
+ try {
+ const res = await fetch(search_tv(title), {
+ next: { revalidate: 21600 },
+ });
+ const data = await res.json();
+ return data;
+ } catch (error) {
+ throw new Error(error.message);
+ }
+};
diff --git a/src/app/web-series/components/searchBar.jsx b/src/app/web-series/components/searchBar.jsx
new file mode 100644
index 0000000..81dd25f
--- /dev/null
+++ b/src/app/web-series/components/searchBar.jsx
@@ -0,0 +1,49 @@
+"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={17}
+ />
+ <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
new file mode 100644
index 0000000..d1564e0
--- /dev/null
+++ b/src/app/web-series/components/searchResults.jsx
@@ -0,0 +1,35 @@
+"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/videoPlayer.jsx b/src/app/web-series/components/videoPlayer.jsx
new file mode 100644
index 0000000..cc8feb3
--- /dev/null
+++ b/src/app/web-series/components/videoPlayer.jsx
@@ -0,0 +1,66 @@
+"use client";
+
+import { useState } from "react";
+import styles from "../styles/videoPlayer.module.css";
+
+const SeriesPlayer = ({ id: id }) => {
+ const [iframe, iframeContent] = useState(null);
+ const [episode, setEpisode] = useState("");
+ const [season, setSeason] = useState("");
+
+ async function VideoPlayerInitialize() {
+ if (!episode || !season) {
+ alert("Please provide the required episode and season number.");
+ return;
+ }
+ iframeContent(await iframeGenerator(id, season, episode));
+ document.getElementById("video-player").style.display = "none";
+ }
+
+ return (
+ <main className={styles.Main}>
+ <div className={styles.EpisodeSeasonInput}>
+ <input
+ name="Season"
+ type="number"
+ placeholder="Season Number"
+ onChange={(e) => {
+ if (Number(e.target.value) > 0) {
+ setSeason(e.target.value);
+ }
+ }}
+ ></input>
+ <input
+ name="Episode"
+ type="number"
+ placeholder="Episode Number"
+ onChange={(e) => {
+ if (Number(e.target.value) > 0) {
+ setEpisode(e.target.value);
+ }
+ }}
+ ></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>
+ );
+};
+
+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;