Skip to content

Commit

Permalink
Add announcements page
Browse files Browse the repository at this point in the history
  • Loading branch information
tananaev committed Feb 25, 2024
1 parent 8bd7cba commit 4aa3a83
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 6 deletions.
2 changes: 2 additions & 0 deletions modern/src/Navigation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import GroupConnectionsPage from './settings/GroupConnectionsPage';
import UserConnectionsPage from './settings/UserConnectionsPage';
import LogsPage from './reports/LogsPage';
import SharePage from './settings/SharePage';
import AnnouncementPage from './settings/AnnouncementPage';

const Navigation = () => {
const navigate = useNavigate();
Expand Down Expand Up @@ -111,6 +112,7 @@ const Navigation = () => {

<Route path="settings">
<Route path="accumulators/:deviceId" element={<AccumulatorsPage />} />
<Route path="announcement" element={<AnnouncementPage />} />
<Route path="calendars" element={<CalendarsPage />} />
<Route path="calendar/:id" element={<CalendarPage />} />
<Route path="calendar" element={<CalendarPage />} />
Expand Down
1 change: 1 addition & 0 deletions modern/src/resources/l10n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"sharedRemove": "Remove",
"sharedRemoveConfirm": "Remove item?",
"sharedNoData": "No data",
"sharedSubject": "Subject",
"sharedYes": "Yes",
"sharedNo": "No",
"sharedKm": "km",
Expand Down
106 changes: 106 additions & 0 deletions modern/src/settings/AnnouncementPage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
Accordion,
AccordionSummary,
AccordionDetails,
Typography,
Container,
TextField,
Button,
} from '@mui/material';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { useTranslation } from '../common/components/LocalizationProvider';
import PageLayout from '../common/components/PageLayout';
import SettingsMenu from './components/SettingsMenu';
import { useCatchCallback } from '../reactHelper';
import useSettingsStyles from './common/useSettingsStyles';
import SelectField from '../common/components/SelectField';
import { prefixString } from '../common/util/stringUtils';

const AnnouncementPage = () => {
const navigate = useNavigate();
const classes = useSettingsStyles();
const t = useTranslation();

const [users, setUsers] = useState([]);
const [notificator, setNotificator] = useState();
const [message, setMessage] = useState({});

const handleSend = useCatchCallback(async () => {
const query = new URLSearchParams();
users.forEach((userId) => query.append('userId', userId));
const response = await fetch(`/api/notifications/send/${notificator}?${query.toString()}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(message),
});
if (response.ok) {
navigate(-1);
} else {
throw Error(await response.text());
}
}, [users, notificator, message, navigate]);

return (
<PageLayout menu={<SettingsMenu />} breadcrumbs={['serverAnnouncement']}>
<Container maxWidth="xs" className={classes.container}>
<Accordion defaultExpanded>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography variant="subtitle1">
{t('sharedRequired')}
</Typography>
</AccordionSummary>
<AccordionDetails className={classes.details}>
<SelectField
multiple
value={users}
onChange={(e) => setUsers(e.target.value)}
endpoint="/api/users"
label={t('settingsUsers')}
/>
<SelectField
value={notificator}
onChange={(e) => setNotificator(e.target.value)}
endpoint="/api/notifications/notificators"
keyGetter={(it) => it.type}
titleGetter={(it) => t(prefixString('notificator', it.type))}
label={t('notificationNotificators')}
/>
<TextField
value={message.subject}
onChange={(e) => setMessage({ ...message, subject: e.target.value })}
label={t('sharedSubject')}
/>
<TextField
value={message.body}
onChange={(e) => setMessage({ ...message, body: e.target.value })}
label={t('commandMessage')}
/>
</AccordionDetails>
</Accordion>
<div className={classes.buttons}>
<Button
type="button"
color="primary"
variant="outlined"
onClick={() => navigate(-1)}
>
{t('sharedCancel')}
</Button>
<Button
type="button"
color="primary"
variant="contained"
onClick={handleSend}
disabled={!notificator || !message.subject || !message.body}
>
{t('commandSend')}
</Button>
</div>
</Container>
</PageLayout>
);
};

export default AnnouncementPage;
21 changes: 15 additions & 6 deletions modern/src/settings/components/SettingsMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import TodayIcon from '@mui/icons-material/Today';
import PublishIcon from '@mui/icons-material/Publish';
import SmartphoneIcon from '@mui/icons-material/Smartphone';
import HelpIcon from '@mui/icons-material/Help';
import CampaignIcon from '@mui/icons-material/Campaign';
import { Link, useLocation } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { useTranslation } from '../../common/components/LocalizationProvider';
Expand Down Expand Up @@ -139,12 +140,20 @@ const SettingsMenu = () => {
<Divider />
<List>
{admin && (
<MenuItem
title={t('settingsServer')}
link="/settings/server"
icon={<StorageIcon />}
selected={location.pathname === '/settings/server'}
/>
<>
<MenuItem
title={t('serverAnnouncement')}
link="/settings/announcement"
icon={<CampaignIcon />}
selected={location.pathname === '/settings/announcement'}
/>
<MenuItem
title={t('settingsServer')}
link="/settings/server"
icon={<StorageIcon />}
selected={location.pathname === '/settings/server'}
/>
</>
)}
<MenuItem
title={t('settingsUsers')}
Expand Down

0 comments on commit 4aa3a83

Please sign in to comment.