-
Notifications
You must be signed in to change notification settings - Fork 16
[6주차]레시피지 과제 제출합니다 #15
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
base: master
Are you sure you want to change the base?
Changes from all commits
a58b97c
6c2d57f
24dfc1a
8982f1f
efbf220
735f087
c775be8
f1fdd7d
3d6b5dd
3764624
6f09c84
d3a3261
8b09dea
40962b0
e390301
d847955
59fa31f
568e0ba
a43501a
7421e27
2cea3a2
e4b1457
3802eae
877553f
9bd8e16
c33b39a
079149b
5d131a8
7576a03
8e87385
f80b565
5971bde
509918c
a53bfb4
185fa5b
48562d6
016f64e
e1f308c
7a20431
734aebd
f9f94b7
32f8cca
5c161ae
4145589
608ec8b
22d56b1
d503b29
3d3a3a5
9984f82
43277a2
a8e42d0
20e0f15
1194164
bb2b79d
6d558f1
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,6 @@ | ||
| { | ||
| "trailingComma": "es5", | ||
| "tabWidth": 2, | ||
| "semi": true, | ||
| "singleQuote": true | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| { | ||
| "presets": ["next/babel"], | ||
| "plugins": [ | ||
| [ | ||
| "styled-components", | ||
| { "ssr": true, "displayName": true, "preprocess": false } | ||
| ] | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| { | ||
| "extends": ["next/babel", "next/core-web-vitals"] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # 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* | ||
| .pnpm-debug.log* | ||
|
|
||
| # local env files | ||
| .env*.local | ||
|
|
||
| # vercel | ||
| .vercel | ||
| .env | ||
|
|
||
| # typescript | ||
| *.tsbuildinfo | ||
| next-env.d.ts |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| # NextJS Introduction |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| import React from 'react'; | ||
|
|
||
| import styled from 'styled-components'; | ||
| import Link from 'next/link'; | ||
|
|
||
| const Header = () => { | ||
| return ( | ||
| <HeaderWrapper> | ||
| <Link href={'/home'}> | ||
| <BannerImg src={`/netflix.png`}></BannerImg> | ||
| </Link> | ||
| <Link href={'/tv-shows'}> | ||
| <BannerTag>TV Shows</BannerTag> | ||
| </Link> | ||
| <Link href={'/movies'}> | ||
| <BannerTag>Movies</BannerTag> | ||
| </Link> | ||
| <Link href={'/my-list'}> | ||
| <BannerTag>My List</BannerTag> | ||
| </Link> | ||
| </HeaderWrapper> | ||
| ); | ||
| }; | ||
|
|
||
| const HeaderWrapper = styled.div` | ||
| width: 375px; | ||
| padding: 1.5rem; | ||
|
|
||
| position: relative; | ||
|
|
||
| display: flex; | ||
| justify-content: space-around; | ||
| align-items: center; | ||
|
|
||
| color: white; | ||
|
|
||
| position: fixed; | ||
| `; | ||
|
|
||
| const BannerTag = styled.div` | ||
| color: white; | ||
| font-size: 17.2px; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 0.5rem; | ||
| `; | ||
|
|
||
| const BannerImg = styled.img` | ||
| width: 2.5rem; | ||
| `; | ||
|
|
||
| export default React.memo(Header); | ||
|
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. React.memo !! 말로만 들었는데 사용되는 모습 보고 배워갑니다 ! |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import styled from 'styled-components'; | ||
| import NavBar from './NavBar'; | ||
|
|
||
| export default function Layout({ children }) { | ||
| return ( | ||
| <Container> | ||
| <Content>{children}</Content> | ||
| <NavBar /> | ||
| </Container> | ||
| ); | ||
| } | ||
|
|
||
| const Container = styled.div` | ||
| width: 375px; | ||
| `; | ||
|
|
||
| const Content = styled.div` | ||
| width: 100%; | ||
| height: calc(100vh - 48px); | ||
| `; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| import styled from 'styled-components'; | ||
|
|
||
| export default function MovieModal({ | ||
| backdrop_path, | ||
| title, | ||
| overview, | ||
| name, | ||
| release_date, | ||
| first_air_date, | ||
| vote_average, | ||
| setModalOpen, | ||
| }) { | ||
| return ( | ||
| <Presentation> | ||
| <Wrapper_modal> | ||
| <Modal> | ||
| <Modal_close onClick={() => setModalOpen(false)}>X</Modal_close> | ||
| <Modal_poster | ||
| src={`https://image.tmdb.org/t/p/original/${backdrop_path}`} | ||
| alt="modal__poster-img" | ||
| /> | ||
|
|
||
| <Modal__content> | ||
| <Modal__details> | ||
| {release_date ? release_date : first_air_date} | ||
| </Modal__details> | ||
| <Modal_title>{title ? title : name}</Modal_title> | ||
| <Modal_overview>Rating:{vote_average}</Modal_overview> | ||
| <Modal_overview>{overview}</Modal_overview> | ||
| </Modal__content> | ||
| </Modal> | ||
| </Wrapper_modal> | ||
| </Presentation> | ||
| ); | ||
| } | ||
|
|
||
| const Modal = styled.div` | ||
| position: relative; | ||
| max-width: 500px; | ||
| box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2), | ||
| 0px 5px 8px 0px rgba(0, 0, 0, 0.14), 0px 1px 14px 0px rgba(0, 0, 0, 0.12); | ||
| background: #111; | ||
| overflow: hidden; | ||
| border-radius: 8px; | ||
| transition: all 400ms ease-in-out 2s; | ||
| animation: fadeIn 400ms; | ||
| ::-webkit-scrollbar { | ||
| display: none; | ||
| visibility: hidden; | ||
| } | ||
| -ms-overflow-style: none; /* IE and Edge */ | ||
| scrollbar-width: none; | ||
|
Comment on lines
+37
to
+52
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. 모달기능..! 최근 웹페이지에 정말 자주 사용되는 기능인데 구현할 엄두를 못냈었어요... 레시피지팀의 멋진 모달을 보며.. 배워갑니다 ㅎㅎ |
||
| `; | ||
| const Modal_poster = styled.img` | ||
| width: 100%; | ||
| height: auto; | ||
| `; | ||
|
|
||
| const Modal__content = styled.div` | ||
| padding: 40px; | ||
| color: white; | ||
| `; | ||
| const Modal_title = styled.h2` | ||
| padding: 0; | ||
| font-size: 40px; | ||
| margin: 16px 0; | ||
| `; | ||
|
|
||
| const Modal__details = styled.p` | ||
| font-weight: 600; | ||
| font-size: 18px; | ||
| `; | ||
|
|
||
| const Modal_overview = styled.p` | ||
| font-size: 20px; | ||
| line-height: 1.5; | ||
| `; | ||
|
|
||
| const Modal_close = styled.span` | ||
| position: absolute; | ||
| right: 20px; | ||
| top: 20px; | ||
| cursor: pointer; | ||
| z-index: 1000; | ||
| color: white; | ||
| `; | ||
|
|
||
| const Presentation = styled.div` | ||
| z-index: 500; | ||
| position: absolute; | ||
| `; | ||
|
|
||
| const Wrapper_modal = styled.div` | ||
| position: fixed; | ||
| inset: 0px; | ||
| background-color: rgb(0 0 0 / 71%); | ||
| -webkit-tap-highlight-color: transparent; | ||
| display: flex; | ||
| justify-content: center; | ||
| `; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import Head from 'next/head'; | ||
|
|
||
| export default function MyHead({ title }) { | ||
| return ( | ||
| <Head> | ||
| <title>{title} | Next Movies</title> | ||
|
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. 헤드 이름도 변경하게 한 부분.. 디테일 너무 잘 살려주신 것 같아요 ㅎㅎ |
||
| </Head> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| import React from 'react'; | ||
| import styled from 'styled-components'; | ||
| import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; | ||
| import { | ||
| faHouse, | ||
| faMagnifyingGlass, | ||
| faPlay, | ||
| faArrowDown, | ||
| faBars, | ||
| } from '@fortawesome/free-solid-svg-icons'; | ||
|
|
||
| import Link from 'next/link'; | ||
| import { useRouter } from 'next/router'; | ||
|
|
||
| const NavBar = () => { | ||
| const router = useRouter(); | ||
| return ( | ||
| <Nav> | ||
| <Container> | ||
| <Link href="/home"> | ||
| <NavItem current={router.pathname === '/home'}> | ||
| <FontAwesomeIcon icon={faHouse} size={'1x'} /> | ||
| <NavText>Home</NavText> | ||
| </NavItem> | ||
| </Link> | ||
| <Link href="/search"> | ||
| <NavItem current={router.pathname === '/search'}> | ||
| <FontAwesomeIcon icon={faMagnifyingGlass} size={'1x'} /> | ||
| <NavText>Search</NavText> | ||
| </NavItem> | ||
| </Link> | ||
| <Link href="/comming-soon"> | ||
| <NavItem current={router.pathname === '/comming-soon'}> | ||
| <FontAwesomeIcon icon={faPlay} size={'1x'} /> | ||
| <NavText>Comming Soon</NavText> | ||
| </NavItem> | ||
| </Link> | ||
| <Link href="/downloads"> | ||
| <NavItem current={router.pathname === '/downloads'}> | ||
| <FontAwesomeIcon icon={faArrowDown} size={'1x'} /> | ||
|
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. size 값이 1x 로 반복되는데 기본값으로 설정하는 것도 나쁘지 않을 것 같습니다 ! |
||
| <NavText>Downloads</NavText> | ||
| </NavItem> | ||
| </Link> | ||
| <Link href="/menu"> | ||
| <NavItem current={router.pathname === '/menu'}> | ||
| <FontAwesomeIcon icon={faBars} size={'1x'} /> | ||
| <NavText>More</NavText> | ||
| </NavItem> | ||
| </Link> | ||
| </Container> | ||
| </Nav> | ||
| ); | ||
| }; | ||
|
|
||
| const Nav = styled.nav` | ||
| width: 375px; | ||
| height: 48px; | ||
|
|
||
| position: fixed; | ||
| bottom: 0; | ||
| `; | ||
|
|
||
| const Container = styled.div` | ||
| width: 100%; | ||
| height: 100%; | ||
|
|
||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| gap: 2.5rem; | ||
|
|
||
| background: #121212; | ||
| `; | ||
|
|
||
| const NavItem = styled.div` | ||
| display: flex; | ||
| flex-direction: column; | ||
| align-items: center; | ||
| gap: 5px; | ||
| color: ${(props) => props.current && 'white'}; | ||
| `; | ||
|
|
||
| const NavText = styled.div` | ||
| font-family: 'SF Pro Display'; | ||
| font-style: normal; | ||
| font-weight: 500; | ||
| font-size: 8.2px; | ||
| `; | ||
|
|
||
| export default NavBar; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import styled from 'styled-components'; | ||
|
|
||
| export default function Wrapper({ children }) { | ||
| return <Container>{children}</Container>; | ||
| } | ||
|
|
||
| const Container = styled.div` | ||
| width: 375px; | ||
| height: 100vh; | ||
| margin-right: 30rem; | ||
|
|
||
| display: flex; | ||
| flex-direction: column; | ||
| align-items: center; | ||
|
|
||
| @media screen and (max-width: 767px) { | ||
| margin-right: 5.5rem; | ||
| } | ||
|
|
||
| `; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| import { useState } from 'react'; | ||
|
|
||
| export default function useInput() { | ||
| const [search, setSearchValue] = useState(''); | ||
| const [searches, setSearchResults] = useState(''); | ||
| const NEXT_PUBLIC_API_KEY = process.env.NEXT_PUBLIC_API_KEY; | ||
|
|
||
| const handleChange = (e) => { | ||
| if (!e.target.value) { | ||
| resetChat(); | ||
| } else { | ||
| setSearchValue(e.target.value); | ||
| tryOut(e); | ||
| } | ||
| }; | ||
|
|
||
| const resetChat = () => { | ||
| setSearchValue(''); | ||
| setSearchResults(''); | ||
| }; | ||
|
|
||
| const tryOut = async (e) => { | ||
| e.preventDefault(); | ||
|
|
||
| const movies = await ( | ||
| await fetch( | ||
| `https://api.themoviedb.org/3/search/movie?api_key=${NEXT_PUBLIC_API_KEY}&language=en-US&query=${e.target.value}&include_adult=false` | ||
| ) | ||
| ).json(); | ||
| setSearchResults(movies); | ||
| }; | ||
|
|
||
| return { search, handleChange, resetChat, searches, tryOut }; | ||
| } |
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.
헤더 버튼을 눌렀을때의 기능..! 저도 구현해보고싶다고 생각만 했었는데 직접 실천에 옮기신 분이 계셨더니.. 존경합니다