Skip to content

Commit 8726611

Browse files
committed
#1183 finishing frontend
1 parent f17c7c0 commit 8726611

3 files changed

Lines changed: 158 additions & 4 deletions

File tree

src/frontend/src/pages/TeamDetailPage/DeleteTeamModalContainer/DeleteTeam.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { useHistory } from 'react-router-dom';
22
import { useToast } from '../../../hooks/toasts.hooks';
3-
import { useDeleteWorkPackage } from '../../../hooks/work-packages.hooks';
43
import { useDeleteTeam } from '../../../hooks/teams.hooks';
54
import LoadingIndicator from '../../../components/LoadingIndicator';
65
import ErrorPage from '../../ErrorPage';
6+
import DeleteTeamView from './DeleteTeamView';
77

88
interface DeleteTeamProps {
99
teamId: string;
@@ -36,7 +36,7 @@ const DeleteTeam: React.FC<DeleteTeamProps> = ({ teamId, showModal, handleClose
3636
if (isLoading) return <LoadingIndicator />;
3737
if (isError) return <ErrorPage message={error?.message} />;
3838

39-
return <DeleteTeamView team={teamId} showModal={showModal} onHide={handleClose} onSubmit={handleConfirm} />;
39+
return <DeleteTeamView teamId={teamId} showModal={showModal} onHide={handleClose} onSubmit={handleConfirm} />;
4040
};
4141

4242
export default DeleteTeam;
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import { yupResolver } from '@hookform/resolvers/yup';
2+
import { useForm } from 'react-hook-form';
3+
import { useSingleTeam } from '../../../hooks/teams.hooks';
4+
import LoadingIndicator from '../../../components/LoadingIndicator';
5+
import ErrorPage from '../../ErrorPage';
6+
import * as yup from 'yup';
7+
import { DeleteTeamInputs } from './DeleteTeam';
8+
import {
9+
Dialog,
10+
DialogActions,
11+
DialogContent,
12+
DialogTitle,
13+
FormControl,
14+
FormLabel,
15+
IconButton,
16+
Typography
17+
} from '@mui/material';
18+
import CloseIcon from '@mui/icons-material/Close';
19+
import { wbsPipe } from 'shared';
20+
import NERFailButton from '../../../components/NERFailButton';
21+
import NERSuccessButton from '../../../components/NERSuccessButton';
22+
import ReactHookTextField from '../../../components/ReactHookTextField';
23+
24+
interface DeleteTeamViewProps {
25+
teamId: string;
26+
showModal: boolean;
27+
onHide: () => void;
28+
onSubmit: (data: DeleteTeamInputs) => Promise<void>;
29+
}
30+
31+
const DeleteTeamView: React.FC<DeleteTeamViewProps> = ({ teamId, showModal, onHide, onSubmit }: DeleteTeamViewProps) => {
32+
const { isLoading, isError, data: team, error } = useSingleTeam(teamId);
33+
34+
const teamNameTester = (teamName: string | undefined) =>
35+
team !== undefined && teamName !== undefined && teamName.toLowerCase === team.teamName.toLowerCase;
36+
37+
const schema = yup.object().shape({
38+
teamName: yup.string().required().test('team-name-test', 'Team name does not match', teamNameTester)
39+
});
40+
41+
const {
42+
handleSubmit,
43+
control,
44+
formState: { errors, isValid }
45+
} = useForm({
46+
resolver: yupResolver(schema),
47+
defaultValues: {
48+
teamName: ''
49+
},
50+
mode: 'onChange'
51+
});
52+
53+
if (isLoading || !team) return <LoadingIndicator />;
54+
if (isError) return <ErrorPage message={error.message} />;
55+
56+
const onSubmitWrapper = async (data: { teamName: string }) => {
57+
const submitVal = { teamId };
58+
59+
await onSubmit(submitVal);
60+
};
61+
62+
return (
63+
<Dialog open={showModal} onClose={onHide}>
64+
<DialogTitle
65+
className="font-weight-bold"
66+
sx={{
67+
'&.MuiDialogTitle-root': {
68+
padding: '1rem 1.5rem 0'
69+
}
70+
}}
71+
>{`Delete Team ${team.teamName}`}</DialogTitle>
72+
<IconButton
73+
aria-label="close"
74+
onClick={onHide}
75+
sx={{
76+
position: 'absolute',
77+
right: 8,
78+
top: 8,
79+
color: (theme) => theme.palette.grey[500]
80+
}}
81+
>
82+
<CloseIcon />
83+
</IconButton>
84+
<DialogContent
85+
sx={{
86+
'&.MuiDialogContent-root': {
87+
padding: '1rem 1.5rem'
88+
}
89+
}}
90+
>
91+
<Typography sx={{ marginBottom: '1rem' }}>Are you sure you want to delete Team {team.teamName}?</Typography>
92+
<Typography sx={{ fontWeight: 'bold' }}>This action cannot be undone!</Typography>
93+
<form
94+
id="delete-team-form"
95+
onSubmit={(e) => {
96+
e.preventDefault();
97+
e.stopPropagation();
98+
handleSubmit(onSubmitWrapper)(e);
99+
}}
100+
>
101+
<FormControl>
102+
<FormLabel sx={{ marginTop: '1rem', marginBottom: '1rem' }}>
103+
To confirm deletion, please type in the name of this team.
104+
</FormLabel>
105+
<ReactHookTextField
106+
control={control}
107+
name="teamName"
108+
errorMessage={errors.teamName}
109+
placeholder="Enter Team Name here"
110+
sx={{ width: 1 }}
111+
type="string"
112+
/>
113+
</FormControl>
114+
</form>
115+
</DialogContent>
116+
<DialogActions>
117+
<NERSuccessButton variant="contained" sx={{ mx: 1 }} onClick={onHide}>
118+
Cancel
119+
</NERSuccessButton>
120+
<NERFailButton variant="contained" type="submit" form="delete-wp-form" sx={{ mx: 1 }} disabled={!isValid}>
121+
Delete
122+
</NERFailButton>
123+
</DialogActions>
124+
</Dialog>
125+
);
126+
};
127+
128+
export default DeleteTeamView;

src/frontend/src/pages/TeamDetailPage/TeamDetailPage.tsx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Grid } from '@mui/material';
1+
import { Button, Grid, ListItemIcon, MenuItem } from '@mui/material';
22
import { useSingleTeam } from '../../hooks/teams.hooks';
33
import { useParams } from 'react-router-dom';
44
import TeamMembersPageBlock from './TeamMembersPageBlock';
@@ -9,6 +9,12 @@ import ActiveProjectCardView from './ProjectCardsView';
99
import DescriptionPageBlock from './DescriptionPageBlock';
1010
import { routes } from '../../utils/routes';
1111
import PageLayout from '../../components/PageLayout';
12+
import { Delete } from '@mui/icons-material';
13+
import { NERButton } from '../../components/NERButton';
14+
import { useCurrentUser } from '../../hooks/users.hooks';
15+
import { isAdmin } from 'shared';
16+
import { useState } from 'react';
17+
import DeleteTeam from './DeleteTeamModalContainer/DeleteTeam';
1218

1319
interface ParamTypes {
1420
teamId: string;
@@ -17,12 +23,29 @@ interface ParamTypes {
1723
const TeamSpecificPage: React.FC = () => {
1824
const { teamId } = useParams<ParamTypes>();
1925
const { isLoading, isError, data, error } = useSingleTeam(teamId);
26+
const user = useCurrentUser();
27+
const [showDeleteModal, setShowDeleteModal] = useState(false);
2028

2129
if (isError) return <ErrorPage message={error?.message} />;
2230
if (isLoading || !data) return <LoadingIndicator />;
2331

32+
const deleteButton = (
33+
<NERButton
34+
variant="contained"
35+
disabled={!isAdmin(user.role)}
36+
startIcon={<Delete />}
37+
onClick={() => setShowDeleteModal(true)}
38+
>
39+
Delete
40+
</NERButton>
41+
);
42+
2443
return (
25-
<PageLayout title={`Team ${data.teamName}`} previousPages={[{ name: 'Teams', route: routes.TEAMS }]}>
44+
<PageLayout
45+
headerRight={deleteButton}
46+
title={`Team ${data.teamName}`}
47+
previousPages={[{ name: 'Teams', route: routes.TEAMS }]}
48+
>
2649
<Grid container spacing={2}>
2750
<Grid item xs={12}>
2851
<TeamMembersPageBlock team={data} />
@@ -40,6 +63,9 @@ const TeamSpecificPage: React.FC = () => {
4063
<DescriptionPageBlock team={data} />
4164
</Grid>
4265
</Grid>
66+
{showDeleteModal && (
67+
<DeleteTeam teamId={teamId} showModal={showDeleteModal} handleClose={() => setShowDeleteModal(false)} />
68+
)}
4369
</PageLayout>
4470
);
4571
};

0 commit comments

Comments
 (0)