import { useContext, useState } from 'react'; import type { FC } from 'react'; import { useBlocker } from 'react-router-dom'; import CancelIcon from '@mui/icons-material/Cancel'; import CheckIcon from '@mui/icons-material/Check'; import CloseIcon from '@mui/icons-material/Close'; import DeleteIcon from '@mui/icons-material/Delete'; import EditIcon from '@mui/icons-material/Edit'; import PersonAddIcon from '@mui/icons-material/PersonAdd'; import VpnKeyIcon from '@mui/icons-material/VpnKey'; import WarningIcon from '@mui/icons-material/Warning'; import { Box, Button, IconButton } from '@mui/material'; import * as SecurityApi from 'api/security'; import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; import { BlockNavigation, ButtonRow, FormLoader, MessageBox, SectionContent } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; import type { SecuritySettingsType, UserType } from 'types'; import { useRest } from 'utils'; import { createUserValidator } from 'validators'; import GenerateToken from './GenerateToken'; import User from './User'; const ManageUsers: FC = () => { const { loadData, saveData, saving, data, updateDataValue, errorMessage } = useRest({ read: SecurityApi.readSecuritySettings, update: SecurityApi.updateSecuritySettings }); const [user, setUser] = useState(); const [creating, setCreating] = useState(false); const [changed, setChanged] = useState(0); const [generatingToken, setGeneratingToken] = useState(); const authenticatedContext = useContext(AuthenticatedContext); const blocker = useBlocker(changed !== 0); const { LL } = useI18nContext(); const table_theme = useTheme({ Table: ` --data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) minmax(120px, max-content) 120px; `, BaseRow: ` font-size: 14px; `, HeaderRow: ` text-transform: uppercase; background-color: black; color: #90CAF9; .th { padding: 8px; height: 36px; border-bottom: 1px solid #565656; } `, Row: ` .td { padding: 8px; border-top: 1px solid #565656; border-bottom: 1px solid #565656; } &:nth-of-type(odd) .td { background-color: #303030; } &:nth-of-type(even) .td { background-color: #1e1e1e; } `, BaseCell: ` &:nth-of-type(2) { text-align: center; } &:last-of-type { text-align: right; } ` }); const content = () => { if (!data) { return ; } const noAdminConfigured = () => !data.users.find((u) => u.admin); const removeUser = (toRemove: UserType) => { const users = data.users.filter((u) => u.username !== toRemove.username); updateDataValue({ ...data, users }); setChanged(changed + 1); }; const createUser = () => { setCreating(true); setUser({ username: '', password: '', admin: true }); }; const editUser = (toEdit: UserType) => { setCreating(false); setUser({ ...toEdit }); }; const cancelEditingUser = () => { setUser(undefined); }; const doneEditingUser = () => { if (user) { const users = [ ...data.users.filter( (u: { username: string }) => u.username !== user.username ), user ]; updateDataValue({ ...data, users }); setUser(undefined); setChanged(changed + 1); } }; const closeGenerateToken = () => { setGeneratingToken(undefined); }; const generateToken = (username: string) => { setGeneratingToken(username); }; const onSubmit = async () => { await saveData(); await authenticatedContext.refresh(); setChanged(0); }; const onCancelSubmit = async () => { await loadData(); setChanged(0); }; interface UserType2 { id: string; username: string; password: string; admin: boolean; } // add id to the type, needed for the table const user_table = data.users.map((u) => ({ ...u, id: u.username })) as UserType2[]; return ( <> {(tableList: UserType2[]) => ( <>
{LL.USERNAME(1)} {LL.IS_ADMIN(0)}
{tableList.map((u: UserType2) => ( {u.username} {u.admin ? : } generateToken(u.username)} > removeUser(u)}> editUser(u)}> ))} )}
{noAdminConfigured() && ( )} {changed !== 0 && ( )} ); }; return ( {blocker ? : null} {content()} ); }; export default ManageUsers;