diff --git a/src/app/routes/Router.tsx b/src/app/routes/Router.tsx index 32ccdd7..a9e4a75 100644 --- a/src/app/routes/Router.tsx +++ b/src/app/routes/Router.tsx @@ -54,7 +54,7 @@ export const Router = () => { }> } /> - } /> + } /> } /> diff --git a/src/mentorship/api/MentorViewApi.ts b/src/mentorship/api/MentorViewApi.ts new file mode 100644 index 0000000..136e1d8 --- /dev/null +++ b/src/mentorship/api/MentorViewApi.ts @@ -0,0 +1,26 @@ +import axiosInstance from '@/global/api/axiosInstance'; +import { MentorData } from '@/user/types'; + +export const getMentorById = async (mentorId: number): Promise => { + const response = await axiosInstance.get(`/v1/mentor/${mentorId}`); + const data = response.data.data; + + return { + nickname: data.nickname ?? '', + education: data.education ?? { schoolName: '', major: '' }, + organization: data.organization ?? { + name: '', + jobCategory: '', + detailedJob: '', + experience: 0, + }, + introduction: data.introduction ?? { title: '', content: '' }, + timezone: data.timezone ?? { days: [], startTime: '', endTime: '' }, + mentoringField: data.mentoringField ?? [], + hashtags: data.hashtags ?? [], + message: data.message ?? '', + portfolio: data.portfolio ?? { url: '', description: '', size: 0 }, + image: data.image ?? { fileName: '', filePath: '' }, + count: data.count ?? 0, + }; +}; \ No newline at end of file diff --git a/src/mentorship/pages/MentorInfoView.tsx b/src/mentorship/pages/MentorInfoView.tsx index 406f01b..3ef3c2e 100644 --- a/src/mentorship/pages/MentorInfoView.tsx +++ b/src/mentorship/pages/MentorInfoView.tsx @@ -1,9 +1,14 @@ import { useState, useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import { ArrowLeft } from 'lucide-react'; import { Bookmark } from 'lucide-react'; import { GlobalButton } from '@/global/ui/GlobalButton'; +import { getMentorById } from '../api/MentorViewApi'; +import { MentorData } from '@/user/types'; +import { reverseJobCategoryMapping, reverseDetailedJobMapping } from '@/user/components/Mapping'; +import { reverseMentoringFieldMapping, reverseDayMapping } from '@/user/components/Mapping'; + import MentorInfoProfile from '../../user/components/profileInfo/MentorInfoProfile'; import MentorInfoBio from '../../user/components/profileInfo/MentorInfoBio'; import MentorInfoFieldsHashtags from '../../user/components/profileInfo/MentorInfoFieldsHashtags'; @@ -12,50 +17,40 @@ import MentorInfoMessage from '../../user/components/profileInfo/MentorInfoMessa import MentorInfoPortfolio from '../../user/components/profileInfo/MentorInfoPortfolio'; const MentorInfoView = () => { + const { mentorId } = useParams<{ mentorId: string }>(); const navigate = useNavigate(); const [isBookmarked, setIsBookmarked] = useState(false); + const [mentorData, setMentorData] = useState(null); - // 테스트용 멘티 데이터 && localStorage에서 데이터 불러오기 (api 연결시 제거) - const [mentorData, setMentorData] = useState(() => { - const savedData = localStorage.getItem("mentorData"); - return savedData ? JSON.parse(savedData) : { - nickname: "바이", - email: "abcd@gmail.com", - education: { - schoolName: "경북대학교", - major: "컴퓨터공학", - }, - organization: { - name: "OO주식회사", - role: "브랜드 마케팅/카피라이팅", - experience: 6, - }, - count: 716, - image: { - fileName: "", - filePath: "", - }, - introduction: { - summary: "브랜드 마케팅에 대한 모든 것을 알려드립니다.", - bio: "안녕하세요!\n저는 OO대학교 경영학과를 졸업하고 현재 XXXX에 다니고 있는 ‘바이’입니다.", - }, - availableDays: ["월", "목"], - timezone: { - startTime: { period: "오전", hour: "10", minute: "00"}, - endTime: { period: "오후", hour: "18", minute: "00"}, - }, - mentoringField: ["취업 준비", "커리어 고민"], - hashtags: ["마케팅", "브랜드마케팅", "이직", "취준", "진로고민상담", "면접노하우"], - message: "안녕하세요, 멘티 여러분!\n브랜드 마케팅 경험을 바탕으로 여러분의 성장을 지원하고 싶습니다.", - portfolio: [ - { - url: "https://example.com/portfolio1.pdf", - description: "브랜드 마케팅 포트폴리오.pdf", - size: 25, - }, - ], + useEffect(() => { + const fetchData = async () => { + try { + if (!mentorId || isNaN(Number(mentorId))) return; + const data = await getMentorById(Number(mentorId)); + + // 매핑 + const localizedData: MentorData = { + ...data, + mentoringField: data.mentoringField.map((f) => reverseMentoringFieldMapping[f] || f), + timezone: { + ...data.timezone, + days: data.timezone.days.map((d) => reverseDayMapping[d] || d), + }, + organization: { + ...data.organization, + jobCategory: reverseJobCategoryMapping[data.organization.jobCategory] || data.organization.jobCategory, + detailedJob: reverseDetailedJobMapping[data.organization.detailedJob] || data.organization.detailedJob, + }, + }; + + setMentorData(localizedData); + } catch (err) { + console.error("멘토 상세 불러오기 실패:", err); + } }; - }); + + fetchData(); + }, [mentorId]); useEffect(() => { const storedBookmark = localStorage.getItem("isBookmarked"); @@ -68,6 +63,8 @@ const MentorInfoView = () => { localStorage.setItem("isBookmarked", newBookmarkState.toString()); }; + if (!mentorData) return
Loading...
; + return (
@@ -98,7 +95,8 @@ const MentorInfoView = () => { { {/* 자기소개 */} {/* 선호 시간대 */} diff --git a/src/user/api/MenteeInfoApi.ts b/src/user/api/MenteeInfoApi.ts new file mode 100644 index 0000000..e1f9115 --- /dev/null +++ b/src/user/api/MenteeInfoApi.ts @@ -0,0 +1,28 @@ +import { MenteeData } from "../menteetypes"; +import axiosInstance from "@/global/api/axiosInstance"; + +// 멘티 프로필 조회 API +export const getMenteeProfile = async (): Promise => { + const response = await axiosInstance.get('/v1/mentee/me'); + const data = response.data.data; + + console.log('멘티 프로필 응답:', response.data); + + return { + nickname: data.nickname ?? '', + education: data.education ?? { + schoolName: '', + major: '', + }, + introduction: data.introduction ?? '', + image: data.image ?? { + filePath: '', + }, + }; +}; + +// 멘티 프로필 수정 API +export const updateMenteeProfile = async (menteeData: MenteeData): Promise => { + const response = await axiosInstance.put('/v1/mentee', menteeData); + return response.data; +}; \ No newline at end of file diff --git a/src/user/api/MentorInfoApi.ts b/src/user/api/MentorInfoApi.ts new file mode 100644 index 0000000..f27d77d --- /dev/null +++ b/src/user/api/MentorInfoApi.ts @@ -0,0 +1,33 @@ +import { MentorData } from '../types'; +import axiosInstance from '@/global/api/axiosInstance'; + +// 멘토 프로필 조회 API +export const getMentorProfile = async (): Promise => { + const response = await axiosInstance.get('/v1/mentor/me'); + const data = response.data.data; + + return { + nickname: data.nickname ?? '', + education: data.education ?? { schoolName: '', major: '' }, + organization: data.organization ?? { + name: '', + jobCategory: '', + detailedJob: '', + experience: 0, + }, + introduction: data.introduction ?? { title: '', content: '' }, + timezone: data.timezone ?? { days: [], startTime: '', endTime: '' }, + mentoringField: data.mentoringField ?? [], + hashtags: data.hashtags ?? [], + message: data.message ?? '', + portfolio: data.portfolio ?? { url: '', description: '', size: 0 }, + image: data.image ?? { fileName: '', filePath: '' }, + count: data.count ?? 0, + }; +}; + +// 멘토 프로필 수정 API +export const updateMentorProfile = async (mentorData: MentorData): Promise => { + const response = await axiosInstance.put('/v1/mentor', mentorData); + return response.data; +}; \ No newline at end of file diff --git a/src/user/components/Mapping.ts b/src/user/components/Mapping.ts new file mode 100644 index 0000000..acc3f9b --- /dev/null +++ b/src/user/components/Mapping.ts @@ -0,0 +1,51 @@ +import { jobCategoryMapping, detailedJobMapping } from "@/global/components/JobCategories"; + +// 직무 (한글로) +export const reverseJobCategoryMapping: { [key: string]: string } = Object.entries(jobCategoryMapping) + .reduce((acc, [kor, eng]) => { + acc[eng] = kor; + return acc; + }, {} as { [key: string]: string }); + + +// 세부 직무 (한글로) +export const reverseDetailedJobMapping: { [key: string]: string } = Object.entries(detailedJobMapping) + .reduce((acc, [kor, eng]) => { + acc[eng] = kor; + return acc; + }, {} as { [key: string]: string }); + + + +// 멘토링 분야 (영어로) +export const mentoringFieldMapping: Record = { + '취업 준비': 'JOB_PREPARATION', + '면접 대비': 'INTERVIEW_PREPARATION', + '업계 동향': 'PRACTICAL_SKILLS', + '커리어 고민': 'PORTFOLIO', +}; + +// 멘토링 분야 (한글로) +export const reverseMentoringFieldMapping: Record = Object.entries(mentoringFieldMapping).reduce((acc, [kor, eng]) => { + acc[eng] = kor; + return acc; +}, {} as Record); + + + +// 요일 (영어로) +export const dayMapping: Record = { + '월': 'MON', + '화': 'TUE', + '수': 'WED', + '목': 'THU', + '금': 'FRI', + '토': 'SAT', + '일': 'SUN', +}; + +// 요일 (한글로) +export const reverseDayMapping: Record = Object.entries(dayMapping).reduce((acc, [kor, eng]) => { + acc[eng] = kor; + return acc; +}, {} as Record); \ No newline at end of file diff --git a/src/user/components/ProfileEdit/EditBio.tsx b/src/user/components/ProfileEdit/EditBio.tsx index 4baa541..782d4f7 100644 --- a/src/user/components/ProfileEdit/EditBio.tsx +++ b/src/user/components/ProfileEdit/EditBio.tsx @@ -3,67 +3,59 @@ import { MenteeData } from '@/user/menteetypes'; interface EditBioProps { mentorData?: MentorData; - setMentorData?: React.Dispatch>; + setMentorData?: React.Dispatch>; menteeData?: MenteeData; setMenteeData?: React.Dispatch>; } const EditBio = ({ mentorData, setMentorData, menteeData, setMenteeData }: EditBioProps) => { - if (!mentorData && !menteeData) return null; return (
자기소개
- {/* 한줄소개 */} -