Skip to content

Commit 3f61906

Browse files
Merge pull request #3 from hihi-hye/feature/moviedbapi
Feature/moviedbapi
2 parents 110cd3a + f38139e commit 3f61906

File tree

11 files changed

+183
-46
lines changed

11 files changed

+183
-46
lines changed

.github/workflows/github-actions.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Push to another repo to deploy to Vercel
2+
3+
on:
4+
push:
5+
branches: [main, feature/moviedbapi]
6+
7+
jobs:
8+
build:
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
- name: Checkout the repository
13+
uses: actions/checkout@v2
14+
15+
- name: Install dependencies (if needed for build script)
16+
run: |
17+
sudo apt-get update
18+
sudo apt-get install -y ruby
19+
sudo gem install mustache
20+
21+
- name: Run build script
22+
run: sh ./build.sh
23+
24+
- name: Push output to another repository
25+
uses: cpina/github-action-push-to-another-repository@main
26+
env:
27+
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
28+
with:
29+
source-directory: 'output'
30+
destination-github-username: 'hiwon-lee' # <- 여기에 대상 사용자 이름
31+
destination-repository-name: 'next-netflix-20th' # <- 여기에 대상 리포지토리 이름
32+
user-email: ${{ secrets.GIT_EMAIL }}
33+
user-name: ${{ secrets.GIT_USERNAME }}
34+
commit-message: ${{ github.event.commits[0].message }}
35+
target-branch: main
36+
37+
- name: Test the output directory variable
38+
run: echo $DESTINATION_CLONED_DIRECTORY

build.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
cd ./
2+
mkdir output
3+
cp -R ./next-netflix-20th/* ./output
4+
cp -R ./output ./next-netflix-20th/

next.config.mjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ const nextConfig = {
33
compiler: {
44
styledComponents: true,
55
},
6+
env: {
7+
API_KEY: process.env.API_KEY,
8+
API_URL: process.env.API_URL,
9+
IMAGE_BASE_URL: process.env.IMAGE_BASE_URL,
10+
},
611
};
712

813
export default nextConfig;

src/app/home/_components/PlayNav.tsx

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,34 @@
11
import styled from 'styled-components';
22
import NamedButton from '@/components/button/NamedButton';
33
import PlayButton from '@/components/button/PlayButton';
4+
import { MovieProps } from '@/types/MovieProps';
45

5-
const PlayNav = ({ movieInfo }) => {
6+
const PlayNav = ({ movie }: { movie: MovieProps }) => {
67
return (
7-
<Container>
8-
<NamedButton
9-
type="button"
10-
src="/icon/plusIcon.svg"
11-
buttonName="My List"
12-
link="/"
13-
/>
14-
<PlayButton movieInfo={movieInfo} />
15-
<NamedButton
16-
type="button"
17-
src="/icon/infoIcon.svg"
18-
buttonName="Info"
19-
link="/"
20-
/>
21-
</Container>
8+
<>
9+
<TopTen>
10+
<div className="topTenIcon">
11+
<p className="top">Top</p>
12+
<p className="ten">10</p>
13+
</div>
14+
<div className="title">#2 in Nigeria Today</div>
15+
</TopTen>
16+
<Container>
17+
<NamedButton
18+
type="button"
19+
src="/icon/plusIcon.svg"
20+
buttonName="My List"
21+
link="/"
22+
/>
23+
<PlayButton movie={movie} />
24+
<NamedButton
25+
type="button"
26+
src="/icon/infoIcon.svg"
27+
buttonName="Info"
28+
link="/"
29+
/>
30+
</Container>
31+
</>
2232
);
2333
};
2434

@@ -31,3 +41,39 @@ const Container = styled.div`
3141
gap: 3rem;
3242
margin-bottom: 2.5rem;
3343
`;
44+
45+
const TopTen = styled.div`
46+
display: flex;
47+
justify-content: center;
48+
gap: 0.2rem;
49+
margin: 0 auto;
50+
margin-bottom: 1rem;
51+
52+
color: #ffffff;
53+
54+
.title {
55+
font-size: 14px;
56+
}
57+
.topTenIcon {
58+
display: flex;
59+
margin: 0.1rem;
60+
61+
flex-direction: column;
62+
font-size: 13.72px;
63+
font-weight: 700;
64+
text-align: center;
65+
66+
width: 14px;
67+
height: 14px;
68+
border: 1px solid white;
69+
70+
.top {
71+
font-size: 4.36px;
72+
margin: 0;
73+
}
74+
.ten {
75+
font-size: 6.86px;
76+
margin: 0;
77+
}
78+
}
79+
`;

src/app/home/page.tsx

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,53 +8,71 @@ import { SubTitle, Title } from './_components/style';
88
import LargeGradientCard from './_components/LargeGradientCard';
99
import PlayNav from './_components/PlayNav';
1010
import TNB from '@/components/TNB';
11+
import { useEffect, useState } from 'react';
12+
import { MovieProps } from '@/types/MovieProps';
13+
import { fetchMovies } from '@/services/movieApi';
1114

1215
const Home = () => {
13-
const items = [
14-
{ image: '/movie1.jpg', title: 'Movie 1' },
15-
{ image: '/movie2.jpg', title: 'Movie 2' },
16-
{ image: '/movie3.jpg', title: 'Movie 3' },
17-
{ image: '/movie4.jpg', title: 'Movie 4' },
18-
{ image: '/movie5.jpg', title: 'Movie 5' },
19-
];
16+
const IMAGE_BASE_URL = process.env.IMAGE_BASE_URL;
17+
18+
const [movies, setMovies] = useState<MovieProps[]>([]);
19+
const [mainMovie, setMainMovie] = useState<MovieProps | null>(null);
20+
21+
useEffect(() => {
22+
const loadMovies = async () => {
23+
try {
24+
const moviesData = await fetchMovies();
25+
setMovies(moviesData);
26+
setMainMovie(mainMovie || moviesData[1]);
27+
} catch (err) {
28+
console.log(err);
29+
}
30+
};
31+
32+
loadMovies();
33+
}, []);
2034

2135
return (
2236
<ScreenWrapper>
2337
<TNB />
24-
<LargeGradientCard
25-
key={'index'}
26-
image={items[3].image}
27-
title={items[3].title}
28-
></LargeGradientCard>
29-
<PlayNav movieInfo={items[3]} />
38+
{mainMovie && (
39+
<>
40+
<LargeGradientCard
41+
key={'index'}
42+
image={`${IMAGE_BASE_URL}w1280/${mainMovie.poster_path}`}
43+
title={mainMovie.title}
44+
/>
45+
<PlayNav movie={mainMovie} />
46+
</>
47+
)}
3048

3149
<Title>Previews</Title>
3250
<CardContainer>
33-
{items.map((item, index) => (
51+
{movies.map((movie, index) => (
3452
<RoundCard
3553
key={index}
36-
image={item.image}
37-
title={item.title}
54+
image={`${IMAGE_BASE_URL}w1280/${movie.poster_path}`}
55+
title={movie.title}
3856
/>
3957
))}
4058
</CardContainer>
4159
<SubTitle>Continue Watching for Emenalo</SubTitle>
4260
<CardContainer>
43-
{items.map((item) => (
61+
{movies.map((movie) => (
4462
<Card
45-
key={item.title}
46-
image={item.image}
47-
title={item.title}
63+
key={movie.title}
64+
image={`${IMAGE_BASE_URL}w1280/${movie.poster_path}`}
65+
title={movie.title}
4866
/>
4967
))}
5068
</CardContainer>
5169
<SubTitle>Popular on Netflix</SubTitle>
5270
<CardContainer>
53-
{items.map((item) => (
71+
{movies.map((movie) => (
5472
<Card
55-
key={item.title}
56-
image={item.image}
57-
title={item.title}
73+
key={movie.title}
74+
image={`${IMAGE_BASE_URL}w1280/${movie.poster_path}`}
75+
title={movie.title}
5876
/>
5977
))}
6078
</CardContainer>

src/components/button/Button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import styled from 'styled-components';
2-
import { ButtonProps } from './type';
2+
import { ButtonProps } from '@/types/ButtonProps';
33

44
const Button = ({ text, src, type }: ButtonProps) => {
55
return (

src/components/button/NamedButton.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import Link from 'next/link';
22
import styled from 'styled-components';
33
import Button from './Button';
4+
import { ButtonProps } from '@/types/ButtonProps';
45

5-
const NamedButton = ({ type, src, buttonName, link = '/' }) => {
6+
const NamedButton = ({ type, src, buttonName, link = '/' }: ButtonProps) => {
67
return (
78
<Link href={link}>
89
<StyledNamedButton>

src/components/button/PlayButton.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
1+
import { MovieProps } from '@/types/MovieProps';
12
import Link from 'next/link';
23
import styled from 'styled-components';
34

4-
const PlayButton = ({ movieInfo }) => {
5+
// 전역으로 뺀 이유 : 영화 상세페이지에서 길게 또 쓰임
6+
const PlayButton = ({ movie }: { movie: MovieProps }) => {
57
return (
6-
<Link href={movieInfo || '/'}>
8+
<StyledLink href={`/movie/${movie.id}` || '/'}>
79
<StyledPlayButton>
810
<img
911
src="/icon/playIcon.png"
1012
alt="play icon"
1113
/>
1214
<span>Play</span>
1315
</StyledPlayButton>
14-
</Link>
16+
</StyledLink>
1517
);
1618
};
1719

1820
export default PlayButton;
1921

22+
const StyledLink = styled(Link)`
23+
text-decoration: none; // Link 자체에 스타일 적용
24+
`;
2025
const StyledPlayButton = styled.div`
2126
display: flex;
2227
align-items: center;
@@ -36,6 +41,5 @@ const StyledPlayButton = styled.div`
3641
font-size: 20px;
3742
font-weight: bold;
3843
color: black;
39-
text-decoration: none;
4044
}
4145
`;

src/services/movieApi.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { MovieProps } from '@/types/MovieProps';
2+
3+
export const fetchMovies = async (): Promise<MovieProps[]> => {
4+
const API_KEY = process.env.API_KEY;
5+
const API_URL = process.env.API_URL;
6+
7+
const endpoint = `${API_URL}movie/popular?api_key=${API_KEY}&language=en-US&page=1`;
8+
const response = await fetch(endpoint);
9+
10+
const data = await response.json();
11+
return data.results as MovieProps[];
12+
};
File renamed without changes.

0 commit comments

Comments
 (0)