forked from codesquad-members-2022/sidedish
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[team-01][FE] 기획전 UI & 기능 구현 (codesquad-members-2022#83)
* Docs: Readme Update * 팀원 소개, Tools, 그라운드룰, 브랜치 전략, 컨벤션 등에 대한 정리 * Design: Navbar, Menu, Icons 컴포넌트 레이아웃 수정 - #10 Co-authored-by: Hemudi <hemudi@users.noreply.github.com> * Feat: Navbar 마우스 이벤트 추가 - #10 * MouseEnter, MouseLeave 이벤트 추가 * SubMenuhover 효과 추가 Co-authored-by: Hemudi <hemudi@users.noreply.github.com> * Design: Global Style 에 font-family 적용 - #15 * theme의 font family 삭제 Co-authored-by: Millie <jaypedia@users.noreply.github.com> * Rename: Header 컴포넌트 폴더 생성해서 그룹화 - #15 Co-authored-by: Millie <jaypedia@users.noreply.github.com> * Design: 기획전 TitleBox, TabBar UI 구현 - #15 * Tab Mouse hover 밑줄 효과 구현 Co-authored-by: Millie <jaypedia@users.noreply.github.com> * Fix: 기획전 Tab hover 시 사용성 개선 - #15 * 기존 border 속성을 box-shadow 로 변경 Co-authored-by: Millie <jaypedia@users.noreply.github.com> * Feat: API fetch 요청하는 util 함수 구현 - #15 * GET 요청만 우선적으로 구현 Co-authored-by: Hemudi <hemudi@users.noreply.github.com> * Design: CardContainer를 Styled Components로 구현 - #15 Co-authored-by: Hemudi <hemudi@users.noreply.github.com> * Design: Card Component UI 구현 - #15 Co-authored-by: Hemudi <hemudi@users.noreply.github.com> * Feat: fetch로 API 요청, Card 동적 생성 - #15 * 임시 데이터로 UI 먼저 구현 Co-authored-by: Hemudi <hemudi@users.noreply.github.com> * Feat: Tab 클릭 시 fetch 요청 후 리렌더링 기능 구현 - #16 * fetch 요청 로직을 fetchTabData 함수로 분리 * 하드 코딩 부분은 추후 리팩토링 예정 Co-authored-by: Millie <jaypedia@users.noreply.github.com> * Refactor: .gitignore 불필요한 옵션 제거 - #17 Co-authored-by: Millie <jaypedia@users.noreply.github.com> * Refactor: Navbar의 div 태그 header로 변경 - #17 Co-authored-by: Millie <jaypedia@users.noreply.github.com> * Refactor: menu와 tabData 데이터 분리 후 동적생성 - #18 * 하드코딩 되었던 컴포넌트를 data 분리 후 map 으로 동적 생성 Co-authored-by: Millie <jaypedia@users.noreply.github.com> Co-authored-by: Hemudi <ksum1205@naver.com> Co-authored-by: Hemudi <hemudi@users.noreply.github.com> Co-authored-by: Millie <jaypedia@users.noreply.github.com>
- Loading branch information
1 parent
9d92169
commit 2584c77
Showing
14 changed files
with
314 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import React, { useState } from 'react'; | ||
import { Navbar, Menu, Icons, MenuBox, MainMenu, SubMenuList, SubMenu } from './Header.style.js'; | ||
import { ReactComponent as Logo } from '../assets/logo.svg'; | ||
import { ReactComponent as Search } from '../assets/search.svg'; | ||
import { ReactComponent as Login } from '../assets/login.svg'; | ||
import { ReactComponent as Cart } from '../assets/cart.svg'; | ||
import menuData from '../data/headerMenu.js'; | ||
|
||
const Header = () => { | ||
const [isOpen, setIsOpen] = useState(false); | ||
|
||
const toggleSubMenu = () => { | ||
setIsOpen(!isOpen); | ||
}; | ||
|
||
return ( | ||
<Navbar onMouseEnter={toggleSubMenu} onMouseLeave={toggleSubMenu}> | ||
<Logo /> | ||
<Menu> | ||
{menuData.map((v, i) => { | ||
return ( | ||
<MenuBox key={i}> | ||
<MainMenu>{v.main}</MainMenu> | ||
<SubMenuList isOpen={isOpen}> | ||
{v.sub.map((name, i) => { | ||
return <SubMenu key={i}>{name}</SubMenu>; | ||
})} | ||
</SubMenuList> | ||
</MenuBox> | ||
); | ||
})} | ||
</Menu> | ||
<Icons> | ||
<Search /> | ||
<Login /> | ||
<Cart /> | ||
</Icons> | ||
</Navbar> | ||
); | ||
}; | ||
|
||
export default Header; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import React, { useEffect, useState } from 'react'; | ||
import Card from '../components/Card'; | ||
import { fetchData } from '../utils/utils'; | ||
import { | ||
SpecialContainer, | ||
SpecialBadge, | ||
SpecialTitle, | ||
SpecialTitleBox, | ||
SpecialTabBar, | ||
SpecialHeader, | ||
SpecialTab, | ||
CardContainer, | ||
} from './Special.style'; | ||
import tabData from '../data/specialTab.js'; | ||
|
||
const Special = () => { | ||
const [data, setData] = useState([]); | ||
const [tabNum, setTabNum] = useState(0); | ||
|
||
useEffect(() => { | ||
fetchTabData(); | ||
}, []); | ||
|
||
const handleTabClick = tabNum => { | ||
setTabNum(tabNum); | ||
fetchTabData(); | ||
}; | ||
|
||
const fetchTabData = async () => { | ||
const TEST_URL = 'http://3.39.42.204/api/dishes'; | ||
const data = await fetchData(TEST_URL); | ||
setData(data.response.slice(0, 3)); | ||
}; | ||
|
||
return ( | ||
<SpecialContainer> | ||
<SpecialHeader> | ||
<SpecialTitleBox> | ||
<SpecialBadge>기획전</SpecialBadge> | ||
<SpecialTitle>한 번 주문하면 두 번 반하는 반찬</SpecialTitle> | ||
</SpecialTitleBox> | ||
<SpecialTabBar> | ||
{tabData.map((v, i) => { | ||
return ( | ||
<SpecialTab | ||
key={i} | ||
onClick={() => handleTabClick(v.index)} | ||
isSelected={tabNum === v.index ? true : false} | ||
> | ||
{v.name} | ||
</SpecialTab> | ||
); | ||
})} | ||
</SpecialTabBar> | ||
</SpecialHeader> | ||
<CardContainer> | ||
{data.map((v, i) => ( | ||
<Card key={i} data={v} /> | ||
))} | ||
</CardContainer> | ||
</SpecialContainer> | ||
); | ||
}; | ||
|
||
export default Special; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import styled from 'styled-components'; | ||
|
||
const SpecialContainer = styled.div` | ||
width: 100%; | ||
`; | ||
|
||
const SpecialHeader = styled.div` | ||
padding: 56px 80px 0 80px; | ||
border-bottom: 1px solid ${props => props.theme.colors.grey4}; | ||
`; | ||
|
||
const SpecialTitleBox = styled.div` | ||
display: flex; | ||
margin-bottom: 24px; | ||
`; | ||
|
||
const SpecialBadge = styled.div` | ||
width: 76px; | ||
height: 42px; | ||
border: 2px solid ${props => props.theme.colors.black}; | ||
border-radius: 20px; | ||
line-height: 42px; | ||
text-align: center; | ||
margin-right: 16px; | ||
`; | ||
|
||
const SpecialTitle = styled.h1` | ||
font-size: ${props => props.theme.fontSize.xLarge}; | ||
font-weight: ${props => props.theme.fontWeight.display}; | ||
color: ${props => props.theme.colors.black}; | ||
`; | ||
|
||
const SpecialTabBar = styled.div` | ||
display: flex; | ||
width: 100%; | ||
`; | ||
|
||
const SpecialTab = styled.div` | ||
font-size: ${props => props.theme.fontSize.large}; | ||
font-weight: ${props => props.theme.fontWeight.bold}; | ||
color: ${props => props.theme.colors.black}; | ||
margin-right: 32px; | ||
padding-bottom: 17px; | ||
box-shadow: 0 ${({ isSelected }) => (isSelected ? '1px' : '0')} ${props => props.theme.colors.black}; | ||
cursor: pointer; | ||
`; | ||
|
||
const CardContainer = styled.div` | ||
display: flex; | ||
justify-content: space-between; | ||
padding: 34px 80px 56px 80px; | ||
border-bottom: 1px solid ${props => props.theme.colors.grey4}; | ||
`; | ||
|
||
export { | ||
SpecialContainer, | ||
SpecialHeader, | ||
SpecialTitleBox, | ||
SpecialBadge, | ||
SpecialTitle, | ||
SpecialTabBar, | ||
SpecialTab, | ||
CardContainer, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from 'react'; | ||
import { CardWrapper, SubTitle, Title, Thumbnail, PriceBox, SalePrice, Badge, DescriptionWrapper } from './Card.syle'; | ||
|
||
const Card = ({ data }) => { | ||
return ( | ||
<CardWrapper> | ||
<Thumbnail src={data.thumbnail} /> | ||
<DescriptionWrapper> | ||
<Title>{data.name}</Title> | ||
<SubTitle>{data.description}</SubTitle> | ||
<PriceBox> | ||
<Title>{data.normalPrice.toLocaleString('ko-KR')}원</Title> | ||
<SalePrice>{data.salePrice.toLocaleString('ko-KR')}원</SalePrice> | ||
</PriceBox> | ||
</DescriptionWrapper> | ||
<Badge>런칭특가</Badge> | ||
</CardWrapper> | ||
); | ||
}; | ||
|
||
export default Card; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import styled from 'styled-components'; | ||
|
||
const CardWrapper = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
cursor: pointer; | ||
`; | ||
|
||
const Thumbnail = styled.div` | ||
width: 411px; | ||
height: 411px; | ||
background-image: url(${({ src }) => src}); | ||
background-repeat: no-repeat; | ||
background-size: cover; | ||
`; | ||
|
||
const Title = styled.h3` | ||
font-size: ${props => props.theme.fontSize.medium}; | ||
font-weight: ${props => props.theme.fontWeight.bold}; | ||
color: ${props => props.theme.colors.grey1}; | ||
margin-right: 8px; | ||
`; | ||
|
||
const SubTitle = styled.p` | ||
font-size: ${props => props.theme.fontSize.small}; | ||
color: ${props => props.theme.colors.grey2}; | ||
margin: 8px 0; | ||
`; | ||
|
||
const PriceBox = styled.div` | ||
display: flex; | ||
`; | ||
|
||
const SalePrice = styled.p` | ||
font-size: ${props => props.theme.fontSize.small}; | ||
color: ${props => props.theme.colors.grey3}; | ||
text-decoration: line-through; | ||
`; | ||
|
||
const Badge = styled.div` | ||
width: 76px; | ||
height: 30px; | ||
border-radius: 20px; | ||
background-color: ${props => props.theme.colors.orange}; | ||
color: ${props => props.theme.colors.white}; | ||
font-size: ${props => props.theme.fontSize.xSmall}; | ||
font-weight: ${props => props.theme.fontWeight.medium}; | ||
text-align: center; | ||
line-height: 30px; | ||
`; | ||
|
||
const DescriptionWrapper = styled.div` | ||
margin: 16px 0; | ||
`; | ||
|
||
export { CardWrapper, Thumbnail, Title, SubTitle, PriceBox, SalePrice, Badge, DescriptionWrapper }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export default [ | ||
{ | ||
main: '든든한 메인 요리', | ||
sub: ['육류 요리', '해산물 요리'], | ||
}, | ||
{ | ||
main: '뜨끈한 국물요리', | ||
sub: ['국/탕/찌개'], | ||
}, | ||
{ | ||
main: '정갈한 밑반찬', | ||
sub: ['나물/무침', '조림/볶음', '절임/장아찌'], | ||
}, | ||
]; |
Oops, something went wrong.