Select Git revision
Mypage.js 17.89 KiB
//마이페이지 구성
import React, { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import '../assets/Mypage.css';
const apiUrl = process.env.REACT_APP_API_URL;
const sportType = ["러닝", "클라이밍", "헬스"];
function Mypage() {
useEffect(() => {
document.body.style.backgroundColor = 'black';
document.body.style.color = 'white'; // 글자 색상 흰색으로 변경
}, []);
const token = localStorage.getItem('authToken');
const userID = localStorage.getItem('userID');
let navigate = useNavigate();
const handleNavClick = (crew) => {
if (crew && crew.crewID) {
navigate(`/CrewPage/${crew.crewID}`, { state: { crew, user } });
} else {
console.error('Crew ID is missing!');
}
}
const [isModalOpen, setIsModalOpen] = useState(false);
const [selectedEvent, setSelectedEvent] = useState(null);
const [crewpage, setCrewPage] = useState(1);
const [totalCrewPages, setTotalCrewPages] = useState(1);
const [eventpage, setEventPage] = useState(1);
const [totalEventPages, setTotalEventPages] = useState(1);
const [editMode, setEditMode] = useState(false);
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormState((prevState) => ({
...prevState,
[name]: value,
}));
};
const handleSave = async () => {
const password = prompt("비밀번호를 입력하세요:");
if (!password) {
alert("정보 수정을 위해선 비밀번호가 필요합니다.");
return;
}
const requestData = {
password: password,
profile: {
profileImage: formState.profileImage, // 기본 이미지 설정
regionID: formState.regionID, // 기본 값 설정 (필요 시)
job: formState.job,
birthDate: formState.birthDate,
experience: formState.experience,
introduction: formState.introduction,
sportTypeID: formState.sportTypeID,
},
};
try {
const response = await fetch(`${apiUrl}/api/users/${userID}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-AUTH-TOKEN': token,
},
body: JSON.stringify(requestData),
});
if (response.ok) {
const updatedUser = await response.json();
setUser(updatedUser);
setEditMode(false);
} else {
console.error('Failed to update user:', response.statusText);
}
} catch (error) {
console.error('Error during update:', error);
}
setEditMode(false);
};
const handleCrewPageChange = (newPage) => {
if (newPage >= 0 && newPage <= totalCrewPages) {
setCrewPage(newPage);
}
};
const handleEventPageChange = (newPage) => {
if (newPage >= 0 && newPage <= totalEventPages) {
setEventPage(newPage);
}
};
const openModal = (event) => {
setSelectedEvent(event);
setIsModalOpen(true);
};
const closeModal = () => {
setSelectedEvent(null);
setIsModalOpen(false);
};
//유저 state
const [user, setUser] = useState(null);
const [crews, setCrews] = useState([]);
const [events, setEvents] = useState([]);
const [view, setView] = useState('crews');
const [formState, setFormState] = useState({
profileImage: '',
regionID: 0,
birthDate: '',
job: '',
sportTypeID: 0,
experience: '',
introduction: '',
});
//지역ID로 지역 조회
const fetchRegion = async (regionID) => {
try {
const regionResponse = await fetch(`${apiUrl}/api/regions/${regionID}`,{
method: 'GET',
headers: {
'X-AUTH-TOKEN': token
}
});
const regionData = await regionResponse.json();
if (regionData.parentRegionID !== null) {
const parentRegionData = await fetchRegion(regionData.parentRegionID);
regionData.regionName = `${parentRegionData.regionName} ${regionData.regionName}`;
}
return regionData;
} catch (error) {
console.error('Error fetching region data:', error);
throw error; // 에러를 상위로 전달
}
};
useEffect(() => {
fetch(`${apiUrl}/api/users/${userID}`, {
method: 'GET',
headers: {
'X-AUTH-TOKEN': token,
},
}) //userID로 요청
.then(response => response.json())
.then(data => setUser(data))
.catch(error => console.error('Error fetching courses:', error));
console.log(userID);
}, []);
useEffect(() => {
if (user) {
setFormState({
profileImage: user.profile?.profileImage || '',
regionID: user.profile?.regionID || '',
birthDate: user.profile?.birthDate || '',
job: user.profile?.job || '',
sportTypeID: user.profile?.sportTypeID || '',
experience: user.profile?.experience || '',
introduction: user.profile?.introduction || '',
});
}
console.log(user);
}, [user]);
//유저가 가입한 크루 데이터
useEffect(() => {
console.log("유저가가입한크루어쩌구");
if (user && user.userID) {
fetch(`${apiUrl}/api/users/${userID}/crews?page=${crewpage}`, {
method: 'GET',
headers: {
'X-AUTH-TOKEN': token,
},
})
.then((response) => response.json())
.then(async (data) => {
const crewsWithRegion = await Promise.all(data.crews.map(async (crew) => {
const region = await fetchRegion(crew.regionID); // 지역 데이터 가져오기
return {
...crew,
regionName: region.regionName, // 지역 이름을 추가
};
}));
setCrews(crewsWithRegion);
setTotalCrewPages(Math.ceil(data.total / data.per_page)); // 총 페이지 수 설정
console.log("fetchData", data, crewsWithRegion)
})
.catch((error) => console.error("크루 데이터를 가져오는 데 실패했습니다:", error));
}
}, [user, crewpage]);
//유저가 가입한 모임 데이터
useEffect(() => {
if (user && user.userID) {
fetch(`${apiUrl}/api/users/${userID}/crews?page=${eventpage}`, {
method: 'GET',
headers: {
'X-AUTH-TOKEN': token,
},
})
.then((response) => response.json())
.then(async (data) => {
if (data && Array.isArray(data.events)) { // data.events가 배열인지 확인
const eventsWithRegion = await Promise.all(data.events.map(async (event) => {
const region = await fetchRegion(event.regionID); // 지역 데이터 가져오기
return {
...event,
regionName: region.regionName, // 지역 이름을 추가
};
}));
setCrews(eventsWithRegion);
setTotalEventPages(data.totalPages); // 총 페이지 수 설정
}
})
.catch((error) => console.error("모임 데이터를 가져오는 데 실패했습니다:", error));
}
}, [user, eventpage]);
//모임 수정
const editEvent = async (eventID) => {
try {
const response = await fetch(`${apiUrl}/api/events/${eventID}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-AUTH-TOKEN': token
},
body: JSON.stringify({
name: selectedEvent.name,
eventDate: selectedEvent.eventDate,
capacity: selectedEvent.capacity,
feeCondition: selectedEvent.feeCondition,
userID: user.userID,
}),
});
if (response.ok) {
setEvents(events.filter(event => event.eventID !== eventID));
console.log("수정완료");
} else {
console.error('수정 실패:', response.statusText);
console.log(selectedEvent)
}
} catch (error) {
console.error('Error updating event:', error);
}
};
//모임 삭제
const deleteEvent = async (eventID) => {
try {
const response = await fetch(`${apiUrl}/api/events/${eventID}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'X-AUTH-TOKEN': token
},
body: JSON.stringify({
userID: user.userID,
}),
});
if (response.ok) {
setEvents(events.filter(event => event.eventID !== eventID));
console.log("삭제완료");
} else {
console.error('삭제 실패:', response.statusText);
}
} catch (error) {
console.error('Error deleting event:', error);
}
};
if (!user) {
return <div>Loading...</div>;
}
return(
<>
{/*<CrewPage user={user} />*/}
<div className='profile'>
<div className='myprofile'>
<p>나의 프로필</p>
<img src={user.profile.profileImage} alt="profileImg"></img> {/* 프로필 이미지 받아오기 */}
</div>
<div className='details'>
<div className='profileDetails'>
<span>이름</span>
<span>생년월일</span>
<span>직업</span>
<span>운동 종목</span>
<span>운동 경험</span>
<span>자기소개</span>
<span> </span>
<span> </span>
</div>
{editMode ? (
<>
<div className='userProfileDetails'>
<span>{user.name}</span>
<input type="date" name="birthDate" value={formState.birthDate} onChange={handleInputChange} placeholder="Birth Date"/>
<input type="text" name="job" value={formState.job} onChange={handleInputChange} placeholder="Job"/>
<select name="sportTypeID" value={formState.sportTypeID} onChange={handleInputChange}>
<option value="">Select Sport Type</option>
{sportType.map((type, index) => (
<option key={index} value={index + 1}>
{type}
</option>
))}
</select>
<input type="text" name="experience" value={formState.experience} onChange={handleInputChange} placeholder="Experience"/>
<input type="text" name="introduction" value={formState.introduction} onChange={handleInputChange} placeholder="Introduction"/>
<button className="save" onClick={handleSave}>저장</button>
<button className='cancel' onClick={() => setEditMode(false)}>취소</button>
</div>
</>
) : (
<>
<div className='userProfileDetails'>
<span>{user.name}</span> {/* 사용자 이름 */}
<span>{user.profile?.birthDate ? new Date(user.profile.birthDate).toLocaleDateString('ko-KR') : ''}</span> {/* 사용자 생년월일 */}
<span>{user.profile?.job ? user.profile.job : "Job date not available"}</span> {/* 사용자 직업 */}
<span>{user.profile?.sportTypeID ? sportType[user.profile.sportTypeID - 1] : "sportTypeId date not available"}</span> {/* 운동 종목 */}
<span>{user.profile?.experience ? user.profile.experience : "experience date not available"}</span> {/* 사용자 설정 내용 */}
<span>{user.profile?.introduction ? user.profile.introduction : "introduction date not available"}</span> {/* 사용자 이름 */}
<span> </span>
<button className="edit" onClick={() => setEditMode(true)}>수정</button>
</div>
</>
)}
</div>
</div>
<div className='crewHeader'>
<h2>가입된 크루 및 모임</h2>
<div className="tabs">
<button className={view === 'crews' ? 'active' : ''} onClick={() => setView('crews')}>크루</button>
<button className={view === 'events' ? 'active' : ''} onClick={() => setView('events')}>모임</button>
</div>
</div>
<div className='entered'>
{view === 'crews' && (
<>
<div className="crews">
{crews.map((crew) => (
<div className="crew" key={crew.crewID}>
<h4>{crew.name}</h4>
<p>{crew.regionName}</p>
<p>{sportType[crew.sportTypeID - 1]}</p>
<button className="enter" onClick={() => handleNavClick(crew)}>입장하기</button>
</div>
))}
</div>
<div className="pagination">
<button onClick={() => handleCrewPageChange(crewpage - 1)} disabled={crewpage === 1} className={crewpage === 1 ? 'disabled' : ''}>
이전
</button>
{[...Array(totalCrewPages)].map((_, index) => (
<button key={index + 1} onClick={() => handleCrewPageChange(index + 1)} className={`page-button ${crewpage === index + 1 ? 'active' : ''}`}>{index + 1}</button>
))}
<button onClick={() => handleCrewPageChange(crewpage + 1)} disabled={crewpage === totalCrewPages} className={crewpage === totalCrewPages ? 'disabled' : ''}>
다음
</button>
</div>
</>
)}
{view === 'events' && (
<>
<div className="meets">
{events.map((event) => (
<div className="meet" key={event.eventID}>
<h4>{event.name}</h4>
<p>{event.regionName}</p>
<p>{sportType[event.sportTypeID - 1]}</p>
<button className="viewDetail" onClick={() => openModal(event)}>자세히보기</button>
</div>
))}
</div>
<div className="pagination">
<button onClick={() => handleEventPageChange(eventpage - 1)} disabled={eventpage === 1} className={eventpage === 1 ? 'disabled' : ''}>
이전
</button>
{[...Array(totalEventPages)].map((_, index) => (
<button key={index + 1} onClick={() => handleEventPageChange(index + 1)} className={`page-button ${eventpage === index + 1 ? 'active' : ''}`}>{index + 1}</button>
))}
<button onClick={() => handleEventPageChange(eventpage + 1)} disabled={eventpage === totalEventPages} className={eventpage === totalEventPages ? 'disabled' : ''}>
다음
</button>
</div>
</>
)}
</div>
{isModalOpen && selectedEvent && (
<div className='modal'>
<div className="modalContent">
{selectedEvent.userID !== user.userID &&(
<>
<div className='modalHeader'>
<span class="closeButton" onClick={closeModal}>×</span>
<h2>{selectedEvent.name}</h2>
</div>
<div className='meetsDetail'>
<p className='item'>{selectedEvent.regionID}</p>
<p className='item'>{sportType[selectedEvent.sportTypeID - 1]}</p>
<p className='item'>{selectedEvent.eventDate}</p>
<p className='item'>{selectedEvent.currentMemberCount}/{selectedEvent.capacity}</p>
<p className='item'>{selectedEvent.feeCondition ? selectedEvent.feeCondition : "설정된 비용/조건이 없습니다."}</p>
</div>
</>)}
{selectedEvent.userID === user.userID && (
<>
<div className='modalHeader'>
<span class="closeButton" onClick={closeModal}>×</span>
<input type="text" value={selectedEvent.name} onChange={(e) => setSelectedEvent({ ...selectedEvent, name: e.target.value })}/>
</div>
<div className='meetsDetail'>
<p className='item'>{selectedEvent.regionID}</p>
<p className='item'>{sportType[selectedEvent.sportTypeID - 1]}</p>
<input className="item" type="date" value={selectedEvent.eventDate} onChange={(e) => setSelectedEvent({ ...selectedEvent, eventDate: e.target.value })}/>
<input className="item" type="number" value={selectedEvent.capacity} onChange={(e) => setSelectedEvent({ ...selectedEvent, capacity: parseInt(e.target.value) || 0})}/>
<input className="item" type="text" value={selectedEvent.feeCondition} onChange={(e) => setSelectedEvent({ ...selectedEvent, feeCondition: e.target.value })}/>
</div>
<button className='editButton' onClick={() => editEvent(selectedEvent.eventID)}>수정하기</button>
<button className='deleteButton' onClick={() => deleteEvent(selectedEvent.eventID)}>삭제하기</button>
</>
)}
</div>
</div>)}
</>
);
}
export default Mypage;