Skip to content

Commit

Permalink
feat: implement join management
Browse files Browse the repository at this point in the history
  • Loading branch information
MinJaeSon committed Feb 17, 2025
1 parent f82e381 commit b0a1521
Show file tree
Hide file tree
Showing 8 changed files with 717 additions and 0 deletions.
143 changes: 143 additions & 0 deletions src/components/CotatoSelectBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import CotatoIcon from './CotatoIcon';

//
//
//

interface CotatoSelectBoxProps {
defaultVal: string;
selectList: string[];
metaDatas?: any[];
}

//
//
//

const CotatoSelectBox = ({ defaultVal, selectList, metaDatas }: CotatoSelectBoxProps) => {
const [isOpen, setIsOpen] = useState(false);
const [selected, setSelected] = useState<string | null>(null);
const [selectedMeta, setSelectedMeta] = useState<any | null>(null);

/**
*
*/
const handleItemClick = (item: string, meta?: any) => {
setSelected(item);
setSelectedMeta(meta);
setIsOpen(false);
};

useEffect(() => {
if (metaDatas?.length) {
setSelectedMeta(metaDatas[metaDatas.length - 1]);
}
}, [metaDatas]);

return (
<Wrapper>
<Container>
<InputBox onClick={() => setIsOpen(!isOpen)}>
<p>{selected || defaultVal}</p>
<span style={{ visibility: 'hidden' }}>{selectedMeta}</span>
<CotatoIcon
icon={isOpen ? 'angle-up-solid' : 'angle-down-solid'}
size="1.25rem"
color={(theme) => theme.colors.common.black_const}
/>
</InputBox>
{isOpen && (
<ListBox>
{selectList.map((selectItem, i) => (
<ListItem
key={i}
isSelected={selected === selectItem}
onClick={() => handleItemClick(selectItem, metaDatas && metaDatas[i])}
>
{selectItem}
</ListItem>
))}
</ListBox>
)}
</Container>
</Wrapper>
);
};

//
//
//

const Wrapper = styled.div`
width: 8.4rem;
min-height: 3.3rem;
height: fit-content;
display: flex;
gap: 0.25rem;
flex-direction: column;
align-items: center;
justify-content: center;
`;

const Container = styled.div`
position: relative;
width: 100%;
height: fit-content;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
`;

const InputBox = styled.div`
display: flex;
padding: 1rem 0.75rem;
justify-content: space-between;
align-items: center;
width: 100%;
height: 3.3rem;
display: flex;
gap: 0.5rem;
border-radius: 0.25rem;
cursor: pointer;
background: ${({ theme }) => theme.colors.gray20};
p {
color: ${({ theme }) => theme.colors.common.black_const} !important;
font-size: ${({ theme }) => theme.fontSize.md};
text-align: center;
}
`;

const ListBox = styled.div`
position: absolute;
top: 3.3rem;
margin-top: 0.25rem;
width: 100%;
height: fit-content;
background: ${({ theme }) => theme.colors.common.white_const};
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: 1px solid ${({ theme }) => theme.colors.gray20};
z-index: 1;
`;

const ListItem = styled.div<{ isSelected: boolean }>`
width: 100%;
height: 3.3rem;
background: ${({ isSelected, theme }) =>
isSelected ? theme.colors.gray20 : theme.colors.common.white_const};
display: flex;
justify-content: center;
align-items: center;
padding: 1rem 0.75rem;
cursor: pointer;
&:hover {
background: ${({ theme }) => theme.colors.gray20};
}
`;

export default CotatoSelectBox;
12 changes: 12 additions & 0 deletions src/enums/MemberStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* **APPROVED** - 활동 중인 부원
* **RETIRED** - OM
* **REQUESTED** - 가입 신청한 회원
* **REJECTED** - 가입 거절된 회원
*/
export const enum MemberStatus {
APPROVED = 'APPROVED',
RETIRED = 'RETIRED',
REQUESTED = 'REQUESTED',
REJECTED = 'REJECTED',
}
47 changes: 47 additions & 0 deletions src/pages/MyPage/components/Mypage/ConfirmButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, { ReactElement, ReactHTMLElement } from 'react';
import styled from 'styled-components';

//
//
//

interface ConfirmButtonProps {
isApproval: boolean;
text: string;
onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
}

const ConfirmButton = ({ isApproval, text, onClick }: ConfirmButtonProps) => {
return (
<Wrapper $isApproval={isApproval} onClick={onClick}>
{text}
</Wrapper>
);
};

//
//
//

const Wrapper = styled.button<{ $isApproval: boolean }>`
width: 8.4rem;
height: 3.3rem;
display: flex;
align-items: center;
justify-content: center;
border-radius: 0.25rem;
color: ${({ theme }) => theme.colors.common.white_const};
text-align: center;
font-size: ${({ theme }) => theme.fontSize.md};
font-weight: 400;
cursor: pointer;
${({ $isApproval, theme }) =>
$isApproval
? ` border: 1px solid ${theme.colors.sub3[80]};
background: ${theme.colors.sub3[60]}`
: `border: 1px solid ${theme.colors.secondary100};
background: ${theme.colors.secondary80}`};
}
`;

export default ConfirmButton;
50 changes: 50 additions & 0 deletions src/pages/MyPage/components/common/EmptyResult.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import CotatoIcon from '@components/CotatoIcon';
import React from 'react';
import styled from 'styled-components';

//
//
//

interface EmptyResultProps {
text: string;
}

//
//
//

const EmptyResult = ({ text }: EmptyResultProps) => {
return (
<Wrapper>
<CotatoIcon icon="user-check-solid" size="2.5rem" color={(theme) => theme.colors.gray60} />
<p>{text}</p>
</Wrapper>
);
};

//
//
//

const Wrapper = styled.div`
width: 100%;
height: 30rem;
border-radius: 0.25rem;
border: 2px solid ${({ theme }) => theme.colors.primary70};
background: ${({ theme }) => theme.colors.common.white};
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1rem;
p {
text-align: center;
color: ${({ theme }) => theme.colors.gray60};
font-size: ${({ theme }) => theme.fontSize.md};
font-weight: 400;
margin: 0;
}
`;

export default EmptyResult;
1 change: 1 addition & 0 deletions src/pages/MyPage/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const MEMBER_POSITION = ['PM', '디자이너', '백엔드', '프론트엔드'];
106 changes: 106 additions & 0 deletions src/pages/MyPage/join-management/MyPageJoinManagementContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Box } from '@mui/material';
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import MyPageJoinManagmentRequestList from './MyPageJoinManagmentRequestList';
import MyPageJoinManagementRejectedList from './MyPageJoinManagementRejectedList';
import api from '@/api/api';

//
//
//

const MyPageJoinManagementContent = () => {
const [selectedTab, setSelectedTab] = useState(0); // 0: 가입 요청, 1: 거절 항목
const [generations, setGenerations] = useState<
{
generationId: number;
generationNumber: number;
startDate: string;
endDate: string;
}[]
>([]);

/**
*
*/
const getGenerations = () => {
api.get('/v1/api/generations').then((res) => {
setGenerations(res.data);
});
};

/**
*
*/
const renderTabs = () => {
return (
<>
<Box sx={{ display: 'flex', alignItems: 'center', gap: '0.25rem' }}>
<Tab active={selectedTab === 0} onClick={() => setSelectedTab(0)}>
가입 요청
</Tab>
<Tab active={selectedTab === 1} onClick={() => setSelectedTab(1)}>
거절 항목
</Tab>
</Box>
</>
);
};

/**
*
*/
const renderContent = () => {
switch (selectedTab) {
case 0:
return <MyPageJoinManagmentRequestList generations={generations} />;
case 1:
return <MyPageJoinManagementRejectedList generations={generations} />;
default:
return <MyPageJoinManagmentRequestList generations={generations} />;
}
};

//
//
//
useEffect(() => {
getGenerations();
}, []);

return (
<Box>
{renderTabs()}
<div style={{ height: '1.5rem' }} />
{renderContent()}
</Box>
);
};

//
//
//

const Tab = styled.div<{ active: boolean }>`
width: 6rem;
height: 2.5rem;
display: flex;
padding: 10px;
justify-content: center;
align-items: center;
gap: 10px;
border-radius: 4px;
cursor: pointer;
${({ active, theme }) =>
active
? `
background: ${theme.colors.primary100_1};
color: ${theme.colors.common.black_const};
`
: `
background: ${theme.colors.gray30};
color: ${theme.colors.gray90};
`}
`;

export default MyPageJoinManagementContent;
Loading

0 comments on commit b0a1521

Please sign in to comment.