diff --git a/frontend/src/mocks/mockData/detailedReviewMockData.ts b/frontend/src/mocks/mockData/detailedReviewMockData.ts index e0d2a8f48..ecdf9e882 100644 --- a/frontend/src/mocks/mockData/detailedReviewMockData.ts +++ b/frontend/src/mocks/mockData/detailedReviewMockData.ts @@ -5,26 +5,101 @@ export const DETAILED_PAGE_MOCK_API_SETTING_VALUES = { memberId: 2, }; -const ANSWER = - '림순의 바람은 그윽한 산들바람처럼 잔잔하게 흘러갔습니다. \n 눈부신 햇살이 그의 어깨를 감싸며, 푸른 하늘 아래 펼쳐진 들판을 바라보았습니다.\n 그의 마음은 자연의 아름다움 속에서 평온을 찾았고, 그 순간마다 삶의 소중함을 느꼈습니다.\n 그는 늘 그러한 순간들을 기억하며, 미래의 나날들을 기대했습니다. \n 바람은 여전히 그를 감싸며, 그의 마음 속 깊은 곳에 있는 꿈과 희망을 불러일으켰습니다.\n 림순은 미소 지으며 앞으로 나아갔습니다.림순의 바람은 그윽한 산들바람처럼 잔잔하게 흘러갔습니다. \n 눈부신 햇살이 그의 어깨를 감싸며, 푸른 하늘 아래 펼쳐진 들판을 바라보았습니다.\n 그의 마음은 자연의 아름다움 속에서 평온을 찾았고, 그 순간마다 삶의 소중함을 느꼈습니다.\n 그는 늘 그러한 순간들을 기억하며, 미래의 나날들을 기대했습니다. 림순의 바람은 그윽한 산들바람처럼 잔잔하게 흘러갔습니다. \n 눈부신 햇살이 그의 어깨를 감싸며, 푸른 하늘 아래 펼쳐진 들판을 바라보았습니다.\n 그의 마음은 자연의 아름다움 속에서 평온을 찾았고, 그 순간마다 삶의 소중함을 느꼈습니다.\n 그는 늘 그러한 순간들을 기억하며, 미래의 나날들을 기대했습니다. \n 바람은 여전히 그를 감싸며, 그의 마음 속 깊은 곳에 있는 꿈과 희망을 불러일으켰습니다.\n 림순은 미소 지으며 앞으로 나아갔습니다.림순의 바람은 그윽한 산들바람처럼 잔잔하게 흘러갔습니다. \n 눈부신 햇살이 그의 어깨를 감싸며, 푸른 하늘 아래 펼쳐진 들판을 바라보았습니다.\n 그의 마음은 자연의 아름다움 속에서 평온을 찾았고, 그 순간마다 삶의 소중함을 느꼈습니다.\n 그는 늘 그러한 순간들을 기억하며, 미래의 나날들을 기대했습니다. '; +const revieweeName = 'badahertz52'; export const DETAILED_REVIEW_MOCK_DATA: DetailReviewData = { - id: 123456, - createdAt: new Date('2024-07-16'), - revieweeName: 'badahertz52', + formId: 1, + revieweeName: revieweeName, projectName: 'review-me', - contents: [ + createdAt: '2024-05-05', + sections: [ { - id: 1, - question: '[공개] 동료의 개발 역량 향상을 위해 피드백을 남겨 주세요.', - answer: ANSWER, + sectionId: 1, + header: `💡 ${revieweeName}와 함께 한 기억을 떠올려볼게요.`, + questions: [ + { + questionId: 1, + required: true, + questionType: 'CHECKBOX', + content: `프로젝트 기간 동안, ${revieweeName}의 강점이 드러났던 순간을 선택해주세요. (1~2개)`, + optionGroup: { + optionGroupId: 1, + minCount: 1, + maxCount: 2, + options: [ + { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력', isChecked: true }, + { optionId: 2, content: '💡 문제 해결 능력', isChecked: false }, + ], + }, + }, + ], + }, + { + sectionId: 2, + header: '이제 선택한 순간을 바탕으로 리뷰를 작성해볼게요', + questions: [ + { + questionId: 2, + required: true, + questionType: 'CHECKBOX', + content: `${revieweeName}에서 어떤 부분이 인상 깊었는지 선택해주세요. (1개 이상)`, + optionGroup: { + optionGroupId: 1, + minCount: 1, + maxCount: 3, + options: [ + { + optionId: 4, + content: '반대 의견을 내더라도 듣는 사람이 기분 나쁘지 않게 이야기해요.', + isChecked: true, + }, + { optionId: 5, content: '팀원들의 의견을 잘 모아서 회의가 매끄럽게 진행되도록 해요.', isChecked: true }, + ], + }, + }, + { + questionId: 3, + required: true, + questionType: 'TEXT', + content: '위에서 선택한 사항에 대해 조금 더 자세히 설명해주세요.', + optionGroup: null, + hasGuideline: true, + guideline: `상황을 자세하게 기록할수록 ${revieweeName}에게 도움이 돼요. OO 덕분에 팀이 원활한 소통을 이뤘거나, 함께 일하면서 배울 점이 있었는지 떠올려 보세요.`, + answer: '쑤쑤 쑤퍼노바 인상깊어요', + }, + ], + }, + { + sectionId: 3, + header: '응원의 한마디를 남겨주세요', + questions: [ + { + questionId: 4, + required: true, + questionType: 'TEXT', + content: `앞으로의 성장을 위해서 ${revieweeName}이 어떤 목표를 설정하면 좋을까요?`, + optionGroup: null, + hasGuideline: true, + guideline: `어떤 점을 보완하면 좋을지와 함께 '이렇게 해보면 어떨까?'하는 간단한 솔루션을 제안해봐요.`, + answer: '어디까지 성장할려구~?', + }, + ], + }, + { + sectionId: 4, + header: '응원의 한마디를 남겨주세요', + questions: [ + { + questionId: 5, + required: false, + questionType: 'TEXT', + content: `${revieweeName}에게 전하고 싶은 다른 리뷰가 있거나 응원의 말이 있다면 적어주세요.`, + optionGroup: null, + hasGuideline: false, + guideline: null, + answer: '응원합니다 화이팅!!', + }, + ], }, - - { id: 2, question: '[공개] 동료의 소프트 스킬의 성장을 위해 피드백을 남겨 주세요.', answer: ANSWER }, - { id: 3, question: '[비공개] 팀 동료로 근무한다면 같이 일 하고 싶은 개발자인가요?', answer: ANSWER }, - ], - keywords: [ - { id: 11, content: '친절해요' }, - { id: 22, content: '이야기를 잘 들어줘요.' }, ], }; diff --git a/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/index.tsx b/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/index.tsx index abaabc85d..e8a32b743 100644 --- a/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/index.tsx +++ b/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/index.tsx @@ -7,6 +7,7 @@ import * as S from './styles'; interface DetailedReviewPageContentsProps { groupAccessCode: string; } + const DetailedReviewPageContents = ({ groupAccessCode }: DetailedReviewPageContentsProps) => { const { param: reviewId, queryString: memberId } = useSearchParamAndQuery({ paramKey: 'reviewId', @@ -30,10 +31,17 @@ const DetailedReviewPageContents = ({ groupAccessCode }: DetailedReviewPageConte handleClickToggleButton={() => console.log('click toggle ')} /> {/* 시연 때 숨김 */} - {detailedReview.contents.map(({ id, question, answer }, index) => ( + {/* {detailedReview.contents.map(({ id, question, answer }, index) => ( - ))} - + ))} */} + {detailedReview.sections.map((section) => + section.questions.map((question, index) => ( + + + {question.questionType === 'CHECKBOX' && } + + )), + )} ); }; diff --git a/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/styles.ts b/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/styles.ts index c4409e3a7..d04e98c0c 100644 --- a/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/styles.ts +++ b/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/styles.ts @@ -2,4 +2,11 @@ import styled from '@emotion/styled'; export const DetailedReviewPageContents = styled.div` width: ${({ theme }) => theme.formWidth}; + border: 0.1rem solid ${({ theme }) => theme.colors.lightPurple}; + border-radius: ${({ theme }) => theme.borderRadius.basic}; +`; + +export const ReviewContentContainer = styled.div` + margin-bottom: 7rem; + padding: 0 4rem; `; diff --git a/frontend/src/pages/DetailedReviewPage/components/KeywordSection/index.tsx b/frontend/src/pages/DetailedReviewPage/components/KeywordSection/index.tsx index 1096d9ee0..252bb6b09 100644 --- a/frontend/src/pages/DetailedReviewPage/components/KeywordSection/index.tsx +++ b/frontend/src/pages/DetailedReviewPage/components/KeywordSection/index.tsx @@ -1,22 +1,19 @@ -import { Keyword } from '@/types'; +import { Options } from '@/types'; -import ReviewSectionHeader from '../ReviewSectionHeader'; +// import ReviewSectionHeader from '../ReviewSectionHeader'; import * as S from './styles'; interface KeywordSectionProps { - keywords: Keyword[]; - index: number; + options: Options[]; } -const KEY_WORD_HEADER = '키워드'; -const KeywordSection = ({ keywords, index }: KeywordSectionProps) => { +const KeywordSection = ({ options }: KeywordSectionProps) => { return ( - - {keywords.map(({ id, content }) => ( - {content} + {options.map(({ optionId, content }) => ( + {content} ))} diff --git a/frontend/src/pages/DetailedReviewPage/components/KeywordSection/styles.ts b/frontend/src/pages/DetailedReviewPage/components/KeywordSection/styles.ts index b3b8900f8..3e186b1e8 100644 --- a/frontend/src/pages/DetailedReviewPage/components/KeywordSection/styles.ts +++ b/frontend/src/pages/DetailedReviewPage/components/KeywordSection/styles.ts @@ -2,13 +2,13 @@ import styled from '@emotion/styled'; export const KeywordSection = styled.section` width: 100%; - margin-top: 3.2rem; + margin-top: 2rem; `; export const KeywordContainer = styled.div` display: flex; flex-wrap: wrap; - row-gap: 3.2rem; + row-gap: 2.5rem; column-gap: 2.4rem; `; @@ -21,7 +21,7 @@ export const KeywordBox = styled.div` height: fit-content; padding: 0.8rem 2.5rem; - font-size: 1.6rem; + font-size: ${({ theme }) => theme.fontSize.small}; line-height: 2.4rem; text-align: center; diff --git a/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/index.tsx b/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/index.tsx index 8e4f477de..6c2dac8d7 100644 --- a/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/index.tsx +++ b/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/index.tsx @@ -2,7 +2,7 @@ import { ProjectImg, ReviewDate } from '@/components'; import { ProjectImgProps } from '@/components/common/ProjectImg'; import { ReviewDateProps } from '@/components/common/ReviewDate'; -import LockToggle from '../LockToggle'; +// import LockToggle from '../LockToggle'; import * as S from './styles'; @@ -19,9 +19,9 @@ const ReviewDescription = ({ thumbnailUrl, projectName, revieweeName, - isPublic, + // isPublic, date, - handleClickToggleButton, + // handleClickToggleButton, }: ReviewDescriptionProps) => { return ( diff --git a/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/styles.ts b/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/styles.ts index fa6daaa98..26543f61f 100644 --- a/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/styles.ts +++ b/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/styles.ts @@ -6,14 +6,20 @@ export const Description = styled.section` justify-content: space-between; width: 100%; - height: 6rem; + height: 9rem; margin: 0; - padding-left: 0; + + padding: 1rem 3rem; + + background-color: ${({ theme }) => theme.colors.lightPurple}; + border-radius: ${({ theme }) => theme.borderRadius.basic} 0 0; `; + export const DescriptionSide = styled.div` display: flex; width: 100%; `; + //NOTE: 6rem :깃헙 로고 사이즈 export const ProjectInfoContainer = styled.div` display: flex; @@ -43,6 +49,7 @@ export const RevieweeNameAndDateContainer = styled.div` export const RevieweeNameWrapper = styled.p` margin-top: 0; `; + export const RevieweeName = styled.span` color: ${({ theme }) => theme.colors.primary}; `; diff --git a/frontend/src/pages/DetailedReviewPage/components/ReviewSection/index.tsx b/frontend/src/pages/DetailedReviewPage/components/ReviewSection/index.tsx index 9c5f44311..fe29d99fd 100644 --- a/frontend/src/pages/DetailedReviewPage/components/ReviewSection/index.tsx +++ b/frontend/src/pages/DetailedReviewPage/components/ReviewSection/index.tsx @@ -4,20 +4,21 @@ import ReviewSectionHeader from '../ReviewSectionHeader'; import * as S from './styles'; -const INDEX_OFFSET = 1; +// const INDEX_OFFSET = 1; interface ReviewSectionProps { question: string; answer: string; - index: number; } -const ReviewSection = ({ question, answer, index }: ReviewSectionProps) => { +const ReviewSection = ({ question, answer }: ReviewSectionProps) => { return ( - - - - + + {answer && ( + + + + )} ); }; diff --git a/frontend/src/pages/DetailedReviewPage/components/ReviewSectionHeader/index.tsx b/frontend/src/pages/DetailedReviewPage/components/ReviewSectionHeader/index.tsx index ebc2b5a1f..50fa0dab5 100644 --- a/frontend/src/pages/DetailedReviewPage/components/ReviewSectionHeader/index.tsx +++ b/frontend/src/pages/DetailedReviewPage/components/ReviewSectionHeader/index.tsx @@ -1,16 +1,11 @@ import * as S from './styles'; interface ReviewSectionHeaderProps { - number: number; text: string; } -const ReviewSectionHeader = ({ number, text }: ReviewSectionHeaderProps) => { - return ( - - {number}. {text} - - ); +const ReviewSectionHeader = ({ text }: ReviewSectionHeaderProps) => { + return {text}; }; export default ReviewSectionHeader; diff --git a/frontend/src/pages/ReviewListPage/components/PageContents/styles.ts b/frontend/src/pages/ReviewListPage/components/PageContents/styles.ts index 3f0535b82..aa4c51ca3 100644 --- a/frontend/src/pages/ReviewListPage/components/PageContents/styles.ts +++ b/frontend/src/pages/ReviewListPage/components/PageContents/styles.ts @@ -4,7 +4,7 @@ export const Layout = styled.div` display: flex; flex-direction: column; gap: 4rem; - width: 80%; + width: ${({ theme }) => theme.formWidth}; `; export const ReviewSection = styled.div` diff --git a/frontend/src/pages/ReviewListPage/components/SearchSection/index.tsx b/frontend/src/pages/ReviewListPage/components/SearchSection/index.tsx index 9d1f19551..033261d43 100644 --- a/frontend/src/pages/ReviewListPage/components/SearchSection/index.tsx +++ b/frontend/src/pages/ReviewListPage/components/SearchSection/index.tsx @@ -12,7 +12,7 @@ const SearchSection = ({ handleChange, options, placeholder }: SearchSectionProp return ( - + diff --git a/frontend/src/pages/ReviewListPage/components/SearchSection/styles.ts b/frontend/src/pages/ReviewListPage/components/SearchSection/styles.ts index 10e881714..d0ece5d78 100644 --- a/frontend/src/pages/ReviewListPage/components/SearchSection/styles.ts +++ b/frontend/src/pages/ReviewListPage/components/SearchSection/styles.ts @@ -7,7 +7,7 @@ export const Container = styled.div` height: 4rem; button { - width: 9rem; + width: 8rem; color: ${({ theme }) => theme.colors.primary}; } `; diff --git a/frontend/src/styles/theme.ts b/frontend/src/styles/theme.ts index 2e0b9a84e..1892fac28 100644 --- a/frontend/src/styles/theme.ts +++ b/frontend/src/styles/theme.ts @@ -3,7 +3,7 @@ import { CSSProperties } from 'react'; import { ThemeProperty } from '../types'; -export const formWidth = '65rem'; +export const formWidth = '70rem'; export const sidebarWidth: ThemeProperty = { desktop: '25rem', mobile: '100vw', diff --git a/frontend/src/types/review.ts b/frontend/src/types/review.ts index 14b0f1ccf..de5fc8c45 100644 --- a/frontend/src/types/review.ts +++ b/frontend/src/types/review.ts @@ -8,19 +8,44 @@ export interface ReviewItem { answer: string; } -export interface DetailReviewContent { - id: number; - question: string; - answer: string; +export interface Options { + optionId: number; + content: string; + isChecked: boolean; +} + +export interface OptionGroup { + optionGroupId: number; + minCount: number; + maxCount: number; + options: Options[]; +} + +export type QuestionType = 'CHECKBOX' | 'TEXT'; + +export interface QuestionData { + questionId: number; + required: boolean; + questionType: QuestionType; + content: string; + optionGroup: OptionGroup | null; + hasGuideline?: boolean; + guideline?: string | null; + answer?: string; +} + +export interface DetailReviewSection { + sectionId: number; + header: string; + questions: QuestionData[]; } export interface DetailReviewData { - id: number; - createdAt: Date; - projectName: string; + formId: number; revieweeName: string; - contents: DetailReviewContent[]; - keywords: Keyword[]; + projectName: string; + createdAt: string; + sections: DetailReviewSection[]; } // api