-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: 슬라이더 방식으로 질문 카드가 자연스럽게 전환되는 기능 추가
- Loading branch information
Showing
3 changed files
with
112 additions
and
1 deletion.
There are no files selected for viewing
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
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,76 @@ | ||
import { useEffect, useRef, useState } from 'react'; | ||
|
||
import { Button } from '@/components'; | ||
import QuestionCard from '@/components/QuestionCard'; | ||
import ReviewWritingCard from '@/components/ReviewWritingCard'; | ||
import { ButtonStyleType } from '@/types'; | ||
|
||
import * as S from './styles'; | ||
|
||
const REVIEWEE = '쑤쑤'; | ||
|
||
const QUESTIONS = [ | ||
{ | ||
title: `💡${REVIEWEE}와 함께 한 기억을 떠올려볼게요.`, | ||
question: `프로젝트 기간 동안, ${REVIEWEE}의 강점이 드러났던 순간을 선택해주세요. (1~2개)`, | ||
}, | ||
{ | ||
title: `선택한 순간들을 바탕으로 ${REVIEWEE}에 대한 리뷰를 작성해볼게요.`, | ||
question: `커뮤니케이션, 협업 능력에서 어떤 부분이 인상 깊었는지 선택해주세요. (1개 이상)`, | ||
}, | ||
{ | ||
title: ``, | ||
question: `앞으로의 성장을 위해서 ${REVIEWEE}가 어떤 목표를 설정하면 좋을까요?`, | ||
}, | ||
]; | ||
|
||
const ReviewWritingFormPage = () => { | ||
const [currentIndex, setCurrentIndex] = useState(0); | ||
const [slideWidth, setSlideWidth] = useState(0); | ||
|
||
const wrapperRef = useRef<HTMLDivElement | null>(null); | ||
|
||
useEffect(() => { | ||
if (wrapperRef.current) setSlideWidth(wrapperRef.current.clientWidth); | ||
}, [wrapperRef]); | ||
|
||
const handlePrev = () => { | ||
if (currentIndex > 0) { | ||
setCurrentIndex(currentIndex - 1); | ||
} | ||
}; | ||
|
||
const handleNext = () => { | ||
if (currentIndex < QUESTIONS.length - 1) { | ||
setCurrentIndex(currentIndex + 1); | ||
} | ||
}; | ||
|
||
const buttons = [ | ||
{ styleType: 'secondary' as ButtonStyleType, onClick: handlePrev, text: '이전' }, | ||
{ styleType: 'primary' as ButtonStyleType, onClick: handleNext, text: '다음' }, | ||
]; | ||
|
||
return ( | ||
<S.CardLayout> | ||
<S.SliderContainer ref={wrapperRef} translateX={currentIndex * slideWidth}> | ||
{QUESTIONS.map(({ question, title }, index) => ( | ||
<S.Slide key={index}> | ||
<ReviewWritingCard title={title}> | ||
<QuestionCard questionType="normal" question={question} /> | ||
</ReviewWritingCard> | ||
</S.Slide> | ||
))} | ||
</S.SliderContainer> | ||
<S.ButtonContainer> | ||
{buttons.map((button, index) => ( | ||
<Button key={index} styleType={button.styleType} onClick={button.onClick}> | ||
{button.text} | ||
</Button> | ||
))} | ||
</S.ButtonContainer> | ||
</S.CardLayout> | ||
); | ||
}; | ||
|
||
export default ReviewWritingFormPage; |
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,32 @@ | ||
import styled from '@emotion/styled'; | ||
|
||
export const CardLayout = styled.div` | ||
position: relative; | ||
overflow: hidden; | ||
width: ${({ theme }) => theme.formWidth}; | ||
border-radius: ${({ theme }) => theme.borderRadius.basic}; | ||
border: 0.1rem solid ${({ theme }) => theme.colors.lightPurple}; | ||
`; | ||
|
||
export const SliderContainer = styled.div<{ translateX: number }>` | ||
transform: ${({ translateX }) => `translateX(-${translateX}px)`}; | ||
display: flex; | ||
width: 100%; | ||
transition: transform 0.5s ease-in-out; | ||
`; | ||
|
||
export const Slide = styled.div` | ||
flex: 0 0 100%; | ||
box-sizing: border-box; | ||
`; | ||
|
||
export const ButtonContainer = styled.div` | ||
display: flex; | ||
justify-content: flex-end; | ||
gap: 2rem; | ||
button { | ||
width: 10rem; | ||
} | ||
`; |