103 lines
3.3 KiB
JavaScript
103 lines
3.3 KiB
JavaScript
import { useState, useEffect } from 'react'
|
|
import { useUser } from '../context/UserContext'
|
|
import { getUsers } from '../api'
|
|
|
|
export default function UserManagement({ onClose }) {
|
|
const { token } = useUser()
|
|
const [users, setUsers] = useState([])
|
|
const [loading, setLoading] = useState(true)
|
|
const [error, setError] = useState('')
|
|
|
|
useEffect(() => {
|
|
const fetchUsers = async () => {
|
|
try {
|
|
const data = await getUsers(token)
|
|
setUsers(data)
|
|
setError('')
|
|
} catch (err) {
|
|
setError('Fehler beim Laden der Benutzer')
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
fetchUsers()
|
|
}, [token])
|
|
|
|
const roleLabels = {
|
|
user: 'Viewer',
|
|
moderator: 'Operator',
|
|
superadmin: 'Admin'
|
|
}
|
|
|
|
const roleColors = {
|
|
user: 'text-neutral-400',
|
|
moderator: 'text-blue-400',
|
|
superadmin: 'text-yellow-400'
|
|
}
|
|
|
|
const getAvatarUrl = (user) => {
|
|
if (!user.discord_id || !user.avatar) return null
|
|
return `https://cdn.discordapp.com/avatars/${user.discord_id}/${user.avatar}.png?size=64`
|
|
}
|
|
|
|
return (
|
|
<div className="modal-backdrop fade-in" onClick={onClose}>
|
|
<div className="modal fade-in-scale" style={{ maxWidth: '32rem' }} onClick={(e) => e.stopPropagation()}>
|
|
<div className="modal-header">
|
|
<h2 className="modal-title">Benutzerliste</h2>
|
|
<button onClick={onClose} className="btn btn-ghost">
|
|
Schließen
|
|
</button>
|
|
</div>
|
|
|
|
<div className="modal-body">
|
|
{error && (
|
|
<div className="alert alert-error mb-4">{error}</div>
|
|
)}
|
|
|
|
<p className="text-sm text-neutral-500 mb-4">
|
|
Benutzer, die sich über Discord angemeldet haben. Rollen werden durch Discord-Rollen bestimmt.
|
|
</p>
|
|
|
|
{loading ? (
|
|
<div className="text-center py-4 text-neutral-400">Laden...</div>
|
|
) : users.length === 0 ? (
|
|
<div className="text-center py-4 text-neutral-500">Noch keine Benutzer angemeldet</div>
|
|
) : (
|
|
<div className="space-y-2">
|
|
{users.map((user) => (
|
|
<div key={user.id} className="card p-3 flex items-center gap-3">
|
|
{getAvatarUrl(user) ? (
|
|
<img
|
|
src={getAvatarUrl(user)}
|
|
alt=""
|
|
className="w-10 h-10 rounded-full"
|
|
/>
|
|
) : (
|
|
<div className="w-10 h-10 rounded-full bg-neutral-700 flex items-center justify-center">
|
|
<span className="text-neutral-400 text-sm">
|
|
{user.username?.charAt(0)?.toUpperCase()}
|
|
</span>
|
|
</div>
|
|
)}
|
|
|
|
<div className="flex-1 min-w-0">
|
|
<div className="text-white font-medium truncate">{user.username}</div>
|
|
<div className="text-xs text-neutral-500 truncate">
|
|
{user.discord_id}
|
|
</div>
|
|
</div>
|
|
|
|
<span className={`text-sm font-medium ${roleColors[user.role]}`}>
|
|
{roleLabels[user.role]}
|
|
</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|