Skip to content
Open
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
11 changes: 11 additions & 0 deletions src/apis/management.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
310 changes: 310 additions & 0 deletions src/assets/management/stop-project-img.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 28 additions & 8 deletions src/components/management/end-project/CommentInput.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<CommentBox>
<ProfileContainer>
<Profile />
<Name>이름</Name>
<TagBox>
<TagPart>역할</TagPart>
</TagBox>
{member.imageUrl ? <ProfileImg src={member.imageUrl} /> : <Profile />}
<Name>{member.name}</Name>
<TagContainer>
{member.roleList?.map((role: Role, index) => (
<TagBox key={index}>
<TagPart>{role.name}</TagPart>
</TagBox>
))}
</TagContainer>
</ProfileContainer>
<CommentInput />
</CommentBox>
Expand All @@ -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;
Expand All @@ -39,7 +59,7 @@ const Name = styled.p`
`;

const TagBox = styled.div`
width: 37px;
width: 40px;
height: 24px;
background: white;
border-radius: 3px;
Expand All @@ -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`
Expand Down
46 changes: 38 additions & 8 deletions src/components/management/end-project/Comments.tsx
Original file line number Diff line number Diff line change
@@ -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<string>('');
const [members, setMembers] = useState<MemberTypes[]>([]);

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 (
<Container>
<TeamName>UMC 6th 팀매니저</TeamName>
<InfoText>프로젝트가 종료되었어요!</InfoText>
<Text>그동안 고생한 팀원들에게 코멘트를 남길 수 있어요</Text>
<CommentsList>
<CommentInputBox />
<CommentInputBox />
<CommentInputBox />
<CommentInputBox />
<CommentInputBox />
<CommentInputBox />
<CommentInputBox />
<CommentInputBox />
{members.map((member) => (
<CommentInputBox key={member.teamManageId} member={member} />
))}
</CommentsList>
<BtnContainer>
<RandomBtn>임의로 작성</RandomBtn>
Expand Down
80 changes: 80 additions & 0 deletions src/components/management/end-project/StopProject.tsx
Original file line number Diff line number Diff line change
@@ -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<boolean>(false);

const openModal = () => {
setShowModal(true);
};

const closeModal = () => {
setShowModal(false);
};

return (
<StopProjectContainer>
<PeopleImg />
<TitleText>프로젝트가 완료되기 전에 팀을 나가시나요?</TitleText>
<ContentText>팀장의 종료 이전에 팀을 나가면 포트폴리오에</ContentText>
<ContentText>프로젝트 기록이 남지 않습니다.</ContentText>
<EndBtn onClick={openModal}>
<EndIcon />
<BtnText>팀 나가기</BtnText>
</EndBtn>
{showModal && <StopProjectModal closeModal={closeModal} />}
</StopProjectContainer>
);
};

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};
`;
94 changes: 94 additions & 0 deletions src/components/management/end-project/StopProjectModal.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<ModalBackground>
<ModalContainer>
<TitleText>{'팀 매니저'}를 정말 나가실건가요?</TitleText>
<ContentText>팀에서 나가기 전, 다시 한번 확인해 주세요.</ContentText>
<BtnContainer>
{/* navigate 수정하기 */}
<EndBtn onClick={() => navigate(`/management/end/comment`)}>
종료하기
</EndBtn>
<CancelBtn onClick={closeModal}>취소</CancelBtn>
</BtnContainer>
</ModalContainer>
</ModalBackground>
);
};

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};
`;
13 changes: 11 additions & 2 deletions src/components/management/member/Member.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ import {

interface MemberProps {
teamManageId: number;
imageUrl: string;
name: string;
roleList: Role[];
refreshMembers: () => void;
}

export const Member = ({
teamManageId,
imageUrl,
name,
roleList,
refreshMembers
Expand Down Expand Up @@ -55,7 +57,7 @@ export const Member = ({

return (
<MemberContainer>
<ProfileImg />
{imageUrl ? <ProfileImg src={imageUrl} /> : <DefaultProfileImage />}
<NameContainer>
<NameText>{name}</NameText>
{tags.map((tag, index) => (
Expand Down Expand Up @@ -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`
Expand Down
17 changes: 17 additions & 0 deletions src/components/management/member/Members.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const Members = () => {
members.map((member) => (
<Member
key={member.teamManageId}
imageUrl={member.imageUrl || ''}
teamManageId={member.teamManageId}
name={member.name}
roleList={member.roleList || []}
Expand Down Expand Up @@ -63,4 +64,20 @@ const MemberContainer = styled.div`
margin-top: 10px;
overflow-y: scroll;
overflow-x: hidden;

&::-webkit-scrollbar {
width: 9px;
height: 182px;
}

&::-webkit-scrollbar-thumb {
background: ${({ theme }) => theme.colors.lightGray};
border-radius: 76px;
}

&::-webkit-scrollbar-thumb:active {
background: ${({ theme }) => theme.colors.darkGray};
}

\` ;
`;
Loading