172 lines
4.8 KiB
JavaScript
172 lines
4.8 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { userApi } from '../api/users';
|
|
|
|
const AdminUsersPage = () => {
|
|
const [users, setUsers] = useState([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState('');
|
|
const [inviteLink, setInviteLink] = useState('');
|
|
const [isCopied, setIsCopied] = useState(false);
|
|
|
|
const generateInviteLink = async () => {
|
|
try {
|
|
setError('');
|
|
const invitation = await userApi.createInvitation();
|
|
const newInviteLink = `${window.location.origin}/register?invite=${invitation.token}`;
|
|
setInviteLink(newInviteLink);
|
|
setIsCopied(false);
|
|
} catch (error) {
|
|
setError('Erreur lors de la génération du lien d\'invitation');
|
|
console.error(error);
|
|
}
|
|
};
|
|
|
|
const copyToClipboard = () => {
|
|
if (inviteLink) {
|
|
navigator.clipboard.writeText(inviteLink).then(() => {
|
|
setIsCopied(true);
|
|
setTimeout(() => setIsCopied(false), 2000);
|
|
}).catch((error) => {
|
|
setError('Impossible de copier le lien.');
|
|
console.error(error);
|
|
});
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
const loadUsers = async () => {
|
|
try {
|
|
setLoading(true);
|
|
const users = await userApi.getUsers();
|
|
setUsers(users);
|
|
} catch (requestError) {
|
|
setError('Erreur lors du chargement des utilisateurs');
|
|
console.error(requestError);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
loadUsers();
|
|
}, []);
|
|
|
|
const handleDeleteUser = async (userId) => {
|
|
if (!window.confirm('Êtes-vous sûr de vouloir supprimer cet utilisateur ?')) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await userApi.deleteUser(userId);
|
|
setUsers(users.filter(user => user.id !== userId));
|
|
} catch (err) {
|
|
setError('Erreur lors de la suppression de l\'utilisateur');
|
|
console.error(err);
|
|
}
|
|
};
|
|
|
|
const handleMakeAdmin = async (userId) => {
|
|
if (!window.confirm('Êtes-vous sûr de vouloir promouvoir cet utilisateur ?')) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await userApi.promoteUser(userId);
|
|
setUsers(users.map(user =>
|
|
user.id === userId ? { ...user, is_admin: true } : user
|
|
));
|
|
} catch (err) {
|
|
setError('Erreur lors de la promotion de l\'utilisateur');
|
|
console.error(err);
|
|
}
|
|
};
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="card admin-page">
|
|
<h2>Gestion des comptes</h2>
|
|
<p>Chargement des utilisateurs...</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="card admin-page">
|
|
<h2>Gestion des comptes</h2>
|
|
{error && <div className="alert alert-danger">{error}</div>}
|
|
|
|
<div className="admin-toolbar">
|
|
<button
|
|
onClick={generateInviteLink}
|
|
className="btn btn-primary"
|
|
>
|
|
Inviter un utilisateur
|
|
</button>
|
|
{inviteLink && (
|
|
<div className="invite-link-box">
|
|
<input
|
|
type="text"
|
|
value={inviteLink}
|
|
readOnly
|
|
className="invite-link-input"
|
|
/>
|
|
<button
|
|
onClick={copyToClipboard}
|
|
className="btn btn-secondary"
|
|
>
|
|
{isCopied ? 'Copié!' : 'Copier'}
|
|
</button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="table-responsive">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Nom d'utilisateur</th>
|
|
<th>Rôle</th>
|
|
<th>Inscrit le</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{users.map((user) => (
|
|
<tr key={user.id}>
|
|
<td>{user.username}</td>
|
|
<td>
|
|
{user.is_admin ? (
|
|
<span style={{ color: 'var(--accent)', fontWeight: '500' }}>Administrateur</span>
|
|
) : (
|
|
<span style={{ color: 'var(--text)', fontWeight: '500' }}>Utilisateur</span>
|
|
)}
|
|
</td>
|
|
<td>{new Date(user.date_joined).toLocaleDateString('fr-FR')}</td>
|
|
<td>
|
|
<div className="btn-group">
|
|
{!user.is_admin && (
|
|
<button
|
|
onClick={() => handleMakeAdmin(user.id)}
|
|
className="btn btn-secondary btn-small"
|
|
>
|
|
Promouvoir
|
|
</button>
|
|
)}
|
|
<button
|
|
onClick={() => handleDeleteUser(user.id)}
|
|
className="btn btn-danger btn-small"
|
|
>
|
|
Supprimer
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default AdminUsersPage;
|