diff --git a/src/api/get.ts b/src/api/get.ts index 3af9b19c..c1174855 100644 --- a/src/api/get.ts +++ b/src/api/get.ts @@ -56,6 +56,9 @@ export const getLetterRecentType = async (letterId: string | undefined) => export const getReviewsCustomer = async (params: any) => await getInstance('/reviews/customers', params); +export const getReviews = async (counselorId: number, params: any) => + await getPublicInstance(`/reviews/${counselorId}`, params); + // Conuselor Controller export const getMyInfo = async () => await getInstance('counselors/my-info'); export const getProfiles = async () => await getInstance('counselors/profiles'); @@ -64,7 +67,9 @@ export const getCounselorConsults = async ( counselorId: string | undefined, params: any, ) => await getInstance(`/counselors/consults/${counselorId}`, params); - +//마인더 프로필 페이지 마인더 프로필 조회 +export const getCounselors = async (counselorId: string | undefined) => + await getPublicInstance(`/counselors/${counselorId}`); // SearchWord Controller export const getSearchWords = async () => await getInstance('/searchWords'); diff --git a/src/api/patch.ts b/src/api/patch.ts index 6ce73c78..2b1310e4 100644 --- a/src/api/patch.ts +++ b/src/api/patch.ts @@ -1,4 +1,4 @@ -import { patchInstance } from './axios'; +import { patchInstance, patchPublicInstance } from './axios'; //Admin Controller //admin 미결제 상담 승인 export const patchAdminsUnpaidConsults = async (consultId: number) => @@ -16,7 +16,7 @@ export const patchAdminsPendingProfiles = async ( //Counselor Controller //카테고리/들준마 상담사 리스트 반환 export const patchCounselors = async (sortType: string, body: any) => - await patchInstance(`/counselors?sortType=${sortType}`, body); + await patchPublicInstance(`/counselors?sortType=${sortType}`, body); //LetterMessage Controller //Message 최초 생성 export const patchLetterMessage = async (body: any) => diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorInfo.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorInfo.tsx index bc51f474..9063a03d 100644 --- a/src/components/Buyer/BuyerCounselorProfile/CounselorInfo.tsx +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorInfo.tsx @@ -2,30 +2,65 @@ import styled from 'styled-components'; import { Grey1, Grey3, Grey6 } from 'styles/color'; import { Body3 } from 'styles/font'; import { consultTypeList } from 'utils/constant'; +import { convertTimeToString } from 'utils/convertTimeToString'; +import { ConsultTimes } from 'utils/type'; interface CounselorInfoProps { - consultType: number; + consultType: string[]; letterPrice: number; chattingPrice: number; + consultTimes: ConsultTimes; } export const CounselorInfo = ({ consultType, letterPrice, chattingPrice, + consultTimes, }: CounselorInfoProps) => { - const availableConsult = consultTypeList[consultType]; return (
상담 방식 - {availableConsult} + {consultType.join(', ')}
상담 시간 - - 월-금 21:00-24:00 -
- 토-일 09:00-22:00 -
+
+ {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} +
상담료 diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx index ad26fea8..ae3a3d0c 100644 --- a/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorProfileCard.tsx @@ -4,13 +4,14 @@ import { Body3, Caption2, 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 { CartegoryState } from 'utils/type'; interface CounselorProfileCardProps { nickname: string; level: number; rating: number; reviewNumber: number; - tagList: CartegoryStateArray; - iconNumber: number; + tagList: CartegoryState[]; + consultStyle: number; } export const CounselorProfileCard = ({ nickname, @@ -18,44 +19,49 @@ export const CounselorProfileCard = ({ rating, reviewNumber, tagList, - iconNumber, + consultStyle, }: CounselorProfileCardProps) => { //여기 dummy data 나중에는 page에서 props로 뿌리는게 나을듯함 return ( -
-
- {nickname} - - Lv {level} - + +
+
+ {nickname} + + Lv {level} + +
+
+ + + {rating + ' (' + reviewNumber + ')'} + +
+
+ {tagList.map((value) => { + return ; + })} +
-
- - - {rating + ' (' + reviewNumber + ')'} - +
+
-
- {tagList.map((value) => { - return ; - })} -
-
-
- -
+
); }; - const Wrapper = styled.div` display: flex; - justify-content: center; - gap: 6.8rem; + flex-direction: column; + align-items: center; +`; +const CardWrapper = styled.div` + display: flex; + width: 33.5rem; + justify-content: space-between; padding: 1.6rem 2rem; - padding-bottom: 1.6rem; border-bottom: 1px solid ${Grey6}; .col1 { display: flex; diff --git a/src/components/Buyer/BuyerCounselorProfile/CounselorReview.tsx b/src/components/Buyer/BuyerCounselorProfile/CounselorReview.tsx index 164e9628..84e963fb 100644 --- a/src/components/Buyer/BuyerCounselorProfile/CounselorReview.tsx +++ b/src/components/Buyer/BuyerCounselorProfile/CounselorReview.tsx @@ -1,40 +1,87 @@ +import { getReviews } from 'api/get'; +import { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; import styled from 'styled-components'; import { Grey1, Grey4, Grey6 } from 'styles/color'; -import { Body1, Body2, Body3 } from 'styles/font'; +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 { useRecoilState } from 'recoil'; +import { isLoadingState } from 'utils/atom'; +import { LoadingSpinner } from 'utils/LoadingSpinner'; interface CounselorReviewProps { - reviewList: Review[]; + counselorId: number; } -export const CounselorReview = ({ reviewList }: CounselorReviewProps) => { - return ( - - - 상담 후기 - - - {reviewList.map((value) => { - return ( - -
- {value.name} - {value.time} -
-
- -
-
- {value.comment} -
-
- ); - })} -
- ); +export const CounselorReview = ({ counselorId }: CounselorReviewProps) => { + const navigate = useNavigate(); + const [reviews, setReviews] = useState([]); + const [isLoading, setIsLoading] = useRecoilState(isLoadingState); + useEffect(() => { + const fetchReviewData = async () => { + setIsLoading(true); + const params = { + cursorId: 0, + }; + const res: any = await getReviews(counselorId, { params }); + if (res.status === 200) { + setReviews(res.data); + } else if (res.response.status === 404) { + alert('존재하지 않는 상담사의 리뷰 요청입니다.'); + navigate('/buyer'); + } + console.log(isLoading); + setIsLoading(false); + }; + fetchReviewData(); + }, []); + if (isLoading) { + return ( + <> + + + ); + } else { + if (reviews.length === 0) { + return ( + + + 아직 후기가 없어요. + + ); + } else { + return ( + + {reviews.map((value) => { + return ( + +
+ {value.nickname} + {value.updateAt} +
+
+ +
+
+ {value.comment} +
+
+ ); + })} +
+ ); + } + } }; const Wrapper = styled.div` padding: 1.2rem 2rem 2rem 2rem; margin-bottom: 5.2rem; `; +const EmptyWrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; +`; const ReviewCard = styled.div` padding: 1.6rem; border-radius: 1.2rem; @@ -49,3 +96,7 @@ const ReviewCard = styled.div` align-items: center; } `; +const EmptyIcon = styled(Empty)` + margin-top: 5vh; + padding: 4.7rem 4.413rem 4.603rem 4.5rem; +`; diff --git a/src/components/Buyer/Common/ReadyConsultCard.tsx b/src/components/Buyer/Common/ReadyConsultCard.tsx index 6db56cb5..8c4f0c3b 100644 --- a/src/components/Buyer/Common/ReadyConsultCard.tsx +++ b/src/components/Buyer/Common/ReadyConsultCard.tsx @@ -55,18 +55,8 @@ export const ReadyConsultCard = ({ const newStates = [...bookmarkStates]; newStates[index] = !newStates[index]; setBookmarkStates(newStates); - console.log(consultTimes); }; - const [timeData, setTimeData] = useState([ - null, - null, - null, - null, - null, - null, - null, - ]); - useEffect(() => {}, []); + return (
상담 방식 - {consultType} + {consultType.join(', ')}
상담가능 시간 @@ -174,10 +164,18 @@ export const ReadyConsultCard = ({
상담료 - - 편지 1건 {letterPrice.toLocaleString()}원
- 실시간 30분당 {chattingPrice.toLocaleString()}원 -
+
+ {letterPrice !== undefined ? ( + + 편지 1건 {letterPrice.toLocaleString()}원 + + ) : null} + {chattingPrice !== undefined ? ( + + 채팅 30분당 {chattingPrice.toLocaleString()}원 + + ) : null} +
) : null} diff --git a/src/components/Buyer/Common/SearchResults.tsx b/src/components/Buyer/Common/SearchResults.tsx index 576b9dcd..fc2e1dd2 100644 --- a/src/components/Buyer/Common/SearchResults.tsx +++ b/src/components/Buyer/Common/SearchResults.tsx @@ -17,22 +17,23 @@ export const SearchResults = () => { {dummy.map((value, index) => { const tagListCast: CartegoryState[] = value.tagList as CartegoryState[]; return ( - + <> + // ); })}
diff --git a/src/pages/Buyer/BuyerCounselorProfile.tsx b/src/pages/Buyer/BuyerCounselorProfile.tsx index 0f20d607..e7a96da1 100644 --- a/src/pages/Buyer/BuyerCounselorProfile.tsx +++ b/src/pages/Buyer/BuyerCounselorProfile.tsx @@ -1,3 +1,4 @@ +import { getCounselors } from 'api/get'; import { CounselorExp, CounselorFooter, @@ -8,49 +9,84 @@ import { CounselorReview, } from 'components/Buyer/BuyerCounselorProfile'; import { useEffect, useState } from 'react'; -import { useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import styled from 'styled-components'; +import { AppendCategoryType } from 'utils/AppendCategoryType'; import { counselorDummyData as dummy } from 'utils/buyerDummy'; import { reviewDummy } from 'utils/buyerDummy'; -import { CartegoryState } from 'utils/type'; +import { consultStyleToCharNum } from 'utils/convertStringToCharNum'; +import { + CartegoryState, + ConsultCosts, + ConsultTimes, + MinderProfile, +} from 'utils/type'; 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: boolean, + experience: '', + level: 0, + nickname: '', + ratingAverage: 0, + totalReview: 0, + }); useEffect(() => { - const fetchData = async () => {}; + const fetchData = async () => { + const res: any = await getCounselors(id); + if (res.status === 200) { + setProfileData(res.data); + } else if (res.response.status === 404) { + alert('존재하지 않는 상담 아이디입니다.'); + navigate('/buyer'); + } + }; + fetchData(); }, []); //Nav 버튼 toggle const [isInfo, setIsInfo] = useState(true); if (id !== undefined) { const counselorId = parseInt(id, 10); - const tagListCast: CartegoryState[] = dummy[1].tagList as CartegoryState[]; return ( {isInfo ? ( <> - + ) : ( - + )} { setSearchData(res.data); } else if (res.response.status === 400) { alert('검색어는 2~20자 사이여야 합니다.'); - navigate('/buyer/search'); + navigate('/buyer'); } } catch (e) { console.log(e); diff --git a/src/utils/type.ts b/src/utils/type.ts index f00652da..0d2e6640 100644 --- a/src/utils/type.ts +++ b/src/utils/type.ts @@ -28,11 +28,12 @@ type LetterState = '질문' | '답장' | '추가질문' | '추가답장'; type CartegoryStateArray = CartegoryState[]; -type Review = { - name: string; +export type Review = { + nickname: string; rating: number; comment: string; - time: string; + updateAt: string; + reviewId: number; }; type ConsultInfoItem = { @@ -78,7 +79,7 @@ export type ConsultTimes = { export type SearchResultData = { consultCategories: CartegoryState[]; consultCosts: ConsultCosts; - consultStyle: '조언'; + consultStyle: string; consultTimes: ConsultTimes; consultTypes: string[]; counselorId: number; @@ -103,3 +104,18 @@ export interface BuyerReview { rating: number; comment: string; } +export interface MinderProfile { + consultCategories: CartegoryState[]; + consultCosts: ConsultCosts; + consultStyle: string; + consultTimes: ConsultTimes; + consultTypes: string[]; + counselorId: number; + introduction: string; + // isWishList: boolean; + experience: string; + level: number; + nickname: string; + ratingAverage: number; + totalReview: number; +}