import {useEffect, useState} from "react";
import {Api} from "../network/Api";
import "../css/Mentors.css"
import Center from "./Center";
// 리액트에서 이미지를 넣으려면 이렇게 변수에 경로를 담아 사용해야 한다.
import myImg from "../img/122416681.jpg";
import {useNavigate} from "react-router";
// Mentors 컴포넌트 선언
const Mentors = () => {
const nav = useNavigate(); // React Router의 useNavigate 훅을 통한 사용자 이동 함수
const [mentors, setMentors] = useState([]); // 멘토들의 정보를 담는 상태
const [error, setError] = useState(null); // 오류 처리를 위한 상태
const [mentoringField, setMentoringField] = useState([]); // 멘토링 분야를 담는 상태
// 멘토링 분야의 메뉴 정보
const menu = [
{
name: "전체보기",
background: "#F6FFED",
color: "389e0d"
},
{
name: "인사/총무/노무",
background: "#FFF0F6",
color: "#C41D7F"
},
{
name: "마케팅/MD",
background: "#F9F0FF",
color: "#531DAB"
},
// ... (메뉴 정보 생략)
];
// 컴포넌트가 렌더링된 이후에 실행되는 효과 훅
useEffect(() => {
// 멘토 데이터를 가져오는 비동기 함수
const fetchMentors = async () => {
try {
// Api 함수를 통해 멘토 데이터를 가져옴
const mentorsData = await Api(`api/v1/mentors`, "GET");
console.log(mentorsData.data);
setMentors(mentorsData.data); // 상태 업데이트
} catch (e) {
setError(e); // 오류 처리
}
};
fetchMentors(); // 멘토 데이터 가져오기 실행
}, []);
useEffect(() => {
// 멘토링 분야 데이터를 가져오는 비동기 함수
const fetchField = async () => {
try {
setMentoringField([]); // 상태 초기화
const mentoringFieldData = await Api(`api/v1/mentoringField`, "GET");
console.log(mentoringFieldData);
setMentoringField(mentoringFieldData.data); // 상태 업데이트
} catch (e) {
setError(e); // 오류 처리
}
};
fetchField(); // 멘토링 분야 데이터 가져오기 실행
}, []);
// 멘토 상세 정보 페이지로 이동하는 함수
const mentorDetail = (mentor) => {
nav(`/mentorDetail?mentorId=${mentor.mentorId}`);
};
return (
<div className="App">
<Center>
{/* 카테고리 메뉴 */}
<div className="infoMent">
<div className="infoTopMent">
<div className="category">
{menu.map((item, idx) => (
<div
key={idx}
style={{ background: item.background, color: item.color }}
className="categoryItem"
>
<span>{item.name}</span>
</div>
))}
</div>
</div>
</div>
<div>
<h1>Mentor</h1>
</div>
<div className="card_wrap">
{/* 멘토 카드들 */}
{mentors.map((mentor, idx) => (
<div key={idx} onClick={() => mentorDetail(mentor)}>
<div className="card_detail">
<div className="story">
<div className="story_title">{mentor.company}</div>
{/* 멘토 분야 카테고리 */}
<div
style={{ background: mentor.background, color: mentor.color }}
className="categoryItem"
>
{mentor.categoryItem}
</div>
</div>
<div className="card_img">
{/* 멘토 이미지 */}
<img style={{ width: "150px", height: "150px" }} src={myImg} />
</div>
<div>
<strong>
{mentor.username} <span> 멘토 </span>
</strong>
</div>
<div className="story_profile">
<span>{mentor.department}</span>
</div>
{/* 멘토 경력 정보 */}
<div>{mentor.majorCareer}</div>
</div>
</div>
))}
</div>
</Center>
</div>
);
};
export default Mentors; // Mentors 컴포넌트 내보내기
➡️ 멘토의 상세 정보를 나타내는 MentorDetail 컴포넌트.
➡️ URL에서 mentorId 매개변수를 추출하고, 해당 mentorId를 사용하여 서버로부터 멘토의 상세 정보를 가져와 화면에 표시.
➡️ 아직 UI를 예쁘게 꾸미진 못하겠어서 우선 필요한 데이터만이라도 받아오게 했다.
왼쪽과 오른쪽으로 나누는 것 조차 전혀 모르겠어서 학원 오가는 길에 유튜브로 영상을 찾아보던 중 HTML 구조를 잘 설명해준 영상을 보고 전체적은 구조를 잡는 방법을 이해하게 됐고 그래서 그나마 이렇게라도 만들 수 있었다.
학원에 능력자들이 많아서 그들이 만든 ui를 보자면 내 화면은 정말 별게 없어 보이지만 이 부분을 처음 다루는데 이만큼 한것만으로도 나는 만족스럽다.🙂
(프로젝트 발표할 때는 먼저 완성한 조장님이 여기를 예쁘게 꾸며주셔서 그걸로 발표했지만 그건 내가 한게 아니니 난 내가 한걸로만 기록. 나중엔 좀 더 예쁘게 할 수 있게되겠지😗)
import { useEffect, useState } from "react";
import axios from "axios"; // Axios를 이용한 HTTP 요청
import myImg from "../img/122416681.jpg";
import "../css/MentorDetail.css";
const MentorDetail = () => {
const [mentor, setMentor] = useState({}); // 멘토 정보를 담는 상태
useEffect(() => {
// 페이지가 처음 들어올 때 실행되는 코드
const url = new URL(window.location.href); // 현재 URL을 가져옴
const mentorId = url.searchParams.get('mentorId'); // mentorId 매개변수를 추출
// mentorId를 사용하여 서버로부터 멘토 정보를 가져오는 HTTP 요청 (GET)
axios.get(`http://localhost:8080/api/v1/mentors/${mentorId}`)
.then((res) => {
console.log(res.data);
setMentor(res.data); // 상태 업데이트하여 멘토 정보 저장
})
.catch((err) => {
console.log(err);
});
}, []);
return (
<div className="App">
<div className="mentor_detail_box">
<div className="mentor-container">
<div className="profile-image">
{/* 멘토 프로필 이미지 */}
<img style={{ width: '150px', height: '150px' }} src={myImg} />
</div>
{/* 멘토 정보 */}
<div>{mentor.company}</div>
<div>{mentor.department}</div>
<div>{mentor.majorCareer}</div>
<div className="name">{mentor.username}</div>
</div>
<div className="mentor_introduction">
<div>
<div className="mentor_introduction_detail">
<h2>대표 멘토링 분야</h2>
</div>
{/* 멘토링 분야 정보 */}
{mentor.mentoringFields &&
Array.isArray(mentor.mentoringFields) &&
mentor.mentoringFields.map((item, idx) => (
<div key={idx}>
<p>#{item.fieldName}</p>
</div>
))}
<div className="mentor_introduction_detail">
<h2>멘토 소개</h2>
</div>
{/* 멘토 소개 */}
<div className="mentor_introduction_detail">
{mentor.introduction}
</div>
<div>
<h2>주요 경력</h2>
{/* 멘토 주요 경력 정보 */}
{mentor.majorCareer}
</div>
</div>
</div>
</div>
</div>
);
};
export default MentorDetail; // MentorDetail 컴포넌트 내보내기
참고 - HTML 구조잡기
import { useEffect, useState } from "react";
import Center from "./Center";
import "../css/MentorRequests.css";
import axios from "axios";
import { useNavigate } from "react-router";
import { Api } from "../network/Api";
const MentorRequests = () => {
const nav = useNavigate(); // React Router의 useNavigate 훅을 통한 사용자 이동 함수
const [mentoringField, setMentoringField] = useState([]); // 멘토링 분야 정보를 담는 상태
const [selectedFields, setSelectedFields] = useState([]); // 선택된 분야 정보를 담는 상태
const [user, setUser] = useState({
company: "",
department: "",
introduction: "",
majorCareer: "",
profilePicture: ""
}); // 사용자 정보를 담는 상태
useEffect(() => {
// 멘토링 분야 정보를 가져오는 효과 훅
const fetchField = async () => {
try {
setMentoringField([]); // 상태 초기화
const mentoringFieldData = await Api(`api/v1/mentoringField`, "GET"); // API로 멘토링 분야 데이터 요청
console.log(mentoringFieldData.data);
setMentoringField(mentoringFieldData.data); // 상태 업데이트
} catch (e) {
// 오류 처리
console.error("Error:", e);
}
};
fetchField(); // 멘토링 분야 데이터 가져오기 실행
}, []);
const onFieldSelect = (fieldId) => {
// 선택한 분야 정보를 추가하거나 제거하는 함수
if (selectedFields.includes(fieldId)) {
// 만약 이미 선택된 분야라면 선택을 취소
setSelectedFields(selectedFields.filter(id => id !== fieldId));
} else {
// 선택되지 않은 분야라면 선택
setSelectedFields([...selectedFields, fieldId]);
}
};
const onChangeHandler = (e) => {
// 입력 필드 변경 시 호출되는 함수
const { value, name } = e.target;
setUser({ ...user, [name]: value }); // 해당 입력 필드의 값을 업데이트
};
useEffect(() => {
// 로컬 스토리지에서 userId를 가져와서 user 상태 업데이트
const userId = localStorage.getItem("userId");
setUser((prevUser) => ({ ...prevUser, userId }));
}, []);
const onSubmitHandler = async (e) => {
// 폼 제출 시 호출되는 함수
e.preventDefault();
try {
const userId = localStorage.getItem("userId");
const requestData = {
mentorId: userId,
mentoringFieldId: selectedFields
};
// HTTP POST 요청을 통해 멘토 지원 정보를 서버로 전송
await axios.post(
`http://localhost:8080/api/v1/mentors/field`,
{ ...requestData, ...user }, // 사용자 정보 및 선택한 분야 데이터 전송
{
withCredentials: true,
headers: {
"Content-Type": "application/json"
}
}
);
nav("/mentors"); // 멘토 리스트 페이지로 이동
} catch (error) {
console.error("Error:", error);
}
};
return (
<div className="App">
<Center>
<div className="mentor-requests-container">
<div className="header">
<h1>멘토지원</h1>
</div>
<div className="item-content">
{/* 멘토 지원 폼 */}
<form onSubmit={onSubmitHandler}>
{/* 회사명 입력 */}
<div className="item-input">
<label htmlFor="company">회사명</label>
<input
type="text"
id="companyName"
placeholder="예) play data"
name="company"
onChange={onChangeHandler}
/>
</div>
{/* 부서 입력 */}
<div className="item-input">
<label htmlFor="department">부서</label>
<input
type="text"
id="department"
placeholder="예) 제품개발팀"
name="department"
onChange={onChangeHandler}
/>
</div>
{/* 주요 경력 입력 */}
<div className="item-input">
<label htmlFor="majorCareer">주요 경력</label>
<input
type="text"
id="majorCareer"
placeholder="내용을 입력해 주세요."
name="majorCareer"
onChange={onChangeHandler}
/>
</div>
{/* 멘토링 가능 분야 선택 */}
<label htmlFor="selectedFields">멘토링 가능 분야</label>
<div className="mentor_field">
{/* 멘토링 분야 목록 */}
{mentoringField.map((item, idx) => (
<div
key={idx}
className={`field_detail ${
selectedFields.includes(item.id) ? "selected" : ""
}`}
onClick={() => onFieldSelect(item.id)}
>
<label className="field-content">
<input type="checkbox" name="mentor_request" />
<div className="item-inner">
<div className="item-title">{item.fieldName}</div>
</div>
</label>
</div>
))}
</div>
{/* 멘토 소개 입력 */}
<div className="item-input-introduction">
<label htmlFor="introduction">멘토 소개</label>
<textarea
type="text"
id="introduction"
placeholder="내용을 입력해 주세요."
name="introduction"
className="custom-textarea"
onChange={onChangeHandler}
/>
</div>
{/* 제출 버튼 */}
<input type="submit" value={"등록"} />
</form>
</div>
</div>
</Center>
</div>
);
};
export default MentorRequests; // MentorRequests 컴포넌트 내보내기
와 리액트까지..!
정말 하루하루 열심히 고군분투하며 살아가고 계신게 여기까지 느껴지네요
RESPECT 드립니다