From ec398833e941e58f88e14aa148f1cb6a0520e3b5 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 2 Mar 2024 14:35:47 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=ED=99=94=EB=A9=B4=20=ED=81=AC?= =?UTF-8?q?=EA=B8=B0=EC=97=90=20=EB=94=B0=EB=9D=BC=20WebSlider=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WebSlider/CircleWebSlideCard.tsx | 136 ++++++++++++++++++ .../components/WebSlider/CircleWebSlider.tsx | 22 +++ .../circle/home/components/WebSlider/index.ts | 1 + src/pages/circle/home/components/index.ts | 1 + 4 files changed, 160 insertions(+) create mode 100644 src/pages/circle/home/components/WebSlider/CircleWebSlideCard.tsx create mode 100644 src/pages/circle/home/components/WebSlider/CircleWebSlider.tsx create mode 100644 src/pages/circle/home/components/WebSlider/index.ts diff --git a/src/pages/circle/home/components/WebSlider/CircleWebSlideCard.tsx b/src/pages/circle/home/components/WebSlider/CircleWebSlideCard.tsx new file mode 100644 index 00000000..e120427f --- /dev/null +++ b/src/pages/circle/home/components/WebSlider/CircleWebSlideCard.tsx @@ -0,0 +1,136 @@ +import { css } from '@emotion/react'; +import styled from '@emotion/styled'; +import { memo, useState } from 'react'; +import { generatePath, useHistory } from 'react-router'; + +// import { Icons } from '@/assets'; +import { Article } from '@/assets/icons'; +import { ClearButton } from '@/components'; +import { PAGE_URL } from '@/configs/path'; + +export const CircleWebSlideCard: React.FC<{ model: Model.Circle }> = memo( + ({ model: { id: circleId, mainImage, name, newLineDescription } }) => { + const { push } = useHistory(); + const [isFlipped, setFlip] = useState(false); + const handleClick = () => { + if (isFlipped) setFlip(c => !c); + else push(generatePath(PAGE_URL.CircleJoin, { circleId })); + }; + const handleFlip = (e: React.MouseEvent) => { + e.stopPropagation(); + setFlip(c => !c); + }; + + return ( + + + + + + {name} +

+ + +

+ {name} + + + +
+
+
+ ); + }, +); + +const Card = styled.article` + box-sizing: border-box; + width: 90%; + max-width: 360px; + background: #fff; + border: 1px solid #dadada; + box-shadow: 1px 2px 5px rgb(0 0 0 / 15%); + border-radius: 5px; + overflow: hidden; + text-align: left; +`; + +const Body = styled.div` + position: absolute; + width: 100%; + height: calc(100% - 40px); + transition: transform 0.65s; + transform-style: preserve-3d; + + > div { + position: absolute; + backface-visibility: hidden; + } +`; + +const Cover = styled.div<{ mainImage: string | null }>` + top: 6px; + left: 6px; + width: calc(100% - 12px); + height: calc(100% - 6px); + border-radius: 5px; + + ${({ mainImage }) => + mainImage + ? css` + background: center / contain no-repeat url(${mainImage}); + ` + : css` + background: center / contain no-repeat url('/images/empty.png'); + background-size: 65%; + `} + background-color: #efefef; +`; + +const Name = styled.h3` + margin: 0 35px 0 13px; + line-height: 36px; + font-size: 12px; + font-weight: bold; + backface-visibility: hidden; +`; + +const Inner = styled.div<{ isFlipped: boolean }>` + position: relative; + width: 100%; + padding-bottom: 140%; // 5:7 비율 + + ${Body}, ${Name} { + transform: ${({ isFlipped }) => (isFlipped ? 'rotateY(180deg)' : 'rotateY(0deg)')}; + } +`; + +const Content = styled.div` + padding: 13px 9px; + width: 100%; + height: 100%; + background-color: #f8f8f8; + border-radius: 5px; + transform: rotateY(180deg); + overflow: hidden; +`; + +const ContentName = styled.div` + margin-bottom: 9px; + line-height: 18px; + font-size: 15px; + font-weight: bold; +`; + +const Footer = styled.div` + position: absolute; + bottom: 0; + width: 100%; + height: 40px; +`; + +const Icon = styled(Article)` + position: absolute; + top: 9px; + right: 5px; +`; diff --git a/src/pages/circle/home/components/WebSlider/CircleWebSlider.tsx b/src/pages/circle/home/components/WebSlider/CircleWebSlider.tsx new file mode 100644 index 00000000..6aa24ecd --- /dev/null +++ b/src/pages/circle/home/components/WebSlider/CircleWebSlider.tsx @@ -0,0 +1,22 @@ +import styled from '@emotion/styled'; +import { observer } from 'mobx-react-lite'; + +import { ListComponent } from '../CircleListFrame'; +import { CircleSlideCard } from '../Slider/CircleSlideCard'; + +export const CircleWebSlider: ListComponent = observer(({ items }) => { + return ( + + {items.map(item => ( + + ))} + + ); +}); + +const WebScrollWrapper = styled.div` + display: flex; + gap: 20px; + height: 400px; + overflow-x: auto; +`; diff --git a/src/pages/circle/home/components/WebSlider/index.ts b/src/pages/circle/home/components/WebSlider/index.ts new file mode 100644 index 00000000..b519abc6 --- /dev/null +++ b/src/pages/circle/home/components/WebSlider/index.ts @@ -0,0 +1 @@ +export { CircleWebSlider as WebSlider } from './CircleWebSlider'; diff --git a/src/pages/circle/home/components/index.ts b/src/pages/circle/home/components/index.ts index 30471392..1104a3a0 100644 --- a/src/pages/circle/home/components/index.ts +++ b/src/pages/circle/home/components/index.ts @@ -1,4 +1,5 @@ export * from './List'; export * from './Slider'; +export * from './WebSlider'; export { CircleListFrame as ListFrame } from './CircleListFrame';