Skip to content
11 changes: 11 additions & 0 deletions src/app/api/project/projectApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,14 @@ export const deleteProject = async (projectId) => {
}
};

// μŠ€ν”„λ¦°νŠΈλ³„ 기여도 λž­ν‚Ή 쑰회
export const fetchSprintContributions = async (sprintId) => {
try {
const res = await axiosWithAuthorization.get(`/contributions/${sprintId}`);
console.log("μŠ€ν”„λ¦°νŠΈλ³„ 기여도 λž­ν‚Ή 쑰회:", res.data);
return res.data.data;
} catch (error) {
const message = error?.response?.data?.data?.message ?? "μŠ€ν”„λ¦°νŠΈλ³„ 기여도 λž­ν‚Ή 쑰회λ₯Ό μ‘°νšŒν•  수 μ—†μŠ΅λ‹ˆλ‹€.";
throw new Error(message);
}
};
15 changes: 15 additions & 0 deletions src/app/api/user/userApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,19 @@ export const fetchUserData = async () => {
const message = error?.response?.data?.data?.message ?? "νšŒμ› 정보λ₯Ό μ‘°νšŒν•  수 μ—†μŠ΅λ‹ˆλ‹€.";
throw new Error(message);
}
};


// [개인 νŽ˜μ΄μ§€] κ°œλ³„ νšŒμ› 기여도 점수 쑰회
export const fetchUserContributionData = async (projectId, sprintId) => {
try {
const res = await axiosWithAuthorization.get(`/contributions/${projectId}/me`, {
params: { sprintId },
});
console.log("[개인 νŽ˜μ΄μ§€] κ°œλ³„ νšŒμ› 기여도 점수 쑰회:", res.data);
return res.data.data;
} catch (error) {
const message = error?.response?.data?.data?.message ?? "[개인 νŽ˜μ΄μ§€] κ°œλ³„ νšŒμ› 기여도 점수λ₯Ό μ‘°νšŒν•  수 μ—†μŠ΅λ‹ˆλ‹€.";
throw new Error(message);
}
};
9 changes: 7 additions & 2 deletions src/app/home/home.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,12 @@ export default function Home() {
}, [selectedId]);


// νŒ€ μ„€λͺ… 15κΈ€μž 이상이면 μΆ•μ•½ ν‘œμ‹œ
// νŒ€ 이름 4κΈ€μž 이상이면 μΆ•μ•½ ν‘œμ‹œ
const reduceName = (name) => {
return name.length > 4 ? name.slice(0, 4) + ".." : name;
};

// νŒ€ μ„€λͺ… 10κΈ€μž 이상이면 μΆ•μ•½ ν‘œμ‹œ
const reduceDescription = (name) => {
return name.length > 10 ? name.slice(0, 10) + ".." : name;
};
Expand Down Expand Up @@ -276,7 +281,7 @@ export default function Home() {
window.location.href = `/team/${team.teamId}`;
}}>
<S.TitleContainer>
<S.Title>{team.teamName}</S.Title>
<S.Title>{reduceName(team.teamName)}</S.Title>
<S.MoreButton
onClick={(e) => {
e.stopPropagation();
Expand Down
24 changes: 21 additions & 3 deletions src/app/mypage/mypage.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import LeaderModal from "./leader_modal";
import { fetchProjectData, fetchProjectUser } from "@/app/api/project/projectApi";
import { fetchMySprintTaskData } from "@/app/api/sprint/sprintApi";
import { completeTask, sosTask } from "@/app/api/task/taskApi";
import { fetchUserContributionData } from "@/app/api/user/userApi"

import { useAlert } from "@/context/AlertContext";

Expand All @@ -35,6 +36,8 @@ export default function My({ projectId }) {
const [currentSprint, setCurrentSprint] = useState(null);
const [currentSprintIndex, setCurrentSprintIndex] = useState(0);

const [myContributionScore, setMyContributionScore] = useState(null);

const [clickCountMap, setClickCountMap] = useState({});

useEffect(() => {
Expand Down Expand Up @@ -184,6 +187,21 @@ export default function My({ projectId }) {
}
};

useEffect(() => {
const loadMyContribution = async () => {
if (!ProjectId || !currentSprint?.id) return;

try {
const data = await fetchUserContributionData(ProjectId, currentSprint.id);
setMyContributionScore(data?.score ?? 0);
} catch (error) {
setMyContributionScore(0); // μ‹€νŒ¨ μ‹œ 0으둜 λŒ€μ²΄
}
};

loadMyContribution();
}, [ProjectId, currentSprint?.id]);

// λͺ¨λ‹¬ μƒνƒœμ— 따라 슀크둀 μ œμ–΄
useEffect(() => {
const disableScroll = () => {
Expand Down Expand Up @@ -216,7 +234,7 @@ export default function My({ projectId }) {
<M.ProfileSection>
<M.ProfileImage $profileImage={projectUserData?.profileImageUrl} />
<M.ProfileInfo>
<M.Username>{projectUserData?.projectNickname} <span style={{ fontWeight: "normal" }}>λ‹˜μ˜ λ§ˆμ΄νŽ˜μ΄μ§€</span></M.Username>
<M.Username>{projectUserData?.nickname} <span style={{ fontWeight: "normal" }}>λ‹˜μ˜ λ§ˆμ΄νŽ˜μ΄μ§€</span></M.Username>
<div style={{ display: "flex", gap: "10px", alignItems: "center" }}>

<Link href={`/project/${projectData?.projectId}/feedback`}>
Expand Down Expand Up @@ -268,7 +286,7 @@ export default function My({ projectId }) {
<M.ContributionWrapper>
<M.ContributionTitle>기여도</M.ContributionTitle>
{typeof currentSprint?.progress === "number" && !isNaN(currentSprint.progress) && (
<ContributionCircle percentage={currentSprint.progress} />
<ContributionCircle percentage={myContributionScore} />
)}
</M.ContributionWrapper>

Expand All @@ -277,7 +295,7 @@ export default function My({ projectId }) {
<M.RoleWrapper>
<M.RoleTitle>μ—­ν• </M.RoleTitle>
<M.RoleText>
{projectUserData?.data?.role === "ADMIN" ? "νŒ€μž₯" : "νŒ€μ›"}
{projectUserData?.role === "ADMIN" ? "νŒ€μž₯" : "νŒ€μ›"}
</M.RoleText>
</M.RoleWrapper>

Expand Down
7 changes: 5 additions & 2 deletions src/app/project/meeting_modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export default function MeetingModal({
setStartTime,
endTime,
setEndTime,
sprintId,
sprintId,
sprintTitle,
isEditing,
onMeetingSaved,
onMeetingDeleted
Expand Down Expand Up @@ -116,7 +117,7 @@ export default function MeetingModal({
return (
<m.ModalOverlay>
<ModalContent onClick={(e) => e.stopPropagation()}>
<m.Title>Sprint {sprintId} νŒ€ λ―ΈνŒ…</m.Title>
<m.Title>Sprint {sprintTitle} νŒ€ λ―ΈνŒ…</m.Title>
<m.CloseButton onClick={onClose}>
<IoClose size={24} />
</m.CloseButton>
Expand All @@ -130,6 +131,8 @@ export default function MeetingModal({
setMeetingTitle(e.target.value);
setIsTitleChanged(true);
}}
maxLength={15}
placeholder="회의 λͺ…을 μž…λ ₯ν•˜μ„Έμš” (15자 이내)"
/>
</m.InputWrapper>
{/* λ‚ μ§œ μž…λ ₯ */}
Expand Down
Loading