From d3c7705bedebd65c94f9eea691aaf2fe03b0cafe Mon Sep 17 00:00:00 2001
From: Anton Tananaev <anton@traccar.org>
Date: Sat, 19 Aug 2023 13:58:45 -0700
Subject: Move to Vite

---
 modern/src/settings/UsersPage.jsx | 112 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)
 create mode 100644 modern/src/settings/UsersPage.jsx

(limited to 'modern/src/settings/UsersPage.jsx')

diff --git a/modern/src/settings/UsersPage.jsx b/modern/src/settings/UsersPage.jsx
new file mode 100644
index 00000000..d04f2a2b
--- /dev/null
+++ b/modern/src/settings/UsersPage.jsx
@@ -0,0 +1,112 @@
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import {
+  Table, TableRow, TableCell, TableHead, TableBody,
+} from '@mui/material';
+import LoginIcon from '@mui/icons-material/Login';
+import LinkIcon from '@mui/icons-material/Link';
+import { useCatch, useEffectAsync } from '../reactHelper';
+import { formatBoolean, formatTime } from '../common/util/formatter';
+import { useTranslation } from '../common/components/LocalizationProvider';
+import PageLayout from '../common/components/PageLayout';
+import SettingsMenu from './components/SettingsMenu';
+import CollectionFab from './components/CollectionFab';
+import CollectionActions from './components/CollectionActions';
+import TableShimmer from '../common/components/TableShimmer';
+import { useManager } from '../common/util/permissions';
+import SearchHeader, { filterByKeyword } from './components/SearchHeader';
+import { usePreference } from '../common/util/preferences';
+import useSettingsStyles from './common/useSettingsStyles';
+
+const UsersPage = () => {
+  const classes = useSettingsStyles();
+  const navigate = useNavigate();
+  const t = useTranslation();
+
+  const manager = useManager();
+
+  const hours12 = usePreference('twelveHourFormat');
+
+  const [timestamp, setTimestamp] = useState(Date.now());
+  const [items, setItems] = useState([]);
+  const [searchKeyword, setSearchKeyword] = useState('');
+  const [loading, setLoading] = useState(false);
+
+  const handleLogin = useCatch(async (userId) => {
+    const response = await fetch(`/api/session/${userId}`);
+    if (response.ok) {
+      window.location.replace('/');
+    } else {
+      throw Error(await response.text());
+    }
+  });
+
+  const actionLogin = {
+    key: 'login',
+    title: t('loginLogin'),
+    icon: <LoginIcon fontSize="small" />,
+    handler: handleLogin,
+  };
+
+  const actionConnections = {
+    key: 'connections',
+    title: t('sharedConnections'),
+    icon: <LinkIcon fontSize="small" />,
+    handler: (userId) => navigate(`/settings/user/${userId}/connections`),
+  };
+
+  useEffectAsync(async () => {
+    setLoading(true);
+    try {
+      const response = await fetch('/api/users');
+      if (response.ok) {
+        setItems(await response.json());
+      } else {
+        throw Error(await response.text());
+      }
+    } finally {
+      setLoading(false);
+    }
+  }, [timestamp]);
+
+  return (
+    <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'settingsUsers']}>
+      <SearchHeader keyword={searchKeyword} setKeyword={setSearchKeyword} />
+      <Table className={classes.table}>
+        <TableHead>
+          <TableRow>
+            <TableCell>{t('sharedName')}</TableCell>
+            <TableCell>{t('userEmail')}</TableCell>
+            <TableCell>{t('userAdmin')}</TableCell>
+            <TableCell>{t('sharedDisabled')}</TableCell>
+            <TableCell>{t('userExpirationTime')}</TableCell>
+            <TableCell className={classes.columnAction} />
+          </TableRow>
+        </TableHead>
+        <TableBody>
+          {!loading ? items.filter(filterByKeyword(searchKeyword)).map((item) => (
+            <TableRow key={item.id}>
+              <TableCell>{item.name}</TableCell>
+              <TableCell>{item.email}</TableCell>
+              <TableCell>{formatBoolean(item.administrator, t)}</TableCell>
+              <TableCell>{formatBoolean(item.disabled, t)}</TableCell>
+              <TableCell>{formatTime(item.expirationTime, 'date', hours12)}</TableCell>
+              <TableCell className={classes.columnAction} padding="none">
+                <CollectionActions
+                  itemId={item.id}
+                  editPath="/settings/user"
+                  endpoint="users"
+                  setTimestamp={setTimestamp}
+                  customActions={manager ? [actionLogin, actionConnections] : [actionConnections]}
+                />
+              </TableCell>
+            </TableRow>
+          )) : (<TableShimmer columns={6} endAction />)}
+        </TableBody>
+      </Table>
+      <CollectionFab editPath="/settings/user" />
+    </PageLayout>
+  );
+};
+
+export default UsersPage;
-- 
cgit v1.2.3

