Merge pull request #29 from navi-sa/learning
TP-40366 | Create team feature implemented
This commit is contained in:
11
src/Pages/Team/Hook.tsx
Normal file
11
src/Pages/Team/Hook.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
export const useAuthData = () => {
|
||||
const [userRole, setUserRole] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
const userData = JSON.parse(localStorage.getItem('user-data') || '{}');
|
||||
setUserRole(userData?.roles || []);
|
||||
}, []);
|
||||
|
||||
return userRole;
|
||||
};
|
||||
@@ -44,7 +44,14 @@
|
||||
width: fit-content;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.create-team-btn-wrapper {
|
||||
padding: 6px 0 12px 0px;
|
||||
}
|
||||
.create-team-btn {
|
||||
width: 164px;
|
||||
height: 36px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.content-wrapper {
|
||||
width: 50%;
|
||||
padding: 0 12px 12px;
|
||||
@@ -98,3 +105,15 @@
|
||||
.filter-container {
|
||||
border: 1px solid var(--navi-color-gray-border);
|
||||
}
|
||||
.input-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0 8px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.email-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0 8px;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export const FETCH_TEAM_DATA = `${window?.config?.BASE_API_URL}/teams`;
|
||||
export const CREATE_TEAM = `${window?.config?.BASE_API_URL}/houston/teams/add`;
|
||||
|
||||
export const FETCH_SINGLE_TEAM_DATA = (payload: string): string => {
|
||||
return `${window?.config?.BASE_API_URL}/teams/${payload}`;
|
||||
@@ -8,6 +9,10 @@ export const UPDATE_TEAM_DATA = (): string => {
|
||||
return `${window?.config?.BASE_API_URL}/teams`;
|
||||
};
|
||||
|
||||
export const regularExpression = /^[a-zA-Z][a-zA-Z0-9_ -]{1,48}[a-zA-Z0-9]$/;
|
||||
|
||||
export const emailRegularExpression = /^[a-zA-Z]+\.[a-zA-Z]+@navi\.com$/;
|
||||
|
||||
export interface TeamsData {
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -37,3 +42,8 @@ export const userInputPlaceholders = {
|
||||
'Email-id': 'email ids',
|
||||
'Slack user-id': 'slack user ids',
|
||||
};
|
||||
export interface CreateTeamProps {
|
||||
open: boolean;
|
||||
startTeamSearch: () => void;
|
||||
setOpen: (open: boolean) => void;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
|
||||
import Typography from '@navi/web-ui/lib/primitives/Typography';
|
||||
import { toast } from '@navi/web-ui/lib/primitives/Toast';
|
||||
|
||||
import FallbackComponent from '@src/components/Fallback';
|
||||
import { ApiService } from '@src/services/api';
|
||||
import { FETCH_TEAM_DATA } from './constants';
|
||||
import TeamResultsTable from './partials/TeamResultsTable';
|
||||
|
||||
import CreateTeam from './partials/CreateTeam';
|
||||
import styles from './Team.module.scss';
|
||||
|
||||
import Button from '@navi/web-ui/lib/primitives/Button';
|
||||
import { AddIcon } from '@navi/web-ui/lib/icons';
|
||||
import { useAuthData } from './Hook';
|
||||
const Team: FC = () => {
|
||||
const [data, setData] = useState<any>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
|
||||
const Role = useAuthData();
|
||||
|
||||
const startTeamSearch = (): void => {
|
||||
const endPoint = FETCH_TEAM_DATA;
|
||||
@@ -38,6 +41,10 @@ const Team: FC = () => {
|
||||
startTeamSearch();
|
||||
}, []);
|
||||
|
||||
const createHandler = () => {
|
||||
setOpen(true);
|
||||
};
|
||||
|
||||
const returnTable = (): JSX.Element => {
|
||||
if (isLoading) {
|
||||
return <FallbackComponent />;
|
||||
@@ -63,9 +70,29 @@ const Team: FC = () => {
|
||||
{' '}
|
||||
{data?.length} teams{' '}
|
||||
</Typography>
|
||||
<div className={styles['create-team-btn-wrapper']}>
|
||||
{Role.includes('Admin') && (
|
||||
<Button
|
||||
startAdornment={<AddIcon color="white" />}
|
||||
fullWidth
|
||||
onClick={createHandler}
|
||||
variant="primary"
|
||||
className={styles['create-team-btn']}
|
||||
>
|
||||
Create new team
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
{returnTable()}
|
||||
|
||||
<CreateTeam
|
||||
open={open}
|
||||
setOpen={setOpen}
|
||||
startTeamSearch={startTeamSearch}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
132
src/Pages/Team/partials/CreateTeam.tsx
Normal file
132
src/Pages/Team/partials/CreateTeam.tsx
Normal file
@@ -0,0 +1,132 @@
|
||||
import TeamResultsTable from './TeamResultsTable';
|
||||
import { CREATE_TEAM, TeamsData } from '../constants';
|
||||
import { returnFormattedDate } from '@src/services/globalUtils';
|
||||
import styles from '../Team.module.scss';
|
||||
import { Typography } from '@navi/web-ui/lib/primitives';
|
||||
import { useState } from 'react';
|
||||
import { ADD_TEAM_DATA } from '../constants';
|
||||
import { AlertOutlineIcon } from '@navi/web-ui/lib/icons';
|
||||
import { BorderedInput, ModalDialog } from '@navi/web-ui/lib/primitives';
|
||||
import { toast } from '@navi/web-ui/lib/primitives/Toast';
|
||||
import { regularExpression, emailRegularExpression } from '../constants';
|
||||
import { CreateTeamProps } from '../constants';
|
||||
import { ApiService } from '@src/services/api';
|
||||
|
||||
const CreateTeam: React.FC<CreateTeamProps> = ({
|
||||
open,
|
||||
startTeamSearch,
|
||||
setOpen,
|
||||
}) => {
|
||||
const [teamName, setTeamName] = useState<string>('');
|
||||
const [teamNameError, setTeamNameError] = useState<string>('');
|
||||
const [emailError, setEmailError] = useState<string>('');
|
||||
const [email, setEmail] = useState<string>('');
|
||||
|
||||
const validateTeamName = (value: string): void => {
|
||||
value = value.trim();
|
||||
if (!regularExpression.test(value)) {
|
||||
setTeamNameError('Please enter a valid team name');
|
||||
} else {
|
||||
setTeamNameError('');
|
||||
}
|
||||
};
|
||||
|
||||
const validateEmail = (value: string): void => {
|
||||
if (!emailRegularExpression.test(value)) {
|
||||
setEmailError('This is not a Navi e-mail ID');
|
||||
} else {
|
||||
setEmailError('');
|
||||
}
|
||||
};
|
||||
|
||||
const handleTeamNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const inputValue = e.target.value;
|
||||
setTeamName(inputValue);
|
||||
validateTeamName(inputValue);
|
||||
};
|
||||
const handleEmailChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const inputValue = e.target.value;
|
||||
setEmail(inputValue);
|
||||
validateEmail(inputValue);
|
||||
};
|
||||
|
||||
const addTeamHandler = (): void => {
|
||||
ApiService.post(CREATE_TEAM, { name: teamName, manager_email: email })
|
||||
.then((response: any) => {
|
||||
toast.success('Team added successfully');
|
||||
startTeamSearch();
|
||||
setOpen(false);
|
||||
setTeamName('');
|
||||
})
|
||||
.catch(error => {
|
||||
const toastMessage = `${
|
||||
error?.response?.data?.error?.message
|
||||
? `${error?.response?.data?.error?.message},`
|
||||
: 'Something went wrong. Please try again later'
|
||||
}`;
|
||||
toast.error(toastMessage);
|
||||
});
|
||||
};
|
||||
|
||||
const clearErrors = () => {
|
||||
setOpen(false);
|
||||
setTeamNameError('');
|
||||
setEmailError('');
|
||||
setTeamName('');
|
||||
setEmail('');
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="team-wrapper">
|
||||
{open && (
|
||||
<ModalDialog
|
||||
open={open}
|
||||
footerButtons={[
|
||||
{
|
||||
label: 'Cancel',
|
||||
onClick: clearErrors,
|
||||
},
|
||||
{
|
||||
label: 'Submit',
|
||||
onClick: addTeamHandler,
|
||||
disabled: !!teamNameError || !!emailError || !teamName || !email,
|
||||
},
|
||||
]}
|
||||
header="Set up new team "
|
||||
onClose={clearErrors}
|
||||
>
|
||||
<div className="input-wrapper">
|
||||
<Typography variant="p4">
|
||||
<BorderedInput
|
||||
inputLabel="Team name"
|
||||
inputSize="full-width"
|
||||
type="text"
|
||||
value={teamName}
|
||||
onChange={handleTeamNameChange}
|
||||
error={teamNameError}
|
||||
Icon={<AlertOutlineIcon color="#e92c2c" />}
|
||||
placeholder="E.g. NaviPay_Operations"
|
||||
/>
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
<div className="email-wrapper">
|
||||
<Typography variant="p4" color="#F98600">
|
||||
<BorderedInput
|
||||
inputLabel="Manager e-mail ID"
|
||||
inputSize="full-width"
|
||||
type="text"
|
||||
value={email}
|
||||
onChange={handleEmailChange}
|
||||
placeholder="a.b@navi.com"
|
||||
error={emailError}
|
||||
Icon={<AlertOutlineIcon color="#e92c2c" />}
|
||||
/>
|
||||
</Typography>
|
||||
</div>
|
||||
</ModalDialog>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default CreateTeam;
|
||||
Reference in New Issue
Block a user