Skip to content
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

[#16] feat: ✨ 모달 페이지 이벤트 구현중 #20

Merged
merged 2 commits into from
Apr 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,30 @@ import PopUpContainer from "./component/popUp/PopUpContainer.jsx";
import ShowMoreBtn from "./component/ShowMoreBtn.jsx";
import SlideContainer from "./component/slideContainer/SlideContainer.jsx";
import GlobalStyle from "./style.js";
import { useState } from "react";
import api from "./api.js";

function App() {
const [toggle, setToggle] = useState(false);
const [detailData, setDetailData] = useState(null);
const onPopUpToggle = () => setToggle(!toggle);

const onFetchDetailData = async (id) => {
const detailData = await api(`/detail/${id}`);
if(detailData) {
setDetailData(detailData);
onPopUpToggle();
}
}

return (
<>
<GlobalStyle />
<Header />
<BestTab />
<SlideContainer />
<BestTab onFetchDetailData={onFetchDetailData}/>
<SlideContainer onFetchDetailData={onFetchDetailData}/>
<ShowMoreBtn />
<PopUpContainer/>
{toggle ? <PopUpContainer detailData={detailData} onPopUpToggle={onPopUpToggle}/> : null}
</>
);
}
Expand Down
9 changes: 6 additions & 3 deletions src/component/bestTab/BestItems.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const BestItemsStyle = styled.div`
padding: 2.5rem;
`;

export default function BestItems({ childs }) {
export default function BestItems({ childs, onFetchDetailData }) {

const getRandom = (n, max) => {
const set = new Set();
Expand All @@ -28,13 +28,16 @@ export default function BestItems({ childs }) {
{
getRandom(3, childs.length).map(idx => (
<ItemCard
src={childs[idx].img}
src={childs[idx].main_image}
title={childs[idx].title}
description={childs[idx].description}
salePrice={getSalePrice(childs[idx].price, childs[idx].discount)}
normalPrice={childs[idx].price}
labels={childs[idx].label}
key={idx}/>
key={idx}
id={childs[idx]._id}
onFetchDetailData={onFetchDetailData}
/>
))
}
</BestItemsStyle>
Expand Down
4 changes: 2 additions & 2 deletions src/component/bestTab/BestTab.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const BestTabStyle = styled.div`
margin-bottom: 5rem;
`;

export default function BestTab() {
export default function BestTab({onFetchDetailData}) {
const [active, setActive] = useState(0);
const [bestItems, setBestItems] = useState(null);

Expand All @@ -31,7 +31,7 @@ export default function BestTab() {
<BestTabStyle>
<h2>후기가 증명하는 베스트 반찬</h2>
<BestTabNavigator bestItems={bestItems} active={active} setActive={setActive}/>
<BestTabContainer bestItem={bestItems[active]}/>
<BestTabContainer bestItem={bestItems[active]} onFetchDetailData={onFetchDetailData}/>
</BestTabStyle>
)
}
4 changes: 2 additions & 2 deletions src/component/bestTab/BestTabContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import BestItems from "./BestItems";

const BestTabContainerStyle = styled.div``;

export default function BestTabContainer({ bestItem }) {
export default function BestTabContainer({ bestItem, onFetchDetailData }) {
return (
<BestTabContainerStyle>
{<BestItems childs={bestItem.childs}/>}
<BestItems childs={bestItem.childs} onFetchDetailData={onFetchDetailData}/>
</BestTabContainerStyle>
)
}
11 changes: 6 additions & 5 deletions src/component/popUp/PopUpContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ const PopUpDetailContainerStyle = styled.div`
background-color: #fff;
width: 60rem;
margin: 6vh auto;
position: relative;
`;

const CloseBtnStyle = styled.button`
color: #fff;
opacity: 0.8;
position: absolute;
right: -4rem;
right: -2.5rem;
font-size: 1.25rem;
cursor: pointer;

Expand All @@ -45,15 +46,15 @@ const CloseBtnStyle = styled.button`
}
`;

export default function PopUpContainer () {
export default function PopUpContainer ({ detailData, onPopUpToggle }) {

return (
<PopUpContainerStyle>
<PopUpDetailContainerStyle>
<PopUpImages/>
<PopUpInformations/>
<CloseBtnStyle onClick={onPopUpToggle}><FaTimes></FaTimes></CloseBtnStyle>
<PopUpImages detailData={detailData} />
<PopUpInformations detailData={detailData}/>
</PopUpDetailContainerStyle>
<CloseBtnStyle><FaTimes></FaTimes></CloseBtnStyle>
</PopUpContainerStyle>
)
}
23 changes: 14 additions & 9 deletions src/component/popUp/PopUpImages.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import styled from 'styled-components';
import { useState } from 'react';

const PopUpImagesStyle = styled.div`

Expand All @@ -7,7 +8,7 @@ const PopUpImagesStyle = styled.div`
const PopUpMainImageStyle = styled.div`
width: 100%;
height: 24.5rem;
background-image: url("https://cdn.pixabay.com/photo/2017/09/10/14/23/jjolmyeon-2735716__340.jpg");
background-image: ${props => `url(${props.src})`};
background-size: cover;
margin-bottom: 0.5rem;
border-radius: 0.3125rem;
Expand All @@ -24,22 +25,26 @@ const PopUpThumbnailImageStyle = styled.img.attrs(props => ({
}))`
width: 100%;
border-radius: 0.25rem;
border: 1px solid #fff;
cursor: pointer;
border: ${props => props.active ? '2px solid #82D32D' : '2px solid transparent'};
height: 4.5rem;
`;

export default function PopUpImages () {
export default function PopUpImages ({ detailData }) {
const { main_image, thumbnail_images } = detailData;
const images = [main_image, ...thumbnail_images];
const [ activeImage, setActiveImage ] = useState(images[0]);

const onChangeMainImage = (idx) => {
setActiveImage(images[idx]);
}

return (
<PopUpImagesStyle>
<PopUpMainImageStyle/>
<PopUpMainImageStyle src={activeImage}/>
<PopUpThumbnailImagesStyle>
<PopUpThumbnailImageStyle src="https://cdn.pixabay.com/photo/2017/09/10/14/23/jjolmyeon-2735716__340.jpg"/>
<PopUpThumbnailImageStyle src="https://cdn.pixabay.com/photo/2017/09/10/14/23/jjolmyeon-2735716__340.jpg"/>
<PopUpThumbnailImageStyle src="https://cdn.pixabay.com/photo/2017/09/10/14/23/jjolmyeon-2735716__340.jpg"/>
<PopUpThumbnailImageStyle src="https://cdn.pixabay.com/photo/2017/09/10/14/23/jjolmyeon-2735716__340.jpg"/>
{images.map((URL, idx) => <PopUpThumbnailImageStyle active={activeImage === URL} src={URL} onClick={() => onChangeMainImage(idx)}/>)}
</PopUpThumbnailImagesStyle>
</PopUpImagesStyle>

)
}
70 changes: 12 additions & 58 deletions src/component/popUp/PopUpInformations.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled from 'styled-components';
import Label from '../util/Label';
import { FaAngleUp, FaAngleDown } from 'react-icons/fa';
import PopUpItemCountContainer from './PopUpItemCountContainer';

const PopUpInformationsStyle = styled.div`
`;
Expand Down Expand Up @@ -58,44 +58,6 @@ const PopUpItemBuyingInformationTitle = styled.div`
const PopUpItemBuyingInformationContent = styled.div`
line-height: 1.5rem;
`;
const PopUpItemCountContainer = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
padding: 1.5rem 0;
border-bottom: 1px solid #e0e0e0;
& > *:last-child {
display: grid;
grid-template-columns: 5rem 2rem;
line-height: 0;
}
`;

const PopUpItemCountTitle = styled.div`
color: #828282;
width: 5rem;
`;

const PopUpItemCount = styled.input.attrs({
type: 'text'
})`
font-size: 1rem;
padding: 0rem 1rem;
border: 1px solid #E0E0E0;
text-align: center;
`;

const PopUpItemCountBtns = styled.div`
border: 1px solid #E0E0E0;
border-left: 0px;
`;

const PopUpItemCountBtn = styled.button`
width: 100%;
&:first-child {
border-bottom: 1px solid #E0E0E0;
}
`;

const PopUpItemTotalPriceContainer = styled.div`
display: flex;
Expand Down Expand Up @@ -133,44 +95,36 @@ const PopUpItemOrderBtn = styled.button`
}
`;

export default function PopUpInformations() {
export default function PopUpInformations({ detailData }) {
const { title, description, price, discount, stock, point, delivery_fee, delivery_info } = detailData;

return (
<PopUpInformationsStyle>
<PopUpItemTitle>[헬로]안녕하세요</PopUpItemTitle>
<PopUpItemDescription>맛있는 일본인의 소울푸드!</PopUpItemDescription>
<PopUpItemTitle>{title}</PopUpItemTitle>
<PopUpItemDescription>{description}</PopUpItemDescription>
<PopUpItemPriceContainer>
<Label text="이벤트특가"/>
<SalePriceStyle>5,200원</SalePriceStyle>
<NormalPriceStyle>6,000원</NormalPriceStyle>
<SalePriceStyle>{Math.floor(price - (price * (discount / 100)))}원</SalePriceStyle>
<NormalPriceStyle>{price}원</NormalPriceStyle>
</PopUpItemPriceContainer>
<PopUpItemBuyingInformations>
<PopUpItemBuyingInformation>
<PopUpItemBuyingInformationTitle>적립금</PopUpItemBuyingInformationTitle>
<PopUpItemBuyingInformationContent>52원</PopUpItemBuyingInformationContent>
<PopUpItemBuyingInformationContent>{point}원</PopUpItemBuyingInformationContent>
</PopUpItemBuyingInformation>
<PopUpItemBuyingInformation>
<PopUpItemBuyingInformationTitle>배송정보</PopUpItemBuyingInformationTitle>
<PopUpItemBuyingInformationContent>서울 경기 새벽배송 / 전국택배 (제주 및 도서산간 불가) [월 · 화 · 수 · 목 · 금 · 토] 수령 가능한 상품입니다</PopUpItemBuyingInformationContent>
<PopUpItemBuyingInformationContent>{delivery_info}</PopUpItemBuyingInformationContent>
</PopUpItemBuyingInformation>
<PopUpItemBuyingInformation>
<PopUpItemBuyingInformationTitle>배송비</PopUpItemBuyingInformationTitle>
<PopUpItemBuyingInformationContent>2,500원 <b>(40,000원 이상 구매 시 무료)</b></PopUpItemBuyingInformationContent>
<PopUpItemBuyingInformationContent>{delivery_fee}</PopUpItemBuyingInformationContent>
</PopUpItemBuyingInformation>
</PopUpItemBuyingInformations>
<PopUpItemCountContainer>
<PopUpItemCountTitle>수량</PopUpItemCountTitle>
<div>
<PopUpItemCount value="1"></PopUpItemCount>
<PopUpItemCountBtns>
<PopUpItemCountBtn><FaAngleUp/></PopUpItemCountBtn>
<PopUpItemCountBtn><FaAngleDown/></PopUpItemCountBtn>
</PopUpItemCountBtns>
</div>
</PopUpItemCountContainer>
<PopUpItemCountContainer stock={stock}/>
<PopUpItemTotalPriceContainer>
<PopUpItemTotalPriceTitle>총 주문금액</PopUpItemTotalPriceTitle>
<PopUpTotalPrice>5,200원</PopUpTotalPrice>
<PopUpTotalPrice>{price}</PopUpTotalPrice>
</PopUpItemTotalPriceContainer>
<PopUpItemOrderBtn>주문하기</PopUpItemOrderBtn>
</PopUpInformationsStyle>
Expand Down
63 changes: 63 additions & 0 deletions src/component/popUp/PopUpItemCountContainer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import styled from 'styled-components';
import { FaAngleUp, FaAngleDown, FaRProject } from 'react-icons/fa';
import { useState } from 'react';


const PopUpItemCountContainerStyle = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
padding: 1.5rem 0;
border-bottom: 1px solid #e0e0e0;
& > *:last-child {
display: grid;
grid-template-columns: 5rem 2rem;
line-height: 0;
}
`;

const PopUpItemCountTitle = styled.div`
color: #828282;
width: 5rem;
`;

const PopUpItemCount = styled.input.attrs({
type: 'text'
})`
font-size: 1rem;
padding: 0rem 1rem;
border: 1px solid #E0E0E0;
text-align: center;
`;

const PopUpItemCountBtns = styled.div`
border: 1px solid #E0E0E0;
border-left: 0px;
`;

const PopUpItemCountBtn = styled.button`
width: 100%;
&:first-child {
border-bottom: 1px solid #E0E0E0;
}
`;

export default function PopUpItemCountContainer ({ stock }) {
const [ count, setCount ] = useState(1);

return (
<PopUpItemCountContainerStyle>
<PopUpItemCountTitle>수량</PopUpItemCountTitle>
<div>
<PopUpItemCount value={count}></PopUpItemCount>
<PopUpItemCountBtns>
<PopUpItemCountBtn><FaAngleUp/></PopUpItemCountBtn>
<PopUpItemCountBtn><FaAngleDown/></PopUpItemCountBtn>
</PopUpItemCountBtns>
</div>
</PopUpItemCountContainerStyle>
)
}



4 changes: 2 additions & 2 deletions src/component/slideContainer/SlideContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ const SliderArrowBtnsStyle = styled.div`
justify-content: space-between;
`;

export default function SlideContainer() {
export default function SlideContainer({ onFetchDetailData }) {
return (
<SlideContainerStyle>
<h2>후기가 증명하는 베스트 반찬</h2>
<SlideItems/>
<SlideItems onFetchDetailData={onFetchDetailData}/>
<SliderArrowBtnsStyle>
<SliderArrowBtn><FaChevronLeft /></SliderArrowBtn>
<SliderArrowBtn><FaChevronRight /></SliderArrowBtn>
Expand Down
10 changes: 5 additions & 5 deletions src/component/slideContainer/SlideItems.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ const SlideItemsStyle = styled.div`
padding: 2.5rem 0;
`;

export default function SlideItems() {
export default function SlideItems({ onFetchDetailData }) {
return (
<SlideItemsStyle>
<ItemCard src = "http://web.archive.org/web/20190129014225im_/https://cdn.bmf.kr/_data/product/IF235/20ea0478c029ad4fda3fa2885d53c5d4.jpg" title = "[집밥의완성]초여름보양세트" description = "무더위에 대비하는 6월 한상차림 초여름 보양세트" salePrice="5000" normalPrice="6000" text="이벤트특가" color="#fff" bgColor="#82D32D"/>
<ItemCard src = "http://web.archive.org/web/20190129014225im_/https://cdn.bmf.kr/_data/product/IF235/20ea0478c029ad4fda3fa2885d53c5d4.jpg" title = "[집밥의완성]초여름보양세트" description = "무더위에 대비하는 6월 한상차림 초여름 보양세트" salePrice="5000" normalPrice="6000" text="이벤트특가" color="#fff" bgColor="#82D32D"/>
<ItemCard src = "http://web.archive.org/web/20190129014225im_/https://cdn.bmf.kr/_data/product/IF235/20ea0478c029ad4fda3fa2885d53c5d4.jpg" title = "[집밥의완성]초여름보양세트" description = "무더위에 대비하는 6월 한상차림 초여름 보양세트" salePrice="5000" normalPrice="6000" text="런칭특가" color="#fff" bgColor="#86C6FF"/>
<ItemCard src = "http://web.archive.org/web/20190129014225im_/https://cdn.bmf.kr/_data/product/IF235/20ea0478c029ad4fda3fa2885d53c5d4.jpg" title = "[집밥의완성]초여름보양세트" description = "무더위에 대비하는 6월 한상차림 초여름 보양세트" salePrice="5000" normalPrice="6000" text="이벤트특가" color="#fff" bgColor="#82D32D"/>
<ItemCard onFetchDetailData={onFetchDetailData} src = "http://web.archive.org/web/20190129014225im_/https://cdn.bmf.kr/_data/product/IF235/20ea0478c029ad4fda3fa2885d53c5d4.jpg" title = "[집밥의완성]초여름보양세트" description = "무더위에 대비하는 6월 한상차림 초여름 보양세트" salePrice="5000" normalPrice="6000" text="이벤트특가" color="#fff" bgColor="#82D32D"/>
<ItemCard onFetchDetailData={onFetchDetailData} src = "http://web.archive.org/web/20190129014225im_/https://cdn.bmf.kr/_data/product/IF235/20ea0478c029ad4fda3fa2885d53c5d4.jpg" title = "[집밥의완성]초여름보양세트" description = "무더위에 대비하는 6월 한상차림 초여름 보양세트" salePrice="5000" normalPrice="6000" text="이벤트특가" color="#fff" bgColor="#82D32D"/>
<ItemCard onFetchDetailData={onFetchDetailData} src = "http://web.archive.org/web/20190129014225im_/https://cdn.bmf.kr/_data/product/IF235/20ea0478c029ad4fda3fa2885d53c5d4.jpg" title = "[집밥의완성]초여름보양세트" description = "무더위에 대비하는 6월 한상차림 초여름 보양세트" salePrice="5000" normalPrice="6000" text="런칭특가" color="#fff" bgColor="#86C6FF"/>
<ItemCard onFetchDetailData={onFetchDetailData} src = "http://web.archive.org/web/20190129014225im_/https://cdn.bmf.kr/_data/product/IF235/20ea0478c029ad4fda3fa2885d53c5d4.jpg" title = "[집밥의완성]초여름보양세트" description = "무더위에 대비하는 6월 한상차림 초여름 보양세트" salePrice="5000" normalPrice="6000" text="이벤트특가" color="#fff" bgColor="#82D32D"/>
</SlideItemsStyle>
)
}
Loading