Skip to content

Instantly share code, notes, and snippets.

@feliwir
Created October 22, 2024 11:43
Show Gist options
  • Save feliwir/9bfd73ff9fda8445c76f19a5f0196cbd to your computer and use it in GitHub Desktop.
Save feliwir/9bfd73ff9fda8445c76f19a5f0196cbd to your computer and use it in GitHub Desktop.
import axios from 'axios';
import { useAuth } from './AuthContext';
// Create a function to set up the axios instance
const createAPIInstance = (serverUrl: string, token: string | null) => {
// Create an axios instance
const api = axios.create({
baseURL: serverUrl + '/api/v1/', // Use the provided server URL as the base URL
});
// Add a request interceptor to include the Authorization header
api.interceptors.request.use(
(config) => {
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
return api;
};
// Custom hook to use the axios instance in any component
export const useAPI = () => {
const { serverUrl, token } = useAuth(); // Get serverUrl and token from AuthContext
if (!serverUrl) {
throw new Error('Server URL is not set.');
}
// Create an axios instance configured with the current server URL and token
const api = createAPIInstance(serverUrl, token);
return api; // Return the axios instance for use
};
import React, { useState, useEffect } from 'react';
import {
Box,
Button,
List,
ListItem,
ListItemText,
IconButton,
Dialog,
DialogTitle,
DialogContent,
TextField,
DialogActions,
ListItemSecondaryAction,
CircularProgress,
} from '@mui/material';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete';
import AddIcon from '@mui/icons-material/Add';
import axios from 'axios'; // Axios for making API requests
import { useAuth } from '../AuthContext';
import { useAPI } from '../api';
interface User {
uid: string;
enabled: boolean;
login: string;
type: string;
display_name: string;
email: string;
created_at: string;
updated_at: string;
}
const UserManagement: React.FC = () => {
const api = useAPI(); // Access server URL and token from AuthContext
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState<boolean>(true); // Add loading state
const [openDialog, setOpenDialog] = useState(false);
const [currentUser, setCurrentUser] = useState<Partial<User> | null>(null);
// Fetch user list on component mount
useEffect(() => {
const fetchUsers = async () => {
try {
setLoading(true);
console.log('Fetching users...');
const response = await api.get(`/users`);
console.log(response.data);
setUsers(response.data);
} catch (error) {
console.error('Error fetching users', error);
} finally {
setLoading(false);
}
};
fetchUsers();
}, [api]);
const handleDeleteUser = async (uid: string) => {
try {
await api.delete(`/users/${uid}`);
setUsers(users.filter(user => user.uid !== uid));
} catch (error) {
console.error('Error deleting user', error);
}
};
const handleOpenDialog = (user?: User) => {
setCurrentUser(user || { login: '', email: '' });
setOpenDialog(true);
};
const handleCloseDialog = () => {
setOpenDialog(false);
setCurrentUser(null);
};
const handleSaveUser = async () => {
if (currentUser) {
try {
if (currentUser.uid) {
// Edit existing user
await api.put(`/users/${currentUser.uid}`, currentUser);
setUsers(users.map(u => (u.uid === currentUser.uid ? currentUser as User : u)));
} else {
console.log('Adding new user...');
// Add new user
const response = await axios.post(`/users`, currentUser);
setUsers([...users, response.data]);
}
handleCloseDialog();
} catch (error) {
console.error('Error saving user', error);
}
}
};
return (
<Box sx={{ padding: 3 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 2 }}>
<h2>User Management</h2>
<Button variant="contained" startIcon={<AddIcon />} onClick={() => handleOpenDialog()}>
Add User
</Button>
</Box>
{/* Show a progress indicator while loading */}
{loading || users == null ? (
<Box sx={{ display: 'flex', justifyContent: 'center', padding: '20px' }}>
<CircularProgress />
</Box>
) : (
<List>
{users.map(user => (
<ListItem key={user.uid}>
<ListItemText primary={user.login} secondary={user.email} />
<ListItemSecondaryAction>
<IconButton edge="end" aria-label="edit" onClick={() => handleOpenDialog(user)}>
<EditIcon />
</IconButton>
<IconButton edge="end" aria-label="delete" onClick={() => handleDeleteUser(user.uid)}>
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
))}
</List>
)}
{/* Dialog for adding/editing users */}
<Dialog open={openDialog} onClose={handleCloseDialog}>
<DialogTitle>{currentUser?.uid ? 'Edit User' : 'Add User'}</DialogTitle>
<DialogContent>
<TextField
autoFocus
margin="dense"
label="Name"
fullWidth
value={currentUser?.login || ''}
onChange={(e) => setCurrentUser({ ...currentUser, login: e.target.value })}
/>
<TextField
margin="dense"
label="Email"
fullWidth
value={currentUser?.email || ''}
onChange={(e) => setCurrentUser({ ...currentUser, email: e.target.value })}
/>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseDialog}>Cancel</Button>
<Button onClick={handleSaveUser} variant="contained">
{currentUser?.uid ? 'Save Changes' : 'Add User'}
</Button>
</DialogActions>
</Dialog>
</Box>
);
};
export default UserManagement;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment