diff --git a/src/components/Identity/CreateUserDialog.jsx b/src/components/Identity/CreateUserDialog.jsx
new file mode 100644
index 0000000..699e46d
--- /dev/null
+++ b/src/components/Identity/CreateUserDialog.jsx
@@ -0,0 +1,149 @@
+import { Button, CloseButton, Dialog, Field, IconButton, Input, Portal, Text, VStack } from '@chakra-ui/react';
+import { useState, useEffect } from 'react';
+import { FaPlus } from 'react-icons/fa';
+import { useNavigate } from 'react-router-dom';
+import { withMask } from 'use-mask-input';
+import ToastWizard from '../toastWizard';
+import server, { JSONResponse } from '../../networking';
+
+function CreateUserDialog() {
+ const navigate = useNavigate();
+
+ const [dialogOpen, setDialogOpen] = useState(false);
+ const [fname, setFname] = useState('');
+ const [lname, setLname] = useState('');
+ const [username, setUsername] = useState('');
+ const [email, setEmail] = useState('');
+ const [contact, setContact] = useState('');
+ const [role, setRole] = useState('');
+ const [creatingUser, setCreatingUser] = useState(false);
+
+ const isDisabled = !fname || !lname || !username || !email || !contact || !role;
+
+ const handleCreateUser = async () => {
+ if (isDisabled) {
+ ToastWizard.standard("error", "All fields are required.");
+ return;
+ }
+
+ setCreatingUser(true);
+
+ try {
+ const response = await server.post('/admin/createUser', {
+ fname,
+ lname,
+ username,
+ email,
+ contact,
+ role
+ })
+
+ if (response.data instanceof JSONResponse) {
+ if (response.data.isErrorStatus()) {
+ const errObject = {
+ response: {
+ data: response.data
+ }
+ };
+ throw new Error(errObject);
+ }
+
+ // Success case
+ ToastWizard.standard("success", "Account Created", `Welcome ${fname} to the family! Login instructions have been sent via email!`);
+ setDialogOpen(false);
+ if (response.data.raw.newUserID) {
+ navigate(`/profile/${response.data.raw.newUserID}`);
+ }
+ } else {
+ throw new Error("Unexpected response format");
+ }
+ } catch (err) {
+ if (err.response && err.response.data instanceof JSONResponse) {
+ console.log("Error response in user creation request:", err.response.data.fullMessage());
+ if (err.response.data.userErrorType()) {
+ ToastWizard.standard("error", "User creation failed.", err.response.data.message);
+ } else {
+ ToastWizard.standard("error", "Something went wrong", "Couldn't create user. Please try again.")
+ }
+ } else {
+ console.log("Unexpected error in user creation request:", err);
+ ToastWizard.standard("error", "Something went wrong", "Couldn't create user. Please try again.")
+ }
+ } finally {
+ setCreatingUser(false);
+ }
+ }
+
+ const handleEnterKey = (e) => {
+ if (e.key === 'Enter') {
+ handleCreateUser();
+ }
+ }
+
+ return (
+ setDialogOpen(e.open)} unmountOnExit>
+
+
+
+
+
+
+
+
+ Create New Account
+
+
+
+ Create new accounts to enable more people to gain access to ArchAIve's innovative artefact digitisation services!
+ Users will be able to access most of the platform's features, except those that are sensitive like managing other users.
+ Every user's activity is monitored closely, empowering you to redress in any dire situations at all times.
+
+
+
+ First Name
+ setFname(e.target.value)} />
+
+
+
+ Last Name
+ setLname(e.target.value)} />
+
+
+
+ Username
+ setUsername(e.target.value)} />
+
+
+
+ Email
+ setEmail(e.target.value)} />
+
+
+
+ Contact
+ setContact(e.target.value)} />
+
+
+
+ Role
+ setRole(e.target.value)} />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default CreateUserDialog
\ No newline at end of file
diff --git a/src/pages/AdminConsole.jsx b/src/pages/AdminConsole.jsx
index 5407d89..9769402 100644
--- a/src/pages/AdminConsole.jsx
+++ b/src/pages/AdminConsole.jsx
@@ -12,7 +12,7 @@ function AdminConsole() {
return (
Admin Console
-
+
User Management
@@ -25,18 +25,6 @@ function AdminConsole() {
-
-
- Data Management
-
- Analyse and manage batches, collections, artefacts and other data that goes into the platform.
-
-
-
-
-
-
-
Platform Controls
diff --git a/src/pages/Profile.jsx b/src/pages/Profile.jsx
index 10a6d77..3091463 100644
--- a/src/pages/Profile.jsx
+++ b/src/pages/Profile.jsx
@@ -241,7 +241,7 @@ function Profile() {
Security & Authentication
- Last Login: {originalAccountInfo.lastLogin}
+ Last Login: {originalAccountInfo.lastLogin || 'Never'}
diff --git a/src/pages/UserManagement.jsx b/src/pages/UserManagement.jsx
index d6820af..75bc85c 100644
--- a/src/pages/UserManagement.jsx
+++ b/src/pages/UserManagement.jsx
@@ -1,16 +1,14 @@
-import { Box, Button, IconButton, SimpleGrid, Skeleton, Spinner, Text } from '@chakra-ui/react'
-import { FaPlus } from 'react-icons/fa'
+import { Box, SimpleGrid, Skeleton, Text } from '@chakra-ui/react'
import IAMStatisticBox from '../components/Identity/IAMStatisticBox'
import IAMUserCard from '../components/Identity/IAMUserCard'
-import { useNavigate } from 'react-router-dom'
import { useSelector } from 'react-redux'
import { useState } from 'react'
import server, { JSONResponse } from '../networking';
import ToastWizard from '../components/toastWizard';
import { useEffect } from 'react'
+import CreateUserDialog from '../components/Identity/CreateUserDialog'
function UserManagement() {
- const navigate = useNavigate();
const { loaded, superuser } = useSelector(state => state.auth);
const [userData, setUserData] = useState({});
@@ -68,7 +66,7 @@ function UserManagement() {
User Management
-
+