diff --git a/src/apis/management.ts b/src/apis/management.ts
index a6f5884..6fb79f5 100644
--- a/src/apis/management.ts
+++ b/src/apis/management.ts
@@ -1,6 +1,17 @@
import { Axios } from '@apis/axios.ts';
import { TeamData } from '../types/management.ts';
+// 나.. 조회
+export const getMe = async () => {
+ try {
+ const response = await Axios.get(`/api/member`);
+ return response.data.result.name;
+ console.log(response);
+ } catch (error) {
+ console.error(error);
+ }
+};
+
// 내 팀 조회
export const getMyTeam = async () => {
try {
diff --git a/src/assets/management/stop-project-img.svg b/src/assets/management/stop-project-img.svg
new file mode 100644
index 0000000..e542191
--- /dev/null
+++ b/src/assets/management/stop-project-img.svg
@@ -0,0 +1,310 @@
+
diff --git a/src/components/management/end-project/CommentInput.tsx b/src/components/management/end-project/CommentInput.tsx
index 5e5c63e..8c3adb0 100644
--- a/src/components/management/end-project/CommentInput.tsx
+++ b/src/components/management/end-project/CommentInput.tsx
@@ -1,15 +1,24 @@
import styled from 'styled-components';
import Profile from '@assets/management/default-profile.svg';
+import { MemberTypes, Role } from '../../../types/member.ts';
-export const CommentInputBox = () => {
+interface CommentInputBoxProps {
+ member: MemberTypes;
+}
+
+export const CommentInputBox = ({ member }: CommentInputBoxProps) => {
return (
-
- 이름
-
- 역할
-
+ {member.imageUrl ? : }
+ {member.name}
+
+ {member.roleList?.map((role: Role, index) => (
+
+ {role.name}
+
+ ))}
+
@@ -29,6 +38,17 @@ const ProfileContainer = styled.div`
margin-bottom: 8px;
`;
+const ProfileImg = styled.img`
+ width: 40px;
+ height: 40px;
+ border-radius: 100%;
+`;
+
+const TagContainer = styled.div`
+ display: flex;
+ gap: 3px;
+`;
+
const Name = styled.p`
font-size: 14px;
font-weight: 500;
@@ -39,7 +59,7 @@ const Name = styled.p`
`;
const TagBox = styled.div`
- width: 37px;
+ width: 40px;
height: 24px;
background: white;
border-radius: 3px;
@@ -52,7 +72,7 @@ const TagPart = styled.p`
color: ${({ theme }) => theme.colors.mainBlue};
font-size: 9px;
font-weight: 500;
- line-height: 13.5px;
+ line-height: 24px;
`;
const CommentInput = styled.input`
diff --git a/src/components/management/end-project/Comments.tsx b/src/components/management/end-project/Comments.tsx
index f979feb..e55163b 100644
--- a/src/components/management/end-project/Comments.tsx
+++ b/src/components/management/end-project/Comments.tsx
@@ -1,21 +1,51 @@
import styled from 'styled-components';
import { CommentInputBox } from '@components/management/end-project/CommentInput.tsx';
+import { useEffect, useState } from 'react';
+import { MemberTypes } from '../../../types/member.ts';
+import { getMembers } from '@apis/management.ts';
+import { Axios } from '@apis/axios.ts';
export const Comments = () => {
+ const [me, setMe] = useState('');
+ const [members, setMembers] = useState([]);
+
+ useEffect(() => {
+ const getMe = async () => {
+ try {
+ const response = await Axios.get(`/api/member`);
+ setMe(response.data.result.name);
+ } catch (error) {
+ console.error(error);
+ }
+ };
+ getMe();
+ }, []);
+
+ const fetchMembers = async () => {
+ try {
+ const response = await getMembers(1);
+ const filteredMembers = response.filter(
+ (member: MemberTypes) => member.name !== me
+ );
+ setMembers(filteredMembers);
+ } catch (error) {
+ console.error(error);
+ }
+ };
+
+ useEffect(() => {
+ fetchMembers();
+ }, []);
+
return (
UMC 6th 팀매니저
프로젝트가 종료되었어요!
그동안 고생한 팀원들에게 코멘트를 남길 수 있어요
-
-
-
-
-
-
-
-
+ {members.map((member) => (
+
+ ))}
임의로 작성
diff --git a/src/components/management/end-project/StopProject.tsx b/src/components/management/end-project/StopProject.tsx
new file mode 100644
index 0000000..ee922a6
--- /dev/null
+++ b/src/components/management/end-project/StopProject.tsx
@@ -0,0 +1,80 @@
+import styled from 'styled-components';
+import People from '@assets/management/stop-project-img.svg';
+import End from '@assets/management/end-icon.svg';
+import { useState } from 'react';
+import { StopProjectModal } from '@components/management/end-project/StopProjectModal.tsx';
+
+export const StopProject = () => {
+ const [showModal, setShowModal] = useState(false);
+
+ const openModal = () => {
+ setShowModal(true);
+ };
+
+ const closeModal = () => {
+ setShowModal(false);
+ };
+
+ return (
+
+
+ 프로젝트가 완료되기 전에 팀을 나가시나요?
+ 팀장의 종료 이전에 팀을 나가면 포트폴리오에
+ 프로젝트 기록이 남지 않습니다.
+
+
+ 팀 나가기
+
+ {showModal && }
+
+ );
+};
+
+const StopProjectContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+`;
+
+const PeopleImg = styled(People)`
+ margin-top: 91px;
+`;
+
+const TitleText = styled.h1`
+ font-size: 18px;
+ font-weight: 500;
+ color: ${({ theme }) => theme.colors.black};
+ margin: 37px 0 10px 0;
+`;
+
+const ContentText = styled.p`
+ font-size: 12px;
+ font-weight: 500;
+ color: ${({ theme }) => theme.colors.darkGray};
+ line-height: 18px;
+ margin: 0;
+`;
+
+const EndBtn = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 10px;
+ width: 118px;
+ height: 103px;
+ border-radius: 4px;
+ border: solid 1px ${({ theme }) => theme.colors.red};
+ margin-top: 19px;
+ cursor: pointer;
+`;
+
+const EndIcon = styled(End)`
+ width: 37px;
+ height: 37px;
+ margin-top: 19px;
+`;
+
+const BtnText = styled(ContentText)`
+ color: ${({ theme }) => theme.colors.red};
+`;
diff --git a/src/components/management/end-project/StopProjectModal.tsx b/src/components/management/end-project/StopProjectModal.tsx
new file mode 100644
index 0000000..9a15702
--- /dev/null
+++ b/src/components/management/end-project/StopProjectModal.tsx
@@ -0,0 +1,94 @@
+import styled from 'styled-components';
+import { useNavigate } from 'react-router-dom';
+
+interface ModalStateProps {
+ closeModal: () => void;
+}
+
+export const StopProjectModal = ({ closeModal }: ModalStateProps) => {
+ const navigate = useNavigate();
+
+ return (
+
+
+ {'팀 매니저'}를 정말 나가실건가요?
+ 팀에서 나가기 전, 다시 한번 확인해 주세요.
+
+ {/* navigate 수정하기 */}
+ navigate(`/management/end/comment`)}>
+ 종료하기
+
+ 취소
+
+
+
+ );
+};
+
+const ModalBackground = styled.div`
+ width: 100%;
+ height: 100%;
+ background: rgb(0, 0, 0, 0.1);
+ position: fixed;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ top: 0;
+ left: 0;
+`;
+
+const ModalContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 350px;
+ height: 200px;
+ background: white;
+ border-radius: 6px;
+ box-shadow: 1.52px 3.04px 9.12px rgba(0, 0, 0 0.08);
+`;
+
+const TitleText = styled.h1`
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 21px;
+ color: ${({ theme }) => theme.colors.black};
+ margin: 58px 0 12px 0;
+`;
+
+const ContentText = styled.p`
+ font-size: 12px;
+ line-height: 18px;
+ color: ${({ theme }) => theme.colors.darkGray};
+ margin: 0 0 40px 0;
+`;
+
+const BtnContainer = styled.div`
+ display: flex;
+ gap: 4px;
+`;
+
+const Btn = styled.button`
+ width: 158px;
+ height: 36px;
+ border: none;
+ border-radius: 4px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 12px;
+ font-weight: 700;
+ line-height: 18px;
+ cursor: pointer;
+`;
+
+const EndBtn = styled(Btn)`
+ background: ${({ theme }) => theme.colors.red};
+ color: white;
+`;
+
+const CancelBtn = styled(Btn)`
+ background: white;
+ color: ${({ theme }) => theme.colors.mainBlue};
+ border: solid 1px ${({ theme }) => theme.colors.mainBlue};
+`;
diff --git a/src/components/management/member/Member.tsx b/src/components/management/member/Member.tsx
index 9dd17eb..0e9753c 100644
--- a/src/components/management/member/Member.tsx
+++ b/src/components/management/member/Member.tsx
@@ -15,6 +15,7 @@ import {
interface MemberProps {
teamManageId: number;
+ imageUrl: string;
name: string;
roleList: Role[];
refreshMembers: () => void;
@@ -22,6 +23,7 @@ interface MemberProps {
export const Member = ({
teamManageId,
+ imageUrl,
name,
roleList,
refreshMembers
@@ -55,7 +57,7 @@ export const Member = ({
return (
-
+ {imageUrl ? : }
{name}
{tags.map((tag, index) => (
@@ -113,9 +115,16 @@ const MemberContainer = styled.div`
align-items: center;
`;
-const ProfileImg = styled(DefaultProfileImg)`
+const ProfileImg = styled.img`
width: 40px;
height: 40px;
+ border-radius: 100%;
+`;
+
+const DefaultProfileImage = styled(DefaultProfileImg)`
+ width: 40px;
+ height: 40px;
+ border-radius: 100%;
`;
const NameContainer = styled.div`
diff --git a/src/components/management/member/Members.tsx b/src/components/management/member/Members.tsx
index 8120cae..767e854 100644
--- a/src/components/management/member/Members.tsx
+++ b/src/components/management/member/Members.tsx
@@ -34,6 +34,7 @@ export const Members = () => {
members.map((member) => (
theme.colors.lightGray};
+ border-radius: 76px;
+ }
+
+ &::-webkit-scrollbar-thumb:active {
+ background: ${({ theme }) => theme.colors.darkGray};
+ }
+
+\` ;
`;
diff --git a/src/components/sidebar/SideBar.tsx b/src/components/sidebar/SideBar.tsx
index 1a28246..419c837 100644
--- a/src/components/sidebar/SideBar.tsx
+++ b/src/components/sidebar/SideBar.tsx
@@ -20,21 +20,49 @@ import End from '@assets/sidebar/end.svg';
import { useLocation, useNavigate } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { DropDown } from '@components/sidebar/DropDown.tsx';
-import { getMyTeam } from '@apis/management.ts';
+import { getMe, getMembers, getMyTeam } from '@apis/management.ts';
import { TeamProps } from '../../types/management.ts';
+import { MemberTypes } from '../../types/member.ts';
export const SideBar = () => {
const [teams, setTeams] = useState([]);
const [currentTeam, setCurrentTeam] = useState(null);
const [hover, setHover] = useState(false);
const [showDropDown, setShowDropDown] = useState(false);
+ const [isLeader, setIsLeader] = useState(false);
const navigate = useNavigate();
const location = useLocation();
+ useEffect(() => {
+ const checkLeader = async () => {
+ try {
+ const members = await getMembers(1);
+ const me = await getMe();
+
+ // 팀장
+ const leader = members.reduce(
+ (prev: MemberTypes, curr: MemberTypes) => {
+ return prev.teamManageId < curr.teamManageId ? prev : curr;
+ }
+ );
+ setIsLeader(me.teamManageId === leader.teamManageId);
+ } catch (error) {
+ console.error(error);
+ }
+ };
+ checkLeader();
+ }, []);
+
const handleNavigate = (path: string) => {
navigate(path);
};
+ const handleNavigateEnd = () => {
+ if (isLeader) {
+ navigate(`/management/end`);
+ } else navigate(`/management/stop`);
+ };
+
const handleDropDown = () => {
setShowDropDown((prev) => !prev);
};
@@ -191,19 +219,16 @@ export const SideBar = () => {
마이페이지
)}
- {
- // 추후에 path 수정이 필요할 수 있음
- handleNavigate(`/management`);
- }}
- isHovered={hover}
- >
+
{hover && (
-
- 프로젝트
-
- 종료
+
+ {isLeader ? '프로젝트 종료' : '팀 나가기'}
)}
@@ -269,7 +294,7 @@ const Wrapper = styled.div`
interface SelectedProps {
selected?: boolean;
- redText?: boolean;
+ red?: boolean;
isHovered?: boolean;
}
@@ -283,8 +308,8 @@ const SideBarText = styled.p`
white-space: nowrap;
overflow: hidden;
- ${({ redText, theme }) =>
- redText &&
+ ${({ red, theme }) =>
+ red &&
`
color: ${theme.colors.red};
`}
@@ -293,8 +318,6 @@ const SideBarText = styled.p`
const IconContainer = styled.div`
width: 100%;
height: 51px;
- background-color: ${({ selected, theme }) =>
- selected ? theme.colors.background : 'white'};
display: flex;
justify-content: ${({ isHovered }) => (isHovered ? 'flex-start' : 'center')};
padding-left: ${({ isHovered }) => (isHovered ? '19px' : '0')};
@@ -304,6 +327,14 @@ const IconContainer = styled.div`
cursor: pointer;
transition: width 0.3s ease;
+ // 얘 안돼 ㅜ.ㅜ
+ background-color: ${({ selected, theme, red }) => {
+ if (selected) {
+ return red ? '#FFE9E9' : theme.colors.background;
+ }
+ return 'white';
+ }};
+
&:last-child {
margin-top: 18px;
}
diff --git a/src/pages/management/extra.tsx b/src/pages/management/extra.tsx
index cb5fa61..2836031 100644
--- a/src/pages/management/extra.tsx
+++ b/src/pages/management/extra.tsx
@@ -1,11 +1,13 @@
import { Route, Routes } from 'react-router-dom';
import { EndProject } from '@components/management/end-project/EndProject.tsx';
import { Comments } from '@components/management/end-project/Comments.tsx';
+import { StopProject } from '@components/management/end-project/StopProject.tsx';
export const ExtraManagementPage = () => {
return (
} />
+ } />
} />
);