개발자 박가나
[241106 TIL] 본캠프 26일차 ('포켓몬 도감 만들기' 프로젝트 1일차) 본문
📌 오늘의 TIL
|
[포켓몬 도감] 프로젝트
프로젝트 셋업
vite를 사용해서 프로젝트를 셋업해준다.
yarn create vite [폴더명] --template react
디자인 및 퍼블리싱
styled-components 라이브러리를 이용해서 스타일을 적용시켜 주었다.
- 페이지
/* Home.jsx */
import { useNavigate } from 'react-router-dom';
import styled from 'styled-components';
import Button from '../components/Button';
const Wrap = styled.div`
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 20px;
`;
const Logo = styled.img`
width: 90vw;
max-width: 600px;
`;
export default function Home() {
const navigate = useNavigate();
return (
<Wrap>
<Logo src="src/assets/logo.png" alt="logo" />
<Button background="red" label="포켓몬 도감 시작하기" handleClick={() => navigate('/dex')} />
</Wrap>
);
}
/* Dex.jsx */
import styled from 'styled-components';
import Dashboard from '../components/Dashboard';
import PokemonList from '../components/PokemonList';
import MOCK_DATA from '../Data';
const Wrap = styled.div`
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
margin: 20px;
`;
export default function Dex() {
return (
<Wrap>
<Dashboard />
<PokemonList data={MOCK_DATA} />
</Wrap>
);
}
/* Detail.jsx */
import { useNavigate } from 'react-router-dom';
import styled from 'styled-components';
import Button from '../components/Button';
const Wrap = styled.div`
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 30px;
`;
const Character = styled.img`
width: 200px;
`;
const Name = styled.p`
font-size: 24px;
font-weight: 700;
color: #ff0000;
`;
const Description = styled.p`
font-size: 16px;
`;
export default function Detail() {
const navigate = useNavigate();
return (
<Wrap>
<Character src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/143.png" alt="character" />
<Name>잠만보</Name>
<Description>타입 : 노말</Description>
<Description>노말 타입의 포켓몬으로, 큰 몸집과 느긋한 성격을 가집니다.</Description>
<Button label="뒤로 가기" background="black" handleClick={() => navigate('/dex')} />
</Wrap>
);
}
- 컴포넌트
/* Button.jsx */
import styled from 'styled-components';
const Container = styled.div`
${({ type, background }) => `
background-color: ${background};
border-radius: 4px;
color: #ffffff;
font-size: ${type === 'main' ? '16px' : '14px'};
font-weight: ${type === 'main' ? '700' : '500'};
padding: ${type === 'main' ? '10px 20px' : '5px 10px'};
cursor: pointer;
`}
`;
export default function Button({ type = 'main', background, label, handleClick }) {
return (
<Container type={type} background={background} onClick={handleClick}>
{label}
</Container>
);
}
/* Bashboard.jsx */
import styled from 'styled-components';
import PokemonBall from './PokemonBall';
const Container = styled.div`
width: 100%;
max-width: 1240px;
background-color: #f0f0f0;
border-radius: 10px;
padding: 20px;
`;
const Title = styled.p`
font-size: 24px;
font-weight: 700;
color: #ff0000;
text-align: center;
margin-bottom: 20px;
`;
const BallContainer = styled.div`
display: flex;
justify-content: space-around;
gap: 10px;
overflow: scroll;
`;
export default function Dashboard() {
return (
<Container>
<Title>나만의 포켓몬</Title>
<BallContainer>
<PokemonBall />
<PokemonBall />
<PokemonBall />
<PokemonBall />
<PokemonBall />
<PokemonBall />
</BallContainer>
</Container>
);
}
/* PokemonBall.jsx */
import styled from 'styled-components';
const Container = styled.div`
min-width: 120px;
min-height: 120px;
display: flex;
justify-content: center;
align-items: center;
background-color: #ffffff;
border: 2px dashed #cccccc;
border-radius: 10px;
`;
const Ball = styled.img`
width: 60px;
`;
export default function PokemonBall() {
return (
<Container>
<Ball src="/src/assets/pokeball.png" />
</Container>
);
}
/* PokemonCard.jsx */
import styled from 'styled-components';
import Button from './Button';
import { useNavigate } from 'react-router-dom';
const Container = styled.div`
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
background-color: #ffffff;
border-radius: 10px;
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1);
transition: transform 0.2s, box-shadow 0.2s;
padding: 10px;
&:hover {
transform: translateY(-5px);
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.1);
}
`;
const Character = styled.img`
width: 100px;
`;
const Name = styled.p`
font-size: 16px;
font-weight: 700;
color: #000000;
`;
const Description = styled.p`
font-size: 14px;
color: #666666;
`;
export default function PokemonCard({ data }) {
const navigate = useNavigate();
return (
<Container onClick={() => navigate(`/detail/${data.id}`)}>
<Character src={data.img_url} />
<Name>{data.korean_name}</Name>
<Description>No. {String(data.id).padStart(3, '0')}</Description>
<Button type="sub" background="red" label="추가" handleClick={() => {}} />
</Container>
);
}
/* PokemonList.jsx */
import styled from 'styled-components';
import PokemonCard from './PokemonCard';
const Container = styled.div`
width: 100%;
max-width: 1240px;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 20px;
background-color: #f0f0f0;
border-radius: 10px;
padding: 20px;
`;
export default function PokemonList({ data }) {
return (
<Container>
{data.map((pokemon) => {
return <PokemonCard key={pokemon.id} data={pokemon} />;
})}
</Container>
);
}
'내일배움캠프' 카테고리의 다른 글
[241108 TIL] 본캠프 28일차 ('포켓몬 도감 만들기' 프로젝트 3일차) (0) | 2024.11.08 |
---|---|
[241107 TIL] 본캠프 27일차 ('포켓몬 도감 만들기' 프로젝트 2일차) (0) | 2024.11.07 |
[241105 TIL] 본캠프 25일차 (0) | 2024.11.05 |
[241104 TIL] 본캠프 24일차 (0) | 2024.11.04 |
[241101 TIL] 본캠프 23일차 (1) | 2024.11.01 |