diff --git a/src/resources/l10n/en.json b/src/resources/l10n/en.json
index 9bb222f313..608c36d84b 100644
--- a/src/resources/l10n/en.json
+++ b/src/resources/l10n/en.json
@@ -337,6 +337,7 @@
"serverLogoInverted": "Inverted Logo Image",
"serverChangeDisable": "Disable Server Change",
"serverDisableShare": "Disable Device Sharing",
+ "serverReboot": "Reboot",
"mapTitle": "Map",
"mapActive": "Active Maps",
"mapOverlay": "Map Overlay",
diff --git a/src/settings/PreferencesPage.jsx b/src/settings/PreferencesPage.jsx
index f596b478e7..3b7fcaed0a 100644
--- a/src/settings/PreferencesPage.jsx
+++ b/src/settings/PreferencesPage.jsx
@@ -18,7 +18,7 @@ import useMapStyles from '../map/core/useMapStyles';
import useMapOverlays from '../map/overlay/useMapOverlays';
import { useCatch } from '../reactHelper';
import { sessionActions } from '../store';
-import { useRestriction } from '../common/util/permissions';
+import { useAdministrator, useRestriction } from '../common/util/permissions';
import useSettingsStyles from './common/useSettingsStyles';
const deviceFields = [
@@ -35,6 +35,7 @@ const PreferencesPage = () => {
const navigate = useNavigate();
const t = useTranslation();
+ const admin = useAdministrator();
const readonly = useRestriction('readonly');
const user = useSelector((state) => state.session.user);
@@ -86,6 +87,13 @@ const PreferencesPage = () => {
}
});
+ const handleReboot = useCatch(async () => {
+ const response = await fetch('/api/server/reboot', { method: 'POST' });
+ if (!response.ok) {
+ throw Error(await response.text());
+ }
+ });
+
return (
} breadcrumbs={['settingsTitle', 'sharedPreferences']}>
@@ -352,6 +360,15 @@ const PreferencesPage = () => {
>
{t('sharedEmulator')}
+ {admin && (
+
+ )}