boxes-fe/src/components/Admin.js

235 lines
6.7 KiB
JavaScript

// 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';
import './Admin.css'; // Import the CSS file
import {
Typography,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
Button,
Alert,
Container,
Box,
TextField,
Tab
} from '@mui/material';
export default function Admin() {
const [users, setUsers] = useState([]);
const [username, setUsername] = useState('');
const [email, setEmail] = 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 fetchUsers = async () => {
try {
const response = await axios.get(`${process.env.REACT_APP_API_URL}/admin/user`, {
headers: { Authorization: `Bearer ${localStorage.getItem('token')}` }
});
setUsers(response.data);
} catch (error) {
console.error('Error fetching users:', error);
// Optionally, set an error message
// setErrorMessage('Failed to fetch users. Please try again.');
}
};
const handleCreateUser = async (e) => {
e.preventDefault();
try {
const response = await axios.post(`${process.env.REACT_APP_API_URL}/admin/user`, {
username,
password,
email
}, {
headers: { Authorization: `Bearer ${localStorage.getItem('token')}` }
});
setUsers([...users, response.data]);
setUsername('');
setPassword('');
setEmail('');
} 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));
//setUsers(prevUsers => prevUsers.filter(user => user.id !== id));
fetchUsers();
} 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 (
<Container maxWidth="md">
<Typography variant="h4" gutterBottom>
Admin
</Typography>
<Box component="form" onSubmit={handleCreateUser} sx={{ mb: 4 }}>
<Typography variant="h6" gutterBottom>
Add New User
</Typography>
<TextField
label="Username"
variant="outlined"
value={username}
onChange={(e) => setUsername(e.target.value)}
sx={{ mr: 2 }}
/>
<TextField
label="Password"
type="password"
variant="outlined"
value={password}
onChange={(e) => setPassword(e.target.value)}
sx={{ mr: 2 }}
/>
<TextField
label="Email"
variant="outlined"
value={email}
onChange={(e) => setEmail(e.target.value)}
sx={{ mr: 2 }}
/>
<Button type="submit" sx={{ backgroundColor: PRIMARY_COLOR, borderBottom: '1px solid', borderColor: '#444', color: SECONDARY_COLOR }} variant="contained" color="primary">
Add User
</Button>
</Box>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>ID</TableCell>
<TableCell>Username</TableCell>
<TableCell>Email</TableCell>
<TableCell>Actions</TableCell>
</TableRow>
</TableHead>
<TableBody>
{users.map(user => (
<TableRow key={user.ID}>
<TableCell style={{ width: '30px' }}>{user.ID}</TableCell>
<TableCell style={{ width: '100px'}}>{user.username}</TableCell>
<TableCell style={{ width: '300px'}}>{user.email}</TableCell>
<TableCell>
<Button
variant="contained"
color="error"
onClick={() => handleDeleteUser(user.ID)}
>
Delete User
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<Box sx={{ mt: 4 }}>
<Button
variant="contained"
color="primary"
onClick={handleBackupDatabase}
sx={{ mr: 2, backgroundColor: PRIMARY_COLOR, borderBottom: '1px solid', borderColor: '#444', color: SECONDARY_COLOR }}
>
Backup Database
</Button>
<Button
variant="contained"
color="secondary"
component="label"
sx={{ backgroundColor: PRIMARY_COLOR, borderBottom: '1px solid', borderColor: '#444', color: SECONDARY_COLOR }}
>
Restore Database
<input
type="file"
hidden
ref={fileInputRef}
onChange={handleRestoreDatabase}
/>
</Button>
</Box>
</Container>
);
}