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 } catch (e) {
75 console.error(e);
76 addToast(t('options.plus.deleteAdminError'));
77 }
78 };
79
80 const canEdit = canEditEventOptions();
81
82 return (
83 <Card
84 sx={{
85 position: 'relative',
86 maxWidth: '100%',
87 width: '480px',
88 pb: 3,
89 }}
90 >
91 <Box
92 display="flex"
93 justifyContent="space-between"
94 width="100%"
95 p={2}
96 py={1}
97 >
98 <Typography variant="h4" pt={1}>
99 {t('options.plus.title')}
100 </Typography>
101 </Box>
102 <Divider />
103 <Box p={2} display="flex" justifyContent="space-between" width="100%">
104 <Typography pt={1} variant="body2" color="GrayText">
105 {t('options.plus.admins')}
106 </Typography>
107 {canEdit ? (
108 <Button
109 variant="text"
110 endIcon={<AddIcon />}
111 onClick={toggleAddAdminDialog}
112 >
113 {t('generic.add')}
114 </Button>
115 ) : (
116 <Tooltip title={t('options.plus.notRightForAddAdmin')}>
117 <div>
118 <Button variant="text" disabled endIcon={<AddIcon />}>
119 {t('generic.add')}
120 </Button>
121 </div>
122 </Tooltip>
123 )}
124 </Box>
125 <List disablePadding>
126 <ListItem
127 secondaryAction={
128 <Chip label={t('options.plus.creator')} size="medium" />
129 }
130 >
131 <ListItemIcon>
132 <AccountCircleOutlinedIcon />
133 </ListItemIcon>
134 <ListItemText primary={event.email} />
135 </ListItem>
136 {event.administrators?.map(email => (
137 <ListItem
138 secondaryAction={
139 canEditEventOptions() && (
140 <IconButton size="medium" onClick={() => deleteAdmin({email})}>
141 <DeleteOutlineIcon />
142 </IconButton>
143 )
144 }
145 >
146 <ListItemIcon>
147 <AccountCircleOutlinedIcon />
148 </ListItemIcon>
149 <ListItemText primary={email} />
150 </ListItem>
151 ))}
152 </List>
153 <FormDialog
154 title={t('options.plus.addAdmin')}
155 open={addAdminDialogOpen}
156 cancel={toggleAddAdminDialog}
157 onSubmit={addAdmin}
158 disabled={!isEmailValid}
159 >
160 <TextField
161 fullWidth
162 error={emailError}
163 label={t('options.plus.addAdmin.email')}
164 value={adminEmail}
165 onChange={e => setAdminEmail(e.target.value)}
166 helperText={emailError && t('options.plus.addAdmin.emailHelper')}
167 variant="standard"
168 />
169 </FormDialog>
170 </Card>
171 );
172};
173
174export default CarosterPlusSettings;