Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/33 invite api #53

Merged
merged 5 commits into from
Jun 8, 2024
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
6 changes: 6 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import WorkSpacePage from '@finnect/pages/workspace/WorkSpacePage';

import { GlobalStyle } from '@finnect/styles/GlobalStyle';
import Theme from '@finnect/styles/Theme';
import InviteSigninPage from './pages/login/InviteSigninPage';

const router = createBrowserRouter([
{
Expand All @@ -29,6 +30,11 @@ const router = createBrowserRouter([
element: <SignupPage />,
errorElement: <ErrorPage />,
},
{
path: '/signin/:workspaceId/:workspaceName',
element: <InviteSigninPage />,
errorElement: <ErrorPage />,
},
]);

const App = () => {
Expand Down
34 changes: 33 additions & 1 deletion src/apis/member/usePostMember.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { axiosClient } from '@finnect/apis/AxiosClient';
import { IMemberProps } from '@finnect/interface/MemberInterface';
import {
IMemberProps,
InviteMemeberProps,
InviteProps,
} from '@finnect/interface/MemberInterface';

export const postMember = async (
nickname: string,
Expand All @@ -18,3 +22,31 @@ export const postMember = async (
throw error;
}
};

export const postAddMember = async (
workspaceId: number
): Promise<InviteMemeberProps> => {
try {
const response = await axiosClient.post(`/workspaces/members`, {
workspaceId,
});
return response.data;
} catch (error) {
console.error(error);
throw error;
}
};

export const postInviteMember = async (
emails: string[]
): Promise<InviteProps> => {
try {
const response = await axiosClient.post(`/workspaces/invitation`, {
emails,
});
return response.data;
} catch (error) {
console.error(error);
throw error;
}
};
17 changes: 12 additions & 5 deletions src/components/common/modal/header/InviteModal.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Modal, Input, Button } from 'antd';
import { Modal, Input, Button, message } from 'antd';
import { useRecoilState } from 'recoil';

import {
emailState,
invitedEmailsState,
} from '@finnect/atoms/header/useInviteModal';
import { postInviteMember } from '@finnect/apis/member/usePostMember';

const InviteModal = ({
visible,
Expand All @@ -17,9 +17,16 @@ const InviteModal = ({
const [invitedEmails, setInvitedEmails] =
useRecoilState<string[]>(invitedEmailsState);

const handleInvite = () => {
setInvitedEmails([...invitedEmails, email]);
setEmail('');
const handleInvite = async () => {
try {
await postInviteMember([email]);
setInvitedEmails([...invitedEmails, email]);
setEmail('');
message.success('초대장이 성공적으로 전송되었습니다.');
onClose();
} catch (error) {
message.error('초대장 전송에 실패했습니다. 다시 시도해 주세요.');
}
};

return (
Expand Down
2 changes: 0 additions & 2 deletions src/components/common/sider/Records.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ const Records = () => {
localStorage.setItem('selectedMenuItem', selectedItem);
});

console.log('test');

return (
<Menu.SubMenu
key='records'
Expand Down
11 changes: 11 additions & 0 deletions src/interface/MemberInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,14 @@ export interface IMemberProps {
role: string;
phone: string;
}

export interface InviteMemeberProps {
status: number;
workspaceId: number;
}

export interface InviteProps {
email: string[];
result: string;
status: number;
}
1 change: 0 additions & 1 deletion src/pages/RootPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import HeaderBox from '@finnect/components/common/header/HeaderBox';

import SiderBox from '@finnect/components/common/sider/SiderBox';
import { StyledSliderWrapper } from '@finnect/styles/Layout';
import HeaderBox from '@finnect/components/common/header/HeaderBox';

const CustomLayout = styled(Layout)`
width: 100vw;
Expand Down
116 changes: 116 additions & 0 deletions src/pages/login/InviteSigninPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import React, { useState } from 'react';
import { Button, Space, message } from 'antd';
import styled from 'styled-components';
import reactLogo from '@finnect/assets/react.svg';
import { authApi } from '@finnect/apis/auth/auth.api';
import IDbox from '@finnect/components/login/IDbox';
import PWbox from '@finnect/components/login/PWbox';
import { useNavigate, useParams } from 'react-router-dom';
import { postAddMember } from '@finnect/apis/member/usePostMember';

const InviteSigninPage: React.FC = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const navigate = useNavigate();
const { workspaceId: workspaceIdParam, workspaceName: encodedWorkspaceName } =
useParams();

const workspaceId = workspaceIdParam ? parseInt(workspaceIdParam, 10) : null;
const workspaceName = encodedWorkspaceName
? decodeURIComponent(encodedWorkspaceName)
: '';

const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setPassword(e.target.value);
};

const handleLogin = async () => {
if (workspaceId === null) {
return message.error('유효하지 않은 워크스페이스 ID입니다.');
}

try {
const response = await authApi(username, password);
const response2 = await postAddMember(workspaceId);
console.log('Login response:', response);
if (response.status === 200 && response2.status === 200) {
localStorage.setItem('personalName', response.personalName);

console.log('Login successful');

localStorage.setItem('selectedWorkSpace', workspaceName as string);
localStorage.setItem('selectedWorkSpaceId', workspaceIdParam as string);

navigate('/');
return message.success('로그인 및 초대 성공.');
} else {
message.error('로그인 실패: 아이디 또는 비밀번호를 확인해주세요.');
}
} catch (error) {
console.error('Login failed:', error);
message.error('로그인 실패: 아이디 또는 비밀번호를 확인해주세요.');
}
};

const handleEnterPress = () => {
handleLogin();
};

return (
<SignInWrapper>
<SignInContainer>
<LogoWrapper>
<figure className='Logo'>
<img src={reactLogo} alt='logo' />
</figure>
</LogoWrapper>
<InputWrapper>
<IDbox setUsername={setUsername} />
<PWbox
password={password}
onPasswordChange={handlePasswordChange}
onEnterPress={handleEnterPress}
/>
</InputWrapper>
<Space direction='vertical' style={{ width: '100%' }}>
<Button
type='primary'
style={{ width: '100%' }}
onClick={handleLogin}
>
로그인
</Button>
</Space>
</SignInContainer>
</SignInWrapper>
);
};

export default InviteSigninPage;

const SignInWrapper = styled.div`
display: flex;
padding: 2rem;
align-items: center;
justify-content: center;
`;

const InputWrapper = styled.div`
margin-bottom: 1rem;
`;

const SignInContainer = styled.div`
display: flex;
flex-direction: column;
`;

const LogoWrapper = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;

img {
width: 191px;
}
`;
Loading