aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorreal-zephex <[email protected]>2024-05-25 16:58:02 +0530
committerreal-zephex <[email protected]>2024-05-25 16:58:02 +0530
commit2d0bcaeeeffef4e6ed6f445378b9729e70901f61 (patch)
tree40f63b16c4e11551b45b2989728eb659af47c6e2
parent✅ fix(anime): fix continue watching functionality and minor tweaks (diff)
downloaddramalama-2d0bcaeeeffef4e6ed6f445378b9729e70901f61.tar.xz
dramalama-2d0bcaeeeffef4e6ed6f445378b9729e70901f61.zip
🚀 refactor(movie): revamped movie section
-rw-r--r--src/app/anime/components/search.jsx2
-rw-r--r--src/app/anime/continueWatching/page.jsx2
-rw-r--r--src/app/movies/[id]/page.jsx151
-rw-r--r--src/app/movies/components/cacher.js5
-rw-r--r--src/app/movies/components/descriptionTabs.jsx67
-rw-r--r--src/app/movies/components/faqs.jsx33
-rw-r--r--src/app/movies/components/popular.jsx49
-rw-r--r--src/app/movies/components/requestsHandler.js36
-rw-r--r--src/app/movies/components/search.jsx71
-rw-r--r--src/app/movies/components/searchFormatter.jsx51
-rw-r--r--src/app/movies/components/search_2.jsx63
-rw-r--r--src/app/movies/components/trending.jsx48
-rw-r--r--src/app/movies/components/videoPlayer.jsx17
-rw-r--r--src/app/movies/components/video_player.jsx68
-rw-r--r--src/app/movies/page.jsx86
-rw-r--r--src/app/movies/styles/info.module.css150
-rw-r--r--src/app/movies/styles/page.module.css3
-rw-r--r--src/app/movies/styles/pop_trend.module.css79
-rw-r--r--src/app/movies/styles/search.module.css84
-rw-r--r--src/app/movies/styles/video_player.module.css31
-rw-r--r--utils/movie_urls.js19
21 files changed, 384 insertions, 731 deletions
diff --git a/src/app/anime/components/search.jsx b/src/app/anime/components/search.jsx
index 0fe883b..2631791 100644
--- a/src/app/anime/components/search.jsx
+++ b/src/app/anime/components/search.jsx
@@ -28,7 +28,7 @@ const SearchBar = () => {
return (
<main>
<section>
- <div className="flex w-full md:flex-nowrap gap-2 lg:w-1/2">
+ <div className="flex w-full md:flex-nowrap gap-2 lg:w-1/2">
<Input
type="text"
label="Search for anime"
diff --git a/src/app/anime/continueWatching/page.jsx b/src/app/anime/continueWatching/page.jsx
index e58360e..8951f4a 100644
--- a/src/app/anime/continueWatching/page.jsx
+++ b/src/app/anime/continueWatching/page.jsx
@@ -2,7 +2,7 @@
import React, { useState, useEffect } from "react";
import NextImage from "next/image";
-import { Card, CardFooter, Image, Button, Link } from "@nextui-org/react";
+import { CarFooter, Image, Link } from "@nextui-org/react";
const ContinueWatching = () => {
const [localItems, setLocalItems] = useState(null);
diff --git a/src/app/movies/[id]/page.jsx b/src/app/movies/[id]/page.jsx
index 313fc83..11389e7 100644
--- a/src/app/movies/[id]/page.jsx
+++ b/src/app/movies/[id]/page.jsx
@@ -1,118 +1,53 @@
-import styles from "../styles/info.module.css";
-import { getInfoURL } from "../../../../utils/movie_urls";
-import Image from "next/image";
-import { PiThumbsUpFill } from "react-icons/pi";
-import { FaRegCheckCircle } from "react-icons/fa";
-import { RxDividerVertical } from "react-icons/rx";
-import { FaDollarSign } from "react-icons/fa";
-import { FaSackDollar } from "react-icons/fa6";
-import VIDEO_PLAYER from "../components/video_player";
+import { Image, Chip, Accordion, AccordionItem } from "@nextui-org/react";
-export default async function MOVIE_INFO({ params }) {
+import { MovieInfoData } from "../components/requestsHandler";
+import DescriptionTabs from "../components/descriptionTabs";
+import MovieVideoPlayer from "../components/videoPlayer";
+import Questions from "../components/faqs";
+
+const MovieInfoPage = async ({ params }) => {
const id = params.id;
- const data = await get_movie_info(id);
+
+ const data = await MovieInfoData(id);
return (
- <main
- style={{
- backgroundImage: `url(https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${data.backdrop_path})`,
- backgroundRepeat: "no-repeat",
- backgroundSize: "cover",
- }}
- className={styles.Main}
- >
- <section className={styles.MovieInfoSection}>
- <section className={styles.MovieInfo}>
- <div className={styles.HeroSection}>
- <Image
- src={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${data.poster_path}`}
- width={200}
- height={300}
- alt="Movie Poster"
- priority
- ></Image>
- <div className={styles.HeroTitle}>
- <h2>{data.title || "Not found"}</h2>
- <p className={styles.tagline}>
- <span>{data.tagline || "Not found"}</span>
- </p>
- <p className={styles.MovieDescription}>
- {data.overview || "Not found"}
- </p>
+ <main>
+ <section className="pt-12 m-auto w-full lg:w-9/12">
+ <MovieVideoPlayer 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={180}
+ height={300}
+ alt="Anime Title Poster"
+ className="m-2"
+ ></Image>
+ <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.name}</p>
+ </Chip>
+ ))}
</div>
</div>
- <div className={styles.OtherInfo}>
- <section className={styles.Ratings}>
- <span>
- <PiThumbsUpFill size={16} />
- <p>{data.vote_average || "Not found"}</p>
- </span>
- <span className={styles.divider}>
- <RxDividerVertical size={22} />
- </span>
- <span>
- <FaRegCheckCircle size={16} />
- <p>{data.vote_count || "Not found"}</p>
- </span>
- </section>
- <section className={styles.Money}>
- <span title="revenue">
- <FaSackDollar />
- <p>
- $
- {data.revenue.toLocaleString() ||
- "Not found"}
- </p>
- </span>
- <span className={styles.divider}>
- <RxDividerVertical size={22} />
- </span>
- <span title="budget">
- <FaDollarSign />
- <p>
- $
- {data.budget.toLocaleString() ||
- "Not found"}
- </p>
- </span>
- </section>
- <section className={styles.Money}>
- <span title="Released on">
- <p>
- Release Date:{" "}
- {data.release_date || "Not found"}
- </p>
- </span>
- </section>
- <section className={styles.Genre}>
- {data.genres.map((item) => (
- <p key={item.id}>{item.name || "Not found"}</p>
- ))}
- </section>
- </div>
- <section className={styles.VideoPlayer}>
- <VIDEO_PLAYER id={id} />
- <p
- style={{
- textAlign: "center",
- margin: 0,
- fontSize: 12,
- }}
- >
- IMPORTANT: Please use adblockers like uBlock Orgin
- or Ghostery for an ad free experience.
- </p>
- </section>
- <br />
- <br />
- </section>
+ </div>
+ <DescriptionTabs data={data} />
+ <Questions />
</section>
</main>
);
-}
-
-const get_movie_info = async (id) => {
- const res = await fetch(getInfoURL(id), { next: { revalidate: 21620 } });
- const data = await res.json();
- return data;
};
+
+export default MovieInfoPage;
diff --git a/src/app/movies/components/cacher.js b/src/app/movies/components/cacher.js
index 169508a..801fe95 100644
--- a/src/app/movies/components/cacher.js
+++ b/src/app/movies/components/cacher.js
@@ -1,10 +1,9 @@
-import { getInfoURL } from "../../../../utils/movie_urls";
+import { MovieInfoData } from "./requestsHandler";
const PreFetchMovieInfo = async (data) => {
try {
const fetchPromises = data.results.map(async (element) => {
- const link = `${getInfoURL(element.id)}`;
- await fetch(link, { next: { revalidate: 21600 } });
+ await MovieInfoData(element.id);
});
await Promise.all(fetchPromises);
diff --git a/src/app/movies/components/descriptionTabs.jsx b/src/app/movies/components/descriptionTabs.jsx
new file mode 100644
index 0000000..2f5ca91
--- /dev/null
+++ b/src/app/movies/components/descriptionTabs.jsx
@@ -0,0 +1,67 @@
+"use client";
+
+import { Tabs, Tab, Card, CardBody, Link } 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 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.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>Released on</strong>:{" "}
+ <span>{data.release_date || "not sure"}</span>
+ </h4>
+ <h4>
+ <strong>Status</strong>:{" "}
+ <span>{data.status || "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>
+ </Tabs>
+ </div>
+ );
+}
diff --git a/src/app/movies/components/faqs.jsx b/src/app/movies/components/faqs.jsx
new file mode 100644
index 0000000..4fa5043
--- /dev/null
+++ b/src/app/movies/components/faqs.jsx
@@ -0,0 +1,33 @@
+"use client";
+
+import { Accordion, AccordionItem } from "@nextui-org/react";
+
+const Questions = () => {
+ return (
+ <Accordion>
+ <AccordionItem
+ key="1"
+ aria-label="Accordion 1"
+ title="Why are there ads in the player?"
+ >
+ We do not host any media on our own servers. We simply aggregate
+ data from third-party providers. While these services are free
+ for public use, someone has to bear the costs of hosting the
+ servers and infrastructure. Therefore, the video player includes
+ advertisements to help cover these expenses.
+ </AccordionItem>
+ <AccordionItem
+ key="2"
+ aria-label="Accordion 2"
+ title="Okay but I still don't want to see ads..."
+ >
+ To avoid ads, you can utilize ad blockers such as Ghostery,
+ uBlock Origin, or any preferred ad blocker. Adjust your browser
+ settings to maximize tracking prevention or similar features for
+ enhanced protection against ads
+ </AccordionItem>
+ </Accordion>
+ );
+};
+
+export default Questions;
diff --git a/src/app/movies/components/popular.jsx b/src/app/movies/components/popular.jsx
deleted file mode 100644
index 3ef0501..0000000
--- a/src/app/movies/components/popular.jsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import { POPULAR } from "../../../../utils/movie_urls";
-import PreFetchMovieInfo from "./cacher";
-import styles from "../styles/pop_trend.module.css";
-import Image from "next/image";
-import Link from "next/link";
-
-export default async function POPULAR_MOVIES() {
- const data = await get_popular();
- PreFetchMovieInfo(data);
-
- return (
- <main className={styles.Main}>
- <h2>Popular Movies</h2>
- <section className={styles.MovieContainer}>
- {data &&
- data.results &&
- data.results.slice(0, 16).map((item, index) => (
- <Link
- href={`/movies/${item.id}`}
- style={{
- textDecoration: "none",
- color: "white",
- }}
- key={index}
- >
- <div className={styles.MovieEntryPrev}>
- <div className={styles.MovieEntry}>
- <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="Movie Poster"
- priority
- ></Image>
- <p>{item.title}</p>
- </div>
- </div>
- </Link>
- ))}
- </section>
- </main>
- );
-}
-
-const get_popular = async () => {
- const res = await fetch(POPULAR, { next: { revalidate: 21600 } });
- const data = await res.json();
- return data;
-};
diff --git a/src/app/movies/components/requestsHandler.js b/src/app/movies/components/requestsHandler.js
new file mode 100644
index 0000000..5f4db8b
--- /dev/null
+++ b/src/app/movies/components/requestsHandler.js
@@ -0,0 +1,36 @@
+"use server";
+
+import {
+ SEARCH,
+ TRENDING,
+ POPULAR,
+ getInfoURL,
+ TOP_RATED,
+ NOW_IN_THEATERS,
+ UPCOMING_MOVIES,
+} from "../../../../utils/movie_urls";
+
+export const SearchMovie = async (title) => {
+ const res = await fetch(SEARCH(title), { next: { revalidate: 21600 } });
+ const data = await res.json();
+ return data;
+};
+
+export const MovieHomepageDataFetcher = async (type) => {
+ const dataAvailable = {
+ trending: TRENDING,
+ popular: POPULAR,
+ top: TOP_RATED,
+ };
+ const res = await fetch(dataAvailable[type], {
+ next: { revalidate: 21600 },
+ });
+ const data = await res.json();
+ return data;
+};
+
+export const MovieInfoData = async (id) => {
+ const res = await fetch(getInfoURL(id), { cache: "force-cache" });
+ const data = await res.json();
+ return data;
+};
diff --git a/src/app/movies/components/search.jsx b/src/app/movies/components/search.jsx
index dca163a..35b8432 100644
--- a/src/app/movies/components/search.jsx
+++ b/src/app/movies/components/search.jsx
@@ -1,38 +1,53 @@
"use client";
import { useState } from "react";
-import styles from "../styles/search.module.css";
-import { FaSearch } from "react-icons/fa";
-import SearchResults from "./search_2";
+import { Input, Progress } from "@nextui-org/react";
-export default function SEARCH_COMPONENT() {
- const [title, setTitle] = useState("");
- const [result, setResults] = useState(null);
+import { SearchMovie } from "./requestsHandler";
+import MovieSearchFormatter from "./searchFormatter";
- const fetch_results = async (title) => {
- setResults(await SearchResults(title));
- };
+const MovieSearchBar = () => {
+ const [movieTitle, setMovieTitle] = useState("");
+ const [loading, setLoading] = useState(<></>);
+ const [movieResults, setMovieResults] = useState(<></>);
+
+ async function handleInputChange() {
+ setLoading(
+ <Progress
+ size="sm"
+ isIndeterminate
+ aria-label="Loading..."
+ className="w-full"
+ />
+ );
+ const data = await SearchMovie(movieTitle);
+ setLoading(<></>);
+ setMovieResults(await MovieSearchFormatter(data));
+ }
return (
- <main className={styles.Main}>
- <section className={styles.InputContainer}>
- <FaSearch
- color="white"
- className={styles.SearchIcon}
- size={22}
- />
- <input
- placeholder="Enter movie 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);
+ <section>
+ <div className="flex flex-col w-full md:flex-nowrap gap-2 lg:w-1/2">
+ <Input
+ type="text"
+ label="Search for movie"
+ placeholder="Enter movie title"
+ onChange={(event) => {
+ if (event.target.value.trim() !== "") {
+ setMovieTitle(event.target.value);
}
}}
- ></input>
- </section>
-
- <section className={styles.SearchResults}>{result}</section>
- </main>
+ onKeyDown={async (event) => {
+ if (event.key === "Enter" || event.code === "Enter") {
+ await handleInputChange();
+ }
+ }}
+ />
+ {loading}
+ </div>
+ <div className="mt-2">{movieResults}</div>
+ </section>
);
-}
+};
+
+export default MovieSearchBar;
diff --git a/src/app/movies/components/searchFormatter.jsx b/src/app/movies/components/searchFormatter.jsx
new file mode 100644
index 0000000..47b684f
--- /dev/null
+++ b/src/app/movies/components/searchFormatter.jsx
@@ -0,0 +1,51 @@
+import { Card, CardHeader, CardBody, Image, Link } from "@nextui-org/react";
+import NextImage from "next/image";
+
+import styles from "../../page.module.css";
+
+const MovieSearchFormatter = 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={`/movies/${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={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${item.poster_path}`}
+ width={190}
+ 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.original_title}
+ </h4>
+ </CardHeader>
+ </Card>
+ </Link>
+ );
+ }
+ })}
+ </section>
+ );
+};
+
+export default MovieSearchFormatter;
diff --git a/src/app/movies/components/search_2.jsx b/src/app/movies/components/search_2.jsx
deleted file mode 100644
index cf3fc69..0000000
--- a/src/app/movies/components/search_2.jsx
+++ /dev/null
@@ -1,63 +0,0 @@
-"use server";
-
-import { SEARCH } from "../../../../utils/movie_urls";
-import PreFetchMovieInfo from "./cacher";
-import Image from "next/image";
-import Link from "next/link";
-import styles from "../styles/search.module.css";
-
-const SearchResults = async (title) => {
- const data = await get_search_results(title);
- PreFetchMovieInfo(data);
- if (data.results.length > 0) {
- return (
- <div className={styles.MovieSearchResultsContainer}>
- {data &&
- data.results &&
- data.results.map((item, index) => {
- if (item.poster_path) {
- return (
- <Link
- href={`/movies/${item.id}`}
- key={index}
- style={{
- backgroundImage: `url(https://image.tmdb.org/t/p/original${item.backdrop_path})`,
- backgroundRepeat: "no-repeat",
- backgroundSize: "cover",
- textDecoration: "none",
- color: "white",
- borderRadius: "0.5rem",
- overflow: "hidden",
- }}
- className={styles.MovieResultsPrev}
- >
- <section className={styles.MovieEntry}>
- <p>
- {item.title || item.original_title}
- </p>
- <Image
- src={`https://image.tmdb.org/t/p/original${item.poster_path}`}
- width={130}
- height={230}
- alt="Movie Poster"
- priority
- />
- </section>
- </Link>
- );
- }
- })}
- </div>
- );
- } else {
- return <p className={styles.NoResults}>No results found!</p>;
- }
-};
-
-const get_search_results = async (title) => {
- const res = await fetch(SEARCH + title, { next: { revalidate: 21600 } });
- const data = await res.json();
- return data;
-};
-
-export default SearchResults;
diff --git a/src/app/movies/components/trending.jsx b/src/app/movies/components/trending.jsx
deleted file mode 100644
index 8e20ba1..0000000
--- a/src/app/movies/components/trending.jsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import { TRENDING } from "../../../../utils/movie_urls";
-import PreFetchMovieInfo from "./cacher";
-import styles from "../styles/pop_trend.module.css";
-import Link from "next/link";
-import Image from "next/image";
-
-export default async function TREDNING_MOVIES() {
- const data = await get_popular();
- PreFetchMovieInfo(data);
-
- return (
- <main className={styles.Main}>
- <h2>Trending Movies</h2>
- <section className={styles.MovieContainer}>
- {data &&
- data.results &&
- data.results.slice(0, 16).map((item, index) => (
- <Link
- href={`/movies/${item.id}`}
- style={{
- textDecoration: "none",
- color: "white",
- }}
- key={index}
- >
- <div className={styles.MovieEntryPrev}>
- <div className={styles.MovieEntry}>
- <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="Movie Poster"
- ></Image>
- <p>{item.title}</p>
- </div>
- </div>
- </Link>
- ))}
- </section>
- </main>
- );
-}
-
-const get_popular = async () => {
- const res = await fetch(TRENDING, { next: { revalidate: 21620 } });
- const data = await res.json();
- return data;
-};
diff --git a/src/app/movies/components/videoPlayer.jsx b/src/app/movies/components/videoPlayer.jsx
new file mode 100644
index 0000000..b7cdd81
--- /dev/null
+++ b/src/app/movies/components/videoPlayer.jsx
@@ -0,0 +1,17 @@
+const MovieVideoPlayer = async ({ id: id }) => {
+ const videoFrameGenerator = (id) => {
+ return (
+ <iframe
+ src={`https://vidsrc.pro/embed/movie/${id}`}
+ allowFullScreen
+ referrerPolicy="origin"
+ height={720}
+ className="w-full h-[240px] lg:h-[720px]"
+ ></iframe>
+ );
+ };
+
+ return <section>{videoFrameGenerator(id)}</section>;
+};
+
+export default MovieVideoPlayer;
diff --git a/src/app/movies/components/video_player.jsx b/src/app/movies/components/video_player.jsx
deleted file mode 100644
index 74f6180..0000000
--- a/src/app/movies/components/video_player.jsx
+++ /dev/null
@@ -1,68 +0,0 @@
-"use client";
-
-import styles from "../styles/video_player.module.css";
-import { useState, useEffect } from "react";
-
-export default function VIDEO_PLAYER({ id: id }) {
- const [frame, setFrame] = useState(null);
-
- useEffect(() => {
- make_player(`https://vidsrc.icu/embed/movie/${id}`);
- }, []);
-
- function make_player(url) {
- setFrame(
- <iframe
- src={url}
- referrerPolicy="origin"
- allowFullScreen
- className={styles.VideoPlayer}
- ></iframe>
- );
- }
-
- return (
- <section className={styles.VideoContainer}>
- <div className={styles.sourcesButtonContainer}>
- <button
- onClick={() =>
- make_player(`https://vidsrc.pro/embed/movie/${id}`)
- }
- >
- Vidsrc.pro
- </button>
- <button
- onClick={() =>
- make_player(`https://blackvid.space/embed?tmdb=${id}`)
- }
- >
- Blackvid
- </button>
- <button
- onClick={() =>
- make_player(`https://vidsrc.to/embed/movie/${id}`)
- }
- >
- Vidsrc.to
- </button>
- <button
- onClick={() =>
- make_player(`https://vidsrc.icu/embed/movie/${id}`)
- }
- >
- Vidsrc.icu
- </button>
- <button
- onClick={() =>
- make_player(
- `https://player.autoembed.cc/embed/movie/${id}`
- )
- }
- >
- Autoembded.cc
- </button>
- </div>
- {frame}
- </section>
- );
-}
diff --git a/src/app/movies/page.jsx b/src/app/movies/page.jsx
index 24c2ed9..c9c8e8e 100644
--- a/src/app/movies/page.jsx
+++ b/src/app/movies/page.jsx
@@ -1,17 +1,81 @@
-import POPULAR_MOVIES from "./components/popular";
-import TREDNING_MOVIES from "./components/trending";
-import SEARCH_COMPONENT from "./components/search";
-import styles from "./styles/page.module.css";
+import { Card, CardHeader, CardBody, Image, Link } from "@nextui-org/react";
+import NextImage from "next/image";
+
+import MovieSearchBar from "./components/search";
+import { MovieHomepageDataFetcher } from "./components/requestsHandler";
+import PreFetchMovieInfo from "./components/cacher";
+import styles from "../page.module.css";
export default async function MOVIE_HOME() {
+ const popular_data = await MovieHomepageDataFetcher("popular");
+ const trending_data = await MovieHomepageDataFetcher("trending");
+ const top_data = await MovieHomepageDataFetcher("top");
+
+ const dataToBeLoaded = [popular_data, trending_data];
+
+ for (let items of dataToBeLoaded) {
+ PreFetchMovieInfo(items);
+ }
+
+ const dataFormatter = (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={`/movies/${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={`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 overflow-hidden"
+ shadow="lg"
+ priority
+ />
+ </CardBody>
+ <CardHeader>
+ <h4
+ className={`antialiased text-small text-center uppercase w-44 overflow-hidden whitespace-nowrap text-ellipsis `}
+ >
+ {item.original_title}
+ </h4>
+ </CardHeader>
+ </Card>
+ </Link>
+ ))}
+ </div>
+ </section>
+ );
+ };
+
return (
- <main className={styles.MovieMain}>
- <SEARCH_COMPONENT />
- <POPULAR_MOVIES />
- <br />
- <TREDNING_MOVIES />
- <br />
- <br />
+ <main className="pt-12 ">
+ <div className="lg:ml-2">
+ <MovieSearchBar />
+ </div>
+ <div className="lg:ml-1">
+ {dataFormatter("Popular Movies", popular_data)}
+ <div className="mt-2">
+ {dataFormatter("Trending Movies", trending_data)}
+ </div>
+ <div className="mt-2">
+ {dataFormatter("Top Rated Movies", top_data)}
+ </div>
+ </div>
<br />
</main>
);
diff --git a/src/app/movies/styles/info.module.css b/src/app/movies/styles/info.module.css
deleted file mode 100644
index b848f7f..0000000
--- a/src/app/movies/styles/info.module.css
+++ /dev/null
@@ -1,150 +0,0 @@
-.Main {
- margin-top: 60px;
- color: white;
-}
-
-.MovieInfoSection {
- background-color: #1f1f1fcc;
- backdrop-filter: blur(10px);
-}
-
-.MovieInfo {
- max-width: 60%;
- margin: 0 auto;
-}
-
-.HeroSection {
- display: flex;
- align-items: center;
-}
-
-.HeroSection img {
- border-radius: 1rem;
- padding: 0.5rem 0 0 0;
-}
-
-.HeroTitle {
- display: flex;
- flex-direction: column;
- margin-left: 0.6rem;
- padding: 0.3rem;
-}
-
-.HeroTitle h2 {
- font-size: 28px;
- margin: 0;
-}
-
-.tagline {
- margin: 0.2rem 0 0 0;
- font-size: 12px;
-}
-
-.tagline span {
- background-color: #12121286;
- padding: 0.2rem;
- border-radius: 0.5rem;
-}
-
-.MovieDescription {
- font-size: 18px;
- margin: 0.2rem 0 0 0;
- max-height: 140px;
- overflow: auto;
-}
-
-.MovieDescription::-webkit-scrollbar {
- width: 5px;
-}
-
-.MovieDescription::-webkit-scrollbar-thumb {
- background-color: var(--nord-yellow);
- border-radius: 1rem;
-}
-
-.OtherInfo {
- display: flex;
- flex-direction: column;
- align-items: center;
- margin: 1rem 0 0 0;
- background-color: #12121286;
- padding: 1rem;
- border-radius: 0.5rem;
-}
-
-.Ratings {
- display: flex;
-}
-
-.divider {
- margin: 0 0.5rem 0 0.5rem;
-}
-
-.Ratings span {
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.Ratings p {
- margin: 0 0 0 0.4rem;
-}
-
-.Money {
- margin: 0.5rem 0 0 0;
- display: flex;
-}
-
-.Money p {
- margin: 0 0 0 0.4rem;
-}
-
-.Money span {
- display: flex;
- align-items: center;
-}
-
-.Genre {
- display: flex;
-}
-
-.Genre p {
- background-color: #12121257;
- margin: 0.5rem 0.2rem 0 0.2rem;
- padding: 0.3rem;
- border-radius: 0.5rem;
-}
-
-@media screen and (max-width: 768px) {
- .MovieInfo {
- max-width: 100%;
- }
-
- .VideoPlayer {
- width: 98%;
- margin: 1rem auto;
- }
-
- .VideoPlayer iframe {
- height: 250px;
- }
-
- .HeroTitle h2 {
- font-size: 22px;
- }
-
- .HeroSection img {
- width: 170px;
- height: 267px;
- }
-
- .MovieDescription {
- font-size: 16px;
- }
-
- .OtherInfo {
- width: 90%;
- margin: 1rem auto;
- }
-
-} \ No newline at end of file
diff --git a/src/app/movies/styles/page.module.css b/src/app/movies/styles/page.module.css
deleted file mode 100644
index 5cba0a1..0000000
--- a/src/app/movies/styles/page.module.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.MovieMain {
- margin-top: 65px;
-}
diff --git a/src/app/movies/styles/pop_trend.module.css b/src/app/movies/styles/pop_trend.module.css
deleted file mode 100644
index 362debd..0000000
--- a/src/app/movies/styles/pop_trend.module.css
+++ /dev/null
@@ -1,79 +0,0 @@
-.Main {
- color: white;
- margin-left: 0.2rem;
- margin-right: 0.2rem;
-}
-
-.Main h2 {
- color: white;
- margin: 0.4rem 0 0 0;
- text-transform: uppercase;
- font-size: 30px;
-}
-
-.MovieContainer {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
- grid-gap: 0.5rem;
- align-items: center;
-}
-
-.MovieContainer::-webkit-scrollbar {
- height: 0;
-}
-
-.MovieContainer:hover .MovieEntryPrev {
- opacity: 0.5;
-}
-
-.MovieContainer:hover .MovieEntryPrev:hover {
- opacity: 1;
- transform: translateY(-5px) scale(1.02);
-
-}
-
-.MovieEntryPrev {
- transition: opacity 200ms ease, transform 200ms ease;
-}
-
-.MovieEntry {
- background-color: #1f1f1fc2;
- padding: 0.5rem;
- /* border-radius: 0.5rem; */
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: column;
- cursor: pointer;
- backdrop-filter: blur(10px);
- border-radius: 0.5rem;
- overflow: hidden;
-}
-
-.MovieEntry img {
- border-radius: 0.5rem;
- box-shadow: 0px 0px 10px 8px rgb(32, 32, 32);
-}
-
-
-.MovieEntry p {
- width: 160px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- text-align: center;
- margin: 0.3rem 0 0 0;
-}
-
-@media screen and (max-width: 768px) {
- .Main h1 {
- font-size: 24px;
- text-align: start;
- }
-
- .MovieContainer {
- display: flex;
- overflow-x: auto;
- overflow-y: hidden;
- }
-} \ No newline at end of file
diff --git a/src/app/movies/styles/search.module.css b/src/app/movies/styles/search.module.css
deleted file mode 100644
index d3b1a75..0000000
--- a/src/app/movies/styles/search.module.css
+++ /dev/null
@@ -1,84 +0,0 @@
-.Main {
- margin: 0 0.4rem 0 0.4rem;
-}
-
-.InputContainer {
- display: flex;
- align-items: center;
- background-color: #1f1f1f;
- padding: 0.4rem;
- width: 40vw;
- border-radius: 0.5rem;
-
-
-}
-
-.SearchIcon {
- margin-left: 0.4rem;
-}
-
-.InputContainer input {
- background-color: transparent;
- outline: none;
- border: none;
- padding: 0.4rem;
- font-family: "Lexend Deca", serif;
- margin-left: 0.2rem;
- font-size: large;
- color: white;
- width: 100%;
- font-size: 20px;
-}
-
-/* Search Results */
-
-.MovieSearchResultsContainer {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
- grid-gap: 0.5rem;
- align-items: center;
- margin: 0.2rem 0.2rem 0 0.2rem;
-}
-
-.MovieSearchResultsContainer:hover .MovieResultsPrev {
- opacity: 0.5;
-}
-
-.MovieSearchResultsContainer:hover .MovieResultsPrev:hover {
- opacity: 1;
- scale: 1.02;
-}
-
-.MovieResultsPrev {
- transition: opacity 200ms ease, scale 200ms ease;
-}
-
-.MovieEntry {
- display: flex;
- align-items: center;
- justify-content: space-between;
- color: white;
- backdrop-filter: blur(10px);
- padding: 0.4rem;
- background-color: #1212129f;
-}
-
-.MovieEntry img {
- border-radius: 0.5rem;
-}
-
-.MovieEntry p {
- margin: 0 0.2rem 0 0;
- font-size: 18px;
-}
-
-.NoResults {
- color: white;
- text-align: center;
-}
-
-@media screen and (max-width: 768px) {
- .InputContainer {
- width: 100%;
- }
-} \ No newline at end of file
diff --git a/src/app/movies/styles/video_player.module.css b/src/app/movies/styles/video_player.module.css
deleted file mode 100644
index 2e022f0..0000000
--- a/src/app/movies/styles/video_player.module.css
+++ /dev/null
@@ -1,31 +0,0 @@
-.VideoContainer {
- margin: 0.5rem 0 0 0;
-}
-
-.VideoContainer button {
- font-family: "Lexend Deca", serif;
- outline: none;
- border: none;
- background-color: #121212be;
-
- color: white;
- margin-right: 0.2rem;
- padding: 0.5rem;
- border-radius: 0.5rem;
- cursor: pointer;
-}
-
-.sourcesButtonContainer {
- display: flex;
- overflow: auto;
-}
-
-.VideoPlayer {
- width: 100%;
- height: 700px;
- aspect-ratio: "16/9";
- border: none;
- outline: none;
- border-radius: 0.5rem;
- margin: 0.5rem 0 0 0;
-} \ No newline at end of file
diff --git a/utils/movie_urls.js b/utils/movie_urls.js
index 066041d..b99675a 100644
--- a/utils/movie_urls.js
+++ b/utils/movie_urls.js
@@ -1,9 +1,20 @@
export const API_KEY = "171fe27dbfecc58e2a18fbced644cda9";
export const PROXY = "https://sup-proxy.zephex0-f6c.workers.dev/api-json?url=";
-// MOVIES
export const TRENDING = `${PROXY}https://api.themoviedb.org/3/trending/movie/day?api_key=${API_KEY}`;
-export const SEARCH = `https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&query=`;
+
+export const SEARCH = (title) => {
+ return `https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&query=${title}`;
+};
+
export const POPULAR = `${PROXY}https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`;
-export const getInfoURL = (movieId) =>
- `${PROXY}https://api.themoviedb.org/3/movie/${movieId}?api_key=${API_KEY}`;
+
+export const getInfoURL = (movieId) => {
+ return `${PROXY}https://api.themoviedb.org/3/movie/${movieId}?api_key=${API_KEY}`;
+};
+
+export const TOP_RATED = `${PROXY}https://api.themoviedb.org/3/movie/top_rated?api_key=${API_KEY}`;
+
+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}`;