From bdd48555bf59552864d5a59a3ee43291e4136b47 Mon Sep 17 00:00:00 2001 From: real-zephex Date: Fri, 7 Jun 2024 09:55:23 +0530 Subject: =?UTF-8?q?=F0=9F=9A=80=20feat(ui):=20added=20manga=20with=20bette?= =?UTF-8?q?r=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next.config.mjs | 1 - src/app/anime/[id]/page.jsx | 6 +- src/app/anime/components/search_results.jsx | 23 +-- src/app/anime/page.jsx | 18 +-- src/app/components/header/header.jsx | 54 ++++--- src/app/kdrama/[id]/page.jsx | 8 +- src/app/kdrama/components/searchFormatter.jsx | 8 +- src/app/kdrama/page.jsx | 12 +- src/app/loading.jsx | 2 +- src/app/manga/[id]/page.jsx | 50 +++++++ src/app/manga/components/chapterPages.jsx | 35 +++++ src/app/manga/components/descriptionTabs.jsx | 159 +++++++++++++++++++++ src/app/manga/components/inputContainer.jsx | 116 +++++++++++++++ src/app/manga/components/requests.js | 28 ++++ src/app/manga/page.jsx | 21 +++ src/app/movies/components/searchFormatter.jsx | 10 +- src/app/movies/components/videoPlayer.jsx | 2 +- src/app/movies/page.jsx | 14 +- src/app/page.jsx | 46 ++---- src/app/web-series/[id]/page.jsx | 6 +- src/app/web-series/components/cacher.js | 4 +- src/app/web-series/components/search.jsx | 6 +- .../components/seriesSearchFormatter.jsx | 10 +- src/app/web-series/components/videoPlayer.jsx | 8 +- src/app/web-series/page.jsx | 14 +- tailwind.config.js | 25 +++- utils/manga_urls.js | 15 ++ 27 files changed, 566 insertions(+), 135 deletions(-) create mode 100644 src/app/manga/[id]/page.jsx create mode 100644 src/app/manga/components/chapterPages.jsx create mode 100644 src/app/manga/components/descriptionTabs.jsx create mode 100644 src/app/manga/components/inputContainer.jsx create mode 100644 src/app/manga/components/requests.js create mode 100644 src/app/manga/page.jsx create mode 100644 utils/manga_urls.js diff --git a/next.config.mjs b/next.config.mjs index 216839b..c587eaf 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -5,7 +5,6 @@ const nextConfig = { { protocol: "https", hostname: "asianimg.pro", - pathname: "/cover/**", }, { protocol: "https", diff --git a/src/app/anime/[id]/page.jsx b/src/app/anime/[id]/page.jsx index b121400..6740aac 100644 --- a/src/app/anime/[id]/page.jsx +++ b/src/app/anime/[id]/page.jsx @@ -23,8 +23,8 @@ const AnimeInfoHomepage = async ({ params }) => { className="h-screen bg-white dark:bg-black" >
-
-
+
+
{ key={index} color="warning" variant="faded" - className="mr-1 mb-1" + className="mb-1 mr-1" >

{item}

diff --git a/src/app/anime/components/search_results.jsx b/src/app/anime/components/search_results.jsx index 691b276..ba5c7cf 100644 --- a/src/app/anime/components/search_results.jsx +++ b/src/app/anime/components/search_results.jsx @@ -1,10 +1,8 @@ -"use server"; - import { search_results } from "../data-fetch/request"; import { preFetchAnimeInfo } from "./cacher"; import styles from "../../page.module.css"; -import { Card, CardHeader, CardBody } from "@nextui-org/react"; +import { Card, CardHeader, CardBody, CardFooter } from "@nextui-org/react"; import Link from "next/link"; import Image from "next/image"; @@ -15,7 +13,7 @@ const SearchResults = async (title) => { return (
{data && data.results.map((item, index) => ( @@ -23,26 +21,31 @@ const SearchResults = async (title) => { key={index} href={`/anime/${item.id}`} aria-label="anime redirection links" - className="flex flex-col items-center mx-1 " + className="mx-1 flex flex-col items-center" + title={item.title} > - + Searched Anime Poster - +

{item.title}

-
+
))} diff --git a/src/app/anime/page.jsx b/src/app/anime/page.jsx index ce5ca34..bb8d6f1 100644 --- a/src/app/anime/page.jsx +++ b/src/app/anime/page.jsx @@ -19,7 +19,7 @@ const AnimeHomepage = async () => { const header = (title) => ( <> -

+

{title}

@@ -33,22 +33,22 @@ const AnimeHomepage = async () => { key={index} href={`/anime/${item.id}`} aria-label="anime redirection links" - className="flex flex-col items-center mx-1 " + className="mx-1 flex flex-col items-center" > - + Anime Poster

{item.title}

@@ -60,7 +60,7 @@ const AnimeHomepage = async () => { ); return ( -
+
@@ -68,7 +68,7 @@ const AnimeHomepage = async () => {
{header("Popular Animes")}
{format(popular_data)}
@@ -77,7 +77,7 @@ const AnimeHomepage = async () => {
{header("Recent Animes")}
{format(recent_data)}
@@ -85,7 +85,7 @@ const AnimeHomepage = async () => {
{header("Top Airing Animes")}
{format(airing_data)}
diff --git a/src/app/components/header/header.jsx b/src/app/components/header/header.jsx index 104911b..950b807 100644 --- a/src/app/components/header/header.jsx +++ b/src/app/components/header/header.jsx @@ -1,30 +1,38 @@ import Link from "next/link"; -import styles from "../../page.module.css"; import { ThemeSwitcher } from "../themeSwitcher"; +import { + Navbar, + NavbarBrand, + NavbarContent, + NavbarItem, + Button, +} from "@nextui-org/react"; export default async function Header() { return ( -
-

- Dramalama -

- {/*
- -

Anime

- - -

Kdrama

- - -

Series

- - -

Movies

- -
*/} - -
+ + +

+ Dramalama +

+
+ + + + + + + + + +
); } diff --git a/src/app/kdrama/[id]/page.jsx b/src/app/kdrama/[id]/page.jsx index 94f5adb..b18c0ee 100644 --- a/src/app/kdrama/[id]/page.jsx +++ b/src/app/kdrama/[id]/page.jsx @@ -18,9 +18,9 @@ export default async function DramaInfo({ params }) { }} className="h-screen bg-white dark:bg-black" > -
-
-
+
+
+

{item}

diff --git a/src/app/kdrama/components/searchFormatter.jsx b/src/app/kdrama/components/searchFormatter.jsx index cc23fa7..21a52a5 100644 --- a/src/app/kdrama/components/searchFormatter.jsx +++ b/src/app/kdrama/components/searchFormatter.jsx @@ -1,5 +1,3 @@ -"use server"; - import { Card, CardHeader, CardBody } from "@nextui-org/react"; import Link from "next/link"; import Image from "next/image"; @@ -18,7 +16,7 @@ const SearchedDataFormatter = async (data) => { key={index} href={`/kdrama/${encodeURIComponent(item.id)}`} aria-label="anime redirection links" - className="flex flex-col items-center mx-1" + className="mx-1 flex flex-col items-center" title={item.title} > @@ -28,12 +26,12 @@ const SearchedDataFormatter = async (data) => { src={item.image} width={185} height={120} - className="rounded-md h-64" + className="h-64 rounded-md" priority /> -

+

{item.title}

diff --git a/src/app/kdrama/page.jsx b/src/app/kdrama/page.jsx index afcb8a2..f5e1e0e 100644 --- a/src/app/kdrama/page.jsx +++ b/src/app/kdrama/page.jsx @@ -18,7 +18,7 @@ const KdramaHomepage = async () => { const header = (title) => ( <> -

+

{title}

@@ -32,22 +32,22 @@ const KdramaHomepage = async () => { key={index} href={`/kdrama/${encodeURIComponent(item.id)}`} aria-label="anime redirection links" - className="flex flex-col items-center mx-1" + className="mx-1 flex flex-col items-center" > - + Kdrama Poster

{item.title}

@@ -59,7 +59,7 @@ const KdramaHomepage = async () => { ); return ( -
+
diff --git a/src/app/loading.jsx b/src/app/loading.jsx index 2f12723..2fd3711 100644 --- a/src/app/loading.jsx +++ b/src/app/loading.jsx @@ -2,7 +2,7 @@ import { CircularProgress } from "@nextui-org/react"; const LoadingScreen = async () => { return ( -
+
{ + const { id } = params; + + const data = await MangaInfoResults(id); + + return ( +
+
+
+ {/* header section */} +
+ Manga Poster +
+

+ {data.title.english || data.title.romaji} +

+ {data.genres && + data.genres.map((item, index) => ( + + {item} + + ))} +
+
+ +
+
+
+ ); +}; + +export default MangaInfoPage; diff --git a/src/app/manga/components/chapterPages.jsx b/src/app/manga/components/chapterPages.jsx new file mode 100644 index 0000000..59320fd --- /dev/null +++ b/src/app/manga/components/chapterPages.jsx @@ -0,0 +1,35 @@ +"use server"; + +import { MangaPages } from "./requests"; +import Image from "next/image"; + +const MangaChapters = async (id) => { + const data = await MangaPages(id); + + let chapterPages = []; + for (let items of data.chapter.data) { + chapterPages.push(`${data.baseUrl}/data/${data.chapter.hash}/${items}`); + } + console.log(chapterPages); + + return ( +
+ {chapterPages && + chapterPages.length > 0 && + chapterPages.map((item, index) => ( +
+ Manga Pages +

{index}

+
+ ))} +
+ ); +}; + +export default MangaChapters; diff --git a/src/app/manga/components/descriptionTabs.jsx b/src/app/manga/components/descriptionTabs.jsx new file mode 100644 index 0000000..19191ab --- /dev/null +++ b/src/app/manga/components/descriptionTabs.jsx @@ -0,0 +1,159 @@ +"use client"; + +import { + Tabs, + Tab, + Card, + CardBody, + Divider, + Image, + Select, + SelectItem, +} from "@nextui-org/react"; +import { FaRegThumbsUp, FaRegStar } from "react-icons/fa"; +import Link from "next/link"; +import { useState } from "react"; + +import MangaChapters from "./chapterPages"; + +const MangaDescriptionTabs = ({ data }) => { + const [pages, setPages] = useState(<>); + + async function get_pages(id) { + setPages(

Loading...

); + const data = await MangaChapters(id); + setPages(data); + } + + return ( +
+ + + + + + + + + +

+ Status:{" "} + {data.status || "not sure"} +

+

+ Type:{" "} + {data.type || "not sure"} +

+

+ + Started on + + :{" "} + + {data.startDate.day}-{data.startDate.month}- + {data.startDate.year} + +

+

+ + Ended on + + :{" "} + + {data.endDate.day}-{data.endDate.month}- + {data.endDate.year} + +

+
+
+ +

{data.popularity}

+
+ +
+ +

+ {Number(data.rating) / 10} +

+
+
+
+
+
+ + + + {data.recommendations && + data.recommendations.length > 0 && + data.recommendations.map((item, index) => ( + + + + +

+ {item.title.english || + item.title.romaji} +

+
+
+ + ))} +
+
+
+ + + + +
{pages}
+
+
+
+
+
+ ); +}; + +export default MangaDescriptionTabs; diff --git a/src/app/manga/components/inputContainer.jsx b/src/app/manga/components/inputContainer.jsx new file mode 100644 index 0000000..7526f9a --- /dev/null +++ b/src/app/manga/components/inputContainer.jsx @@ -0,0 +1,116 @@ +"use client"; + +import { + Input, + Progress, + Card, + CardBody, + Image, + Chip, +} from "@nextui-org/react"; +import Link from "next/link"; +import { useState } from "react"; + +import { SearchedMangaResults } from "./requests"; + +const MangaSearchBox = () => { + const [searchedMangaTitle, setMangaSearchedTitle] = useState(""); + const [results, setResults] = useState( +
+

+ Start typing and results will show here +

+
, + ); + const [loading, setLoading] = useState(<>); + + async function GetResults() { + if (!searchedMangaTitle) { + setResults(<>); + return; + } + setLoading( + , + ); + const data = await SearchedMangaResults(searchedMangaTitle); + const format = ( +
+ {data && data.results.length > 0 ? ( + data.results.map((item, index) => ( + + + + +

+ {item.title.english || + item.title.romaji} +

+
+ {item.genres && + item.genres.map((item, index) => ( + + {item} + + ))} +
+
+
+ + )) + ) : ( +

+ No results found for the searched title +

+ )} +
+ ); + setLoading(<>); + setResults(format); + } + return ( +
+
+ { + setMangaSearchedTitle(event.target.value); + }} + onKeyDown={async () => { + await GetResults(); + }} + /> + {loading} + {results} +
+
+ ); +}; + +export default MangaSearchBox; diff --git a/src/app/manga/components/requests.js b/src/app/manga/components/requests.js new file mode 100644 index 0000000..d3d9e9c --- /dev/null +++ b/src/app/manga/components/requests.js @@ -0,0 +1,28 @@ +"use server"; +import { + manga_search_url, + manga_info_url, + manga_chapters_pages, +} from "../../../../utils/manga_urls"; + +export const SearchedMangaResults = async (title) => { + const res = await fetch(manga_search_url(title), { + next: { revalidate: 21600 }, + }); + const data = await res.json(); + return data; +}; + +export const MangaInfoResults = async (id) => { + const res = await fetch(manga_info_url(id), { + next: { revalidate: 21600 }, + }); + const data = await res.json(); + return data; +}; + +export const MangaPages = async (id) => { + const res = await fetch(manga_chapters_pages(id), { cache: "force-cache" }); + const data = await res.json(); + return data; +}; diff --git a/src/app/manga/page.jsx b/src/app/manga/page.jsx new file mode 100644 index 0000000..6992fa7 --- /dev/null +++ b/src/app/manga/page.jsx @@ -0,0 +1,21 @@ +import MangaSearchBox from "./components/inputContainer"; + +const MangaHomePage = async () => { + return ( +
+
+

+ Welcome to
+ + Dramalama-Manga + +

+
+
+ +
+
+ ); +}; + +export default MangaHomePage; diff --git a/src/app/movies/components/searchFormatter.jsx b/src/app/movies/components/searchFormatter.jsx index ded6022..f6a578e 100644 --- a/src/app/movies/components/searchFormatter.jsx +++ b/src/app/movies/components/searchFormatter.jsx @@ -1,5 +1,3 @@ -"use server"; - import { Card, CardHeader, CardBody } from "@nextui-org/react"; import Image from "next/image"; import Link from "next/link"; @@ -8,7 +6,7 @@ import styles from "../../page.module.css"; const MovieSearchFormatter = async (data) => { return (
{data && data.results.map((item, index) => { @@ -18,7 +16,7 @@ const MovieSearchFormatter = async (data) => { key={index} href={`/movies/${item.id}`} aria-label="anime redirection links" - className="flex flex-col items-center mx-1 " + className="mx-1 flex flex-col items-center" > @@ -27,13 +25,13 @@ const MovieSearchFormatter = async (data) => { 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" + className="h-64 rounded-md" priority />

{item.original_title}

diff --git a/src/app/movies/components/videoPlayer.jsx b/src/app/movies/components/videoPlayer.jsx index b7cdd81..154d633 100644 --- a/src/app/movies/components/videoPlayer.jsx +++ b/src/app/movies/components/videoPlayer.jsx @@ -2,7 +2,7 @@ const MovieVideoPlayer = async ({ id: id }) => { const videoFrameGenerator = (id) => { return ( ); }; @@ -28,7 +28,7 @@ const SeriesVideoPlayer = ({ id: id }) => { function renderVideoFrame() { if (seasonNumber === "" || episodeNumber === "") { alert( - "Make sure that you have entered the episode number and the season number." + "Make sure that you have entered the episode number and the season number.", ); return; } @@ -39,7 +39,7 @@ const SeriesVideoPlayer = ({ id: id }) => { return (
{videoFrame} -
+
{ const HomepageDataFormatter = (title, data) => { return (
-

{title}

+

{title}

{data && data.results.map((item, index) => ( @@ -36,22 +36,22 @@ const SeriesHomepage = async () => { key={index} href={`/web-series/${item.id}`} aria-label="anime redirection links" - className="flex flex-col items-center mx-1 " + className="mx-1 flex flex-col items-center" > - + Movie Poster

{item.name}

@@ -65,7 +65,7 @@ const SeriesHomepage = async () => { }; return ( -
+
diff --git a/tailwind.config.js b/tailwind.config.js index ad61c55..f7d82ce 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -17,5 +17,28 @@ module.exports = { extend: {}, }, darkMode: "class", - plugins: [nextui()], + plugins: [ + nextui({ + themes: { + light: { + colors: { + background: "#FFFFFF", // or DEFAULT + foreground: "#11181C", // or 50 to 900 DEFAULT + primary: { + //... 50 to 900 + foreground: "#FFFFFF", + DEFAULT: "#006FEE", + }, + }, + }, + + dark: { + colors: { + background: "#1f1f1f", // or DEFAULT + foreground: "#ECEDEE", // or 50 to 900 DEFAULT + }, + }, + }, + }), + ], }; diff --git a/utils/manga_urls.js b/utils/manga_urls.js new file mode 100644 index 0000000..f45f275 --- /dev/null +++ b/utils/manga_urls.js @@ -0,0 +1,15 @@ +import { PROXY } from "./movie_urls"; + +const base_url = `https://consumet-jade.vercel.app/meta/anilist-manga/`; + +export const manga_search_url = (title) => { + return `${base_url}${title}`; +}; + +export const manga_info_url = (id) => { + return `${base_url}info/${id}?provider=mangadex`; +}; + +export const manga_chapters_pages = (id) => { + return `https://api.mangadex.org/at-home/server/${id}`; +}; -- cgit v1.2.3