-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[6주차] gotcha팀 미션 제출합니다 #14
base: master
Are you sure you want to change the base?
Changes from all commits
13d5e27
841d111
f7dd432
107d08e
f3ff54d
d8ab520
dc56d11
7f93a87
4726352
565fe63
53de400
f2d34aa
54af881
727764c
7362a46
13a33f7
318f8d9
81e9cdc
fc16c08
839ea3a
5e9e156
185a48f
4ffd269
313ca85
07e4b9a
ef4fb35
a76c3ac
b2f8cd9
10b702f
7da6aeb
ced3a4c
738139f
ecbad8b
f6dcd49
28ac8cf
e4f877f
8ece9e1
583ef41
c355e3c
25f9579
a45a8b3
c5ae4d8
5bb17cd
fcf1a5a
5f7a250
7ae6111
0306120
1737dbc
669f712
cbeca62
4921b42
2fd517b
18b555c
c2407d9
43fc3e9
0e1b447
a741f08
a4c2150
39d7503
3df89f1
5f89f22
3f4c744
826b836
a79e43d
5c1d349
8d3cf17
69a9e71
73e1269
05ea54d
d70af5d
1256228
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": "next/core-web-vitals" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env*.local | ||
.env | ||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import axios from "axios"; | ||
|
||
const BASE_URL = "https://api.themoviedb.org/3/"; | ||
|
||
const api = axios.create({ | ||
baseURL: BASE_URL, | ||
headers: { | ||
"Content-Type": "application/json", | ||
Authorization: `Bearer ` + process.env.NEXT_PUBLIC_AUTH, | ||
Comment on lines
+4
to
+9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. axios 인스턴스 설정 좋네요 ㅎㅎ |
||
}, | ||
}); | ||
|
||
export default api; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import api from "./index"; | ||
|
||
// export async function getMovies(url: string) { | ||
// const res = await fetch(`https://api.themoviedb.org/3/${url}`); | ||
// return res.json(); | ||
// } | ||
|
||
export const getMovies = (url: string) => { | ||
return api.get(url).then((res: any) => res.data); | ||
}; | ||
|
||
export const getImageUrl = (path = "", size = 400) => { | ||
return `https://image.tmdb.org/t/p/w${size}${path}`; | ||
}; | ||
|
||
export const getSearchResults = (searchQuery: string) => { | ||
return api | ||
.get(`https://api.themoviedb.org/3/search/movie?query=${searchQuery}`) | ||
.then((res: any) => res.data); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
'use client'; | ||
import React, { useState, useEffect } from 'react'; | ||
import Image from 'next/image'; | ||
|
||
const Header = () => { | ||
const MENU_LIST = ['TV Shows', 'Movies', 'My List']; | ||
const [scrollPosition, setScrollPosition] = useState(0); | ||
|
||
const handleScroll = () => { | ||
setScrollPosition(window.scrollY); | ||
}; | ||
|
||
useEffect(() => { | ||
window.addEventListener('scroll', handleScroll); | ||
return () => { | ||
window.removeEventListener('scroll', handleScroll); | ||
}; | ||
}, []); | ||
|
||
return ( | ||
<div | ||
className={`fixed top-0 flex justify-between items-center w-full max-w-[450px] h-[57px] px-4 md:px-5 lg:px-6 py-8 pr-8 z-50 transition-all duration-300 ease ${ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tailwind로 바꾸신 점 좋은 것 같습니다:) |
||
scrollPosition > 100 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
? 'bg-black' | ||
: 'bg-gradient-to-b from-[rgba(18, 18, 18, 0.9)] to-[rgba(18, 18, 18, 0)]' | ||
}`} | ||
> | ||
<div> | ||
<Image | ||
src={'/images/netflix-logo.svg'} | ||
width={57} | ||
height={57} | ||
alt="logo" | ||
/> | ||
Comment on lines
+29
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. next/image 를 통해 최적화 하신 점 좋네요 ㅎㅎ |
||
</div> | ||
{MENU_LIST.map((menu) => { | ||
return ( | ||
<span key={menu} className="text-white text-17.2 cursor-pointer"> | ||
{menu} | ||
</span> | ||
); | ||
})} | ||
</div> | ||
); | ||
}; | ||
export default Header; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
"use client"; | ||
|
||
import { useRouter } from "next/navigation"; | ||
import Lottie from "react-lottie-player"; | ||
import netflix from "@/public/netflix_landing.json"; | ||
|
||
const LandingLogo = () => { | ||
const router = useRouter(); | ||
return ( | ||
<Lottie | ||
animationData={netflix} | ||
style={{ width: "100%" }} | ||
play | ||
loop={false} | ||
onComplete={() => router.push("/main")} | ||
/> | ||
); | ||
}; | ||
|
||
export default LandingLogo; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React from "react"; | ||
import Image from "next/image"; | ||
|
||
const MainControlBox = () => { | ||
return ( | ||
<div className="flex flex-col items-center gap-11 pt-2.5 px-11 pb-11 w-full"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Taillwind css 를 잘 적용하시는 거 같아요!!
Comment on lines
+4
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오 tailwind 로 마이그레이션 성공하셨네요 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 축하드립니다 |
||
<div className="flex items-center justify-center"> | ||
<Image src={"/images/topten.svg"} width={15} height={15} alt="topten" /> | ||
<div className="text-white text-13px font-bold line-height-2rem text-center ml-5"> | ||
in Nigeria Today | ||
</div> | ||
</div> | ||
<div className="w-full flex flex-row justify-around"> | ||
<div className="flex flex-col items-center justify-center gap-1 text-white cursor-pointer"> | ||
<Image src={"/images/plus.svg"} width={24} height={24} alt="plus" /> | ||
<span>My List</span> | ||
</div> | ||
|
||
<button className="flex items-center justify-center bg-neutral-300 rounded-md w-28 h-11 gap-2.5 cursor-pointer border-none"> | ||
<Image | ||
src={"/images/play_icon.svg"} | ||
width={24} | ||
height={24} | ||
alt="play_icon" | ||
/> | ||
<span className="font-semibold text-xl">Play</span> | ||
</button> | ||
|
||
<div className="flex flex-col items-center justify-center gap-1 text-white cursor-pointer"> | ||
<Image src={"/images/info.svg"} width={24} height={24} alt="info" /> | ||
<span>Info</span> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
export default MainControlBox; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
"use client"; | ||
import Image from "next/image"; | ||
import { useEffect, useState } from "react"; | ||
import { getImageUrl } from "@/api/movieApi"; | ||
|
||
interface MainImageProps { | ||
data: { | ||
results?: { | ||
id: number; | ||
poster_path: string; | ||
}[]; | ||
}; | ||
} | ||
|
||
const MainImage = ({ data }: MainImageProps) => { | ||
const [randomNum, setRandomNum] = useState(0); | ||
const [opacity, setOpacity] = useState(100); | ||
|
||
const getRandomNum = () => { | ||
setRandomNum(Math.floor(Math.random() * 10) + 1); | ||
}; | ||
|
||
const handleOpacity = () => { | ||
setOpacity(0); | ||
setTimeout(() => setOpacity(100), 500); | ||
}; | ||
|
||
useEffect(() => { | ||
if (randomNum === 0) { | ||
getRandomNum(); | ||
} | ||
const timeout = setTimeout(() => { | ||
setRandomNum(((randomNum + 1) % 3) + 1); | ||
}, 10000); | ||
const timeopacity = setTimeout(() => { | ||
handleOpacity(); | ||
}, 9500); | ||
|
||
return () => { | ||
clearTimeout(timeout); | ||
clearTimeout(timeopacity); | ||
}; | ||
}, [randomNum]); | ||
|
||
return ( | ||
<div className="relative flex justify-center items-start w-full h-3/5 "> | ||
{data?.results && randomNum !== 0 && ( | ||
<img | ||
src={getImageUrl(data?.results[randomNum].poster_path)} | ||
alt="banner_img" | ||
style={{ | ||
width: "100%", | ||
height: "100%", | ||
objectFit: "cover", | ||
opacity: opacity / 100, | ||
transition: "all 0.5s ease-in-out", | ||
}} | ||
/> | ||
)} | ||
<div className="absolute z-10 w-full h-full bg-gradient-to-b from-black via-transparent to-black"></div> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. gradient 적용하신 디테일 좋은 것 같습니다:) |
||
</div> | ||
); | ||
}; | ||
|
||
export default MainImage; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
'use client'; | ||
import React from 'react'; | ||
import { getImageUrl } from '../../api/movieApi'; | ||
import Image from 'next/image'; | ||
import { useRouter } from 'next/navigation'; | ||
|
||
interface MainItemListProps { | ||
title: string; | ||
data: { | ||
results: { | ||
id: number; | ||
poster_path: string; | ||
}[]; | ||
}; | ||
circle: boolean; | ||
} | ||
|
||
const MainItemList = ({ title, data, circle }: MainItemListProps) => { | ||
const router = useRouter(); | ||
const movePage = (id: number) => { | ||
router.push(`/detail/${id}`); | ||
}; | ||
|
||
return ( | ||
<div className="w-full h-full flex flex-col"> | ||
<div className="font-bold text-2xl text-white pb-4">{title}</div> | ||
<div className="flex flex-row justify-between w-full overflow-x-scroll gap-4 scrollbar-none"> | ||
{data.results && | ||
data.results.map((movie) => ( | ||
<div | ||
key={movie.id} | ||
onClick={() => movePage(movie.id)} | ||
className={`min-w-[100px] ${ | ||
circle ? 'h-[100px] rounded-full' : 'h-[150px] rounded-md' | ||
} overflow-hidden relative transition-transform transform scale-100 hover:scale-95 hover:transition-all duration-200 ease-in-out`} | ||
> | ||
<Image | ||
src={getImageUrl(movie.poster_path)} | ||
alt="movie poster" | ||
width={100} | ||
height={circle ? 100 : 161} | ||
loading="eager" | ||
placeholder="blur" | ||
blurDataURL="https://via.placeholder.com/100" | ||
style={{ objectFit: 'cover' }} | ||
/> | ||
</div> | ||
))} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
export default MainItemList; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.env 파일 숨기신 점 잘하신 거 같아요:)