diff --git a/src/app/login/login.js b/src/app/login/login.js
index 3b5a42d..cdf7787 100644
--- a/src/app/login/login.js
+++ b/src/app/login/login.js
@@ -20,7 +20,7 @@ export default function Login() {
window.location.href = res.data.url; // OAuth 인증 페이지 redirect
console.log(res.data)
} catch (error) {
- console.error("로그인 요청 실패:", error.response ? error.response.data : error.message);
+ console.log("로그인 요청 실패:", error.response ? error.response.data : error.message);
}
};
diff --git a/src/app/mypage/approve_modal.js b/src/app/mypage/approve_modal.js
index 1c085f5..9c52b16 100644
--- a/src/app/mypage/approve_modal.js
+++ b/src/app/mypage/approve_modal.js
@@ -117,7 +117,7 @@ export default function ApproveModal({ isOpen, onClose, projectId }) {
console.log("프로젝트 개별 정보 조회:", res.data);
return res.data.data;
} catch (error) {
- showAlert("error", error.response.data.data.message);
+ showAlert("error", "프로젝트 정보를 불러올 수 없습니다.");
console.log(error.response.data);
}
};
@@ -136,7 +136,7 @@ export default function ApproveModal({ isOpen, onClose, projectId }) {
console.log("프로젝트 가입 신청 목록 조회:", res.data);
return res.data.data.content || [];
} catch (error) {
- showAlert("error", error.response.data.data.message);
+ showAlert("error","가입 신청자가 없습니다.");
console.log(error.response.data);
return [];
}
diff --git a/src/app/mypage/mypage.js b/src/app/mypage/mypage.js
index ceb2012..334ffcf 100644
--- a/src/app/mypage/mypage.js
+++ b/src/app/mypage/mypage.js
@@ -93,7 +93,7 @@ export default function My({ projectId }) {
setSprintLast(response.last);
} catch (error) {
- console.error("스프린트 불러오기 실패:", error.message);
+ console.log("스프린트 불러오기 실패:", error.message);
}
};
@@ -135,7 +135,7 @@ export default function My({ projectId }) {
setCurrentSprint(updatedSprints[currentSprintIndex]);
}
} catch (error) {
- console.error("현재 스프린트 갱신 실패:", error.message);
+ console.log("현재 스프린트 갱신 실패:", error.message);
}
};
diff --git a/src/app/task/task.js b/src/app/task/task.js
index 4d509d6..e95114d 100644
--- a/src/app/task/task.js
+++ b/src/app/task/task.js
@@ -68,7 +68,8 @@ export default function Task({ projectId }) {
}
} catch (error) {
- console.error("태스크 로딩 실패:", error.message);
+ console.log("태스크 로딩 실패:", error.message);
+ showAlert("태스크를 불러올 수 없습니다.")
setHasMore(false);
} finally {
setIsFetching(false);
diff --git a/src/app/team/leave_modal.js b/src/app/team/leave_modal.js
index 579a810..4f8d8e9 100644
--- a/src/app/team/leave_modal.js
+++ b/src/app/team/leave_modal.js
@@ -17,7 +17,7 @@ export default function LeaveModal({ selectedProject, onClose }) {
showAlert("success", "프로젝트 나가기가 완료되었습니다.");
onClose(); // 모달 닫기 후 추가 작업(예: 페이지 리디렉션) 필요 시 추가
} catch (error) {
- console.error(error);
+ console.log(error);
showAlert("error", error.response?.data?.message || "프로젝트 나가기 실패");
}
};
diff --git a/src/app/team/project_modal.js b/src/app/team/project_modal.js
index 6201b50..a55d43f 100644
--- a/src/app/team/project_modal.js
+++ b/src/app/team/project_modal.js
@@ -73,7 +73,8 @@ export default function ProjectModal({
onProjectCreated?.();
onClose(); // 모달 닫기
} catch (error) {
- console.error(`${isEditing ? "프로젝트 수정 실패" : "프로젝트 생성 실패"}:`, error.message);
+ console.log(`${isEditing ? "프로젝트 수정 실패" : "프로젝트 생성 실패"}:`, error.message);
+ showAlert("success", `${isEditing ? "프로젝트 수정 실패" : "프로젝트 생성 실패"}:`);
}
};
diff --git a/src/app/team/section_s.js b/src/app/team/section_s.js
index a74ca6c..1894327 100644
--- a/src/app/team/section_s.js
+++ b/src/app/team/section_s.js
@@ -225,25 +225,28 @@ export const ProjectHButton = styled.button`
`;
const StyledButton = styled.button`
- font-size: 12px;
- font-weight: bold;
- color: white;
- background: ${({ $disabled }) =>
- $disabled ? "#B3B3B3" : "#796AD9"};
- border: 2px solid ${({ $disabled }) =>
- $disabled ? "#B3B3B3" : "#796AD9"};
- border-radius: 12px;
- padding: 6px 12px;
- cursor: pointer;
- min-width: 85px;
- transition: 0.2s ease-in-out;
-
- &:hover {
- background: ${({ $disabled }) =>
- $disabled ? "#B3B3B3" : "#5a46c6"};
- border: 2px solid ${({ $disabled }) =>
- $disabled ? "#B3B3B3" : "#5a46c6"};
- }
+ font-size: 12px;
+ font-weight: bold;
+ color: white;
+
+ background: ${({ $disabled, $joinStatus }) =>
+ $disabled || $joinStatus === "PENDING" ? "#B3B3B3" : "#796AD9"};
+
+ border: 2px solid ${({ $disabled, $joinStatus }) =>
+ $disabled || $joinStatus === "PENDING" ? "#B3B3B3" : "#796AD9"};
+
+ border-radius: 12px;
+ padding: 6px 12px;
+ cursor: pointer;
+ min-width: 85px;
+ transition: 0.2s ease-in-out;
+
+ &:hover {
+ background: ${({ $disabled, $joinStatus }) =>
+ $disabled || $joinStatus === "PENDING" ? "#B3B3B3" : "#5a46c6"};
+ border: 2px solid ${({ $disabled, $joinStatus }) =>
+ $disabled || $joinStatus === "PENDING" ? "#B3B3B3" : "#5a46c6"};
+ }
`;
export const DeleteProjectButton = styled(StyledButton)`
@@ -264,10 +267,14 @@ export function LeaveProjectButton({ onClick }) {
);
}
-export function JoinProjectButton({ onClick, isPending }) {
- return (
-
- {isPending ? "승인대기" : "가입신청"}
-
- );
+export function JoinProjectButton({ onClick, isPending, joinStatus }) {
+ return (
+
+ {joinStatus === "PENDING" ? "승인대기" : "가입 신청"}
+
+ );
}
\ No newline at end of file
diff --git a/src/app/team/team.js b/src/app/team/team.js
index 5fe988a..d9e2e8d 100644
--- a/src/app/team/team.js
+++ b/src/app/team/team.js
@@ -30,6 +30,8 @@ import { useAlert } from "@/context/AlertContext";
import axiosWithAuthorization from "@/context/axiosWithAuthorization";
+
+
export default function Team({ teamId }) {
const { showAlert } = useAlert();
@@ -76,6 +78,7 @@ export default function Team({ teamId }) {
const [isMembersFetching, setIsMembersFetching] = useState(false);
const TeamId = Number(teamId);
+ const normalizeJoinStatus = (status) => status ?? "NONE";
useEffect(() => {
const getUserInfo = async () => {
@@ -141,11 +144,21 @@ export default function Team({ teamId }) {
//project 가입 신청
const requestProjectJoin = async (projectId) => {
try {
- const res = await axiosWithAuthorization.post(`/projects/${projectId}/registration`);
- return res.data.data.teamName;
+ const res = await axiosWithAuthorization.post(`/projects/${projectId}/registration`);
+ return res.data;
+ } catch (error) {
+ throw error.response?.data || error; // 명시적으로 throw
+ }
+ };
+
+ const cancelProjectJoin = async (projectId) => {
+ try {
+ const res = await axiosWithAuthorization.delete(
+ `/projects/${projectId}/registration/cancel`
+ );
+ return res.data;
} catch (error) {
- showAlert("error", error.response.data.data.message);
- console.log(error.response.data);
+ showAlert("error", error.response.data.data.message||"잠시 뒤 다시 시도해주세요");
}
};
@@ -234,19 +247,23 @@ export default function Team({ teamId }) {
const newOtherProjects = [];
content.forEach(project => {
- //유저가 프로젝트에 참여 중
+ const status = project.currentUserParticipation?.status ?? "NONE";
+ const newProject = {
+ ...project,
+
+ };
+
if (project.isParticipant) {
- //상태 INACTIVE -> others
- if (project.currentUserParticipation && project.currentUserParticipation.status === "INACTIVE") {
- newOtherProjects.push(project);
- } else {
- newMyProjects.push(project);
- }
+ if (status === "INACTIVE") {
+ newOtherProjects.push(newProject);
+ } else {
+ newMyProjects.push(newProject);
+ }
} else {
- newOtherProjects.push(project);
+ newOtherProjects.push(newProject);
}
- });
-
+ });
+
setMyProjects(prev => [...prev, ...newMyProjects]);
setOtherProjects(prev => [...prev, ...newOtherProjects]);
@@ -450,22 +467,61 @@ export default function Team({ teamId }) {
};
// 타 프로젝트 가입 신청 <-> 승인 대기
- const handleClick = (projectId) => {
+ const handleClick = async (project) => {
+ const projectId = project.projectInfo.projectId;
+ const status = normalizeJoinStatus(project.joinStatus);
+
+ if (pendingProjects[projectId]) return;
+
setPendingProjects((prev) => ({
...prev,
- [projectId]: !prev[projectId]
+ [projectId]: true,
}));
-
+
try {
- requestProjectJoin(projectId);
+ let updatedJoinStatus;
+
+ if (status === "PENDING") {
+ await cancelProjectJoin(projectId);
+ updatedJoinStatus = "NONE";
+ showAlert("success", "가입 신청이 취소되었습니다.");
+ } else {
+ await requestProjectJoin(projectId);
+ updatedJoinStatus = "PENDING";
+ showAlert("success", "가입 신청이 완료되었습니다.");
+ }
+
+ console.log(`프로젝트 ${projectId}의 새로운 상태:`, updatedJoinStatus);
+
+ // 상태 업데이트
+ setOtherProjects((prev) =>
+ prev.map((p) => {
+ if (p.projectInfo.projectId === projectId) {
+ return {
+ ...p,
+ joinStatus: updatedJoinStatus,
+ currentUserParticipation: {
+ ...(p.currentUserParticipation || {}),
+ status: updatedJoinStatus,
+ },
+ };
+ }
+ return p;
+ })
+ );
} catch (error) {
- // 실패 시 상태를 다시 되돌림 (rollback)
+ showAlert("error", error.message || "오류가 발생했습니다.");
+ } finally {
setPendingProjects((prev) => ({
...prev,
- [projectId]: !prev[projectId]
+ [projectId]: false,
}));
}
};
+
+
+
+
// 멤버 이름 3글자 이상이면 축약 표시
const reduceMemberName = (name) => {
@@ -805,9 +861,11 @@ export default function Team({ teamId }) {
프로젝트 홈
handleClick(project.projectInfo.projectId)}
+ onClick={() => handleClick(project)}
isPending={pendingProjects[project.projectInfo.projectId]}
+ joinStatus={normalizeJoinStatus(project.joinStatus ?? project.currentUserParticipation?.status)}
/>
+
))
diff --git a/src/components/Navbar_b.js b/src/components/Navbar_b.js
index 05d9268..d946eab 100644
--- a/src/components/Navbar_b.js
+++ b/src/components/Navbar_b.js
@@ -6,6 +6,7 @@ import Image from "next/image";
import { useRouter } from "next/navigation";
import { logout } from "@/app/api/logout/logout";
+import { useAlert } from "@/context/AlertContext";
const Navbar_ = () => {
@@ -21,8 +22,8 @@ const Navbar_ = () => {
localStorage.removeItem("storedUser");
router.push("/login");
} catch (error) {
- console.error("로그아웃 실패:", error);
- alert("로그아웃에 실패했습니다.");
+ console.log("로그아웃 실패:", error);
+ showAlert("error", "로그아웃에 실패했습니다.");
}
};
diff --git a/src/components/modals-sw/TeamCreateModal.js b/src/components/modals-sw/TeamCreateModal.js
index cb0c9ee..2394954 100644
--- a/src/components/modals-sw/TeamCreateModal.js
+++ b/src/components/modals-sw/TeamCreateModal.js
@@ -2,6 +2,7 @@
import React, { useEffect, useState } from "react";
import axios from "axios";
import * as S from "./team_create_modal_styles";
+import { useAlert } from "@/context/AlertContext";
const TeamCreateModal = ({ isOpen, onClose, onTeamCreated }) => {
const [teamName, setTeamName] = useState("");
@@ -61,10 +62,11 @@ const TeamCreateModal = ({ isOpen, onClose, onTeamCreated }) => {
onClose();
onTeamCreated();
} catch (error) {
- console.error(
+ console.log(
"팀 생성 실패:",
error.response ? error.response.data : error.message
);
+ showAlert("error", "팀 생성에 실패했습니다.");
}
};