Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/app/login/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/app/mypage/approve_modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
};
Expand All @@ -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 [];
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/mypage/mypage.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export default function My({ projectId }) {
setSprintLast(response.last);

} catch (error) {
console.error("μŠ€ν”„λ¦°νŠΈ 뢈러였기 μ‹€νŒ¨:", error.message);
console.log("μŠ€ν”„λ¦°νŠΈ 뢈러였기 μ‹€νŒ¨:", error.message);
}
};

Expand Down Expand Up @@ -135,7 +135,7 @@ export default function My({ projectId }) {
setCurrentSprint(updatedSprints[currentSprintIndex]);
}
} catch (error) {
console.error("ν˜„μž¬ μŠ€ν”„λ¦°νŠΈ κ°±μ‹  μ‹€νŒ¨:", error.message);
console.log("ν˜„μž¬ μŠ€ν”„λ¦°νŠΈ κ°±μ‹  μ‹€νŒ¨:", error.message);
}
};

Expand Down
3 changes: 2 additions & 1 deletion src/app/task/task.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/app/team/leave_modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 || "ν”„λ‘œμ νŠΈ λ‚˜κ°€κΈ° μ‹€νŒ¨");
}
};
Expand Down
3 changes: 2 additions & 1 deletion src/app/team/project_modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ? "ν”„λ‘œμ νŠΈ μˆ˜μ • μ‹€νŒ¨" : "ν”„λ‘œμ νŠΈ 생성 μ‹€νŒ¨"}:`);
}
};

Expand Down
57 changes: 32 additions & 25 deletions src/app/team/section_s.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)`
Expand All @@ -264,10 +267,14 @@ export function LeaveProjectButton({ onClick }) {
);
}

export function JoinProjectButton({ onClick, isPending }) {
return (
<StyledButton onClick={onClick} $disabled={isPending}>
{isPending ? "μŠΉμΈλŒ€κΈ°" : "κ°€μž…μ‹ μ²­"}
</StyledButton>
);
export function JoinProjectButton({ onClick, isPending, joinStatus }) {
return (
<StyledButton
onClick={onClick}
$disabled={isPending}
$joinStatus={joinStatus}
>
{joinStatus === "PENDING" ? "μŠΉμΈλŒ€κΈ°" : "κ°€μž… μ‹ μ²­"}
</StyledButton>
);
}
100 changes: 79 additions & 21 deletions src/app/team/team.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import { useAlert } from "@/context/AlertContext";

import axiosWithAuthorization from "@/context/axiosWithAuthorization";



export default function Team({ teamId }) {
const { showAlert } = useAlert();

Expand Down Expand Up @@ -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 () => {
Expand Down Expand Up @@ -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||"μž μ‹œ λ’€ λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”");
}
};

Expand Down Expand Up @@ -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]);

Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -805,9 +861,11 @@ export default function Team({ teamId }) {
<S.ProjectHButton>ν”„λ‘œμ νŠΈ ν™ˆ</S.ProjectHButton>
</Link>
<JoinProjectButton
onClick={() => handleClick(project.projectInfo.projectId)}
onClick={() => handleClick(project)}
isPending={pendingProjects[project.projectInfo.projectId]}
joinStatus={normalizeJoinStatus(project.joinStatus ?? project.currentUserParticipation?.status)}
/>

</div>
</S.ProjectBox>
))
Expand Down
5 changes: 3 additions & 2 deletions src/components/Navbar_b.js
Original file line number Diff line number Diff line change
Expand Up @@ -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_ = () => {

Expand All @@ -21,8 +22,8 @@ const Navbar_ = () => {
localStorage.removeItem("storedUser");
router.push("/login");
} catch (error) {
console.error("λ‘œκ·Έμ•„μ›ƒ μ‹€νŒ¨:", error);
alert("λ‘œκ·Έμ•„μ›ƒμ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.");
console.log("λ‘œκ·Έμ•„μ›ƒ μ‹€νŒ¨:", error);
showAlert("error", "λ‘œκ·Έμ•„μ›ƒμ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.");
}
};

Expand Down
4 changes: 3 additions & 1 deletion src/components/modals-sw/TeamCreateModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -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("");
Expand Down Expand Up @@ -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", "νŒ€ 생성에 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.");
}
};

Expand Down