-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f5979ba
commit 1f14558
Showing
17 changed files
with
390 additions
and
2 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
26 changes: 26 additions & 0 deletions
26
apps/jurumarble/src/app/onboarding/components/BottomButton.tsx
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,26 @@ | ||
'use client'; | ||
|
||
import { Button } from 'components/button'; | ||
import { getClassNames } from 'lib/styles/getClassNames'; | ||
import { useRouter } from 'next/navigation'; | ||
|
||
import styles from '../page.module.css'; | ||
|
||
const BottomButton = () => { | ||
const router = useRouter(); | ||
const cx = getClassNames(styles); | ||
return ( | ||
<div className={cx('bottom-wrapper')}> | ||
<Button | ||
width="100%" | ||
height="56px" | ||
variant="primary" | ||
onClick={() => router.push('/')} | ||
> | ||
시작하기 | ||
</Button> | ||
</div> | ||
); | ||
}; | ||
|
||
export default BottomButton; |
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,28 @@ | ||
.container { | ||
width: 100%; | ||
display: flex; | ||
justify-content: center; | ||
/* background-color: var(--bg_01); */ | ||
padding-bottom: 96px; | ||
} | ||
|
||
.container img { | ||
width: 100%; | ||
height: 100%; | ||
object-fit: cover; | ||
} | ||
|
||
.img-wrapper { | ||
max-width: 720px; | ||
margin: 0 auto; | ||
background-color: var(--white); | ||
} | ||
|
||
.bottom-wrapper { | ||
position: fixed; | ||
bottom: 0; | ||
padding: 20px; | ||
width: 100%; | ||
max-width: 480px; | ||
background-color: var(--white); | ||
} |
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 { getClassNames } from 'lib/styles/getClassNames'; | ||
import Image from 'next/image'; | ||
import { Onboarding } from 'public/images'; | ||
|
||
import BottomButton from './components/BottomButton'; | ||
import styles from './page.module.css'; | ||
|
||
const OnboardingPage = () => { | ||
const cx = getClassNames(styles); | ||
|
||
return ( | ||
<div className={cx('container')}> | ||
<div className={cx('img-wrapper')}> | ||
<Image src={Onboarding} width={375} height={2112} alt="온보딩" /> | ||
</div> | ||
<BottomButton /> | ||
</div> | ||
); | ||
}; | ||
|
||
export default OnboardingPage; |
276 changes: 276 additions & 0 deletions
276
apps/jurumarble/src/app/vote/components/OnboardingBottomsheet.tsx
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,276 @@ | ||
import { forwardRef, useRef, useState } from 'react'; | ||
|
||
import { Portal } from 'components/index'; | ||
import { transitions } from 'lib/styles'; | ||
import Image, { StaticImageData } from 'next/image'; | ||
import { | ||
DesktopOnboarding1, | ||
DesktopOnboarding2, | ||
DesktopOnboarding3, | ||
DesktopOnboarding4, | ||
MobileOnboarding1, | ||
MobileOnboarding2, | ||
MobileOnboarding3, | ||
} from 'public/images'; | ||
import { SvgIcX } from 'src/assets/icons/components'; | ||
import styled, { css } from 'styled-components'; | ||
|
||
interface CardProps { | ||
title: string; | ||
description: string; | ||
imgSrc: string | StaticImageData; | ||
} | ||
|
||
const Card = forwardRef<HTMLDivElement, CardProps>( | ||
({ title, description, imgSrc }, ref) => { | ||
return ( | ||
<CardWrapper ref={ref}> | ||
<div className="title">{title}</div> | ||
<div className="description">{description}</div> | ||
<Image className="img" src={imgSrc} alt="img" /> | ||
</CardWrapper> | ||
); | ||
}, | ||
); | ||
|
||
interface Props { | ||
onToggleOnboarding: () => void; | ||
} | ||
|
||
const TAB_LIST = [ | ||
{ tabName: '후보 확대', id: 'enlarge' }, | ||
{ tabName: '후보 선택', id: 'select' }, | ||
{ tabName: '투표 이동', id: 'move' }, | ||
{ tabName: '자세히 보기', id: 'detail' }, | ||
]; | ||
|
||
const CARD_LIST = [ | ||
{ | ||
title: '후보를 확대해서 보기', | ||
description: '마우스를 후보에 올리거나 좌우 방향키를 이용하세요.', | ||
imgSrc: DesktopOnboarding1, | ||
mobileImgSrc: MobileOnboarding1, | ||
}, | ||
{ | ||
title: '투표 후보를 선택하기', | ||
description: '원하는 후보를 클릭하세요.', | ||
imgSrc: DesktopOnboarding2, | ||
mobileImgSrc: MobileOnboarding2, | ||
}, | ||
{ | ||
title: '자세한 내용을 확인하기', | ||
description: '스크롤을 하거나 상하 방향키를 이용하세요.', | ||
imgSrc: DesktopOnboarding3, | ||
mobileImgSrc: MobileOnboarding3, | ||
}, | ||
{ | ||
title: '자세히 보기', | ||
description: '더보기 버튼을 클릭해주세요.', | ||
imgSrc: DesktopOnboarding4, | ||
mobileImgSrc: MobileOnboarding1, | ||
}, | ||
]; | ||
|
||
const OnboardingBottomsheet = ({ onToggleOnboarding }: Props) => { | ||
const [chip, setChip] = useState('mobile'); | ||
|
||
const card1Ref = useRef<HTMLDivElement>(null); | ||
const card2Ref = useRef<HTMLDivElement>(null); | ||
const card3Ref = useRef<HTMLDivElement>(null); | ||
const card4Ref = useRef<HTMLDivElement>(null); | ||
|
||
const cardRefs = [card1Ref, card2Ref, card3Ref, card4Ref]; | ||
|
||
// 탭 클릭시 ref로 이동하는 함수 | ||
|
||
const handleTabClick = (index: number) => { | ||
cardRefs[index]?.current?.scrollIntoView({ | ||
behavior: 'smooth', | ||
block: 'nearest', | ||
inline: 'center', | ||
}); | ||
}; | ||
|
||
return ( | ||
<Portal selector="#portal"> | ||
<BottomSheet> | ||
<Inner> | ||
<Exit onClick={onToggleOnboarding}> | ||
<SvgIcX /> | ||
</Exit> | ||
<Title>투표를 좀 더 재밌게 참여해 볼까요?</Title> | ||
<Description> | ||
투표는 여러가지 조작 방법을 통해 참여할 수 있어요. | ||
</Description> | ||
<TabWrapper> | ||
{TAB_LIST.map(({ id, tabName }, index) => ( | ||
<Tab | ||
key={id} | ||
active={id === 'enlarge'} | ||
onClick={() => handleTabClick(index)} | ||
> | ||
{tabName} | ||
</Tab> | ||
))} | ||
</TabWrapper> | ||
<ChipWrapper> | ||
<Chip active={chip === 'mobile'} onClick={() => setChip('mobile')}> | ||
모바일 | ||
</Chip> | ||
<Chip | ||
active={chip === 'desktop'} | ||
onClick={() => setChip('desktop')} | ||
> | ||
PC | ||
</Chip> | ||
</ChipWrapper> | ||
{CARD_LIST.map( | ||
({ title, description, imgSrc, mobileImgSrc }, index) => ( | ||
<Card | ||
key={title} | ||
title={title} | ||
description={description} | ||
imgSrc={chip === 'mobile' ? imgSrc : mobileImgSrc} | ||
ref={cardRefs[index]} | ||
/> | ||
), | ||
)} | ||
</Inner> | ||
<Background onClick={onToggleOnboarding} /> | ||
</BottomSheet> | ||
</Portal> | ||
); | ||
}; | ||
|
||
const BottomSheet = styled.div` | ||
position: fixed; | ||
width: 100%; | ||
height: 100%; | ||
top: 0; | ||
left: 0; | ||
z-index: 9999; | ||
`; | ||
|
||
const Inner = styled.div` | ||
position: absolute; | ||
z-index: 9999; | ||
background-color: white; | ||
bottom: 0; | ||
right: 0; | ||
left: 0; | ||
margin: auto; | ||
width: 100%; | ||
max-width: 720px; | ||
height: 90%; | ||
animation: ${transitions.popInFromBottom} 0.4s ease-in-out; | ||
border-radius: 16px 16px 0px 0px; | ||
overflow-y: scroll; | ||
&::-webkit-scrollbar { | ||
display: none; | ||
} | ||
`; | ||
|
||
const Background = styled.div` | ||
display: block; | ||
width: 100%; | ||
height: 100%; | ||
background-color: black; | ||
position: absolute; | ||
left: 0; | ||
top: 0; | ||
opacity: 0.4; | ||
`; | ||
|
||
const Title = styled.div` | ||
display: flex; | ||
${({ theme }) => css` | ||
${theme.typography.headline02} | ||
`} | ||
justify-content: flex-start; | ||
padding: 64px 20px 0 20px; | ||
`; | ||
|
||
const Description = styled.div` | ||
display: flex; | ||
${({ theme }) => css` | ||
${theme.typography.body02} | ||
color: ${theme.colors.black_02}; | ||
`} | ||
padding:12px 20px 16px 20px; | ||
`; | ||
// padding: 26px 20px 20px 20px; | ||
const Exit = styled.div` | ||
position: absolute; | ||
top: 26px; | ||
right: 20px; | ||
width: 24px; | ||
height: 24px; | ||
cursor: pointer; | ||
`; | ||
|
||
const TabWrapper = styled.div` | ||
display: flex; | ||
padding: 16px 20px 0 20px; | ||
border-bottom: 1px solid ${({ theme }) => theme.colors.line_01}; | ||
`; | ||
|
||
const Tab = styled.div<{ active: boolean }>` | ||
padding: 16px 10px; | ||
width: 25%; | ||
text-align: center; | ||
cursor: pointer; | ||
${({ active, theme }) => | ||
active | ||
? css` | ||
${theme.typography.body01} | ||
color: ${({ theme }) => theme.colors.black_01}; | ||
border-bottom: 3px solid ${({ theme }) => theme.colors.black_01}; | ||
` | ||
: css` | ||
${theme.typography.body02} | ||
color: ${({ theme }) => theme.colors.black_03}; | ||
`} | ||
`; | ||
|
||
const ChipWrapper = styled.div` | ||
padding: 28px 20px; | ||
display: flex; | ||
gap: 4px; | ||
`; | ||
|
||
const Chip = styled.div<{ active: boolean }>` | ||
padding: 10px; | ||
border-radius: 4px; | ||
cursor: pointer; | ||
${({ theme, active }) => css` | ||
${theme.typography.caption_chip} | ||
color: ${active ? theme.colors.white : theme.colors.black_02}; | ||
background-color: ${active ? theme.colors.black_02 : theme.colors.bg_01}; | ||
`} | ||
`; | ||
|
||
const CardWrapper = styled.div` | ||
padding: 0 20px; | ||
margin-bottom: 42px; | ||
.title { | ||
padding-bottom: 4px; | ||
${({ theme }) => css` | ||
${theme.typography.body01} | ||
`} | ||
} | ||
.description { | ||
${({ theme }) => css` | ||
${theme.typography.body_long03} | ||
padding-bottom: 16px; | ||
`} | ||
} | ||
.img { | ||
width: 100%; | ||
height: 100%; | ||
border-radius: 16px; | ||
} | ||
`; | ||
|
||
export default OnboardingBottomsheet; |
Oops, something went wrong.