From 487aa5154e8c588e5bd6b9f2889fbd0c436fb336 Mon Sep 17 00:00:00 2001 From: Steve White Date: Thu, 17 Oct 2024 00:08:41 -0500 Subject: [PATCH] User and database administration --- src/App.js | 5 ++ src/components/Admin.js | 126 +++++++++++++++++++++++++++++++++++++++ src/components/Navbar.js | 1 + 3 files changed, 132 insertions(+) create mode 100644 src/components/Admin.js diff --git a/src/App.js b/src/App.js index 2c12277..2393a5e 100644 --- a/src/App.js +++ b/src/App.js @@ -6,6 +6,7 @@ import Login from './components/Login'; import Boxes from './components/Boxes'; import Items from './components/Items'; import Navbar from './components/Navbar'; // Correct import here +import Admin from './components/Admin'; // Correct import here import { createContext } from 'react'; import './styles.css' @@ -52,6 +53,10 @@ function AppRoutes({ token, setToken }) { path="/boxes/:id/items" element={token ? : } /> + : } + /> } /> diff --git a/src/components/Admin.js b/src/components/Admin.js new file mode 100644 index 0000000..5f4f578 --- /dev/null +++ b/src/components/Admin.js @@ -0,0 +1,126 @@ +// src/components/Admin.js +import React, { useState, useEffect, useRef } from 'react'; +import axios from 'axios'; +import { Link, useNavigate } from 'react-router-dom'; +import { PRIMARY_COLOR, SECONDARY_COLOR } from '../App'; + +export default function Admin() { + const [users, setUsers] = useState([]); + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + const navigate = useNavigate(); + const fileInputRef = useRef(null); + + + useEffect(() => { + axios.get(`${process.env.REACT_APP_API_URL}/admin/user`, { + headers: { Authorization: `Bearer ${localStorage.getItem('token')}` } + }) + .then(response => { + setUsers(response.data); + }) + .catch(error => { + console.error(error); + }); + }, []); + + const handleCreateUser = async (e) => { + e.preventDefault(); + try { + const response = await axios.post(`${process.env.REACT_APP_API_URL}/admin/user`, { + username, + password + }, { + headers: { Authorization: `Bearer ${localStorage.getItem('token')}` } + }); + setUsers([...users, response.data]); + setUsername(''); + setPassword(''); + } catch (error) { + console.error(error); + } + }; + + const handleDeleteUser = async (id) => { + try { + await axios.delete(`${process.env.REACT_APP_API_URL}/admin/user/${id}`, { + headers: { Authorization: `Bearer ${localStorage.getItem('token')}` } + }); + setUsers(users.filter(user => user.id !== id)); + } catch (error) { + console.error(error); + } + }; + + const handleBackupDatabase = async () => { + try { + const response = await axios.get(`${process.env.REACT_APP_API_URL}/admin/db`, { + headers: { Authorization: `Bearer ${localStorage.getItem('token')}` }, + responseType: 'blob' + }); + const blob = new Blob([response.data], { type: 'application/x-sqlite3' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = 'database.db'; + a.click(); + } catch (error) { + console.error(error); + } + }; + + const handleRestoreDatabase = async (e) => { + e.preventDefault(); + try { + const file = fileInputRef.current.files[0]; + const formData = new FormData(); + formData.append('database', file); + console.log("sending request to restore db") + + const token = localStorage.getItem('token'); + if (!token) { + throw new Error('No token found in local storage'); + } + + const response = await axios.post(`${process.env.REACT_APP_API_URL}/admin/db`, formData, { + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'multipart/form-data' + } + }); + + if (response.status === 200) { + alert('Database restored successfully'); + navigate('/admin'); + } else { + throw new Error(`Failed to restore database: ${response.statusText}`); + } + } catch (error) { + console.error(error); + } + }; + + return ( +
+

Admin

+
    + {users.map(user => ( +
  • + {user.username} + +
  • + ))} +
+
+ setUsername(e.target.value)} placeholder="Username" /> + setPassword(e.target.value)} placeholder="Password" /> + +
+ +
+ + +
+
+ ); +} \ No newline at end of file diff --git a/src/components/Navbar.js b/src/components/Navbar.js index 5ddb1af..2a40079 100644 --- a/src/components/Navbar.js +++ b/src/components/Navbar.js @@ -36,6 +36,7 @@ export default function Navbar() { +