-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FE] feature: 제출할 리뷰를 한 번에 볼 수 있는 preview 모달 제작 #302
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
7a95e58
refactor: Checkbox 컴포넌트를 readonly로 사용할 수 있도록 isReadonly 속성 추가
ImxYJL 116e818
refactor: Checkbox 컴포넌트에 rest props 적용
ImxYJL a862d12
chore: 프리뷰 모달을 표시하기 위한 컴포넌트 복사 (로컬 시연용 코드 복사)
ImxYJL b3a19e3
feat: ContentModal 제작
ImxYJL 55c3689
chore: 누락된 컴포넌트 스타일 업로드
ImxYJL b2809b8
chore: 프리뷰 모달 출력을 위한 모킹 데이터 및 타입 추가
ImxYJL c025476
feat: 작성한 모든 항목 프리뷰 모달 작성
ImxYJL bd8352b
chore: 프리뷰 모달 확인용 임시 페이지 작성
ImxYJL 287041d
chore: 인터페이스의 중복 속성 제거
ImxYJL 27fa4fd
refactor: Content 모달 스크롤바 부활
ImxYJL 0871beb
refactor: 스타일 및 그에 따른 레이아웃 수정
ImxYJL File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
115 changes: 115 additions & 0 deletions
115
frontend/src/components/AnswerListPreviewModal/answerList.ts
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,115 @@ | ||
interface Option { | ||
optionId: number; | ||
content: string; | ||
isChecked: boolean; | ||
} | ||
|
||
interface OptionGroup { | ||
optionGroupId: number; | ||
minCount: number; | ||
maxCount: number; | ||
options: Option[]; | ||
} | ||
|
||
interface BaseQuestion { | ||
questionId: number; | ||
required: boolean; | ||
questionType: 'CHECKBOX' | 'TEXT'; | ||
content: string; | ||
} | ||
|
||
interface CheckboxQuestion extends BaseQuestion { | ||
questionType: 'CHECKBOX'; | ||
optionGroup: OptionGroup; | ||
} | ||
|
||
interface TextQuestion extends BaseQuestion { | ||
questionType: 'TEXT'; | ||
optionGroup: null; | ||
hasGuideline: boolean; | ||
guideline: string | null; | ||
answer: string | null; | ||
} | ||
|
||
type Question = CheckboxQuestion | TextQuestion; | ||
|
||
export interface Section { | ||
sectionId: number; | ||
header: string; | ||
questions: Question[]; | ||
} | ||
|
||
// NOTE: 리뷰 상세 조회의 Section 속성 이하를 가져옴 | ||
export const ANSWER_LIST: Section[] = [ | ||
{ | ||
sectionId: 1, | ||
header: '기억을 떠올려볼게요.', | ||
questions: [ | ||
{ | ||
questionId: 1, | ||
required: true, | ||
questionType: 'CHECKBOX', | ||
content: '프로젝트 기간동안 강점이 드러난 ~ 골라주세요', | ||
optionGroup: { | ||
optionGroupId: 1, | ||
minCount: 1, | ||
maxCount: 2, | ||
options: [ | ||
{ optionId: 1, content: '코드리뷰', isChecked: true }, | ||
{ optionId: 2, content: '프로젝트 관리', isChecked: false }, | ||
{ optionId: 3, content: '커뮤니케이션 능력', isChecked: true }, | ||
], | ||
}, | ||
}, | ||
], | ||
}, | ||
|
||
{ | ||
sectionId: 2, | ||
header: '이제 선택한 순간을 바탕으로 리뷰를 작성해볼게요', | ||
questions: [ | ||
{ | ||
questionId: 2, | ||
required: true, | ||
questionType: 'CHECKBOX', | ||
content: '어떤 부분이 인상깊었나요 ?', | ||
optionGroup: { | ||
optionGroupId: 1, | ||
minCount: 1, | ||
maxCount: 3, | ||
options: [ | ||
{ optionId: 4, content: '코드리뷰', isChecked: true }, | ||
{ optionId: 5, content: '프로젝트 관리', isChecked: true }, | ||
{ optionId: 6, content: '커뮤니케이션 능력', isChecked: false }, | ||
], | ||
}, | ||
}, | ||
{ | ||
questionId: 3, | ||
required: true, | ||
questionType: 'TEXT', | ||
content: '인상깊은 상황을 이야기해주세요', | ||
optionGroup: null, | ||
hasGuideline: true, | ||
guideline: '가이드라인', | ||
answer: '쑤쑤 쑤퍼노바 인상깊어요', | ||
}, | ||
], | ||
}, | ||
{ | ||
sectionId: 3, | ||
header: '응원의 한마디를 남겨주세요', | ||
questions: [ | ||
{ | ||
questionId: 4, | ||
required: false, | ||
questionType: 'TEXT', | ||
content: '응원의 한마디', | ||
optionGroup: null, | ||
hasGuideline: false, | ||
guideline: null, | ||
answer: '응원합니다 화이팅!!', | ||
}, | ||
], | ||
}, | ||
]; |
14 changes: 14 additions & 0 deletions
14
frontend/src/components/AnswerListPreviewModal/components/QuestionCard/index.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,14 @@ | ||
import { QuestionCardStyleType } from '@/types'; | ||
|
||
import * as S from './styles'; | ||
|
||
interface QuestionCardProps { | ||
questionType: QuestionCardStyleType; | ||
question: string; | ||
} | ||
|
||
const QuestionCard = ({ questionType, question }: QuestionCardProps) => { | ||
return <S.QuestionCard questionType={questionType}>{question}</S.QuestionCard>; | ||
}; | ||
|
||
export default QuestionCard; |
11 changes: 11 additions & 0 deletions
11
frontend/src/components/AnswerListPreviewModal/components/QuestionCard/styles.ts
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,11 @@ | ||
import styled from '@emotion/styled'; | ||
|
||
import { QuestionCardStyleType } from '@/types'; | ||
|
||
export const QuestionCard = styled.div<{ questionType: QuestionCardStyleType }>` | ||
margin-bottom: 2rem; | ||
font-size: ${({ questionType, theme }) => (questionType === 'guideline' ? theme.fontSize.basic : '1.8rem')}; | ||
font-weight: ${({ questionType, theme }) => | ||
questionType === 'guideline' ? theme.fontWeight.normal : theme.fontWeight.semibold}; | ||
color: ${({ questionType, theme }) => (questionType === 'guideline' ? theme.colors.placeholder : theme.colors.black)}; | ||
`; |
20 changes: 20 additions & 0 deletions
20
frontend/src/components/AnswerListPreviewModal/components/ReviewWritingCard/index.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,20 @@ | ||
import { EssentialPropsWithChildren } from '@/types'; | ||
|
||
import * as S from './styles'; | ||
|
||
interface ReviewWritingCardProps { | ||
title: string; | ||
} | ||
|
||
const ReviewWritingCard = ({ title, children }: EssentialPropsWithChildren<ReviewWritingCardProps>) => { | ||
return ( | ||
<S.Container> | ||
<S.Header> | ||
<S.Title>{title}</S.Title> | ||
</S.Header> | ||
<S.Main>{children}</S.Main> | ||
</S.Container> | ||
); | ||
}; | ||
|
||
export default ReviewWritingCard; |
23 changes: 23 additions & 0 deletions
23
frontend/src/components/AnswerListPreviewModal/components/ReviewWritingCard/styles.ts
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,23 @@ | ||
import styled from '@emotion/styled'; | ||
|
||
export const Container = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
`; | ||
|
||
export const Header = styled.div` | ||
width: 100%; | ||
height: 5rem; | ||
padding: 1rem 2rem; | ||
background-color: ${({ theme }) => theme.colors.lightPurple}; | ||
`; | ||
|
||
export const Main = styled.div` | ||
padding: 2rem; | ||
`; | ||
|
||
export const Title = styled.span` | ||
margin-bottom: 2rem; | ||
font-size: ${({ theme }) => theme.fontSize.mediumSmall}; | ||
font-weight: ${({ theme }) => theme.fontWeight.semibold}; | ||
`; |
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,56 @@ | ||
import { Fragment } from 'react'; | ||
|
||
import CheckboxItem from '../common/CheckboxItem'; | ||
import ContentModal from '../common/modals/ContentModal'; | ||
|
||
import { Section } from './answerList'; | ||
import QuestionCard from './components/QuestionCard'; | ||
import ReviewWritingCard from './components/ReviewWritingCard'; | ||
import * as S from './styles'; | ||
|
||
interface AnswerListPreviewModalProps { | ||
answerList: Section[]; | ||
closeModal: () => void; | ||
} | ||
|
||
const AnswerListPreviewModal = ({ answerList, closeModal }: AnswerListPreviewModalProps) => { | ||
return ( | ||
<ContentModal handleClose={closeModal}> | ||
<S.AnswerListContainer> | ||
<S.CardLayout> | ||
{answerList.map((section) => ( | ||
<S.ReviewWritingCardWrapper key={section.sectionId}> | ||
<ReviewWritingCard title={section.header}> | ||
{section.questions.map((question) => ( | ||
<Fragment key={question.questionId}> | ||
<QuestionCard questionType="normal" question={question.content} /> | ||
<S.ContentContainer> | ||
{question.questionType === 'CHECKBOX' && ( | ||
<div> | ||
{question.optionGroup?.options.map((option, index) => ( | ||
<CheckboxItem | ||
key={`${question.questionId}_${index}`} | ||
id={`${question.questionId}_${index}`} | ||
name={`${question.questionId}_${index}`} | ||
isChecked={option.isChecked} | ||
isDisabled={true} | ||
label={option.content} | ||
$isReadonly={true} | ||
/> | ||
))} | ||
</div> | ||
)} | ||
<div>{question.questionType === 'TEXT' && <div>{question.answer ?? ''}</div>}</div> | ||
</S.ContentContainer> | ||
</Fragment> | ||
))} | ||
</ReviewWritingCard> | ||
</S.ReviewWritingCardWrapper> | ||
))} | ||
</S.CardLayout> | ||
</S.AnswerListContainer> | ||
</ContentModal> | ||
); | ||
}; | ||
|
||
export default AnswerListPreviewModal; |
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,27 @@ | ||
import styled from '@emotion/styled'; | ||
|
||
export const AnswerListContainer = styled.div``; | ||
|
||
export const CardLayout = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
|
||
gap: 1.2rem; | ||
position: relative; | ||
|
||
overflow: hidden; | ||
|
||
width: ${({ theme }) => theme.formWidth}; | ||
`; | ||
|
||
export const ContentContainer = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
gap: 3rem; | ||
`; | ||
|
||
export const ReviewWritingCardWrapper = styled.div` | ||
overflow: hidden; | ||
border: 0.2rem solid ${({ theme }) => theme.colors.lightPurple}; | ||
border-radius: ${({ theme }) => theme.borderRadius.basic}; | ||
`; |
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
30 changes: 30 additions & 0 deletions
30
frontend/src/components/common/modals/ContentModal/index.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,30 @@ | ||
import CloseIcon from '@/assets/x.svg'; | ||
import { EssentialPropsWithChildren } from '@/types'; | ||
|
||
import ModalBackground from '../ModalBackground'; | ||
import ModalPortal from '../ModalPortal'; | ||
|
||
import * as S from './styles'; | ||
|
||
interface ContentModalProps { | ||
handleClose: () => void; | ||
} | ||
|
||
const ContentModal = ({ handleClose, children }: EssentialPropsWithChildren<ContentModalProps>) => { | ||
return ( | ||
<ModalPortal> | ||
<ModalBackground closeModal={handleClose}> | ||
<S.ContentModalContainer> | ||
<S.ContentModalHeader> | ||
<S.CloseButton onClick={handleClose}> | ||
<img src={CloseIcon} alt="모달 닫기" /> | ||
</S.CloseButton> | ||
</S.ContentModalHeader> | ||
<S.Contents>{children}</S.Contents> | ||
</S.ContentModalContainer> | ||
</ModalBackground> | ||
</ModalPortal> | ||
); | ||
}; | ||
|
||
export default ContentModal; |
44 changes: 44 additions & 0 deletions
44
frontend/src/components/common/modals/ContentModal/styles.ts
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,44 @@ | ||
import styled from '@emotion/styled'; | ||
|
||
export const ContentModalContainer = styled.div` | ||
position: fixed; | ||
top: 50%; | ||
left: 50%; | ||
transform: translate(-50%, -50%); | ||
|
||
display: flex; | ||
flex-direction: column; | ||
gap: 2rem; | ||
align-items: center; | ||
|
||
min-width: 30rem; | ||
max-width: 80vw; | ||
max-height: 90vh; | ||
padding: 3.2rem; | ||
|
||
background-color: ${({ theme }) => theme.colors.white}; | ||
border-radius: ${({ theme }) => theme.borderRadius.basic}; | ||
|
||
overflow: hidden; | ||
`; | ||
|
||
export const ContentModalHeader = styled.div` | ||
display: flex; | ||
justify-content: flex-end; | ||
width: 100%; | ||
height: 3rem; | ||
`; | ||
|
||
export const Contents = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
white-space: pre-line; | ||
|
||
overflow-y: auto; | ||
`; | ||
|
||
export const CloseButton = styled.button` | ||
width: 2.4rem; | ||
height: 2.4rem; | ||
`; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
컨벤션에 맞게
handleChange
로 수정해야 할 것 같아요