Skip to content

Commit

Permalink
[#6] 캐러셀 슬라이드 구현 완료
Browse files Browse the repository at this point in the history
  • Loading branch information
dudn1933 committed Apr 20, 2021
1 parent 692c487 commit ad8d9f5
Show file tree
Hide file tree
Showing 7 changed files with 494 additions and 11 deletions.
2 changes: 2 additions & 0 deletions FE/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"axios": "^0.21.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"styled-components": "^5.2.3",
"web-vitals": "^1.0.1"
},
"scripts": {
Expand Down
8 changes: 6 additions & 2 deletions FE/src/App.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import React from "react";
import styled from "styled-components";
import Main from "./Components/Main/Main";

const App = () => {
const URL =
"https://h3rb9c0ugl.execute-api.ap-northeast-2.amazonaws.com/develop/baminchan/";

return (
<div className="App">
<Main />
<div>
<Main URL={URL} />
</div>
);
};
Expand Down
102 changes: 102 additions & 0 deletions FE/src/Components/Main/Content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React from "react";
import styled from "styled-components";

const Content = ({
detail_hash,
image,
alt,
delivery_type,
title,
description,
n_price,
s_price,
badge,
}) => {
return (
<ContentMain>
<Image src={image} />
<Title>{title}</Title>
<Description>{description}</Description>

{n_price !== undefined ? (
<div>
<NPrice>{n_price}</NPrice>
<SPrice>{s_price}</SPrice>
</div>
) : (
<NPrice false>{s_price}</NPrice>
)}

{badge && <Badge>{badge}</Badge>}
</ContentMain>
);
};

const ContentMain = styled.div`
margin: 0 16px;
`;

const Image = styled.img`
width: 308px;
height: 308px;
border-radius: 5px;
`;

const Title = styled.div`
width: 308px;
font-family: Noto Sans KR;
font-style: normal;
font-weight: normal;
font-size: 16px;
line-height: 23px;
color: #333333;
`;

const Description = styled.div`
width: 308px;
color: #828282;
font-family: Noto Sans KR;
font-style: normal;
font-weight: normal;
font-size: 14px;
line-height: 20px;
`;
const NPrice = styled.span`
width: 73px;
font-family: Noto Sans KR;
font-style: normal;
font-weight: bold;
font-size: 20px;
line-height: 29px;
margin: 0 8px 0 0;
`;

const SPrice = styled.span`
width: 48px;
font-family: Noto Sans KR;
font-style: normal;
font-weight: normal;
font-size: 14px;
line-height: 20px;
text-decoration-line: line-through;
color: #bdbdbd;
margin: 0 8px;
`;

const Badge = styled.div`
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
padding: 4px 16px;
width: 62px;
height: 18px;
background: #82d32d;
border-radius: 5px;
color: white;
font-size: 14px;
line-height: 20px;
`;
export default Content;
164 changes: 161 additions & 3 deletions FE/src/Components/Main/Main.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,165 @@
import React from "react";
import React, { useState, useEffect, useRef } from "react";
import styled from "styled-components";
import axios from "axios";
import Content from "./Content";
import Svg from "../../Svg/Button";

const Main = () => {
return <div>zzz 스타트</div>;
const Main = ({ URL }) => {
const [List, setList] = useState([]);
const [Right, setRight] = useState(Svg.BeforeRight);
const [Left, setLeft] = useState(Svg.BeforeLeft);
const [xtransform, setXtransform] = useState("-1360");
const SlideRef = useRef(null);

const fetchData = async () => {
const data = await axios(URL + "main").then((res) => res.data.body);
setList(data.concat(data));
};

useEffect(() => {
fetchData();
}, []);

const MouseEnter = (e) => {
e.target.classList.contains("Left")
? setLeft(Svg.AfterLeft)
: setRight(Svg.AfterRight);
};
const MouseLeave = (e) => {
e.target.classList.contains("Left")
? setLeft(Svg.BeforeLeft)
: setRight(Svg.BeforeRight);
};

const Slider = (e) => {
const RightClass = e.target.classList.contains("Right");
const LeftClass = e.target.classList.contains("Left");
SlideRef.current.style.transition = "0.5s transform ease-in-out";

if (RightClass) {
SlideRef.current.style.transform = `translateX(${xtransform - 1360}px)`;
const first = List.slice(4, List.length);
const result = first.concat(List.slice(0, 4));

setTimeout(() => {
SlideRef.current.style.transition = "none";
SlideRef.current.style.transform = `translateX(-1360px)`;
setList(result);
}, 500);
}
if (LeftClass) {
SlideRef.current.style.transform = `translateX(${0}px)`;
const first = List.slice(4, List.length);
const result = first.concat(List.slice(0, 4));
setTimeout(() => {
SlideRef.current.style.transition = "none";
SlideRef.current.style.transform = "translateX(-1360px)";
setList(result);
}, 500);
}
};

return (
<Box className="zz">
<CarouselTitle>모두가 좋아하는 든든한 메인요리</CarouselTitle>
<CarouselContent>
<Button
className="Left"
onMouseEnter={MouseEnter}
onMouseLeave={MouseLeave}
onClick={Slider}
>
{Left}
</Button>
{
<Carousel>
<Image ref={SlideRef} xtransform={xtransform}>
{List.map(
(
{
detail_hash,
image,
alt,
delivery_type,
title,
description,
n_price,
s_price,
badge,
},
index
) => {
return (
<Content
key={index}
image={image}
alt={alt}
delivery_type={delivery_type}
title={title}
description={description}
n_price={n_price}
s_price={s_price}
badge={badge}
/>
);
}
)}
</Image>
</Carousel>
}
<Button
className="Right"
onMouseEnter={MouseEnter}
onMouseLeave={MouseLeave}
onClick={Slider}
>
{Right}
</Button>
</CarouselContent>
</Box>
);
};

const Box = styled.div`
width: 1392px;
height: 554px;
margin: auto;
`;

const CarouselTitle = styled.div`
width: 326px;
height: 35px;
margin: 0 36px;
font-family: Noto Sans KR;
font-style: normal;
font-weight: bold;
font-size: 24px;
line-height: 35px;
`;

const CarouselContent = styled.div`
display: flex;
`;
const Button = styled.button`
z-index: 1;
background-color: white;
border: none;
outline: none;
&:active {
transform: translateY(2px);
}
`;

const Carousel = styled.div`
display: flex;
overflow: hidden;
`;

const Image = styled.div`
transform: ${({ xtransform }) => `translateX(${xtransform}px)`};
z-index: 0;
display: flex;
`;

export default Main;
81 changes: 81 additions & 0 deletions FE/src/Svg/Button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
const BeforeRight = (
<svg
className="Right"
width="8"
height="14"
viewBox="0 0 8 14"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
className="Right"
d="M1 13L7 7L1 1"
stroke="#BDBDBD"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);

const AfterRight = (
<svg
className="Right"
width="8"
height="14"
viewBox="0 0 8 14"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
className="Right"
d="M1 13L7 7L1 1"
stroke="#333333"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);

const BeforeLeft = (
<svg
className="Left"
width="8"
height="14"
viewBox="0 0 8 14"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
className="Left"
d="M7 13L1 7L7 1"
stroke="#BDBDBD"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);

const AfterLeft = (
<svg
className="Left"
width="8"
height="14"
viewBox="0 0 8 14"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
className="Left"
d="M7 13L1 7L7 1"
stroke="#333333"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);

export default { BeforeRight, AfterRight, BeforeLeft, AfterLeft };
Loading

0 comments on commit ad8d9f5

Please sign in to comment.