티스토리 뷰
1. Home.tsx
import styled from "styled-components";
import { Link } from "react-router-dom";
const Wrapper = styled.div`
background-color: ${(props) => props.theme.black.darker};
width: 100vw;
height: 210vh;
display: flex;
flex-direction: column;
`;
const Poster = styled.section`
width: 100vw;
height: 70vh;
background-size: cover;
background-position: center center;
display: flex;
flex-direction: column;
justify-content: center;
`;
const Introduction = styled.section`
width: 40%;
height: 80%;
overflow: hidden;
display: flex;
flex-direction: column;
padding: 10px;
background-color: rgba(73, 85, 121, 0.2);
border-radius: 20px;
`;
const IntroductionTitle = styled.h1`
font-size: 55px;
font-weight: bold;
color: #a4a4a4;
margin-bottom: 5px;
`;
const IntroductionOverview = styled.p`
font-size: 30px;
font-weight: 300;
color: #a4a4a4;
`;
const PageBtn = styled.div`
background-color: ${(props) => props.theme.black.lighter};
width: 30%;
height: 35%;
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 20px;
&:hover {
background-color: ${(props) => props.theme.black.darker};
}
`;
function Home() {
return (
<Wrapper>
<Poster
style={{
alignItems: "end",
marginTop: "50px",
backgroundImage: `linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 1)), url(https://cdn.pixabay.com/photo/2020/12/28/20/45/frozen-lake-5868472_1280.jpg)`,
}}
>
<Introduction style={{ marginRight: "50px" }}>
<IntroductionTitle>영화, TV 정보를 한눈에!</IntroductionTitle>
<IntroductionOverview style={{ height: "80vh" }}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum
ut pretium metus. Suspendisse potenti. Phasellus eu hendrerit metus.
Maecenas fermentum ante auctor ligula tincidunt sagittis. Morbi
aliquet metus vel augue porttitor cursus sit amet vitae libero. Ut
blandit pharetra augue id vestibulum.
</IntroductionOverview>
</Introduction>
</Poster>
<Poster
style={{
alignItems: "start",
backgroundImage: `linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 1)), url(https://cdn.pixabay.com/photo/2022/12/30/10/47/typewriter-7686633_1280.jpg)`,
}}
>
<Introduction style={{ marginLeft: "50px" }}>
<IntroductionTitle>영화 확인하기</IntroductionTitle>
<IntroductionOverview style={{ height: "100vh" }}>
Ut suscipit, nisi non eleifend bibendum, purus erat pulvinar augue,
convallis efficitur massa leo molestie purus. Curabitur nec mauris
ullamcorper, vulputate turpis nec, tristique neque. Praesent
euismod, erat quis tincidunt maximus, nisi elit aliquet risus, non
ultricies nisl purus et ex. Aliquam non est risus.
</IntroductionOverview>
<PageBtn>
<Link to="/movies">Movie</Link>
</PageBtn>
</Introduction>
</Poster>
<Poster
style={{
alignItems: "end",
backgroundImage: `linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 1)),url(https://cdn.pixabay.com/photo/2022/12/28/21/10/night-7683839_1280.jpg)`,
}}
>
<Introduction style={{ marginRight: "50px" }}>
<IntroductionTitle>TV 확인하기</IntroductionTitle>
<IntroductionOverview style={{ height: "100vh" }}>
Morbi a mollis nibh. Pellentesque felis libero, sodales finibus
augue sit amet, consequat lacinia ante. Duis in ligula vel purus
facilisis viverra. Sed rutrum lacus a mauris molestie, eu pharetra
est eleifend. Cras eget purus ac quam fringilla congue.
</IntroductionOverview>
<PageBtn>
<Link to="/tvs">Tv</Link>
</PageBtn>
</Introduction>
</Poster>
</Wrapper>
);
}
export default Home;
홈화면은 크게 3가지 영역으로 나누었다. 우선, 가장 윗 부분은 이 웹사이트의 간단한 소개글을 보여준다. 그리고 두 번째 부분은 영화 정보를 확인할 수 있는 부분이며 마지막 부분은 tv 정보를 확인할 수 있는 부분이다. 그런데 각 부분의 title의 밑에는 영어로 이상한 글이 작성되어 있는데, 각 영역의 소개글을 뭐라고 작성해야할지 잘 몰라 임시로 로렘 입숨을 이용하였다. 또한 영역의 이미지는 copyfree 이미지를 이용하였다.
2. latest.tsx
import { useQuery } from "react-query";
import styled from "styled-components";
import { getLatestMovie, getLatestTv, ILatestMovie, ILatestTv } from "../api";
import { makeImagePath } from "../utils";
const Wrapper = styled.div`
background: black;
padding-bottom: 200px;
`;
const Loader = styled.div`
height: 20vh;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
font-weight: bold;
margin-top: 50px;
`;
const LatestMedia = styled.section`
width: 80vw;
height: 80vh;
border-radius: 50px;
background-color: #282a3a;
margin-bottom: 100px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
`;
const LatestNoPoster = styled.section`
width: 65%;
height: 90%;
background-color: #1a120b;
display: flex;
justify-content: center;
align-items: center;
border-radius: 20px;
font-size: 100px;
font-weight: bold;
`;
const LatestMediaPoster = styled.section<{ bgphoto: string }>`
width: 65%;
height: 90%;
background-image: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 1)),
url(${(props) => props.bgphoto});
background-size: cover;
background-position: center;
border-radius: 20px;
`;
const LatestMediaInfos = styled.section`
width: 25%;
height: 90%;
background-color: #d8d8d8;
border-radius: 20px;
margin-left: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10px;
color: #182747;
`;
const Title = styled.p`
font-size: 35px;
font-weight: bold;
margin-bottom: 10px;
`;
const Overview = styled.p`
font-size: 15px;
text-align: center;
margin-bottom: 10px;
`;
const Genres = styled.section`
width: 100%;
display: flex;
justify-content: center;
margin-bottom: 10px;
`;
const OtherInfo = styled.p`
font-size: 20px;
font-weight: bold;
margin-bottom: 10px;
`;
const Genre = styled.span``;
export default function Latest() {
const { data: latestMovie, isLoading: latestMovieLoading } =
useQuery<ILatestMovie>("latestMove", getLatestMovie);
const { data: latestTv, isLoading: latestTvLoading } = useQuery<ILatestTv>(
"latestTv",
getLatestTv
);
return (
<Wrapper
style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
{latestMovieLoading || latestTvLoading ? (
<Loader>Loading...</Loader>
) : (
<>
<LatestMedia style={{ marginTop: "100px" }}>
{latestMovie.backdrop_path ? (
<LatestMediaPoster
bgphoto={makeImagePath(latestMovie.backdrop_path)}
></LatestMediaPoster>
) : (
<LatestNoPoster>No Poster</LatestNoPoster>
)}
<LatestMediaInfos>
<Title>{latestMovie.title}</Title>
<Overview>
{latestMovie.overview
? latestMovie.overview.length > 100
? latestMovie.overview.slice(0, 100) + "..."
: latestMovie.overview
: "No Overview"}
</Overview>
<Genres>
{latestMovie.genres.length === 0 ? (
<p>No Genre Info</p>
) : (
latestMovie.genres.map((genre) => (
<Genre>{`✺ ${genre.name} `}</Genre>
))
)}
</Genres>
<OtherInfo>{`Status: ${latestMovie.status}`}</OtherInfo>
<OtherInfo>{`Laugnage: ${latestMovie.original_language}`}</OtherInfo>
<OtherInfo>{`Popularity: ${latestMovie.popularity}`}</OtherInfo>
<OtherInfo>{`Vote Average: ${latestMovie.vote_average}`}</OtherInfo>
</LatestMediaInfos>
</LatestMedia>
<LatestMedia>
{latestTv.backdrop_path ? (
<LatestMediaPoster
bgphoto={makeImagePath(latestTv.backdrop_path)}
></LatestMediaPoster>
) : (
<LatestNoPoster>No Poster</LatestNoPoster>
)}
<LatestMediaInfos>
<Title>{latestTv.name}</Title>
<Overview>
{latestTv.overview
? latestTv.overview.length > 100
? latestTv.overview.slice(0, 100) + "..."
: latestTv.overview
: "No Overview"}
</Overview>
<Genres>
{latestTv.genres.length === 0 ? (
<p>No Genre Info</p>
) : (
latestTv.genres.map((genre) => (
<Genre>{`✺ ${genre.name} `}</Genre>
))
)}
</Genres>
<OtherInfo>{`Status: ${latestTv.status}`}</OtherInfo>
<OtherInfo>{`Laugnage: ${latestTv.original_language}`}</OtherInfo>
<OtherInfo>{`Popularity: ${latestTv.popularity}`}</OtherInfo>
<OtherInfo>{`Vote Average: ${latestTv.vote_average}`}</OtherInfo>
</LatestMediaInfos>
</LatestMedia>
</>
)}
</Wrapper>
);
}
개인적으로 가장 부끄러운 부분이다. 도대체 어떻게 해야 예쁘게 보여줄 수 있을지 수많은 고민을 했지만, 도저히 생각이 나지 않아 우선 위처럼 표현하였다. 작품의 포스터 이미지의 path가 없을 경우 "No Poster"를 보여준다.
- const { data: latestMovie, isLoading: latestMovieLoading } = useQuery("latestMove", getLatestMovie); : useQuery를 이용해 api를 fetch한 후 json화한 latest movie 데이터를 받아온다.
- const { data: latestTv, isLoading: latestTvLoading } = useQuery<ILatestTv>( "latestTv", getLatestTv ); : 위와 같은 방식으로 latest tv 데이터를 받아온다.
- {latestMovieLoading || latestTvLoading ? ( <Loader>Loading...</Loader> ) : ... : 만약 latest movie, latest tv 중 하나라도 로딩 중이라면 Loading...을 보여준다. 만약 둘 다 로딩이 끝났다면 각 데이터를 보여준다.
참고 사이트
'기록' 카테고리의 다른 글
React Movies 기록 - 5. Search (0) | 2023.02.05 |
---|---|
React Movies 기록 - 4. movies, movie (0) | 2023.02.05 |
React Movies 기록 - 2. App, Header, genres (0) | 2023.02.05 |
React Movies 기록 - 1. 개요, 구조 (0) | 2023.02.05 |
기록) GitHub error 해결 과정 (0) | 2023.01.08 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- BFS
- 리액트
- 코드스테이츠
- 브루트포스
- 넥스트js
- 비트마스킹
- 완전탐색
- Redux
- themoviedb
- 백준
- react
- 동적계획법
- async
- CSS
- 스택
- NextJS
- 알고리즘
- 카카오맵
- 순열
- 자바스크립트
- 구현
- 프로그래머스
- 타입스크립트
- 다이나믹프로그래밍
- 햄버거버튼
- typescript
- SQL
- C++
- aws
- Next.js
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
글 보관함