Skip to content

Commit

Permalink
feat: invite-users (#44)
Browse files Browse the repository at this point in the history
* feat: invite-users

inviting users to project

* feat: invite-users

changing working to add users
  • Loading branch information
vuyaniShabangu authored Jul 25, 2024
1 parent 2d6ac26 commit 93f252c
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 6 deletions.
10 changes: 5 additions & 5 deletions components/ProjectDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
*/

import React, { useState, useEffect } from 'react';
import { Card, Divider, Modal, Button, message } from 'antd';
import { Card, Divider, Modal } from 'antd';
import { useRouter } from 'next/router';
import { EditOutlined, DeleteOutlined, UserAddOutlined } from '@ant-design/icons';
import { EditOutlined, DeleteOutlined } from '@ant-design/icons';
import { Toaster } from 'react-hot-toast';

import { authorizedApiRequest } from '@/global/utils/api';
Expand All @@ -31,6 +31,7 @@ import toast, { ToastType } from '@/global/utils/toast';

import useAuthContext from '../../global/hooks/useAuthContext';
import UpdateProject from '../ProjectUpdate';
import ProjectInviteUsers from '../ProjectInviteUsers';

const CardDivColumn: React.CSSProperties = {
display: 'flex',
Expand Down Expand Up @@ -69,6 +70,7 @@ function convertToTableData(responseData: any): Project {
studyCount: responseData?.study_count,
};
}

const ProjectDetails: React.FC = () => {
const [origin, setOrigin] = useState('');
const [loading, setLoading] = useState(true);
Expand Down Expand Up @@ -201,9 +203,7 @@ const ProjectDetails: React.FC = () => {
<span style={{ textAlign: 'right', maxWidth: 600 }}>{project?.description} </span>
</div>
<Divider />
<Button type="primary" icon={<UserAddOutlined />} ghost>
Invite users to project
</Button>
<ProjectInviteUsers />
</>
}
/>
Expand Down
145 changes: 145 additions & 0 deletions components/ProjectInviteUsers/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import { Button, Form, Modal, Select, SelectProps } from 'antd';
import { FC, useEffect, useState } from 'react';
import { UserAddOutlined } from '@ant-design/icons';
import { useRouter } from 'next/router';

import { authorizedApiRequest } from '@/global/utils/api';
import { API_ROUTES_PATHS, HttpMethods } from '@/global/utils/constants';
import toast, { ToastType } from '@/global/utils/toast';

type User = {
value: string;
label: string;
};

function convertToTableData(responseData: []): User[] {
return responseData.map((element: any) => {
return {
value: element?.id,
label: `${element?.firstName} ${element?.lastName}`,
};
});
}

const ProjectInviteUsers: FC = () => {
const [isModalOpen, setIsModalOpen] = useState(false);
const [users, setUsers] = useState<SelectProps['options']>([]);
const [loading, setloading] = useState(false);
const [selectedUsers, setSelectedUsers] = useState<string[]>([]);

useEffect(() => {
authorizedApiRequest(HttpMethods.GET, API_ROUTES_PATHS.USERS)
.then((data) => {
setUsers(convertToTableData(data?.users));
})
.catch((error) => {
console.log(error);
});
}, []);

const router = useRouter().query;
const projectId = router['project-id'];

const showModal = () => {
setIsModalOpen(true);
};

const handleOk = () => {
setSelectedUsers([]);
setIsModalOpen(false);
};

const handleCancel = () => {
setSelectedUsers([]);
setIsModalOpen(false);
};

const handleChange = (value: string[]) => {
setSelectedUsers([...value]);
};

const handleClear = () => {
setSelectedUsers([]);
};

const InviteUsers = () => {
setloading(true);
const uniqueUsers = new Set(selectedUsers);
const users = [...uniqueUsers];
Promise.all(
users.map((user) =>
authorizedApiRequest(
HttpMethods.POST,
`${API_ROUTES_PATHS.PROJECTS}/${projectId}/users/${user}`,
)
.then((data) => console.log())
.catch((error) => {
console.log(error);
throw error;
}),
),
)
.then((data) => {
toast(ToastType.SUCCESS, 'Users are invited successfully');
setloading(false);
handleOk();
})
.catch((error) => {
console.log(error);
setloading(false);
});
};

return (
<>
<Button onClick={() => showModal()} type="primary" icon={<UserAddOutlined />} ghost>
Add users to project
</Button>
<Modal
title="Add users to project"
open={isModalOpen}
onOk={handleOk}
onCancel={handleCancel}
footer={false}
>
<Form
size="large"
name="basic"
style={{ minWidth: 400, margin: 'auto' }}
onFinish={InviteUsers}
layout="horizontal"
autoComplete="off"
labelCol={{ span: 7 }}
>
<Form.Item label="Users" rules={[{ required: true, message: 'Please select users' }]}>
<Select
mode="multiple"
onClear={handleClear}
value={selectedUsers}
style={{ width: '100%' }}
placeholder="Please select users to add"
onChange={handleChange}
options={users}
showSearch
optionFilterProp="label"
/>
</Form.Item>
<Form.Item style={{ display: 'flex', justifyContent: 'end', width: '100%' }}>
<Button
disabled={!selectedUsers.length}
loading={loading}
size="large"
block
type="primary"
htmlType="submit"
>
Add users
</Button>
</Form.Item>
</Form>
</Modal>
</>
);
};

export default ProjectInviteUsers;
7 changes: 6 additions & 1 deletion global/utils/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,10 @@ export async function authorizedApiRequest(method: HttpMethods, url = '', data =
throw errorObj;
}

return response.json();
const contentLength = response.headers.get('Content-Length');
if (contentLength && parseInt(contentLength) > 0) {
return response.json();
} else {
return;
}
}

0 comments on commit 93f252c

Please sign in to comment.