From 555c91c26d54574f7a6c1ccb016b711d11ab095d Mon Sep 17 00:00:00 2001 From: kyuhho Date: Sat, 29 Jun 2024 20:44:19 +0900 Subject: [PATCH 01/10] feat: add grey background to minder profile page (#329) --- src/components/Common/AppContainer.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/Common/AppContainer.tsx b/src/components/Common/AppContainer.tsx index 493472d4..e8b480c7 100644 --- a/src/components/Common/AppContainer.tsx +++ b/src/components/Common/AppContainer.tsx @@ -30,6 +30,8 @@ export const AppContainer = ({ children }: AppContainerProps) => { const isOpenConsultDetailPage = /^(\/open-consult\/\d+|\/minder\/open-consult\/\d+)$/.test(pathname); + const isProfilePage = /^\/profile\/\d+$/.test(pathname); + const isGreyBackground = pathname === '/minder/mypage/viewProfile' || pathname === '/minder/mypage' || @@ -39,7 +41,8 @@ export const AppContainer = ({ children }: AppContainerProps) => { pathname === '/paymentDetail' || pathname.includes('/chat/') || (pathname.includes('/open-consult') && !isOpenConsultDetailPage) || - (pathname.includes('/consult') && search.includes('type=open-consult')); + (pathname.includes('/consult') && search.includes('type=open-consult')) || + isProfilePage; // // From 7fa15a1d0abe0be6caa05b06a9b08e5413eefe88 Mon Sep 17 00:00:00 2001 From: kyuhho Date: Sat, 29 Jun 2024 20:49:42 +0900 Subject: [PATCH 02/10] feat: add profile nav white bg color (#329) --- .../CounselorProfileNav.tsx | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorProfileNav.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorProfileNav.tsx index 342b29bb..8404b19a 100644 --- a/src/components/Buyer/BuyerCounselorProfile/CounselorProfileNav.tsx +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorProfileNav.tsx @@ -1,13 +1,23 @@ import styled from 'styled-components'; -import { Green, Grey4, Grey6 } from 'styles/color'; +import { Green, Grey4, Grey6, White } from 'styles/color'; import { Subtitle } from 'styles/font'; import { ReactComponent as UnderLine } from 'assets/icons/underline-counselor-info.svg'; import { useState } from 'react'; + +// +// +// + interface CounselorProfileNavProps { isInfo: boolean; setIsInfo: React.Dispatch>; reviewNumber: number; } + +// +// +// + export const CounselorProfileNav = ({ isInfo, setIsInfo, @@ -15,6 +25,11 @@ export const CounselorProfileNav = ({ }: CounselorProfileNavProps) => { const [infoColor, setInfoColor] = useState(Green); const [reviewColor, setReviewColor] = useState(Grey4); + + // + // + // + return ( ); }; + const Wrapper = styled.div` height: 4.4rem; border-bottom: 1px solid ${Grey6}; display: flex; + background-color: ${White}; `; + const InfoWrapper = styled.div` width: 50%; display: flex; @@ -53,6 +71,7 @@ const InfoWrapper = styled.div` padding-top: 0.8rem; cursor: pointer; `; + const ReviewWrapper = styled.div` width: 50%; display: flex; From 7b2c69dfb39b73faa172d39aadb5e87c163ad3a8 Mon Sep 17 00:00:00 2001 From: kyuhho Date: Sun, 30 Jun 2024 16:57:42 +0900 Subject: [PATCH 03/10] feat: apply changed counselor profile layout (#329) --- .../\bCounselorTypeSection.tsx" | 47 ++++++ .../BuyerCounselorProfile/CounselorExp.tsx | 14 +- .../BuyerCounselorProfile/CounselorInfo.tsx | 138 ++++++++++-------- .../CounselorProfileCard.tsx | 63 ++++---- src/pages/Buyer/BuyerCounselorProfile.tsx | 98 +++++++------ 5 files changed, 212 insertions(+), 148 deletions(-) create mode 100644 "src/components/Buyer/BuyerCounselorProfile/\bCounselorTypeSection.tsx" diff --git "a/src/components/Buyer/BuyerCounselorProfile/\bCounselorTypeSection.tsx" "b/src/components/Buyer/BuyerCounselorProfile/\bCounselorTypeSection.tsx" new file mode 100644 index 00000000..a865c035 --- /dev/null +++ "b/src/components/Buyer/BuyerCounselorProfile/\bCounselorTypeSection.tsx" @@ -0,0 +1,47 @@ +import { Flex } from 'components/Common/Flex'; +import { TagA2Cartegory } from 'components/Common/TagA2Cartegory'; +import styled from 'styled-components'; +import { Grey1 } from 'styles/color'; +import { Subtitle } from 'styles/font'; +import { CartegoryState } from 'utils/type'; + +// +// +// + +interface CounselorTypeSectionProps { + tagList: CartegoryState[]; +} + +// +// +// + +const CounselorTypeSection = ({ tagList }: CounselorTypeSectionProps) => { + return ( + + + 이런 분야에 자신 있어요 + + + {tagList.map((value) => ( + + ))} + + + ); +}; + +// +// +// + +const Wrapper = styled.div` + padding: 1.2rem 2rem 3rem 2rem; + margin-bottom: 5.2rem; + display: flex; + flex-direction: column; + gap: 1.2rem; +`; + +export default CounselorTypeSection; diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorExp.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorExp.tsx index 7bb3be00..83925342 100644 --- a/src/components/Buyer/BuyerCounselorProfile/CounselorExp.tsx +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorExp.tsx @@ -1,6 +1,6 @@ import styled from 'styled-components'; -import { Grey1, Grey3 } from 'styles/color'; -import { Body1, Body2 } from 'styles/font'; +import { Grey1, Grey3, White } from 'styles/color'; +import { Body1, Body2, Subtitle } from 'styles/font'; // // @@ -32,7 +32,9 @@ export const CounselorExp = ({ experience }: CounselorExpProps) => { return ( - 경험 소개 + + 마인더를 소개해요 + {formattedMessage(experience)} @@ -41,12 +43,12 @@ export const CounselorExp = ({ experience }: CounselorExpProps) => { }; const Wrapper = styled.div` - padding: 1.2rem 2rem 3rem 2rem; - margin-bottom: 5.2rem; + padding: 1.2rem 2rem 2rem 2rem; `; + const ExpBox = styled.div` padding: 1.6rem; - background-color: rgba(242, 241, 248, 0.8); + background-color: ${White}; border-radius: 1.2rem; margin-top: 1.2rem; `; diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorInfo.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorInfo.tsx index bb5f0a3a..3465c10c 100644 --- a/src/components/Buyer/BuyerCounselorProfile/CounselorInfo.tsx +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorInfo.tsx @@ -1,6 +1,7 @@ +import { Flex } from 'components/Common/Flex'; import styled from 'styled-components'; -import { Grey1, Grey3, Grey6 } from 'styles/color'; -import { Body3 } from 'styles/font'; +import { Grey1, Grey3, Grey6, White } from 'styles/color'; +import { Body3, Body4, Subtitle } from 'styles/font'; import { convertTimeToString } from 'utils/convertTimeToString'; import { ConsultTimes } from 'utils/type'; @@ -26,72 +27,85 @@ export const CounselorInfo = ({ consultTimes, }: CounselorInfoProps) => { return ( - -
- 상담 방식 - {consultType.join(', ')} -
-
- 상담 시간 -
- {consultTimes.MON !== undefined && consultTimes.MON.length !== 0 ? ( - - 월 {convertTimeToString(consultTimes.MON)} - - ) : null} - {consultTimes.TUE !== undefined && consultTimes.TUE.length !== 0 ? ( - - 화 {convertTimeToString(consultTimes.TUE)} - - ) : null} - {consultTimes.WED !== undefined && consultTimes.WED.length !== 0 ? ( - - 수 {convertTimeToString(consultTimes.WED)} - - ) : null} - {consultTimes.THU !== undefined && consultTimes.THU.length !== 0 ? ( - - 목 {convertTimeToString(consultTimes.THU)} - - ) : null} - {consultTimes.FRI !== undefined && consultTimes.FRI.length !== 0 ? ( - - 금 {convertTimeToString(consultTimes.FRI)} - - ) : null} - {consultTimes.SAT !== undefined && consultTimes.SAT.length !== 0 ? ( - - 토 {convertTimeToString(consultTimes.SAT)} - - ) : null} - {consultTimes.SUN !== undefined && consultTimes.SUN.length !== 0 ? ( - - 일 {convertTimeToString(consultTimes.SUN)} - - ) : null} + + + 이렇게 상담할 수 있어요 + + +
+ 상담 방식 + {consultType.join(', ')}
-
-
- 상담 금액 -
- {letterPrice !== undefined ? ( - - 편지 1건 {letterPrice.toLocaleString()}원 - - ) : null} - {chattingPrice !== undefined ? ( - - 채팅 30분당 {chattingPrice.toLocaleString()}원 - - ) : null} +
+ 상담 시간 +
+ {consultTimes.MON !== undefined && consultTimes.MON.length !== 0 ? ( + + 월 {convertTimeToString(consultTimes.MON)} + + ) : null} + {consultTimes.TUE !== undefined && consultTimes.TUE.length !== 0 ? ( + + 화 {convertTimeToString(consultTimes.TUE)} + + ) : null} + {consultTimes.WED !== undefined && consultTimes.WED.length !== 0 ? ( + + 수 {convertTimeToString(consultTimes.WED)} + + ) : null} + {consultTimes.THU !== undefined && consultTimes.THU.length !== 0 ? ( + + 목 {convertTimeToString(consultTimes.THU)} + + ) : null} + {consultTimes.FRI !== undefined && consultTimes.FRI.length !== 0 ? ( + + 금 {convertTimeToString(consultTimes.FRI)} + + ) : null} + {consultTimes.SAT !== undefined && consultTimes.SAT.length !== 0 ? ( + + 토 {convertTimeToString(consultTimes.SAT)} + + ) : null} + {consultTimes.SUN !== undefined && consultTimes.SUN.length !== 0 ? ( + + 일 {convertTimeToString(consultTimes.SUN)} + + ) : null} +
-
- +
+ 상담 금액 +
+ {letterPrice !== undefined ? ( + + 편지 1건 {letterPrice.toLocaleString()}원 + + ) : null} + {chattingPrice !== undefined ? ( + + 채팅 30분당 {chattingPrice.toLocaleString()}원 + + ) : null} +
+
+ + ); }; const Wrapper = styled.div` - padding: 1.6rem 2rem 1.2rem 5%; + background-color: ${White}; + border-radius: 1.2rem; + width: 100%; + box-sizing: border-box; + padding: 1.6rem; display: flex; flex-direction: column; gap: 0.3rem; diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx index ae3a3d0c..4e893a2d 100644 --- a/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx @@ -1,48 +1,51 @@ import styled from 'styled-components'; -import { Green, Grey2, Grey6, White } from 'styles/color'; -import { Body3, Caption2, Heading } from 'styles/font'; +import { Grey1, Grey2, Grey6, White } from 'styles/color'; +import { Body3, Heading } from 'styles/font'; import { Characters } from 'utils/Characters'; -import { ReactComponent as Heart } from 'assets/icons/icon-heart2.svg'; -import { TagA2Cartegory } from '../../Common/TagA2Cartegory'; +import { ReactComponent as HeartIcon } from 'assets/open-consult/open-consult-heart.svg'; import { CartegoryState } from 'utils/type'; +import { Flex } from 'components/Common/Flex'; + +// +// +// + interface CounselorProfileCardProps { nickname: string; level: number; rating: number; reviewNumber: number; - tagList: CartegoryState[]; consultStyle: number; } + +// +// +// + export const CounselorProfileCard = ({ nickname, level, rating, reviewNumber, - tagList, consultStyle, }: CounselorProfileCardProps) => { - //여기 dummy data 나중에는 page에서 props로 뿌리는게 나을듯함 - return (
{nickname} - - Lv {level} - + Lv {level}
- - - {rating + ' (' + reviewNumber + ')'} - -
-
- {tagList.map((value) => { - return ; - })} + {'후기 ' + reviewNumber + '개'} + + + + + {rating} + +
@@ -52,15 +55,19 @@ export const CounselorProfileCard = ({ ); }; + const Wrapper = styled.div` display: flex; flex-direction: column; align-items: center; + background: linear-gradient(90deg, #12c0b5 0%, #e1f8f6 100%); `; + const CardWrapper = styled.div` display: flex; width: 33.5rem; justify-content: space-between; + align-items: center; padding: 1.6rem 2rem; border-bottom: 1px solid ${Grey6}; .col1 { @@ -76,20 +83,12 @@ const CardWrapper = styled.div` .row2 { display: flex; align-items: center; - gap: 0.5rem; - } - .row3 { - display: flex; gap: 0.8rem; } `; -const LevelTag = styled.div` - background-color: ${Green}; - padding: 0.4rem 1.2rem; - border-radius: 0.8rem; -`; -const HeartIcon = styled(Heart)` - width: 1.9rem; - height: 1.8rem; +const Divider = styled.div` + width: 0.1rem; + height: 1.5rem; + background-color: ${White}; `; diff --git a/src/pages/Buyer/BuyerCounselorProfile.tsx b/src/pages/Buyer/BuyerCounselorProfile.tsx index 54ac963d..503c6cac 100644 --- a/src/pages/Buyer/BuyerCounselorProfile.tsx +++ b/src/pages/Buyer/BuyerCounselorProfile.tsx @@ -8,6 +8,7 @@ import { CounselorProfileNav, CounselorReview, } from 'components/Buyer/BuyerCounselorProfile'; +import CounselorTypeSection from 'components/Buyer/BuyerCounselorProfile/\bCounselorTypeSection'; import { Space } from 'components/Common/Space'; import { useLayoutEffect, useState } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; @@ -83,55 +84,56 @@ export const BuyerCounselorProfile = () => { ); - } else { - if (id !== undefined) { - const counselorId = parseInt(id, 10); - return ( - - - - - - {isInfo ? ( - <> - - - - ) : ( - - )} - - + + + + - - ); - } else { - return <>404 error; - } + {isInfo ? ( + <> + + + + + + ) : ( + + )} + + + + ); + } else { + return <>404 error; } }; From 7aac60153a3674606adfbe76fb1779795025fe08 Mon Sep 17 00:00:00 2001 From: kyuhho Date: Sun, 30 Jun 2024 17:02:00 +0900 Subject: [PATCH 04/10] chore: fix file name typo (#329) --- src/components/Buyer/BuyerCounselorProfile/CounselorExp.tsx | 4 ++-- .../Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx | 3 +-- .../Buyer/BuyerCounselorProfile/CounselorTypeSection.tsx | 6 +++--- src/components/Buyer/BuyerCounselorProfile/index.ts | 1 + src/pages/Buyer/BuyerCounselorProfile.tsx | 3 ++- 5 files changed, 9 insertions(+), 8 deletions(-) rename "src/components/Buyer/BuyerCounselorProfile/\bCounselorTypeSection.tsx" => src/components/Buyer/BuyerCounselorProfile/CounselorTypeSection.tsx (88%) diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorExp.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorExp.tsx index 83925342..bcf90f28 100644 --- a/src/components/Buyer/BuyerCounselorProfile/CounselorExp.tsx +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorExp.tsx @@ -1,6 +1,6 @@ import styled from 'styled-components'; -import { Grey1, Grey3, White } from 'styles/color'; -import { Body1, Body2, Subtitle } from 'styles/font'; +import { Grey1, White } from 'styles/color'; +import { Body2, Subtitle } from 'styles/font'; // // diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx index 4e893a2d..a4d2dbc9 100644 --- a/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx @@ -1,9 +1,8 @@ import styled from 'styled-components'; -import { Grey1, Grey2, Grey6, White } from 'styles/color'; +import { Grey1, Grey6, White } from 'styles/color'; import { Body3, Heading } from 'styles/font'; import { Characters } from 'utils/Characters'; import { ReactComponent as HeartIcon } from 'assets/open-consult/open-consult-heart.svg'; -import { CartegoryState } from 'utils/type'; import { Flex } from 'components/Common/Flex'; // diff --git "a/src/components/Buyer/BuyerCounselorProfile/\bCounselorTypeSection.tsx" b/src/components/Buyer/BuyerCounselorProfile/CounselorTypeSection.tsx similarity index 88% rename from "src/components/Buyer/BuyerCounselorProfile/\bCounselorTypeSection.tsx" rename to src/components/Buyer/BuyerCounselorProfile/CounselorTypeSection.tsx index a865c035..9191a6ff 100644 --- "a/src/components/Buyer/BuyerCounselorProfile/\bCounselorTypeSection.tsx" +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorTypeSection.tsx @@ -17,7 +17,9 @@ interface CounselorTypeSectionProps { // // -const CounselorTypeSection = ({ tagList }: CounselorTypeSectionProps) => { +export const CounselorTypeSection = ({ + tagList, +}: CounselorTypeSectionProps) => { return ( @@ -43,5 +45,3 @@ const Wrapper = styled.div` flex-direction: column; gap: 1.2rem; `; - -export default CounselorTypeSection; diff --git a/src/components/Buyer/BuyerCounselorProfile/index.ts b/src/components/Buyer/BuyerCounselorProfile/index.ts index 341d05b8..b71e07c7 100644 --- a/src/components/Buyer/BuyerCounselorProfile/index.ts +++ b/src/components/Buyer/BuyerCounselorProfile/index.ts @@ -5,3 +5,4 @@ export { CounselorInfo } from './CounselorInfo.tsx'; export { CounselorFooter } from './CounselorFooter.tsx'; export { CounselorExp } from './CounselorExp.tsx'; export { CounselorReview } from './CounselorReview.tsx'; +export { CounselorTypeSection } from './CounselorTypeSection.tsx'; diff --git a/src/pages/Buyer/BuyerCounselorProfile.tsx b/src/pages/Buyer/BuyerCounselorProfile.tsx index 503c6cac..8c235de1 100644 --- a/src/pages/Buyer/BuyerCounselorProfile.tsx +++ b/src/pages/Buyer/BuyerCounselorProfile.tsx @@ -7,8 +7,9 @@ import { CounselorProfileHeader, CounselorProfileNav, CounselorReview, + CounselorTypeSection, } from 'components/Buyer/BuyerCounselorProfile'; -import CounselorTypeSection from 'components/Buyer/BuyerCounselorProfile/\bCounselorTypeSection'; + import { Space } from 'components/Common/Space'; import { useLayoutEffect, useState } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; From e0be188d32692e977e541488f2e28b441bf4fe42 Mon Sep 17 00:00:00 2001 From: kyuhho Date: Sun, 30 Jun 2024 22:12:41 +0900 Subject: [PATCH 05/10] feat: apply changed profile minder info card layout (#329) --- .../BuyerCounselorProfile/CounselorInfo.tsx | 226 +++++++++++++----- src/utils/convertTimeToString.ts | 23 ++ 2 files changed, 184 insertions(+), 65 deletions(-) diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorInfo.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorInfo.tsx index 3465c10c..06686846 100644 --- a/src/components/Buyer/BuyerCounselorProfile/CounselorInfo.tsx +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorInfo.tsx @@ -1,8 +1,9 @@ import { Flex } from 'components/Common/Flex'; +import { useMemo } from 'react'; import styled from 'styled-components'; -import { Grey1, Grey3, Grey6, White } from 'styles/color'; +import { Grey1, Grey2, Grey6, LightGreen, White } from 'styles/color'; import { Body3, Body4, Subtitle } from 'styles/font'; -import { convertTimeToString } from 'utils/convertTimeToString'; +import { convertTimeToStringProfileInfo } from 'utils/convertTimeToString'; import { ConsultTimes } from 'utils/type'; // @@ -20,12 +21,99 @@ interface CounselorInfoProps { // // +const COUNSELOR_INFO_GAP = '6.4rem'; + +const DAY_MAPPING: { [key: string]: string } = { + MON: '월', + TUE: '화', + WED: '수', + THU: '목', + FRI: '금', + SAT: '토', + SUN: '일', +}; + +const ORDERED_DAY = ['월', '화', '수', '목', '금', '토', '일']; + +// +// +// + export const CounselorInfo = ({ consultType, letterPrice, chattingPrice, consultTimes, }: CounselorInfoProps) => { + const consultTimesArray = Object.entries(consultTimes); + + const filterdTimes = useMemo( + () => + consultTimesArray + .map(([day, times]) => { + return { day: DAY_MAPPING[day], times }; + }) + .sort( + (a, b) => ORDERED_DAY.indexOf(a.day) - ORDERED_DAY.indexOf(b.day), + ), + [consultTimesArray], + ); + + const getCurrentDay = () => { + const today = new Date(); + const dayIndex = today.getDay(); // 일요일: 0, 월요일: 1, ... , 토요일: 6 + + // match to the index of ORDERED_DAY + if (dayIndex === 0) { + return ORDERED_DAY[6]; + } + + return ORDERED_DAY[dayIndex - 1]; + }; + + const currentDay = getCurrentDay(); + + /** + * + */ + const renderConsultTimes = () => { + return filterdTimes.map((dayItem) => { + if (dayItem.times.length === 0 || dayItem.times === undefined) { + return null; + } + + const isCurrentDay = currentDay === dayItem.day; + + return ( + + + {isCurrentDay ? ( + {dayItem.day} + ) : ( + {dayItem.day} + )} + + + + {convertTimeToStringProfileInfo(dayItem.times)} + + + + ); + }); + }; + + // + // + // + return ( -
- 상담 방식 - {consultType.join(', ')} +
+ 상담 방식 + + {consultType.map((type) => ( + + {type} + + ))} +
-
- 상담 시간 -
- {consultTimes.MON !== undefined && consultTimes.MON.length !== 0 ? ( - - 월 {convertTimeToString(consultTimes.MON)} - - ) : null} - {consultTimes.TUE !== undefined && consultTimes.TUE.length !== 0 ? ( - - 화 {convertTimeToString(consultTimes.TUE)} - - ) : null} - {consultTimes.WED !== undefined && consultTimes.WED.length !== 0 ? ( - - 수 {convertTimeToString(consultTimes.WED)} - - ) : null} - {consultTimes.THU !== undefined && consultTimes.THU.length !== 0 ? ( - - 목 {convertTimeToString(consultTimes.THU)} - - ) : null} - {consultTimes.FRI !== undefined && consultTimes.FRI.length !== 0 ? ( - - 금 {convertTimeToString(consultTimes.FRI)} - - ) : null} - {consultTimes.SAT !== undefined && consultTimes.SAT.length !== 0 ? ( - - 토 {convertTimeToString(consultTimes.SAT)} - - ) : null} - {consultTimes.SUN !== undefined && consultTimes.SUN.length !== 0 ? ( - - 일 {convertTimeToString(consultTimes.SUN)} - - ) : null} -
+
+ 상담 시간 + + {renderConsultTimes()} +
-
- 상담 금액 -
+
+ 상담 금액 + {letterPrice !== undefined ? ( - - 편지 1건 {letterPrice.toLocaleString()}원 - + + 편지 1건 + {letterPrice.toLocaleString()}원 + ) : null} {chattingPrice !== undefined ? ( - - 채팅 30분당 {chattingPrice.toLocaleString()}원 - + + 채팅 30분당 + {chattingPrice.toLocaleString()}원 + ) : null} -
+
@@ -108,18 +192,30 @@ const Wrapper = styled.div` padding: 1.6rem; display: flex; flex-direction: column; - gap: 0.3rem; + gap: 1.6rem; border-bottom: 1px solid ${Grey6}; - .row1 { - display: flex; - gap: 6rem; - } - .row2 { - display: flex; - gap: 6rem; - } - .row3 { + + .row { display: flex; - gap: 6rem; + gap: ${COUNSELOR_INFO_GAP}; } `; + +const DayTag = styled.div<{ isCurrentDay: boolean }>` + display: flex; + justify-content: center; + align-items: center; + padding: 0.3rem 0.8rem; + border-radius: 0.5rem; + background-color: ${(props) => (props.isCurrentDay ? LightGreen : Grey6)}; +`; + +const TimeTag = styled.div<{ isCurrentDay: boolean }>` + display: flex; + justify-content: center; + align-items: center; + padding: 0.3rem 0.8rem; + border-radius: 0.5rem; + max-width: 15rem; + background-color: ${(props) => (props.isCurrentDay ? LightGreen : Grey6)}; +`; diff --git a/src/utils/convertTimeToString.ts b/src/utils/convertTimeToString.ts index e732a20a..4c53e789 100644 --- a/src/utils/convertTimeToString.ts +++ b/src/utils/convertTimeToString.ts @@ -24,6 +24,29 @@ export const convertTimeToString = (timeRanges: string[]) => { return result; } }; + +/** convert 22~23 format to 22시-23시 */ +export const convertTimeToStringProfileInfo = (timeRanges: string[]) => { + if (timeRanges === undefined) { + return null; + } + // 각 시간대의 시작과 끝을 추출하여 TimeRange 배열로 변환 + const timeRangeObjects: TimeRange[] = timeRanges.map((range) => { + const [start, end] = range.split('~'); + return { start, end }; + }); + + // TimeRange 배열을 "hh:mm-hh:mm" 형식의 문자열로 변환 + const formattedTimeRanges: string[] = timeRangeObjects.map( + ({ start, end }) => `${start}시-${end}시`, + ); + + // 변환된 문자열들을 콤마로 이어붙임 + const result: string = formattedTimeRanges.join(', '); + + return result; +}; + export const convertTimeRange = (input: string) => { const timeRanges = input.split('~').map((range: any) => { const hours = parseInt(range, 10); From 25360f0c5dc6d0e1753cddc818f9c93a6c01215f Mon Sep 17 00:00:00 2001 From: kyuhho Date: Mon, 1 Jul 2024 17:00:21 +0900 Subject: [PATCH 06/10] feat: update minder profile response type (#329) --- src/pages/Buyer/BuyerCounselorProfile.tsx | 49 +++++++++++++++-------- src/utils/type.ts | 3 +- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/pages/Buyer/BuyerCounselorProfile.tsx b/src/pages/Buyer/BuyerCounselorProfile.tsx index 8c235de1..5addcaf0 100644 --- a/src/pages/Buyer/BuyerCounselorProfile.tsx +++ b/src/pages/Buyer/BuyerCounselorProfile.tsx @@ -17,7 +17,32 @@ import styled from 'styled-components'; import { AppendCategoryType } from 'utils/AppendCategoryType'; import { LoadingSpinner } from 'utils/LoadingSpinner'; import { consultStyleToCharNum } from 'utils/convertStringToCharNum'; -import { ConsultCosts, ConsultTimes, MinderProfile } from 'utils/type'; +import { + ConsultCosts, + ConsultTimes, + GetCounselorsAllResponse, +} from 'utils/type'; + +// +// +// + +const DEFAULT_PROFILE_DATA: GetCounselorsAllResponse = { + consultCategories: [], + consultCosts: {} as ConsultCosts, + consultStyle: '', + consultTimes: {} as ConsultTimes, + consultTypes: [], + counselorId: -1, + introduction: '', + isWishList: false, + experience: '', + level: 0, + nickname: '', + ratingAverage: 0, + totalReview: 0, + totalConsult: 0, +}; // // @@ -27,21 +52,8 @@ export const BuyerCounselorProfile = () => { const navigate = useNavigate(); const { id } = useParams(); - const [profileData, setProfileData] = useState({ - consultCategories: [], - consultCosts: {} as ConsultCosts, - consultStyle: '', - consultTimes: {} as ConsultTimes, - consultTypes: [], - counselorId: -1, - introduction: '', - isWishList: false, - experience: '', - level: 0, - nickname: '', - ratingAverage: 0, - totalReview: 0, - }); + const [profileData, setProfileData] = + useState(DEFAULT_PROFILE_DATA); //로딩 state const [isLoading, setIsLoading] = useState(false); @@ -113,7 +125,10 @@ export const BuyerCounselorProfile = () => { letterPrice={profileData.consultCosts.편지} chattingPrice={profileData.consultCosts.채팅} /> - + Date: Mon, 1 Jul 2024 17:18:28 +0900 Subject: [PATCH 07/10] feat: apply introduction (#329) --- .../Buyer/BuyerCounselorProfile/CounselorExp.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorExp.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorExp.tsx index bcf90f28..b64d1c7f 100644 --- a/src/components/Buyer/BuyerCounselorProfile/CounselorExp.tsx +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorExp.tsx @@ -1,6 +1,7 @@ +import { Space } from 'components/Common/Space'; import styled from 'styled-components'; import { Grey1, White } from 'styles/color'; -import { Body2, Subtitle } from 'styles/font'; +import { Body1, Body2, Subtitle } from 'styles/font'; // // @@ -8,13 +9,17 @@ import { Body2, Subtitle } from 'styles/font'; interface CounselorExpProps { experience: string; + introduction: string; } // // // -export const CounselorExp = ({ experience }: CounselorExpProps) => { +export const CounselorExp = ({ + experience, + introduction, +}: CounselorExpProps) => { const formattedMessage = (message: string | null): JSX.Element[] | null => { return message ? message.split('\n').map((item, key) => ( @@ -36,6 +41,8 @@ export const CounselorExp = ({ experience }: CounselorExpProps) => { 마인더를 소개해요 + {introduction} + {formattedMessage(experience)} From 6a361c82ce1686c8f8c88a26337090961649fe78 Mon Sep 17 00:00:00 2001 From: kyuhho Date: Mon, 1 Jul 2024 17:25:14 +0900 Subject: [PATCH 08/10] feat: apply total consult number (#329) --- .../Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx | 4 ++++ src/pages/Buyer/BuyerCounselorProfile.tsx | 1 + 2 files changed, 5 insertions(+) diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx index a4d2dbc9..898c1694 100644 --- a/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx @@ -15,6 +15,7 @@ interface CounselorProfileCardProps { rating: number; reviewNumber: number; consultStyle: number; + totalConsult: number; } // @@ -27,6 +28,7 @@ export const CounselorProfileCard = ({ rating, reviewNumber, consultStyle, + totalConsult, }: CounselorProfileCardProps) => { return ( @@ -37,6 +39,8 @@ export const CounselorProfileCard = ({ Lv {level}
+ {'상담 ' + totalConsult + '회'} + {'후기 ' + reviewNumber + '개'} diff --git a/src/pages/Buyer/BuyerCounselorProfile.tsx b/src/pages/Buyer/BuyerCounselorProfile.tsx index 5addcaf0..8ae9fa7c 100644 --- a/src/pages/Buyer/BuyerCounselorProfile.tsx +++ b/src/pages/Buyer/BuyerCounselorProfile.tsx @@ -111,6 +111,7 @@ export const BuyerCounselorProfile = () => { rating={profileData.ratingAverage} reviewNumber={profileData.totalReview} consultStyle={consultStyleToCharNum(profileData.consultStyle) || 9} + totalConsult={profileData.totalConsult} /> Date: Mon, 1 Jul 2024 17:27:28 +0900 Subject: [PATCH 09/10] feat: change review card bg color (#329) --- .../BuyerCounselorProfile/CounselorReview.tsx | 99 ++++++++++++------- 1 file changed, 62 insertions(+), 37 deletions(-) diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorReview.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorReview.tsx index 19a6ce87..2ec1d624 100644 --- a/src/components/Buyer/BuyerCounselorProfile/CounselorReview.tsx +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorReview.tsx @@ -2,22 +2,37 @@ import { getReviewsAll } from 'api/get'; import { useLayoutEffect, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import styled from 'styled-components'; -import { Grey1, Grey6 } from 'styles/color'; +import { Grey1, Grey6, White } from 'styles/color'; import { Body1, Body2, Body3, Heading } from 'styles/font'; import { HeartRate } from 'utils/HeartRate'; import { Review } from 'utils/type'; import { ReactComponent as Empty } from 'assets/icons/graphic-noting.svg'; import useIntersectionObserver from 'hooks/useIntersectionObserver'; import { formattedMessage } from 'utils/formattedMessage'; + +// +// +// + interface CounselorReviewProps { counselorId: number; } + +// +// +// + export const CounselorReview = ({ counselorId }: CounselorReviewProps) => { const navigate = useNavigate(); + const [reviews, setReviews] = useState([]); const [isLoading, setIsLoading] = useState(true); const [isLastElem, setIsLastElem] = useState(false); const preventRef = useRef(true); // 중복 방지 옵션 + + /** + * + */ const fetchReviewData = async (lastReviewId: number) => { const params = { reviewId: lastReviewId, @@ -47,6 +62,7 @@ export const CounselorReview = ({ counselorId }: CounselorReviewProps) => { } } }; + const onIntersect: IntersectionObserverCallback = async (entry) => { if ( entry[0].isIntersecting && @@ -59,6 +75,7 @@ export const CounselorReview = ({ counselorId }: CounselorReviewProps) => { preventRef.current = true; } }; + //현재 대상 및 option을 props로 전달 const { setTarget } = useIntersectionObserver({ root: null, @@ -66,48 +83,55 @@ export const CounselorReview = ({ counselorId }: CounselorReviewProps) => { threshold: 0.8, onIntersect, }); - //첫 렌더 시에 data fetch + + // + // + // useLayoutEffect(() => { fetchReviewData(0); }, []); + // + // + // + if (isLoading) { - return <>; + return null; + } + + if (reviews.length !== 0) { + return ( + + {reviews.map((value) => { + return ( + +
+ {value.nickname} + {value.updateAt} +
+
+ +
+
+ {formattedMessage(value.comment)} +
+
+ ); + })} + {!isLastElem ? ( +
+ ) : ( +
+ )} + + ); } else { - if (reviews.length !== 0) { - return ( - - {reviews.map((value) => { - return ( - -
- {value.nickname} - {value.updateAt} -
-
- -
-
- {formattedMessage(value.comment)} -
-
- ); - })} - {!isLastElem ? ( -
- ) : ( -
- )} - - ); - } else { - return ( - - - 아직 후기가 없어요. - - ); - } + return ( + + + 아직 후기가 없어요. + + ); } }; const Wrapper = styled.div` @@ -126,6 +150,7 @@ const ReviewCard = styled.div` flex-direction: column; gap: 1.2rem; margin-bottom: 1.2rem; + background-color: ${White}; .row1 { display: flex; justify-content: space-between; From a27558b9418134fb2331606bc0910eb04d65f5e6 Mon Sep 17 00:00:00 2001 From: kyuhho Date: Tue, 2 Jul 2024 20:46:12 +0900 Subject: [PATCH 10/10] chore: remove unusing class name (#329) --- src/pages/Buyer/BuyerCounselorProfile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Buyer/BuyerCounselorProfile.tsx b/src/pages/Buyer/BuyerCounselorProfile.tsx index 8ae9fa7c..7452c4e0 100644 --- a/src/pages/Buyer/BuyerCounselorProfile.tsx +++ b/src/pages/Buyer/BuyerCounselorProfile.tsx @@ -102,7 +102,7 @@ export const BuyerCounselorProfile = () => { if (id !== undefined) { const counselorId = parseInt(id, 10); return ( - +