ChandimaPrabath
commited on
Commit
•
3673e75
1
Parent(s):
b10c786
error page
Browse files- frontend/next.config.mjs +22 -2
- frontend/public/404_bg.jpg +0 -0
- frontend/src/app/_error.js +61 -0
- frontend/src/app/globals.css +1 -0
- frontend/src/app/movie/[title]/movie.css +1 -0
- frontend/src/app/movie/[title]/page.js +2 -1
- frontend/src/app/not-found.js +60 -0
- frontend/src/app/player/movie/[title]/page.js +8 -4
- frontend/src/app/tvshows/page.js +2 -8
- frontend/src/components/Header.css +1 -0
- frontend/src/components/Sidebar.css +6 -0
- frontend/src/components/Sidebar.js +4 -4
frontend/next.config.mjs
CHANGED
@@ -1,8 +1,28 @@
|
|
1 |
/** @type {import('next').NextConfig} */
|
2 |
const nextConfig = {
|
3 |
-
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
};
|
7 |
|
8 |
export default nextConfig;
|
|
|
1 |
/** @type {import('next').NextConfig} */
|
2 |
const nextConfig = {
|
3 |
+
images: {
|
4 |
+
dangerouslyAllowSVG: true,
|
5 |
+
remotePatterns: [
|
6 |
+
{
|
7 |
+
protocol: 'https',
|
8 |
+
hostname: 'artworks.thetvdb.com',
|
9 |
+
port: '',
|
10 |
+
pathname: '/**',
|
11 |
},
|
12 |
+
{
|
13 |
+
protocol: 'https',
|
14 |
+
hostname: 'via.placeholder.com',
|
15 |
+
port: '',
|
16 |
+
pathname: '/**',
|
17 |
+
},
|
18 |
+
{
|
19 |
+
protocol: 'https',
|
20 |
+
hostname: 'eu.ui-avatars.com',
|
21 |
+
port: '',
|
22 |
+
pathname: '/api/**',
|
23 |
+
},
|
24 |
+
],
|
25 |
+
},
|
26 |
};
|
27 |
|
28 |
export default nextConfig;
|
frontend/public/404_bg.jpg
ADDED
frontend/src/app/_error.js
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"use client";
|
2 |
+
import Link from "next/link";
|
3 |
+
|
4 |
+
export default function ErrorPage({ errorMessage }) {
|
5 |
+
return (
|
6 |
+
<div style={styles.container}>
|
7 |
+
<h1 style={styles.title}>Something Went Wrong</h1>
|
8 |
+
<p style={styles.message}>{errorMessage}</p>
|
9 |
+
<Link href="/" style={styles.link}>
|
10 |
+
Go Home
|
11 |
+
</Link>
|
12 |
+
</div>
|
13 |
+
);
|
14 |
+
}
|
15 |
+
|
16 |
+
const styles = {
|
17 |
+
container: {
|
18 |
+
position: 'absolute',
|
19 |
+
display: 'flex',
|
20 |
+
flexDirection: 'column',
|
21 |
+
alignItems: 'center',
|
22 |
+
justifyContent: 'center',
|
23 |
+
height: '100dvh',
|
24 |
+
width:'100dvw',
|
25 |
+
top:'0',
|
26 |
+
textAlign: 'center',
|
27 |
+
color: 'white',
|
28 |
+
padding: '20px',
|
29 |
+
overflow: 'hidden',
|
30 |
+
},
|
31 |
+
overlay: {
|
32 |
+
position: "absolute",
|
33 |
+
top: 0,
|
34 |
+
left: 0,
|
35 |
+
right: 0,
|
36 |
+
bottom: 0,
|
37 |
+
background: 'url("/404_bg.jpg") no-repeat center center/cover',
|
38 |
+
filter: "blur(5px)",
|
39 |
+
zIndex: -1, // Sends the overlay behind the text
|
40 |
+
},
|
41 |
+
title: {
|
42 |
+
fontSize: "3rem",
|
43 |
+
fontWeight: "bold",
|
44 |
+
color: "#ff4747",
|
45 |
+
},
|
46 |
+
message: {
|
47 |
+
fontSize: "1.5rem",
|
48 |
+
margin: "20px 0",
|
49 |
+
},
|
50 |
+
link: {
|
51 |
+
marginTop: "20px",
|
52 |
+
padding: "12px 20px",
|
53 |
+
backgroundColor: "var(--bg-primary)", // Semi-transparent red
|
54 |
+
color: "white",
|
55 |
+
textDecoration: "none",
|
56 |
+
borderRadius: "5px",
|
57 |
+
border: "2px solid var(--primary-special-color)",
|
58 |
+
transition: "background-color 0.3s ease",
|
59 |
+
boxShadow: "0 4px 8px rgba(0, 0, 0, 0.5)",
|
60 |
+
},
|
61 |
+
};
|
frontend/src/app/globals.css
CHANGED
@@ -7,6 +7,7 @@
|
|
7 |
:root {
|
8 |
--bg-primary: #11121f;
|
9 |
--bg-secondary: #0c0c16;
|
|
|
10 |
}
|
11 |
|
12 |
body {
|
|
|
7 |
:root {
|
8 |
--bg-primary: #11121f;
|
9 |
--bg-secondary: #0c0c16;
|
10 |
+
--primary-special-color:#5454ff;
|
11 |
}
|
12 |
|
13 |
body {
|
frontend/src/app/movie/[title]/movie.css
CHANGED
@@ -196,6 +196,7 @@
|
|
196 |
.movie-genre-list {
|
197 |
list-style-type: none;
|
198 |
padding: 0;
|
|
|
199 |
display: flex;
|
200 |
text-align: center;
|
201 |
justify-content: center;
|
|
|
196 |
.movie-genre-list {
|
197 |
list-style-type: none;
|
198 |
padding: 0;
|
199 |
+
margin: 0;
|
200 |
display: flex;
|
201 |
text-align: center;
|
202 |
justify-content: center;
|
frontend/src/app/movie/[title]/page.js
CHANGED
@@ -12,6 +12,7 @@ import { faBookmark as faBookmarkRegular } from "@fortawesome/free-regular-svg-i
|
|
12 |
import apiClient from "@/api/apiClient";
|
13 |
import { Spinner } from "@/components/Spinner";
|
14 |
import CastSection from "@/components/CastSection";
|
|
|
15 |
|
16 |
export default function MovieDetailsPage({ params }) {
|
17 |
const [metadata, setMetadata] = useState(null);
|
@@ -46,7 +47,7 @@ export default function MovieDetailsPage({ params }) {
|
|
46 |
}
|
47 |
|
48 |
if (error) {
|
49 |
-
return <
|
50 |
}
|
51 |
|
52 |
const englishTitle =
|
|
|
12 |
import apiClient from "@/api/apiClient";
|
13 |
import { Spinner } from "@/components/Spinner";
|
14 |
import CastSection from "@/components/CastSection";
|
15 |
+
import NotFound from "@/app/not-found";
|
16 |
|
17 |
export default function MovieDetailsPage({ params }) {
|
18 |
const [metadata, setMetadata] = useState(null);
|
|
|
47 |
}
|
48 |
|
49 |
if (error) {
|
50 |
+
return <NotFound/>;
|
51 |
}
|
52 |
|
53 |
const englishTitle =
|
frontend/src/app/not-found.js
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import Link from 'next/link'
|
2 |
+
|
3 |
+
export default function NotFound() {
|
4 |
+
return (
|
5 |
+
<div style={styles.container}>
|
6 |
+
<div style={styles.overlay}></div>
|
7 |
+
<h2 style={styles.title}>Whoops!</h2>
|
8 |
+
<p style={styles.message}>Sorry, the page you're looking for doesn't exist.</p>
|
9 |
+
<Link href="/" style={styles.link}>Go Home</Link>
|
10 |
+
</div>
|
11 |
+
)
|
12 |
+
}
|
13 |
+
|
14 |
+
const styles = {
|
15 |
+
container: {
|
16 |
+
position: 'absolute',
|
17 |
+
display: 'flex',
|
18 |
+
flexDirection: 'column',
|
19 |
+
alignItems: 'center',
|
20 |
+
justifyContent: 'center',
|
21 |
+
height: '100dvh',
|
22 |
+
width:'100dvw',
|
23 |
+
top:'0',
|
24 |
+
textAlign: 'center',
|
25 |
+
color: 'white',
|
26 |
+
padding: '20px',
|
27 |
+
overflow: 'hidden',
|
28 |
+
},
|
29 |
+
overlay: {
|
30 |
+
position: 'absolute',
|
31 |
+
top: 0,
|
32 |
+
left: 0,
|
33 |
+
right: 0,
|
34 |
+
bottom: 0,
|
35 |
+
background: 'url("/404_bg.jpg") no-repeat center center/cover',
|
36 |
+
filter: 'blur(5px)',
|
37 |
+
zIndex: -1, // Sends the overlay behind the text
|
38 |
+
},
|
39 |
+
title: {
|
40 |
+
fontSize: '3rem',
|
41 |
+
fontWeight: 'bold',
|
42 |
+
textShadow: '2px 2px 4px rgba(0, 0, 0, 0.7)',
|
43 |
+
},
|
44 |
+
message: {
|
45 |
+
fontSize: '1.5rem',
|
46 |
+
margin: '20px 0',
|
47 |
+
textShadow: '1px 1px 3px rgba(0, 0, 0, 0.7)',
|
48 |
+
},
|
49 |
+
link: {
|
50 |
+
marginTop: '20px',
|
51 |
+
padding: '12px 20px',
|
52 |
+
backgroundColor: 'var(--bg-primary)', // Semi-transparent red
|
53 |
+
color: 'white',
|
54 |
+
textDecoration: 'none',
|
55 |
+
borderRadius: '5px',
|
56 |
+
border: '2px solid var(--primary-special-color)',
|
57 |
+
transition: 'background-color 0.3s ease',
|
58 |
+
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.5)',
|
59 |
+
},
|
60 |
+
}
|
frontend/src/app/player/movie/[title]/page.js
CHANGED
@@ -6,6 +6,8 @@ import "./MoviePlayerPage.css";
|
|
6 |
import { Spinner } from "@/components/Spinner";
|
7 |
import { ProgressBar, Container, Row, Col, Alert } from "react-bootstrap";
|
8 |
import "bootstrap/dist/css/bootstrap.min.css";
|
|
|
|
|
9 |
|
10 |
const DEBUG = false; // Set to true to enable debug mode
|
11 |
|
@@ -118,15 +120,17 @@ export default function FilmPlayer({ params }) {
|
|
118 |
<Spinner />
|
119 |
</div>
|
120 |
)}
|
121 |
-
{error
|
|
|
|
|
|
|
|
|
122 |
{downloadProgressUrl && downloadProgress ? (
|
123 |
<div className="download-status">
|
124 |
<Alert variant="info">
|
125 |
<strong>{downloadProgress.status}</strong> -{" "}
|
126 |
{downloadProgress.progress.toFixed(2)}%{" "}
|
127 |
-
<p>
|
128 |
-
Wait for {downloadProgress.eta.toFixed(1)} Seconds
|
129 |
-
</p>
|
130 |
</Alert>
|
131 |
</div>
|
132 |
) : (
|
|
|
6 |
import { Spinner } from "@/components/Spinner";
|
7 |
import { ProgressBar, Container, Row, Col, Alert } from "react-bootstrap";
|
8 |
import "bootstrap/dist/css/bootstrap.min.css";
|
9 |
+
import NotFound from "@/app/not-found";
|
10 |
+
import ErrorPage from "@/app/_error";
|
11 |
|
12 |
const DEBUG = false; // Set to true to enable debug mode
|
13 |
|
|
|
120 |
<Spinner />
|
121 |
</div>
|
122 |
)}
|
123 |
+
{error === "Failed to fetch movie card" ? (
|
124 |
+
<NotFound />
|
125 |
+
) : error && (
|
126 |
+
<ErrorPage errorMessage={error} />
|
127 |
+
)}
|
128 |
{downloadProgressUrl && downloadProgress ? (
|
129 |
<div className="download-status">
|
130 |
<Alert variant="info">
|
131 |
<strong>{downloadProgress.status}</strong> -{" "}
|
132 |
{downloadProgress.progress.toFixed(2)}%{" "}
|
133 |
+
<p>Wait for {downloadProgress.eta.toFixed(1)} Seconds</p>
|
|
|
|
|
134 |
</Alert>
|
135 |
</div>
|
136 |
) : (
|
frontend/src/app/tvshows/page.js
CHANGED
@@ -1,14 +1,8 @@
|
|
1 |
-
import
|
2 |
import './TvShows.css';
|
3 |
|
4 |
export default function TVShows() {
|
5 |
return (
|
6 |
-
|
7 |
-
<div className="page-container">
|
8 |
-
<h1>TV Shows</h1>
|
9 |
-
<p className='text-white'>Browse our TV show collection.</p>
|
10 |
-
<Spinner/>
|
11 |
-
</div>
|
12 |
-
</>
|
13 |
);
|
14 |
}
|
|
|
1 |
+
import NotFound from '../not-found';
|
2 |
import './TvShows.css';
|
3 |
|
4 |
export default function TVShows() {
|
5 |
return (
|
6 |
+
<NotFound/>
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
);
|
8 |
}
|
frontend/src/components/Header.css
CHANGED
@@ -38,4 +38,5 @@
|
|
38 |
padding: 15px;
|
39 |
padding-right: 25px;
|
40 |
position: absolute;
|
|
|
41 |
}
|
|
|
38 |
padding: 15px;
|
39 |
padding-right: 25px;
|
40 |
position: absolute;
|
41 |
+
color: white;
|
42 |
}
|
frontend/src/components/Sidebar.css
CHANGED
@@ -57,6 +57,7 @@
|
|
57 |
.sidebar-title {
|
58 |
font-size: 1.25rem;
|
59 |
margin-left: 16px;
|
|
|
60 |
white-space: nowrap;
|
61 |
}
|
62 |
|
@@ -116,4 +117,9 @@
|
|
116 |
font-size: 0.875rem;
|
117 |
font-weight: 500;
|
118 |
margin-left: 10px;
|
|
|
|
|
|
|
|
|
|
|
119 |
}
|
|
|
57 |
.sidebar-title {
|
58 |
font-size: 1.25rem;
|
59 |
margin-left: 16px;
|
60 |
+
margin-bottom: 0;
|
61 |
white-space: nowrap;
|
62 |
}
|
63 |
|
|
|
117 |
font-size: 0.875rem;
|
118 |
font-weight: 500;
|
119 |
margin-left: 10px;
|
120 |
+
}
|
121 |
+
|
122 |
+
|
123 |
+
.sidebar-svg{
|
124 |
+
color: white !important;
|
125 |
}
|
frontend/src/components/Sidebar.js
CHANGED
@@ -9,12 +9,12 @@ import {
|
|
9 |
faBars,
|
10 |
faCogs,
|
11 |
faHome,
|
12 |
-
faStar,
|
13 |
faTv,
|
14 |
faFilm,
|
15 |
faBookBookmark,
|
16 |
faCodeCommit,
|
17 |
faBook,
|
|
|
18 |
} from "@fortawesome/free-solid-svg-icons";
|
19 |
import config from "@/lib/config";
|
20 |
|
@@ -115,12 +115,12 @@ const Sidebar = () => {
|
|
115 |
<SidebarItem icon={faTv} text="TV Shows" />
|
116 |
</Link>
|
117 |
<Link
|
118 |
-
href="/
|
119 |
-
className={`sidebar-link ${pathname === "/
|
120 |
onMouseEnter={handleMouseEnter}
|
121 |
onMouseLeave={handleMouseLeave}
|
122 |
>
|
123 |
-
<SidebarItem icon={
|
124 |
</Link>
|
125 |
<Link
|
126 |
href="/mylist"
|
|
|
9 |
faBars,
|
10 |
faCogs,
|
11 |
faHome,
|
|
|
12 |
faTv,
|
13 |
faFilm,
|
14 |
faBookBookmark,
|
15 |
faCodeCommit,
|
16 |
faBook,
|
17 |
+
faCubes,
|
18 |
} from "@fortawesome/free-solid-svg-icons";
|
19 |
import config from "@/lib/config";
|
20 |
|
|
|
115 |
<SidebarItem icon={faTv} text="TV Shows" />
|
116 |
</Link>
|
117 |
<Link
|
118 |
+
href="/genre"
|
119 |
+
className={`sidebar-link ${pathname === "/genre" ? "active" : ""}`}
|
120 |
onMouseEnter={handleMouseEnter}
|
121 |
onMouseLeave={handleMouseLeave}
|
122 |
>
|
123 |
+
<SidebarItem icon={faCubes} text="Categories" />
|
124 |
</Link>
|
125 |
<Link
|
126 |
href="/mylist"
|