Skip to content
Snippets Groups Projects
Select Git revision
  • 3d8aad3de47055df584d4cdb9b7c6effb5ccfa4a
  • main default protected
  • issue-28
3 results

Mypage.js

Blame
  • 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}>&times;</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}>&times;</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;