diff --git a/index.html b/index.html
index 0c589ec..9d579a2 100644
--- a/index.html
+++ b/index.html
@@ -4,6 +4,12 @@
+
+
+
Vite + React
diff --git a/package.json b/package.json
index 2927530..7317ac2 100644
--- a/package.json
+++ b/package.json
@@ -30,7 +30,6 @@
"react-dropzone": "^14.2.3",
"react-hook-form": "7.37.0",
"react-icons": "^5.0.1",
- "react-pdf": "^7.7.0",
"react-router-dom": "^6.21.1",
"vite-plugin-top-level-await": "^1.4.1",
"yup": "^1.3.3"
diff --git a/src/App.jsx b/src/App.jsx
index 74d5e75..8dbec58 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -26,6 +26,7 @@ import SelectEvent from './pages/SelectEvent';
import DummyVolunteerQR from './pages/DummyVolunteerQR';
import DummyAdminQR from './pages/DummyAdminQR';
import Navbar from './components/Navbar/Navbar';
+import AdminPage from './pages/AdminPage';
const Layout = () => {
return (
@@ -64,26 +65,19 @@ const App = () => {
} />
} />
- {/* SPRINT 4 */}
-
- {/* Jessie and Brendan */}
+
} />
- {/* Rayan and Emmy */}
} />
- {/* Phillip and Katy */}
} />
- {/* Nate and Farhnaz */}
} />
} />
- {/* Matthew and Bobby */}
} />
- {/* If your Sprint 3 task requires you to create a new component, you can use this route to test the look of your component */}
} />
- {/* SPRINT 5 */}
- {/* Kevin and Jasmine */}
} />
} />
+
+ } />
diff --git a/src/components/AdminModals/AddUserModal.jsx b/src/components/AdminModals/AddUserModal.jsx
new file mode 100644
index 0000000..753241c
--- /dev/null
+++ b/src/components/AdminModals/AddUserModal.jsx
@@ -0,0 +1,180 @@
+import {
+ Flex,
+ Modal,
+ ModalOverlay,
+ ModalContent,
+ ModalHeader,
+ ModalFooter,
+ ModalBody,
+ Spinner,
+ FormControl,
+ FormLabel,
+ Input,
+ Button,
+ Select,
+ useToast,
+ ModalCloseButton,
+} from '@chakra-ui/react';
+import Dropzone from '../Dropzone.tsx';
+import { useState} from 'react';
+import { postProfile } from '../../utils/profileUtils.js';
+import PropTypes from 'prop-types';
+
+
+export default function AddUserModal({ isOpen, onClose, setAdminData }) {
+ const [isLoading, setIsLoading] = useState(false);
+ const [userData, setUserData] = useState({
+ first_name: '',
+ last_name: '',
+ role: 'admin',
+ email: '',
+ });
+ const toast = useToast();
+
+ const handleSubmit = async () => {
+ try {
+ await postProfile(userData);
+
+ toast({
+ title: 'New administrator added.',
+ description: 'New administrator added.',
+ position: 'bottom-right',
+ status: 'success',
+ duration: 9000,
+ isClosable: true,
+ });
+
+ setAdminData(prev => [...prev, userData]);
+ setUserData({
+ first_name: '',
+ last_name: '',
+ role: 'admin',
+ email: '',
+ });
+
+ onClose();
+ } catch (err) {
+ console.log('Error:', err);
+ toast({
+ title: 'Error creating new administrator.',
+ description: 'There was an error creating new administator. Please try again.',
+ status: 'error',
+ position: 'bottom-right',
+ duration: 9000,
+ isClosable: true,
+ });
+ }
+ };
+
+ const emailRegex = /\S+@\S+\.\S+/;
+ const isSubmittable =
+ userData.first_name === '' || userData.last_name === '' || !emailRegex.test(userData.email);
+
+ console.log('userData:', userData);
+
+ return (
+
+
+
+
+
+
+ Add New User
+
+
+
+
+
+
+
+ {isLoading ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ First Name
+
+ setUserData({ ...userData, first_name: e.target.value })}
+ />
+
+
+
+ Last Name
+
+ setUserData({ ...userData, last_name: e.target.value })}
+ />
+
+
+
+ Email
+
+ setUserData({ ...userData, email: e.target.value })}
+ />
+
+ Add Role
+
+
+
+ Set Account Type
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+AddUserModal.propTypes = {
+ isOpen: PropTypes.bool.isRequired,
+ onClose: PropTypes.func.isRequired,
+ setAdminData: PropTypes.func.isRequired,
+};
diff --git a/src/components/AdminModals/EditUserModal.jsx b/src/components/AdminModals/EditUserModal.jsx
new file mode 100644
index 0000000..b9ddd4f
--- /dev/null
+++ b/src/components/AdminModals/EditUserModal.jsx
@@ -0,0 +1,226 @@
+import {
+ Flex,
+ Modal,
+ ModalOverlay,
+ ModalContent,
+ ModalHeader,
+ ModalFooter,
+ ModalBody,
+ Spinner,
+ FormControl,
+ FormLabel,
+ Input,
+ Button,
+ Select,
+ useToast,
+ ModalCloseButton,
+} from '@chakra-ui/react';
+import Dropzone from '../Dropzone.tsx';
+import { useState } from 'react';
+import { updateProfile, deleteProfile } from '../../utils/profileUtils.js';
+import PropTypes from 'prop-types';
+
+export default function EditUserModal({ isOpen, onClose, selectedAdmin, setAdminData, adminData }) {
+ const [isLoading, setIsLoading] = useState(false);
+ const [currentUserData, setCurrentUserData] = useState({
+ first_name: selectedAdmin.first_name,
+ last_name: selectedAdmin.last_name,
+ role: 'admin',
+ email: selectedAdmin.email,
+ imageUrl: selectedAdmin.image_url,
+ });
+ const toast = useToast();
+
+ const editAdminDataArray = () => {
+ const arrayIndex = adminData.findIndex(admin => admin.id === selectedAdmin.id);
+
+ if (arrayIndex !== -1) {
+ const newAdminDataArray = [
+ ...adminData.slice(0, arrayIndex),
+ currentUserData,
+ ...adminData.slice(arrayIndex + 1),
+ ];
+
+ return newAdminDataArray;
+ }
+ };
+
+ const handleSubmit = async () => {
+ try {
+ await updateProfile(selectedAdmin.id, currentUserData);
+ toast({
+ title: 'Changes saved.',
+ description: 'Changes saved.',
+ position: 'bottom-right',
+ status: 'success',
+ duration: 9000,
+ isClosable: true,
+ });
+ setAdminData(editAdminDataArray());
+ onClose();
+ } catch (err) {
+ console.log(err);
+ toast({
+ title: 'Error updating administrator.',
+ description: 'There was an error updating administator. Please try again.',
+ status: 'error',
+ position: 'bottom-right',
+ duration: 9000,
+ isClosable: true,
+ });
+ }
+ };
+
+ const handleDelete = async () => {
+ try {
+ await deleteProfile(selectedAdmin.id);
+ toast({
+ title: 'Administrator removed.',
+ description: 'Administrator removed.',
+ position: 'bottom-right',
+ status: 'success',
+ duration: 9000,
+ isClosable: true,
+ });
+ setAdminData(prev => prev.filter(admin => admin.id !== selectedAdmin.id));
+ onClose();
+ } catch (err) {
+ console.log(err);
+ toast({
+ title: 'Error removing administrator.',
+ description: 'There was an error removing administator. Please try again.',
+ status: 'error',
+ position: 'bottom-right',
+ duration: 9000,
+ isClosable: true,
+ });
+ }
+ };
+
+ console.log('currentUserData:', currentUserData);
+
+ return (
+
+
+
+
+
+
+ Edit Admin
+
+
+
+
+
+
+
+ {isLoading ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ First Name
+
+
+ setCurrentUserData({ ...currentUserData, first_name: e.target.value })
+ }
+ />
+
+
+
+ Last Name
+
+
+ setCurrentUserData({ ...currentUserData, last_name: e.target.value })
+ }
+ />
+
+
+
+ Email
+
+ setCurrentUserData({ ...currentUserData, email: e.target.value })}
+ />
+
+ Add Role
+
+
+
+ Set Account Type
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+EditUserModal.propTypes = {
+ isOpen: PropTypes.bool.isRequired,
+ onClose: PropTypes.func.isRequired,
+ selectedAdmin: PropTypes.object.isRequired,
+ setAdminData: PropTypes.func.isRequired,
+ adminData: PropTypes.array.isRequired,
+};
diff --git a/src/components/Dropzone.tsx b/src/components/Dropzone.tsx
index 65a7a2c..8898eb7 100644
--- a/src/components/Dropzone.tsx
+++ b/src/components/Dropzone.tsx
@@ -9,7 +9,7 @@ import { useEffect } from 'react';
// import {FileUploadIcon} from "./Icons/EventsModalIcons.jsx"
-const Dropzone = ({ setEventData, eventData, setIsLoading }) => {
+const Dropzone = ({ setData, data, setIsLoading }) => {
const { getRootProps, getInputProps, isDragAccept, isDragReject, acceptedFiles } = useDropzone({
noKeyboard: true,
accept: { 'image/jpeg': ['.jpeg', '.jpg'], 'image/png': ['.png'] },
@@ -38,7 +38,7 @@ const Dropzone = ({ setEventData, eventData, setIsLoading }) => {
});
const imageUrl = uploadUrl.split('?')[0];
- setEventData({ ...eventData, imageUrl: imageUrl });
+ setData({ ...data, imageUrl: imageUrl });
setIsLoading(false);
return imageUrl;
@@ -63,15 +63,23 @@ const Dropzone = ({ setEventData, eventData, setIsLoading }) => {
className={dropzoneBox}
{...getRootProps()}
backgroundColor="#D9D9D9"
- minW={"37vw"}
+ minW={'37vw'}
height={'30vh'}
justify={'center'}
align={'center'}
borderRadius={'30px'}
- backgroundImage={eventData?.imageUrl}
+ backgroundImage={data?.imageUrl}
>
- } height={'62px'} width={'62px'} borderRadius={100} size={'lg'} aria-label={''} opacity={0.9}/>
+ }
+ height={'62px'}
+ width={'62px'}
+ borderRadius={100}
+ size={'lg'}
+ aria-label={''}
+ opacity={0.9}
+ />
{/*