INIT(app): initial commit
- Initialize project structure - Add base configuration
This commit is contained in:
3
services/nextjs/.eslintrc.json
Normal file
3
services/nextjs/.eslintrc.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "next/core-web-vitals"
|
||||
}
|
||||
36
services/nextjs/README.md
Normal file
36
services/nextjs/README.md
Normal file
@@ -0,0 +1,36 @@
|
||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||
5
services/nextjs/app/(movies)/movies/[id]/error.tsx
Normal file
5
services/nextjs/app/(movies)/movies/[id]/error.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
"use client"
|
||||
|
||||
export default function Error(){
|
||||
return <h1>Something broke...</h1>
|
||||
}
|
||||
3
services/nextjs/app/(movies)/movies/[id]/loading.tsx
Normal file
3
services/nextjs/app/(movies)/movies/[id]/loading.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function Loading() {
|
||||
return <h2>Loading a movie :id</h2>;
|
||||
}
|
||||
26
services/nextjs/app/(movies)/movies/[id]/page.tsx
Normal file
26
services/nextjs/app/(movies)/movies/[id]/page.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Suspense } from "react";
|
||||
import MovieInfo from "@/components/movie-info";
|
||||
import VideosInfo from "@/components/movie-videos";
|
||||
import { getMovie } from "@/components/movie-info";
|
||||
|
||||
interface Iparams {
|
||||
params: { id: string };
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params: { id } }: Iparams) {
|
||||
const movie = await getMovie(id);
|
||||
return { title: movie.title };
|
||||
}
|
||||
|
||||
export default async function MovieDetail({ params: { id } }: Iparams) {
|
||||
return (
|
||||
<div>
|
||||
<Suspense fallback={<h1>Loading movie info</h1>}>
|
||||
<MovieInfo id={id} />
|
||||
</Suspense>
|
||||
<Suspense fallback={<h1>Loading videos info</h1>}>
|
||||
<VideosInfo id={id} />
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
3
services/nextjs/app/about-us/page.tsx
Normal file
3
services/nextjs/app/about-us/page.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function AboutUs(){
|
||||
return <div>gfdgd</div>
|
||||
}
|
||||
BIN
services/nextjs/app/favicon.ico
Normal file
BIN
services/nextjs/app/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
18
services/nextjs/app/layout.tsx
Normal file
18
services/nextjs/app/layout.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import "../styles/global.css";
|
||||
import React from "react";
|
||||
import Navigation from "@/components/navigation";
|
||||
|
||||
export const metadata = {
|
||||
title: "movieClone",
|
||||
};
|
||||
|
||||
export default function Layout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>
|
||||
<Navigation></Navigation>
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
30
services/nextjs/app/page.tsx
Normal file
30
services/nextjs/app/page.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import styles from "../styles/home.module.css";
|
||||
import Movie from "@/components/movie";
|
||||
|
||||
const URL = "https://nomad-movies.nomadcoders.workers.dev/movies";
|
||||
|
||||
export const metadata = {
|
||||
title: "Jovies",
|
||||
};
|
||||
|
||||
async function getMovies() {
|
||||
const response = await fetch(URL);
|
||||
const json = await response.json();
|
||||
return json;
|
||||
}
|
||||
|
||||
export default async function HomePage() {
|
||||
const movies = await getMovies();
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
{movies.map((movie: any) => (
|
||||
<Movie
|
||||
key={movie.id}
|
||||
id={movie.id}
|
||||
poster_path={movie.poster_path}
|
||||
title={movie.title}
|
||||
></Movie>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
29
services/nextjs/components/movie-info.tsx
Normal file
29
services/nextjs/components/movie-info.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import styles from "../styles/movie-info.module.css";
|
||||
|
||||
const URL = "https://nomad-movies.nomadcoders.workers.dev/movies";
|
||||
|
||||
export async function getMovie(id: string) {
|
||||
const response = await fetch(`${URL}/${id}`);
|
||||
return response.json();
|
||||
}
|
||||
|
||||
export default async function MovieInfo({ id }: { id: string }) {
|
||||
const movie = await getMovie(id);
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<img
|
||||
src={movie.poster_path}
|
||||
className={styles.poster}
|
||||
alt={movie.title}
|
||||
/>
|
||||
<div className={styles.info}>
|
||||
<h1 className={styles.title}>{movie.title}</h1>
|
||||
<h3>*{movie.vote_average.toFixed(1)}</h3>
|
||||
<p>{movie.overview}</p>
|
||||
<a href={movie.homepage} target={"_blank"}>
|
||||
Homepage →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
25
services/nextjs/components/movie-videos.tsx
Normal file
25
services/nextjs/components/movie-videos.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import styles from "../styles/movie-videos.module.css";
|
||||
|
||||
const URL = "https://nomad-movies.nomadcoders.workers.dev/movies";
|
||||
|
||||
async function getVideos(id: string) {
|
||||
const response = await fetch(`${URL}/${id}/videos`);
|
||||
return response.json();
|
||||
}
|
||||
|
||||
export default async function VideosInfo({ id }: { id: string }) {
|
||||
const videos = await getVideos(id);
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
{videos.map((video: any) => (
|
||||
<iframe
|
||||
key={video.id}
|
||||
src={`https://youtube.com/embed/${video.key}`}
|
||||
title={video.name}
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
24
services/nextjs/components/movie.tsx
Normal file
24
services/nextjs/components/movie.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import styles from "../styles/movie.module.css";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
interface IMovieProps {
|
||||
title: string;
|
||||
id: string;
|
||||
poster_path: string;
|
||||
}
|
||||
|
||||
export default function Movie({ title, id, poster_path }: IMovieProps) {
|
||||
const router = useRouter();
|
||||
const onClick = () => {
|
||||
router.push(`/movies/${id}`);
|
||||
};
|
||||
return (
|
||||
<div className={styles.movie}>
|
||||
<img src={poster_path} alt={title} onClick={onClick} />
|
||||
<Link href={`/movies/${id}`}>{title}</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
23
services/nextjs/components/navigation.tsx
Normal file
23
services/nextjs/components/navigation.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import styles from "../styles/navigation.module.css"
|
||||
|
||||
export default function Navigation() {
|
||||
const path = usePathname();
|
||||
return (
|
||||
<nav className={styles.nav}>
|
||||
<ul>
|
||||
<li>
|
||||
<Link href="/">Home</Link>
|
||||
{path === "/" ? "🔥" : ""}
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/about-us">About Us</Link>
|
||||
{path === "/about-us" ? "🔥" : ""}
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
6
services/nextjs/next.config.mjs
Normal file
6
services/nextjs/next.config.mjs
Normal file
@@ -0,0 +1,6 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
output: 'standalone',
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
5478
services/nextjs/package-lock.json
generated
Normal file
5478
services/nextjs/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
26
services/nextjs/package.json
Normal file
26
services/nextjs/package.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "nextjstutorial",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"next": "14.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.2.3"
|
||||
}
|
||||
}
|
||||
8
services/nextjs/postcss.config.mjs
Normal file
8
services/nextjs/postcss.config.mjs
Normal file
@@ -0,0 +1,8 @@
|
||||
/** @type {import('postcss-load-config').Config} */
|
||||
const config = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
154
services/nextjs/styles/global.css
Normal file
154
services/nextjs/styles/global.css
Normal file
@@ -0,0 +1,154 @@
|
||||
html,
|
||||
body,
|
||||
div,
|
||||
span,
|
||||
applet,
|
||||
object,
|
||||
iframe,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p,
|
||||
blockquote,
|
||||
pre,
|
||||
a,
|
||||
abbr,
|
||||
acronym,
|
||||
address,
|
||||
big,
|
||||
cite,
|
||||
code,
|
||||
del,
|
||||
dfn,
|
||||
em,
|
||||
img,
|
||||
ins,
|
||||
kbd,
|
||||
q,
|
||||
s,
|
||||
samp,
|
||||
small,
|
||||
strike,
|
||||
strong,
|
||||
sub,
|
||||
sup,
|
||||
tt,
|
||||
var,
|
||||
b,
|
||||
u,
|
||||
i,
|
||||
center,
|
||||
dl,
|
||||
dt,
|
||||
dd,
|
||||
ol,
|
||||
ul,
|
||||
li,
|
||||
fieldset,
|
||||
form,
|
||||
label,
|
||||
legend,
|
||||
table,
|
||||
caption,
|
||||
tbody,
|
||||
tfoot,
|
||||
thead,
|
||||
tr,
|
||||
th,
|
||||
td,
|
||||
article,
|
||||
aside,
|
||||
canvas,
|
||||
details,
|
||||
embed,
|
||||
figure,
|
||||
figcaption,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
output,
|
||||
ruby,
|
||||
section,
|
||||
summary,
|
||||
time,
|
||||
mark,
|
||||
audio,
|
||||
video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol,
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote,
|
||||
q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before,
|
||||
blockquote:after,
|
||||
q:before,
|
||||
q:after {
|
||||
content: "";
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
padding-top: 150px;
|
||||
background-color: black;
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
font-family:
|
||||
system-ui,
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
"Segoe UI",
|
||||
Roboto,
|
||||
Oxygen,
|
||||
Ubuntu,
|
||||
Cantarell,
|
||||
"Open Sans",
|
||||
"Helvetica Neue",
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
8
services/nextjs/styles/home.module.css
Normal file
8
services/nextjs/styles/home.module.css
Normal file
@@ -0,0 +1,8 @@
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 25px;
|
||||
max-width: 90%;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
27
services/nextjs/styles/movie-info.module.css
Normal file
27
services/nextjs/styles/movie-info.module.css
Normal file
@@ -0,0 +1,27 @@
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2fr;
|
||||
gap: 50px;
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.poster {
|
||||
border-radius: 20px;
|
||||
max-width: 70%;
|
||||
place-self: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: white;
|
||||
font-size: 36px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 20px;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
19
services/nextjs/styles/movie-videos.module.css
Normal file
19
services/nextjs/styles/movie-videos.module.css
Normal file
@@ -0,0 +1,19 @@
|
||||
.container {
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 20px;
|
||||
margin-top: 100px;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
|
||||
.container iframe {
|
||||
border-radius: 10px;
|
||||
opacity: 0.8;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.container iframe:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
26
services/nextjs/styles/movie.module.css
Normal file
26
services/nextjs/styles/movie.module.css
Normal file
@@ -0,0 +1,26 @@
|
||||
.movie {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr auto;
|
||||
gap: 20px;
|
||||
cursor: pointer;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.movie img {
|
||||
max-width: 100%;
|
||||
min-height: 100%;
|
||||
border-radius: 10px;
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.movie img {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.movie img:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.movie a {
|
||||
text-align: center;
|
||||
}
|
||||
28
services/nextjs/styles/navigation.module.css
Normal file
28
services/nextjs/styles/navigation.module.css
Normal file
@@ -0,0 +1,28 @@
|
||||
.nav{
|
||||
background-color: #2d2d2d;
|
||||
position: fixed;
|
||||
width: 30%;
|
||||
margin: 0 auto;
|
||||
top: 20px;
|
||||
border-radius: 50px;
|
||||
padding: 20px 0px;
|
||||
left: 50%;
|
||||
z-index: 10;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.nav ul {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 50px;
|
||||
}
|
||||
|
||||
.nav ul li {
|
||||
list-style: none;
|
||||
transform: none;
|
||||
transition: all 0.1s ease-in-out;
|
||||
}
|
||||
|
||||
.nav ul li:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
20
services/nextjs/tailwind.config.ts
Normal file
20
services/nextjs/tailwind.config.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { Config } from "tailwindcss";
|
||||
|
||||
const config: Config = {
|
||||
content: [
|
||||
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
|
||||
"gradient-conic":
|
||||
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
export default config;
|
||||
26
services/nextjs/tsconfig.json
Normal file
26
services/nextjs/tsconfig.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user