diff --git a/frontend/src/components/common/OptionSwitch/styles.ts b/frontend/src/components/common/OptionSwitch/styles.ts index b2be3f531..2e2bf729f 100644 --- a/frontend/src/components/common/OptionSwitch/styles.ts +++ b/frontend/src/components/common/OptionSwitch/styles.ts @@ -10,13 +10,12 @@ export const OptionSwitchContainer = styled.ul` width: 20rem; height: 4.4rem; + margin-top: 0.9rem; padding: 0.7rem; background-color: ${({ theme }) => theme.colors.lightGray}; border-radius: ${({ theme }) => theme.borderRadius.basic}; - margin-top: 0.9rem; - @media screen and (max-width: 530px) { width: 100%; } diff --git a/frontend/src/components/ReviewCard/index.tsx b/frontend/src/components/common/ReviewCard/index.tsx similarity index 61% rename from frontend/src/components/ReviewCard/index.tsx rename to frontend/src/components/common/ReviewCard/index.tsx index 92baf19a9..57b7de1e6 100644 --- a/frontend/src/components/ReviewCard/index.tsx +++ b/frontend/src/components/common/ReviewCard/index.tsx @@ -1,5 +1,8 @@ import { Category } from '@/types'; +import ReviewDate from '../ReviewDate'; +import ReviewKeyword from '../ReviewKeyword'; + import * as S from './styles'; interface ReviewCardProps { @@ -10,19 +13,21 @@ interface ReviewCardProps { } const ReviewCard = ({ createdAt, contentPreview, categories, handleClick }: ReviewCardProps) => { + const date = new Date(createdAt); + return ( - {createdAt} + {contentPreview} - - {categories.map((category) => ( -
{category.content}
+ + {categories.map(({ optionId, content }) => ( + ))} -
+
diff --git a/frontend/src/components/ReviewCard/styles.ts b/frontend/src/components/common/ReviewCard/styles.ts similarity index 61% rename from frontend/src/components/ReviewCard/styles.ts rename to frontend/src/components/common/ReviewCard/styles.ts index 5d333823e..93786a694 100644 --- a/frontend/src/components/ReviewCard/styles.ts +++ b/frontend/src/components/common/ReviewCard/styles.ts @@ -5,15 +5,15 @@ import media from '@/utils/media'; export const Layout = styled.div` display: flex; flex-direction: column; - border: 0.1rem solid ${({ theme }) => theme.colors.lightGray}; + border: 0.2rem solid ${({ theme }) => theme.colors.disabled}; border-radius: 1rem; &:hover { cursor: pointer; - border: 0.15rem solid ${({ theme }) => theme.colors.primaryHover}; + border: 0.2rem solid ${({ theme }) => theme.colors.primaryHover}; - & > div:first-of-type { - background-color: ${({ theme }) => theme.colors.lightPurple}; + & > div { + background-color: ${({ theme }) => theme.colors.palePurple}; } } `; @@ -23,27 +23,22 @@ export const Header = styled.div` align-items: center; width: 100%; - height: 3.8rem; + padding: 2rem 0 0 2.5rem; - background-color: ${({ theme }) => theme.colors.lightGray}; border-radius: 1rem 1rem 0 0; `; -export const Date = styled.p` - height: fit-content; - padding: 0 3rem; - font-size: 1.3rem; -`; - export const Main = styled.div` display: flex; flex-direction: column; gap: 2rem; width: 100%; - padding: 2rem 3rem; + padding: 2rem 2.5rem; font-size: 1.6rem; + + border-radius: 0 0 1rem 1rem; `; export const ContentPreview = styled.p` @@ -52,10 +47,10 @@ export const ContentPreview = styled.p` -webkit-box-orient: vertical; -webkit-line-clamp: 3; - height: 6rem; + height: 7.5rem; padding-right: 2rem; - line-height: 2rem; + line-height: 2.5rem; text-overflow: ellipsis; overflow-wrap: break-word; `; @@ -73,21 +68,16 @@ export const Footer = styled.div` } `; -export const Keyword = styled.div` +export const ReviewKeywordList = styled.ul` display: flex; flex-wrap: wrap; gap: 2.5rem; align-items: center; - font-size: 1.4rem; + font-size: 1.2rem; + list-style-type: none; ${media.small} { gap: 1.2rem; } - - div { - padding: 0.5rem 3rem; - background-color: ${({ theme }) => theme.colors.lightPurple}; - border-radius: 0.8rem; - } `; diff --git a/frontend/src/components/common/ReviewDate/index.tsx b/frontend/src/components/common/ReviewDate/index.tsx index 8c86290cc..921d3e9b5 100644 --- a/frontend/src/components/common/ReviewDate/index.tsx +++ b/frontend/src/components/common/ReviewDate/index.tsx @@ -1,4 +1,3 @@ -import ClockIcon from '@/assets/clock.svg'; import { formatDate } from '@/utils'; import * as S from './styles'; @@ -10,15 +9,11 @@ export interface ReviewDateProps { const ReviewDate = ({ date, dateTitle }: ReviewDateProps) => { const { year, month, day } = formatDate(date); + return ( - - - {dateTitle} - : - - {year}-{month}-{day} + {dateTitle} | {year}.{month}.{day} ); diff --git a/frontend/src/components/common/ReviewDate/styles.ts b/frontend/src/components/common/ReviewDate/styles.ts index 6af512685..dc65be47b 100644 --- a/frontend/src/components/common/ReviewDate/styles.ts +++ b/frontend/src/components/common/ReviewDate/styles.ts @@ -2,31 +2,13 @@ import styled from '@emotion/styled'; import media from '@/utils/media'; -export const ReviewDateText = styled.div` - display: inline-flex; - align-items: center; - justify-content: center; - - ${media.small} { - display: none; - } -`; - -export const ClockImg = styled.img` - width: auto; - height: 1.6rem; - margin-right: 0.8rem; -`; - export const ReviewDate = styled.div` display: flex; align-items: center; + font-weight: ${({ theme }) => theme.fontWeight.semibold}; + color: ${({ theme }) => theme.colors.gray}; ${media.xSmall} { font-size: ${({ theme }) => theme.fontSize.small}; } `; - -export const Colon = styled.span` - margin: 0 1rem; -`; diff --git a/frontend/src/components/common/ReviewKeyword/index.tsx b/frontend/src/components/common/ReviewKeyword/index.tsx new file mode 100644 index 000000000..8b77f0c22 --- /dev/null +++ b/frontend/src/components/common/ReviewKeyword/index.tsx @@ -0,0 +1,11 @@ +import formatKeyword from '@/utils/formatKeyword'; + +import * as S from './styles'; + +const ReviewKeyword = ({ content }: { content: string }) => { + const formattedKeyword = formatKeyword(content); + + return {formattedKeyword}; +}; + +export default ReviewKeyword; diff --git a/frontend/src/components/common/ReviewKeyword/styles.ts b/frontend/src/components/common/ReviewKeyword/styles.ts new file mode 100644 index 000000000..7c5345aae --- /dev/null +++ b/frontend/src/components/common/ReviewKeyword/styles.ts @@ -0,0 +1,11 @@ +import styled from '@emotion/styled'; + +export const ReviewKeyword = styled.li` + padding: 0.5rem 2rem; + + font-weight: ${({ theme }) => theme.fontWeight.semibold}; + color: ${({ theme }) => theme.colors.primary}; + + background-color: ${({ theme }) => theme.colors.lightPurple}; + border-radius: 1.4rem; +`; diff --git a/frontend/src/mocks/mockData/detailedReviewMockData.ts b/frontend/src/mocks/mockData/detailedReviewMockData.ts index 919428f5c..db8e92858 100644 --- a/frontend/src/mocks/mockData/detailedReviewMockData.ts +++ b/frontend/src/mocks/mockData/detailedReviewMockData.ts @@ -26,8 +26,16 @@ export const DETAILED_REVIEW_MOCK_DATA: DetailReviewData = { minCount: 1, maxCount: 2, options: [ - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력', isChecked: true }, - { optionId: 2, content: '💡 문제 해결 능력', isChecked: false }, + { + optionId: 1, + content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)', + isChecked: true, + }, + { + optionId: 2, + content: '💡문제 해결 능력 (예: 프로젝트 중 만난 버그/오류를 분석하고 이를 해결하는 능력)', + isChecked: true, + }, ], }, }, diff --git a/frontend/src/mocks/mockData/reviewListMockData.ts b/frontend/src/mocks/mockData/reviewListMockData.ts index 8f9986c3d..7d73abd0c 100644 --- a/frontend/src/mocks/mockData/reviewListMockData.ts +++ b/frontend/src/mocks/mockData/reviewListMockData.ts @@ -10,8 +10,12 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2024-07-24', contentPreview: `1. 나는 짧은 데이터`, categories: [ - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, - { optionId: 5, content: '🌱 성장 마인드셋' }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, + { + optionId: 5, + content: + '🌱성장 마인드셋 (예: 새로운 분야나 잘 모르는 분야에 도전하는 마음, 꾸준한 노력으로 프로젝트 이전보다 성장하는 모습)', + }, ], }, { @@ -19,8 +23,8 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2023-08-29', contentPreview: `2. 전해주고 싶어 슬픈 시간이 다 흩어진 후에야 들리지만 눈을 감고 느껴봐 움직이는 마음 너를 향한 내 눈빛을 특별한 기적을 기다리지마 눈 앞에선 우리의 거친 길은 알 수 없는 미래와 벽 바꾸지 않아 포기할 수 없어 변치 않을 사랑으로 지켜줘 상처 입은 내 맘까지 시선 속에서 말은 필요 없어 멈춰져 버린 이 시간 사랑해 널 이 느낌 이대로 그려왔던 헤매임의 끝 이 세상 속에서 반복되는 슬픔 이젠 안녕 수많은 알 수 없는 길 속에 희미한 빛을 난 쫓아가 언제까지라도 함께 하는거야 다시 만난 나의 세계`, categories: [ - { optionId: 3, content: '⏰ 시간 관리 능력' }, - { optionId: 4, content: '🤓 기술적 역량, 전문 지식' }, + { optionId: 3, content: '⏰시간 관리 능력 (예: 일정과 마감 기한 준수, 업무의 우선 순위 분배)' }, + { optionId: 4, content: '💻기술적 역량, 전문 지식 (예: 요구 사항을 이해하고 이를 구현하는 능력)' }, ], }, { @@ -41,8 +45,12 @@ export const REVIEW_LIST: ReviewList = { Disco overload I'm into that I'm good to go `, categories: [ - { optionId: 5, content: '🌱 성장 마인드셋' }, - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, + { + optionId: 5, + content: + '🌱성장 마인드셋 (예: 새로운 분야나 잘 모르는 분야에 도전하는 마음, 꾸준한 노력으로 프로젝트 이전보다 성장하는 모습)', + }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, ], }, { @@ -61,8 +69,8 @@ export const REVIEW_LIST: ReviewList = { 아무 걱정도 하지는 마, 나에게 다 맡겨 봐 `, categories: [ - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, - { optionId: 2, content: '💡 문제 해결 능력' }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, + { optionId: 2, content: '💡문제 해결 능력 (예: 프로젝트 중 만난 버그/오류를 분석하고 이를 해결하는 능력)' }, ], }, { @@ -80,8 +88,8 @@ export const REVIEW_LIST: ReviewList = { That tick, that tick, tick bomb `, categories: [ - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, - { optionId: 2, content: '💡 문제 해결 능력' }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, + { optionId: 2, content: '💡문제 해결 능력 (예: 프로젝트 중 만난 버그/오류를 분석하고 이를 해결하는 능력)' }, ], }, { @@ -95,8 +103,12 @@ export const REVIEW_LIST: ReviewList = { Ooh-ooh, ooh-ooh, lalalala-lalala `, categories: [ - { optionId: 5, content: '🌱 성장 마인드셋' }, - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, + { + optionId: 5, + content: + '🌱성장 마인드셋 (예: 새로운 분야나 잘 모르는 분야에 도전하는 마음, 꾸준한 노력으로 프로젝트 이전보다 성장하는 모습)', + }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, ], }, { @@ -104,8 +116,8 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `7. 나는 짧은 데이터`, categories: [ - { optionId: 3, content: '⏰ 시간 관리 능력' }, - { optionId: 2, content: '💡 문제 해결 능력' }, + { optionId: 3, content: '⏰시간 관리 능력 (예: 일정과 마감 기한 준수, 업무의 우선 순위 분배)' }, + { optionId: 2, content: '💡문제 해결 능력 (예: 프로젝트 중 만난 버그/오류를 분석하고 이를 해결하는 능력)' }, ], }, { @@ -113,8 +125,12 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `8. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 4, content: '🤓 기술적 역량, 전문 지식' }, - { optionId: 5, content: '🌱 성장 마인드셋' }, + { optionId: 4, content: '💻기술적 역량, 전문 지식 (예: 요구 사항을 이해하고 이를 구현하는 능력)' }, + { + optionId: 5, + content: + '🌱성장 마인드셋 (예: 새로운 분야나 잘 모르는 분야에 도전하는 마음, 꾸준한 노력으로 프로젝트 이전보다 성장하는 모습)', + }, ], }, { @@ -122,8 +138,12 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `9. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 5, content: '🌱 성장 마인드셋' }, - { optionId: 2, content: '💡 문제 해결 능력' }, + { + optionId: 5, + content: + '🌱성장 마인드셋 (예: 새로운 분야나 잘 모르는 분야에 도전하는 마음, 꾸준한 노력으로 프로젝트 이전보다 성장하는 모습)', + }, + { optionId: 2, content: '💡문제 해결 능력 (예: 프로젝트 중 만난 버그/오류를 분석하고 이를 해결하는 능력)' }, ], }, { @@ -131,8 +151,8 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `10. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, - { optionId: 3, content: '⏰ 시간 관리 능력' }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, + { optionId: 3, content: '⏰시간 관리 능력 (예: 일정과 마감 기한 준수, 업무의 우선 순위 분배)' }, ], }, { @@ -140,8 +160,8 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `11. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, - { optionId: 2, content: '💡 문제 해결 능력' }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, + { optionId: 2, content: '💡문제 해결 능력 (예: 프로젝트 중 만난 버그/오류를 분석하고 이를 해결하는 능력)' }, ], }, { @@ -149,8 +169,12 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `12. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 4, content: '🌱 성장 마인드셋' }, - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, + { + optionId: 4, + content: + '🌱성장 마인드셋 (예: 새로운 분야나 잘 모르는 분야에 도전하는 마음, 꾸준한 노력으로 프로젝트 이전보다 성장하는 모습)', + }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, ], }, { @@ -158,8 +182,12 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2024-07-24', contentPreview: `13. 물론 시중에 출간되어 있는 책들로 공부하는 것도 큰 장점이지만 더 깊은 공부를 하고 싶을 때 공식 문서를 확인해보는 것이 좋기 때문에, 저 개인적인 생각으로는 언어 공부를 아예 처음 입문하시는 분들은 한국에서 출간된 개발 서적으로 공부를 시작하시다가 모르는 부분이.....`, categories: [ - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, - { optionId: 5, content: '🌱 성장 마인드셋' }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, + { + optionId: 5, + content: + '🌱성장 마인드셋 (예: 새로운 분야나 잘 모르는 분야에 도전하는 마음, 꾸준한 노력으로 프로젝트 이전보다 성장하는 모습)', + }, ], }, { @@ -167,8 +195,8 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2023-08-29', contentPreview: `14. 하루스터디는 효율적인 공부 방법을 제공하는 학습 진행 도구 서비스입니다. 하루스터디는 목표 설정 단계, 학습 단계, 회고 단계를 반복하는 학습 사이클을 통해 학습 효율을 끌어올립니다. 하루스터디를 사용하게 되면 '학습을 잘 하는 방법'에 대해서...`, categories: [ - { optionId: 3, content: '⏰ 시간 관리 능력' }, - { optionId: 4, content: '🤓 기술적 역량, 전문 지식' }, + { optionId: 3, content: '⏰시간 관리 능력 (예: 일정과 마감 기한 준수, 업무의 우선 순위 분배)' }, + { optionId: 4, content: '💻기술적 역량, 전문 지식 (예: 요구 사항을 이해하고 이를 구현하는 능력)' }, ], }, { @@ -176,8 +204,12 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `15. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 5, content: '🌱 성장 마인드셋' }, - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, + { + optionId: 5, + content: + '🌱성장 마인드셋 (예: 새로운 분야나 잘 모르는 분야에 도전하는 마음, 꾸준한 노력으로 프로젝트 이전보다 성장하는 모습)', + }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, ], }, { @@ -185,8 +217,8 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `16. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, - { optionId: 2, content: '💡 문제 해결 능력' }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, + { optionId: 2, content: '💡문제 해결 능력 (예: 프로젝트 중 만난 버그/오류를 분석하고 이를 해결하는 능력)' }, ], }, { @@ -194,8 +226,8 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `17. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, - { optionId: 2, content: '💡 문제 해결 능력' }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, + { optionId: 2, content: '💡문제 해결 능력 (예: 프로젝트 중 만난 버그/오류를 분석하고 이를 해결하는 능력)' }, ], }, { @@ -203,8 +235,12 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `18. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 5, content: '🌱 성장 마인드셋' }, - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, + { + optionId: 5, + content: + '🌱성장 마인드셋 (예: 새로운 분야나 잘 모르는 분야에 도전하는 마음, 꾸준한 노력으로 프로젝트 이전보다 성장하는 모습)', + }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, ], }, { @@ -212,8 +248,8 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `19. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 3, content: '⏰ 시간 관리 능력' }, - { optionId: 2, content: '💡 문제 해결 능력' }, + { optionId: 3, content: '⏰시간 관리 능력 (예: 일정과 마감 기한 준수, 업무의 우선 순위 분배)' }, + { optionId: 2, content: '💡문제 해결 능력 (예: 프로젝트 중 만난 버그/오류를 분석하고 이를 해결하는 능력)' }, ], }, { @@ -221,8 +257,12 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `20. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 4, content: '🤓 기술적 역량, 전문 지식' }, - { optionId: 5, content: '🌱 성장 마인드셋' }, + { optionId: 4, content: '💻기술적 역량, 전문 지식 (예: 요구 사항을 이해하고 이를 구현하는 능력)' }, + { + optionId: 5, + content: + '🌱성장 마인드셋 (예: 새로운 분야나 잘 모르는 분야에 도전하는 마음, 꾸준한 노력으로 프로젝트 이전보다 성장하는 모습)', + }, ], }, { @@ -230,8 +270,12 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `21. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 5, content: '🌱 성장 마인드셋' }, - { optionId: 2, content: '💡 문제 해결 능력' }, + { + optionId: 5, + content: + '🌱성장 마인드셋 (예: 새로운 분야나 잘 모르는 분야에 도전하는 마음, 꾸준한 노력으로 프로젝트 이전보다 성장하는 모습)', + }, + { optionId: 2, content: '💡문제 해결 능력 (예: 프로젝트 중 만난 버그/오류를 분석하고 이를 해결하는 능력)' }, ], }, { @@ -239,8 +283,8 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `22. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, - { optionId: 3, content: '⏰ 시간 관리 능력' }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, + { optionId: 3, content: '⏰시간 관리 능력 (예: 일정과 마감 기한 준수, 업무의 우선 순위 분배)' }, ], }, { @@ -248,8 +292,8 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `23. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, - { optionId: 2, content: '💡 문제 해결 능력' }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, + { optionId: 2, content: '💡문제 해결 능력 (예: 프로젝트 중 만난 버그/오류를 분석하고 이를 해결하는 능력)' }, ], }, { @@ -257,8 +301,12 @@ export const REVIEW_LIST: ReviewList = { createdAt: '2021-08-01', contentPreview: `24. 공간을 한 눈에, 예약은 한 번에! 맞춤형 공간예약 서비스 제작 플랫폼 찜꽁입니다! 공간 제공자(관리자)는 에디터를 통해 공간을 생성할 수 있습니다! 생성한 공간은 링크를 통해 사용자에게 제공할 수 있으며, 사용자는 링크를 통해 간편하게 공간을 확인하고 예약을...`, categories: [ - { optionId: 4, content: '🌱 성장 마인드셋' }, - { optionId: 1, content: '🗣️ 커뮤니케이션, 협업 능력' }, + { + optionId: 4, + content: + '🌱성장 마인드셋 (예: 새로운 분야나 잘 모르는 분야에 도전하는 마음, 꾸준한 노력으로 프로젝트 이전보다 성장하는 모습)', + }, + { optionId: 1, content: '🗣️커뮤니케이션, 협업 능력 (예: 팀원간의 원활한 정보 공유, 명확한 의사소통)' }, ], }, ], diff --git a/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/index.tsx b/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/index.tsx index cef4b9e72..0141be1c4 100644 --- a/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/index.tsx +++ b/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/index.tsx @@ -2,7 +2,7 @@ import { useMemo } from 'react'; import { ROUTE_PARAM } from '@/constants'; import { useGetDetailedReview, useSearchParamAndQuery } from '@/hooks'; -import { ReviewDescription, ReviewSection, KeywordSection } from '@/pages/DetailedReviewPage/components'; +import { ReviewDescription, QuestionAnswerSection } from '@/pages/DetailedReviewPage/components'; import { substituteString } from '@/utils'; import * as S from './styles'; @@ -56,14 +56,21 @@ const DetailedReviewPageContents = () => { isPublic={true} handleClickToggleButton={() => console.log('click toggle ')} /> - {parsedDetailedReview.sections.map((section) => - section.questions.map((question) => ( - - - {question.questionType === 'CHECKBOX' && } - - )), - )} + + + {parsedDetailedReview.sections.map((section) => + section.questions.map((question) => ( + + + + )), + )} + ); }; diff --git a/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/styles.ts b/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/styles.ts index 6acc796b6..74eb3bac8 100644 --- a/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/styles.ts +++ b/frontend/src/pages/DetailedReviewPage/components/DetailedReviewPageContents/styles.ts @@ -5,7 +5,9 @@ import media from '@/utils/media'; export const DetailedReviewPageContents = styled.div` width: 70%; margin-top: 2rem; - border: 0.1rem solid ${({ theme }) => theme.colors.lightPurple}; + padding: 2rem 3rem; + + border: 0.2rem solid ${({ theme }) => theme.colors.disabled}; border-radius: ${({ theme }) => theme.borderRadius.basic}; ${media.medium} { @@ -17,10 +19,20 @@ export const DetailedReviewPageContents = styled.div` } `; -export const ReviewContentContainer = styled.div` - margin-bottom: 7rem; - padding: 0 4rem; +export const Separator = styled.div` + width: 100%; + height: 0.3rem; + margin: 3rem 0; + background-color: ${({ theme }) => theme.colors.disabled}; +`; +export const DetailedReviewContainer = styled.div` + display: flex; + flex-direction: column; + gap: 4rem; +`; + +export const ReviewContentContainer = styled.div` ${media.xSmall} { padding: 0 2rem; } diff --git a/frontend/src/pages/DetailedReviewPage/components/KeywordSection/index.tsx b/frontend/src/pages/DetailedReviewPage/components/KeywordSection/index.tsx deleted file mode 100644 index 7c9572616..000000000 --- a/frontend/src/pages/DetailedReviewPage/components/KeywordSection/index.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Options } from '@/types'; - -import * as S from './styles'; - -interface KeywordSectionProps { - options: Options[]; -} - -const KeywordSection = ({ options }: KeywordSectionProps) => { - return ( - - - {options.map(({ optionId, content }) => ( - {content} - ))} - - - ); -}; - -export default KeywordSection; diff --git a/frontend/src/pages/DetailedReviewPage/components/KeywordSection/styles.ts b/frontend/src/pages/DetailedReviewPage/components/KeywordSection/styles.ts deleted file mode 100644 index 09f7c695e..000000000 --- a/frontend/src/pages/DetailedReviewPage/components/KeywordSection/styles.ts +++ /dev/null @@ -1,15 +0,0 @@ -import styled from '@emotion/styled'; - -export const KeywordSection = styled.section` - width: 100%; - margin-top: 2rem; -`; - -export const KeywordList = styled.ul` - padding-left: 2rem; - list-style-type: disc; -`; - -export const KeywordItem = styled.li` - margin-bottom: 0.5rem; -`; diff --git a/frontend/src/pages/DetailedReviewPage/components/MultipleChoiceAnswer/index.tsx b/frontend/src/pages/DetailedReviewPage/components/MultipleChoiceAnswer/index.tsx new file mode 100644 index 000000000..2c0dbd4f7 --- /dev/null +++ b/frontend/src/pages/DetailedReviewPage/components/MultipleChoiceAnswer/index.tsx @@ -0,0 +1,11 @@ +import formatKeyword from '@/utils/formatKeyword'; + +const MultipleChoiceAnswer = ({ selectedOption }: { selectedOption: string }) => { + const isExampleIncluded = selectedOption.includes('예'); + + const formattedAnswer = formatKeyword(selectedOption); + + return
  • {isExampleIncluded ? formattedAnswer : selectedOption}
  • ; +}; + +export default MultipleChoiceAnswer; diff --git a/frontend/src/pages/DetailedReviewPage/components/MultipleChoiceAnswerList/index.tsx b/frontend/src/pages/DetailedReviewPage/components/MultipleChoiceAnswerList/index.tsx new file mode 100644 index 000000000..da9a4d5d1 --- /dev/null +++ b/frontend/src/pages/DetailedReviewPage/components/MultipleChoiceAnswerList/index.tsx @@ -0,0 +1,21 @@ +import { Options } from '@/types'; + +import MultipleChoiceAnswer from '../MultipleChoiceAnswer'; + +import * as S from './styles'; + +interface MultipleChoiceAnswerListProps { + selectedOptionList: Options[]; +} + +const MultipleChoiceAnswerList = ({ selectedOptionList }: MultipleChoiceAnswerListProps) => { + return ( + + {selectedOptionList.map(({ optionId, content }) => ( + + ))} + + ); +}; + +export default MultipleChoiceAnswerList; diff --git a/frontend/src/pages/DetailedReviewPage/components/MultipleChoiceAnswerList/styles.ts b/frontend/src/pages/DetailedReviewPage/components/MultipleChoiceAnswerList/styles.ts new file mode 100644 index 000000000..db52191cf --- /dev/null +++ b/frontend/src/pages/DetailedReviewPage/components/MultipleChoiceAnswerList/styles.ts @@ -0,0 +1,11 @@ +import styled from '@emotion/styled'; + +export const MultipleChoiceAnswerList = styled.ul` + display: flex; + flex-direction: column; + gap: 0.5rem; + + padding-left: 4rem; + + list-style-type: disc; +`; diff --git a/frontend/src/pages/DetailedReviewPage/components/QuestionAnswerSection/index.tsx b/frontend/src/pages/DetailedReviewPage/components/QuestionAnswerSection/index.tsx new file mode 100644 index 000000000..a1606b0a1 --- /dev/null +++ b/frontend/src/pages/DetailedReviewPage/components/QuestionAnswerSection/index.tsx @@ -0,0 +1,28 @@ +import { MultilineTextViewer } from '@/components'; +import { MultipleChoiceAnswerList, QuestionTitle } from '@/pages/DetailedReviewPage/components'; +import { Options, QuestionType } from '@/types'; + +import * as S from './styles'; + +interface QuestionAnswerProps { + question: string; + questionType: QuestionType; + answer?: string; + options?: Options[]; +} + +const QuestionAnswerSection = ({ question, questionType, answer, options }: QuestionAnswerProps) => { + return ( + + + {questionType === 'CHECKBOX' && options && } + {questionType === 'TEXT' && answer && ( + + + + )} + + ); +}; + +export default QuestionAnswerSection; diff --git a/frontend/src/pages/DetailedReviewPage/components/ReviewSection/styles.ts b/frontend/src/pages/DetailedReviewPage/components/QuestionAnswerSection/styles.ts similarity index 59% rename from frontend/src/pages/DetailedReviewPage/components/ReviewSection/styles.ts rename to frontend/src/pages/DetailedReviewPage/components/QuestionAnswerSection/styles.ts index eb8917aa8..59e13d1b2 100644 --- a/frontend/src/pages/DetailedReviewPage/components/ReviewSection/styles.ts +++ b/frontend/src/pages/DetailedReviewPage/components/QuestionAnswerSection/styles.ts @@ -1,16 +1,18 @@ import styled from '@emotion/styled'; -export const ReviewSection = styled.section` +export const QuestionAnswerSection = styled.section` + display: flex; + flex-direction: column; + gap: 2rem; width: 100%; - margin-top: 3.2rem; `; -export const Answer = styled.div` +export const TextAnswerWrapper = styled.div` overflow-y: auto; box-sizing: border-box; width: 100%; - height: 23rem; + height: 20rem; padding: 1rem 1.5rem; font-size: 1.6rem; diff --git a/frontend/src/pages/DetailedReviewPage/components/QuestionTitle/index.tsx b/frontend/src/pages/DetailedReviewPage/components/QuestionTitle/index.tsx new file mode 100644 index 000000000..65fdd38d1 --- /dev/null +++ b/frontend/src/pages/DetailedReviewPage/components/QuestionTitle/index.tsx @@ -0,0 +1,11 @@ +import * as S from './styles'; + +interface QuestionProps { + text: string; +} + +const QuestionTitle = ({ text }: QuestionProps) => { + return {text}; +}; + +export default QuestionTitle; diff --git a/frontend/src/pages/DetailedReviewPage/components/QuestionTitle/styles.ts b/frontend/src/pages/DetailedReviewPage/components/QuestionTitle/styles.ts new file mode 100644 index 000000000..f29376283 --- /dev/null +++ b/frontend/src/pages/DetailedReviewPage/components/QuestionTitle/styles.ts @@ -0,0 +1,5 @@ +import styled from '@emotion/styled'; + +export const QuestionTitle = styled.p` + font-weight: ${({ theme }) => theme.fontWeight.bold}; +`; diff --git a/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/index.tsx b/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/index.tsx index ed4e721b8..72dc2f745 100644 --- a/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/index.tsx +++ b/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/index.tsx @@ -2,7 +2,7 @@ import ReviewDate, { ReviewDateProps } from '@/components/common/ReviewDate'; import * as S from './styles'; -const DATE_TITLE = '리뷰 작성일'; +const DATE_TITLE = '작성일'; interface ReviewDescriptionProps extends Omit { projectName: string; diff --git a/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/styles.ts b/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/styles.ts index e6cfa2323..52ee76dff 100644 --- a/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/styles.ts +++ b/frontend/src/pages/DetailedReviewPage/components/ReviewDescription/styles.ts @@ -9,9 +9,7 @@ export const Description = styled.section` width: 100%; margin: 0; - padding: 1rem 3rem; - background-color: ${({ theme }) => theme.colors.lightPurple}; border-radius: ${({ theme }) => theme.borderRadius.basic} ${({ theme }) => theme.borderRadius.basic} 0 0; ${media.xSmall} { @@ -29,9 +27,7 @@ export const ProjectInfoContainer = styled.div` display: flex; flex-direction: column; justify-content: flex-start; - width: 100%; - margin: 0 1rem; `; export const ProjectName = styled.p` diff --git a/frontend/src/pages/DetailedReviewPage/components/ReviewSection/index.tsx b/frontend/src/pages/DetailedReviewPage/components/ReviewSection/index.tsx deleted file mode 100644 index c059715b6..000000000 --- a/frontend/src/pages/DetailedReviewPage/components/ReviewSection/index.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { MultilineTextViewer } from '@/components'; - -import ReviewSectionHeader from '../ReviewSectionHeader'; - -import * as S from './styles'; - -interface ReviewSectionProps { - question: string; - answer: string; -} - -const ReviewSection = ({ question, answer }: ReviewSectionProps) => { - return ( - - - {answer && ( - - - - )} - - ); -}; - -export default ReviewSection; diff --git a/frontend/src/pages/DetailedReviewPage/components/ReviewSectionHeader/index.tsx b/frontend/src/pages/DetailedReviewPage/components/ReviewSectionHeader/index.tsx deleted file mode 100644 index 50fa0dab5..000000000 --- a/frontend/src/pages/DetailedReviewPage/components/ReviewSectionHeader/index.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import * as S from './styles'; - -interface ReviewSectionHeaderProps { - text: string; -} - -const ReviewSectionHeader = ({ text }: ReviewSectionHeaderProps) => { - return {text}; -}; - -export default ReviewSectionHeader; diff --git a/frontend/src/pages/DetailedReviewPage/components/ReviewSectionHeader/styles.ts b/frontend/src/pages/DetailedReviewPage/components/ReviewSectionHeader/styles.ts deleted file mode 100644 index 517c62e27..000000000 --- a/frontend/src/pages/DetailedReviewPage/components/ReviewSectionHeader/styles.ts +++ /dev/null @@ -1,7 +0,0 @@ -import styled from '@emotion/styled'; - -export const ReviewSectionHeader = styled.p` - margin-bottom: 1rem; - font-size: 1.6rem; - font-weight: bold; -`; diff --git a/frontend/src/pages/DetailedReviewPage/components/index.tsx b/frontend/src/pages/DetailedReviewPage/components/index.tsx index 4bfb172bd..a455c2400 100644 --- a/frontend/src/pages/DetailedReviewPage/components/index.tsx +++ b/frontend/src/pages/DetailedReviewPage/components/index.tsx @@ -1,4 +1,5 @@ -export { default as KeywordSection } from './KeywordSection'; +export { default as QuestionAnswerSection } from './QuestionAnswerSection'; +export { default as QuestionTitle } from './QuestionTitle'; +export { default as MultipleChoiceAnswerList } from './MultipleChoiceAnswerList'; export { default as ReviewDescription } from './ReviewDescription'; -export { default as ReviewSection } from './ReviewSection'; export { default as DetailedReviewPageContents } from './DetailedReviewPageContents'; diff --git a/frontend/src/pages/ReviewListPage/components/ReviewListPageContents/index.tsx b/frontend/src/pages/ReviewListPage/components/ReviewListPageContents/index.tsx index 172242ad0..3d8f11597 100644 --- a/frontend/src/pages/ReviewListPage/components/ReviewListPageContents/index.tsx +++ b/frontend/src/pages/ReviewListPage/components/ReviewListPageContents/index.tsx @@ -2,9 +2,9 @@ import { useContext } from 'react'; import { useNavigate } from 'react-router'; import { ReviewEmptySection } from '@/components'; +import ReviewCard from '@/components/common/ReviewCard'; import UndraggableWrapper from '@/components/common/UndraggableWrapper'; import { ReviewInfoDataContext } from '@/components/layouts/ReviewDisplayLayout/ReviewInfoDataProvider'; -import ReviewCard from '@/components/ReviewCard'; import { REVIEW_EMPTY } from '@/constants'; import { ROUTE } from '@/constants/route'; import { useGetReviewList, useSearchParamAndQuery } from '@/hooks'; diff --git a/frontend/src/utils/formatKeyword.ts b/frontend/src/utils/formatKeyword.ts new file mode 100644 index 000000000..7e2a046e5 --- /dev/null +++ b/frontend/src/utils/formatKeyword.ts @@ -0,0 +1,9 @@ +const formatKeyword = (content: string) => { + const contentWithoutExample = Array.from(content.split(' (예: ')[0]); + const emoji = contentWithoutExample.shift(); + const keyword = contentWithoutExample.join(''); + + return `${emoji} ${keyword}`; +}; + +export default formatKeyword;