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';
27
28interface Props {
29 event: EventType & {id: string};
30}
31
32const CarosterPlusSettings = ({event}: Props) => {
33 const {t} = useTranslation();
34 const {
35 userPermissions: {canEditEventOptions},
36 } = usePermissions();
37 const {addToast} = useToastStore();
38
39 const [addAdminMutation] = useAddEventAdminMutation();
40 const [deleteAdminMutation] = useDeleteEventAdminMutation();
41 const [addAdminDialogOpen, toggleAddAdminDialog] = useReducer(i => !i, false);
42 const [adminEmail, setAdminEmail] = useState('');
43 const isEmailValid = validateEmail(adminEmail);
44 const emailError = adminEmail !== '' && !isEmailValid;
45
46 const addAdmin = async () => {
47 try {
48 await addAdminMutation({
49 variables: {
50 eventId: event.id,
51 email: adminEmail,
52 },
53 });
54 addToast(t('options.plus.adminAdded'));
55 toggleAddAdminDialog();
56 setAdminEmail('');
57 } catch (e) {
58 console.error(e);
59 addToast(t('options.plus.addAdminError'));
60 }
61 };
62
63 const deleteAdmin = async ({email}) => {
64 try {
65 await deleteAdminMutation({
66 variables: {
67 eventId: event.id,
68 email,
69 },
70 });
71 addToast(t('options.plus.adminDeleted'));
72 toggleAddAdminDialog();
73 } catch (e) {
74 console.error(e);
75 addToast(t('options.plus.deleteAdminError'));
76 }
77 };
78
79 return (
80 <Card
81 sx={{
82 position: 'relative',
83 maxWidth: '100%',
84 width: '350px',
85 pb: 3,
86 }}
87 >
88 <Box
89 display="flex"
90 justifyContent="space-between"
91 width="100%"
92 p={2}
93 py={1}
94 >
95 <Typography variant="h4" pt={1}>
96 {t('options.plus.title')}
97 </Typography>
98 </Box>
99 <Divider />
100 <Box p={2} display="flex" justifyContent="space-between" width="100%">
101 <Typography pt={1} variant="body2" color="GrayText">
102 {t('options.plus.admins')}
103 </Typography>
104 <Button
105 variant="text"
106 disabled={!canEditEventOptions()}
107 endIcon={<AddIcon />}
108 onClick={toggleAddAdminDialog}
109 >
110 {t('generic.add')}
111 </Button>
112 </Box>
113 <List disablePadding>
114 <ListItem
115 secondaryAction={
116 <Chip label={t('options.plus.creator')} size="medium" />
117 }
118 >
119 <ListItemIcon>
120 <AccountCircleOutlinedIcon />
121 </ListItemIcon>
122 <ListItemText primary={event.email} />
123 </ListItem>
124 {event.administrators?.map(email => (
125 <ListItem
126 secondaryAction={
127 canEditEventOptions() && (
128 <IconButton size="medium" onClick={() => deleteAdmin({email})}>
129 <DeleteOutlineIcon />
130 </IconButton>
131 )
132 }
133 >
134 <ListItemIcon>
135 <AccountCircleOutlinedIcon />
136 </ListItemIcon>
137 <ListItemText primary={email} />
138 </ListItem>
139 ))}
140 </List>
141 <FormDialog
142 title={t("options.plus.addAdmin")}
143 open={addAdminDialogOpen}
144 cancel={toggleAddAdminDialog}
145 onSubmit={addAdmin}
146 disabled={!isEmailValid}
147 >
148 <TextField
149 fullWidth
150 error={emailError}
151 label={t('options.plus.addAdmin.email')}
152 value={adminEmail}
153 onChange={e => setAdminEmail(e.target.value)}
154 helperText={emailError && t('options.plus.addAdmin.emailHelper')}
155 variant="standard"
156 />
157 </FormDialog>
158 </Card>
159 );
160};
161
162export default CarosterPlusSettings;