Skip to content

Commit

Permalink
Merge pull request #17 from zephex-alt/master
Browse files Browse the repository at this point in the history
Added MOVIES support
  • Loading branch information
real-zephex authored May 6, 2024
2 parents c962784 + 67b9292 commit ec22f9e
Show file tree
Hide file tree
Showing 18 changed files with 751 additions and 6 deletions.
10 changes: 7 additions & 3 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ const nextConfig = {
protocol: "https",
hostname: "sup-proxy.zephex0-f6c.workers.dev",
},
{
protocol: "https",
hostname: "image.tmdb.org",
},
],
},
logging: {
Expand All @@ -40,9 +44,9 @@ const nextConfig = {
},
experimental: {
serverActions: {
allowedOrigins: ["localhost:3000"]
}
}
allowedOrigins: ["localhost:3000"],
},
},
};

export default nextConfig;
3 changes: 2 additions & 1 deletion src/app/components/header/header.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Link from "next/link";
import styles from "../../page.module.css";

export default function Header() {
export default async function Header() {
return (
<main className={styles.main}>
<div className={styles.header}>
Expand All @@ -17,6 +17,7 @@ export default function Header() {
<Link href="/anime">Anime</Link>
<Link href="/kdrama">Kdrama</Link>
<Link href="/manga">Manga</Link>
<Link href="/movies">Movies</Link>
</div>
</div>
</main>
Expand Down
117 changes: 117 additions & 0 deletions src/app/movies/[id]/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
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";

export default async function MOVIE_INFO({ params }) {
const id = params.id;
const data = await get_movie_info(id);

return (
<main
style={{
backgroundImage: `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://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>
</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}</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: 14,
}}
>
NOTE: Please wait for some time for the video to
load. If it buffers for a long time, then try
chanding the server. If the issue persists, please
check your internet connection.
</p>
</section>
<br />
<br />
</section>
</section>
</main>
);
}

const get_movie_info = async (id) => {
const res = await fetch(getInfoURL(id), { next: { revalidate: 21620 } });
const data = await res.json();
return data;
};
17 changes: 17 additions & 0 deletions src/app/movies/components/cacher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { getInfoURL } from "../../../../utils/movie_urls";

const PreFetchMovieInfo = async (data) => {
try {
const fetchPromises = data.results.map(async (element) => {
const link = `${getInfoURL(element.id)}`;
await fetch(link, { next: { revalidate: 21600 } });
});

await Promise.all(fetchPromises);
console.log("Movie info pre-fetched successfully!");
} catch (error) {
console.error("Error occurred while pre-fetching video links:", error);
}
};

export default PreFetchMovieInfo;
58 changes: 58 additions & 0 deletions src/app/movies/components/popular.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
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}>
<h1>Popular Movies</h1>
<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
style={{
borderRadius: "0.5rem",
overflow: "hidden",
backgroundImage: `url(https://image.tmdb.org/t/p/original${item.backdrop_path})`,
backgroundRepeat: "no-repeat",
backgroundSize: "cover",
}}
className={styles.MovieEntryPrev}
>
<div className={styles.MovieEntry}>
<Image
src={`https://image.tmdb.org/t/p/original${item.poster_path}`}
width={200}
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;
};
38 changes: 38 additions & 0 deletions src/app/movies/components/search.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"use client";

import { useState } from "react";
import styles from "../styles/search.module.css";
import { FaSearch } from "react-icons/fa";
import SearchResults from "./search_2";

export default function SEARCH_COMPONENT() {
const [title, setTitle] = useState("");
const [result, setResults] = useState(null);

const fetch_results = async (title) => {
setResults(await SearchResults(title));
};

return (
<main className={styles.Main}>
<section className={styles.InputContainer}>
<FaSearch
color="white"
className={styles.SearchIcon}
size={17}
/>
<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);
}
}}
></input>
</section>

<section className={styles.SearchResults}>{result}</section>
</main>
);
}
57 changes: 57 additions & 0 deletions src/app/movies/components/search_2.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"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);
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>
);
};

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;
57 changes: 57 additions & 0 deletions src/app/movies/components/trending.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
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}>
<h1>Trending Movies</h1>
<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
style={{
borderRadius: "0.5rem",
overflow: "hidden",
backgroundImage: `url(https://image.tmdb.org/t/p/original${item.backdrop_path})`,
backgroundRepeat: "no-repeat",
backgroundSize: "cover",
}}
className={styles.MovieEntryPrev}
>
<div className={styles.MovieEntry}>
<Image
src={`https://image.tmdb.org/t/p/original${item.poster_path}`}
width={200}
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;
};
Loading

0 comments on commit ec22f9e

Please sign in to comment.