frontend/containers/CarosterPlusSettings/index.tsx (view raw)
1import {useReducer, useState} from 'react';
2import Box from '@mui/material/Box';
3import Button from '@mui/material/Button';
4import Card from '@mui/material/Card';
5import Chip from '@mui/material/Chip';
6import Divider from '@mui/material/Divider';
7import List from '@mui/material/List';
8import ListItem from '@mui/material/ListItem';
9import ListItemIcon from '@mui/material//ListItemIcon';
10import ListItemText from '@mui/material/ListItemText';
11import AddIcon from '@mui/icons-material/Add';
12import Typography from '@mui/material/Typography';
13import TextField from '@mui/material/TextField';
14import IconButton from '@mui/material/IconButton';
15import AccountCircleOutlinedIcon from '@mui/icons-material/AccountCircleOutlined';
16import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
17import {useTranslation} from 'react-i18next';
18import usePermissions from '../../hooks/usePermissions';
19import useToastStore from '../../stores/useToastStore';
20import FormDialog from '../FormDialog';
21import {validateEmail} from '../../lib/validation';
22import {
23 Event as EventType,
24 useAddEventAdminMutation,
25 useDeleteEventAdminMutation,
26} from '../../generated/graphql';
27import Tooltip from '@mui/material/Tooltip';
28
29interface Props {
30 event: EventType & {id: string};
31}
32
33const CarosterPlusSettings = ({event}: Props) => {
34 const {t} = useTranslation();
35 const {
36 userPermissions: {canEditEventOptions},
37 } = usePermissions();
38
39 const {addToast} = useToastStore();
40
41 const [addAdminMutation] = useAddEventAdminMutation();
42 const [deleteAdminMutation] = useDeleteEventAdminMutation();
43 const [addAdminDialogOpen, toggleAddAdminDialog] = useReducer(i => !i, false);
44 const [adminEmail, setAdminEmail] = useState('');
45 const isEmailValid = validateEmail(adminEmail);
46 const emailError = adminEmail !== '' && !isEmailValid;
47
48 const addAdmin = async () => {
49 try {
50 await addAdminMutation({
51 variables: {
52 eventId: event.id,
53 email: adminEmail,
54 },
55 });
56 addToast(t('options.plus.adminAdded'));
57 toggleAddAdminDialog();
58 setAdminEmail('');
59 } catch (e) {
60 console.error(e);
61 addToast(t('options.plus.addAdminError'));
62 }
63 };
64
65 const deleteAdmin = async ({email}) => {
66 try {
67 await deleteAdminMutation({
68 variables: {
69 eventId: event.id,
70 email,
71 },
72 });
73 addToast(t('options.plus.adminDeleted'));
74 toggleAddAdminDialog();
75 } catch (e) {
76 console.error(e);
77 addToast(t('options.plus.deleteAdminError'));
78 }
79 };
80
81 const canEdit = canEditEventOptions();
82
83 return (
84 <Card
85 sx={{
86 position: 'relative',
87 maxWidth: '100%',
88 width: '480px',
89 pb: 3,
90 }}
91 >
92 <Box
93 display="flex"
94 justifyContent="space-between"
95 width="100%"
96 p={2}
97 py={1}
98 >
99 <Typography variant="h4" pt={1}>
100 {t('options.plus.title')}
101 </Typography>
102 </Box>
103 <Divider />
104 <Box p={2} display="flex" justifyContent="space-between" width="100%">
105 <Typography pt={1} variant="body2" color="GrayText">
106 {t('options.plus.admins')}
107 </Typography>
108 {canEdit ? (
109 <Button
110 variant="text"
111 endIcon={<AddIcon />}
112 onClick={toggleAddAdminDialog}
113 >
114 {t('generic.add')}
115 </Button>
116 ) : (
117 <Tooltip title={t('options.plus.notRightForAddAdmin')}>
118 <div>
119 <Button variant="text" disabled endIcon={<AddIcon />}>
120 {t('generic.add')}
121 </Button>
122 </div>
123 </Tooltip>
124 )}
125 </Box>
126 <List disablePadding>
127 <ListItem
128 secondaryAction={
129 <Chip label={t('options.plus.creator')} size="medium" />
130 }
131 >
132 <ListItemIcon>
133 <AccountCircleOutlinedIcon />
134 </ListItemIcon>
135 <ListItemText primary={event.email} />
136 </ListItem>
137 {event.administrators?.map(email => (
138 <ListItem
139 secondaryAction={
140 canEditEventOptions() && (
141 <IconButton size="medium" onClick={() => deleteAdmin({email})}>
142 <DeleteOutlineIcon />
143 </IconButton>
144 )
145 }
146 >
147 <ListItemIcon>
148 <AccountCircleOutlinedIcon />
149 </ListItemIcon>
150 <ListItemText primary={email} />
151 </ListItem>
152 ))}
153 </List>
154 <FormDialog
155 title={t('options.plus.addAdmin')}
156 open={addAdminDialogOpen}
157 cancel={toggleAddAdminDialog}
158 onSubmit={addAdmin}
159 disabled={!isEmailValid}
160 >
161 <TextField
162 fullWidth
163 error={emailError}
164 label={t('options.plus.addAdmin.email')}
165 value={adminEmail}
166 onChange={e => setAdminEmail(e.target.value)}
167 helperText={emailError && t('options.plus.addAdmin.emailHelper')}
168 variant="standard"
169 />
170 </FormDialog>
171 </Card>
172 );
173};
174
175export default CarosterPlusSettings;