Skip to content

Commit

Permalink
[Team23] 프론트엔드 UI 완성 (#45)
Browse files Browse the repository at this point in the history
* [Add] Carousel

- 캐러셀 구현
- 캐러셀 틀을 잡기 위해 구조 살짝 변경 - 컴포넌트 트리 참고
- products.length가 8의 배수가 아닌 경우를 생각해서 로직을 짰는데 아직 테스트는 안해봄

* [Fix] Carousel

- 4의 배수가 아닐 때 캐러셀 애니메이션 테스트함
- left 버튼을 누를 때 문제가 있었는데 index 업데이트를 수정하여 고침

* [Fix] Direction of carousel-button

- 왼쪽 버튼을 누르면 이전 슬라이드가, 오른쪽 버튼을 누르면 이후 슬라이드가 나오도록 수정

* [Add] hover ver.1
- 리렌더링 때문에 깜빡거림

* [Feat] 카드 이미지에 hover 시 배송 타입 노출

* [Add] Modal skeleton code

* [Refactor] Modal 컴포넌트 분리
- 공통적으로 사용되는 styled component를 common.jsx에 분리
- 카드에 있는 정보를 모달에 전달

* [Fix] 할인 전후 가격 잘못 넣어서 수정

* [Add] Modal에 클릭한 상품의 데이터를 넣어줌

* [Modify] Apply Portal for modal

- 컴포넌트 구조 변경
    - utils를 구별하려고 했는데 components 안에있는 utils가 rename이 안되어서 외부 utils, 내부 utils로 둠
    - 별로 좋지 않은 느낌인거 같고, 아무래도 이 부분은 팀원들과 함께 논의하면서 진행해야 할거같아서 내꺼에만 저장해놓기!
- Portal
    - index.html에 global-modal 이라는 id값을 가진 돔 생성
    - Modal이라는 포탈을 만들어서 띄워주기
    - 띄워지는거 확인

* [Modify] Locate Portal-modal into Card

- Card의 자식으로 Portal-modal을 집어넣음
- 모달이 뜰 때 fetch로 해당 상품의 정보를 가져오는 방식으로 구현
    - 혹시라도 실시간으로 재고 상황이 달라질까 싶어서 매번 fetch 하는 형식으로 구현했는데, 좋은 방법인지는 모르겠음
- StyledLi 밖에서 setModalState를 해주어야 함
    - 그렇지 않으면 클릭하는 모든 부분이 StyledLi라서 클릭 이벤트가 자꾸 발생해 false로 바꿔도 다시 true가 되어 모달창이 꺼지지 않는 일 발생
- 현재 useEffect 안쓰고 그냥 fetch를 사용했고, 동작은 하는데, 좋은 방법처럼 느껴지지는 않음
    - 근데 useEffect안에 fetch를 사용하는 것이 원칙일까.. 좀 더 공부해볼 필요가 있는 것 같음

* [Refactor] 제니의 퍼블리싱 작업 합치기 & 리팩토링

- 너무 무거워지는 것 같아서 products라는 폴더 만들고 하위 컴포넌트들을 나눠 저장
- 제니의 퍼블리싱 작업 합침
    - 근데 작은 사진들을 클릭했을 때 썸네일에 안뜨는 문제 발생함
- 자잘한 버그가 있는 것 같음. 추후 재확인 필요

* [Refactor] Integration

- 제니의 퍼블리싱 작업을 합침
- 불필요한 주석 제거

* [Add] Install reallyawesome-jennyrousel

- JennyCarousel 설치해서 적용
- 자잘한 css 수정 (title의 margin, section의 width..)

* [Modify] Modal, Carousel

- 모달 창 크기 수정
- 모달 창 내 캐러셀 삽입 (with 제니캐러셀)
- 모든 카테고리 보기 구현

* [Refactor] 모달창 JennyCarousel 수정
- 4개 => 5개로 (개수 지정 가능하도록 수정)
- RecommendCarouselTitle position absolute를 통해 재배치 및 부모 position relative 주기

* [Refactor] 불필요한 주석 삭제

* [Chore] 컴포넌트 디렉토리 이름 수정

Co-authored-by: adelakim <diddnjs02@likelion.org>
Co-authored-by: Jungwon Lee <leejungwon96@gmail.com>
  • Loading branch information
3 people committed Apr 28, 2021
1 parent 5b1790b commit 2bdef3a
Show file tree
Hide file tree
Showing 36 changed files with 30,378 additions and 10,632 deletions.
18,964 changes: 18,940 additions & 24 deletions banchan/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions banchan/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"reallyawesome-jennyrousel": "^0.1.9",
"styled-components": "^5.2.3",
"web-vitals": "^1.0.1"
},
Expand Down
1 change: 1 addition & 0 deletions banchan/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="global-modal"></div>
</body>
</html>
12 changes: 7 additions & 5 deletions banchan/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import "./App.css";
import StateProvider from "./components/StateProvider";
import { createGlobalStyle } from "styled-components";
import { ThemeProvider } from "styled-components";
import theme from "./components/utils/styles/theme";
import './App.css';
import StateProvider from './components/StateProvider';
import { createGlobalStyle } from 'styled-components';
import { ThemeProvider } from 'styled-components';
import theme from './components/componentUtils/styles/theme';

export const GlobalStyle = createGlobalStyle`
*{
padding:0;
margin:0;
}
body{
font-family: 'Noto Sans KR';
box-sizing:border-box;
}
ol, ul {
list-style: none;
}
Expand Down
3 changes: 0 additions & 3 deletions banchan/src/components/StateProvider.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// import { useState } from "react";
import Header from "./header/Header";
import MainPage from "./main/MainPage";
// import Test from "./Test";

const StateProvider = () => {
// const [loginState, setLoginState] = useState(false);
Expand All @@ -11,7 +9,6 @@ const StateProvider = () => {
<>
<Header />
<MainPage />
{/* <Test /> */}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";
import styled from "styled-components";
import { LABEL_TYPE } from "../../utils/variables.js";
import theme from "./styles/theme.js";
import { LABEL_TYPE } from "./variables.js";

const Label = ({ badgeName }) => <StyledLabel type={LABEL_TYPE[badgeName]}>{badgeName}</StyledLabel>;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import styled from 'styled-components';
import theme from '../utils/styles/theme.js';
import theme from '../componentUtils/styles/theme.js';
import { CenterContainer } from './styles/common.jsx';

const Price = ({ product }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import styled from "styled-components";
import theme from "../styles/theme";
import { BUTTON_TYPE } from "../variables.js";
import { Button } from "../styles/common";
import { BUTTON_TYPE } from "../../../utils/variables";

const IconButton = ({ type, fn, disabled = false }) => {
const IconButton = ({ type, fn, disabled = false, margin = 0 }) => {
return (
<StyledIconButton type={type} onClick={fn} disabled={disabled}>
<StyledIconButton type={type} onClick={fn} disabled={disabled} margin={margin}>
{BUTTON_TYPE[type]}
</StyledIconButton>
);
};

const StyledIconButton = styled(Button)`
cursor: pointer;
color: ${(props) =>
props.disabled || props.type === "SEARCH" ? props.theme.colors.lightGray : props.theme.colors.darkGray};
color: ${(props) => {
if (props.type === "CLOSE") return props.theme.colors.white;
if (props.disabled || props.type === "SEARCH") return props.theme.colors.lightGray;
return props.theme.colors.darkGray;
}};
font-size: ${({ type }) => (type === "UP" || type === "DOWN" ? theme.fontSizes.M : "30px")};
margin: ${({ margin }) => `${margin}px`};
`;

export default IconButton;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from "styled-components";
import theme from "../styles/theme";
import { BUTTON_TYPE } from "../variables.js";
import { Button } from "../styles/common";
import { BUTTON_TYPE } from "../../../utils/variables";

const TextButton = ({ type, fn, disabled = false }) => {
return (
Expand All @@ -14,14 +14,13 @@ const TextButton = ({ type, fn, disabled = false }) => {
const StyledTextButton = styled(Button)`
font-size: ${theme.fontSizes.M};
font-weight: bold;
background: ${(props) =>
props.disabled ? theme.colors.lightGrayBG : theme.colors.green};
color: ${(props) =>
props.disabled ? theme.colors.gray : theme.colors.white};
background: ${(props) => (props.disabled ? theme.colors.lightGrayBG : theme.colors.green)};
color: ${(props) => (props.disabled ? theme.colors.gray : theme.colors.white)};
cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")};
width: 440px;
height: 58px;
text-align: center;
box-shadow: 0px 0px 4px rgba(204, 204, 204, 0.5), 0px 2px 4px rgba(0, 0, 0, 0.25);
`;

export default TextButton;
72 changes: 72 additions & 0 deletions banchan/src/components/componentUtils/card/Card.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import styled from "styled-components";
// import theme from "../styles/theme.js";
import Price from "../Price";
import Label from "../Label";
import { CenterContainer, LabelList, StyledDescription, StyledTitle } from "../styles/common.jsx";
import { useState } from "react";
import Modal from "../modal/Modal.jsx";
import ModalCard from "../modal/ModalCard.jsx";
import { URLS } from "../../../utils/variables.js";
import IconButton from "../button/IconButton.jsx";
import Thumbnail from "./Thumbnail";

// const mockImage = "https://recipe1.ezmember.co.kr/cache/recipe/2020/09/23/5e308abb30b00ecb9c1b9b398db5b4451.jpg";

const Card = ({ product, cardSize, margin = 0, type, onModal }) => {
const [modalState, setModalState] = useState(false);
const [detail, setDetail] = useState({});

const requestProductDetailInfo = async () => {
const data = await fetch(URLS.base + `detail/${product.detail_hash}`);
const json = await data.json();
setDetail({ ...json.data });
setModalState(true);
};

return (
<>
<StyledLi cardSize={cardSize} margin={margin} onClick={requestProductDetailInfo}>
<Thumbnail {...{ product, cardSize, type }} />
<StyledTitle>{product.title}</StyledTitle>
<StyledDescription>{product.description}</StyledDescription>
<Price product={product} />
<LabelList>{product.badge && product.badge.map((e) => <Label badgeName={e} />)}</LabelList>
</StyledLi>
<Modal>
{modalState && (
<ModalBackground>
<ModalContainer>
<ModalCard product={{ ...product, ...detail }} />
<IconButton type="CLOSE" fn={() => setModalState(false)} margin={10} />
</ModalContainer>
</ModalBackground>
)}
</Modal>
</>
);
};

const StyledLi = styled.li`
width: ${(props) => props.cardSize};
margin: 0 ${(props) => props.margin}px;
list-style: none;
`;

const ModalBackground = styled(CenterContainer)`
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.4);
width: 100%;
height: 100%;
`;

const ModalContainer = styled.div`
display: flex;
align-items: flex-start;
position: absolute;
left: 50%;
transform: translateX(-48%);
`;

export default Card;
64 changes: 64 additions & 0 deletions banchan/src/components/componentUtils/card/Thumbnail.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { CenterContainer } from "../styles/common";
import styled from "styled-components";

const mockImage = "https://recipe1.ezmember.co.kr/cache/recipe/2020/09/23/5e308abb30b00ecb9c1b9b398db5b4451.jpg";

const Thumbnail = ({ product, cardSize, type }) => {
return (
<StyledThumbnail>
<HoverLayer cardSize={cardSize}>
<DeliveryTypeList>
{product.delivery_type.reduce((acc, val, index, array) => {
acc.push(
<p>
{val}
{index < array.length - 1 && <Divider />}
</p>
);
return acc;
}, [])}
</DeliveryTypeList>
</HoverLayer>
<StyledImg cardSize={cardSize} src={type === "베스트" ? mockImage : product.image} alt="card-image" />
</StyledThumbnail>
);
};

export default Thumbnail;

const StyledThumbnail = styled.div`
position: relative;
`;

const HoverLayer = styled(CenterContainer)`
color: ${(props) => props.theme.colors.white};
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: ${(props) => props.cardSize};
height: ${(props) => props.cardSize};
border-radius: ${(props) => props.theme.borders.radius};
font-size: ${(props) => props.theme.fontSizes.XL};
font-weight: bold;
&:hover {
background: linear-gradient(0deg, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6));
opacity: 1;
}
`;

const DeliveryTypeList = styled.div``;

const Divider = styled.div`
border: 1px solid ${(props) => props.theme.colors.white};
width: 90px;
margin: 16px 0;
`;

const StyledImg = styled.img`
border-radius: ${(props) => props.theme.borders.radius};
margin-bottom: 16px;
width: ${(props) => props.cardSize};
height: ${(props) => props.cardSize};
`;
Loading

0 comments on commit 2bdef3a

Please sign in to comment.