import { useEffect, useState } from 'react'
import { Navigate } from 'react-router-dom'
import { useAuth } from '../context/AuthContext'
import api from '../utils/api'
import AdminPageNav from '../components/AdminPageNav'
const CLUB_ROLE_OPTIONS = [
{ code: 'club_admin', label: 'Vereinsadmin' },
{ code: 'trainer', label: 'Trainer' },
{ code: 'division_lead', label: 'Spartenleitung' },
{ code: 'content_editor', label: 'Inhalte bearbeiten' },
]
const TIER_OPTIONS = ['free', 'premium', 'pro', 'enterprise']
const ROLE_LABEL = {
user: 'Nutzer',
trainer: 'Trainer',
admin: 'Portal-Admin',
superadmin: 'Super-Admin',
}
function AdminUsersPage() {
const { user } = useAuth()
const isSuper = user?.role === 'superadmin'
const isPlatformAdmin = user?.role === 'admin' || user?.role === 'superadmin'
const portalRoleChoices = isSuper
? ['user', 'trainer', 'admin', 'superadmin']
: ['user', 'trainer', 'admin']
const [users, setUsers] = useState([])
const [clubs, setClubs] = useState([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState('')
const [portalDraft, setPortalDraft] = useState({})
const [assignModal, setAssignModal] = useState(null)
const [assignRoles, setAssignRoles] = useState(['trainer'])
const [clubEditModal, setClubEditModal] = useState(null)
const load = async () => {
setError('')
try {
const [u, c] = await Promise.all([api.listAdminUsers(), api.listClubs()])
setUsers(u)
setClubs(c)
const d = {}
for (const row of u) {
d[row.id] = {
role: (row.role || 'user').toLowerCase(),
tier: row.tier || 'free',
}
}
setPortalDraft(d)
} catch (e) {
setError(e.message || String(e))
} finally {
setLoading(false)
}
}
useEffect(() => {
if (!isPlatformAdmin) return
load()
}, [isPlatformAdmin])
if (!isPlatformAdmin) {
return
}
const savePortal = async (profileId) => {
const dr = portalDraft[profileId]
if (!dr) return
try {
await api.updateProfile(profileId, { role: dr.role, tier: dr.tier })
await load()
} catch (e) {
alert(e.message || String(e))
}
}
const submitAssignClub = async () => {
if (!assignModal) return
const clubId = assignModal.clubId
const profileId = assignModal.profileId
if (!clubId || !assignRoles.length) {
alert('Verein und mindestens eine Rolle wählen.')
return
}
try {
await api.addClubMember(clubId, { profile_id: profileId, roles: assignRoles })
setAssignModal(null)
setAssignRoles(['trainer'])
await load()
} catch (e) {
alert(e.message || String(e))
}
}
const saveClubMembership = async () => {
if (!clubEditModal) return
const { clubId, profileId, roles, status } = clubEditModal
try {
await api.updateClubMember(clubId, profileId, { roles, status })
setClubEditModal(null)
await load()
} catch (e) {
alert(e.message || String(e))
}
}
const removeClubMembership = async () => {
if (!clubEditModal) return
if (!confirm('Mitgliedschaft in diesem Verein wirklich entfernen?')) return
try {
await api.removeClubMember(clubEditModal.clubId, clubEditModal.profileId)
setClubEditModal(null)
await load()
} catch (e) {
alert(e.message || String(e))
}
}
return (
Portal-Nutzer & Vereine
Alle Konten mit Vereinszuordnungen. Hier kannst du die Portal-Rolle (Zugriff auf
Admin-Funktionen) und das Tier setzen sowie Nutzer explizit einem Verein mit Rollen
zuordnen.
{loading ? (
Laden…
) : error ? (
{error}
) : (
{users.map((row) => {
const tierValue = portalDraft[row.id]?.tier ?? row.tier ?? 'free'
const tierChoices = [...TIER_OPTIONS]
if (tierValue && !tierChoices.includes(tierValue)) tierChoices.unshift(tierValue)
return (
{row.name || '—'} #{row.id}
{row.email || '—'}
Verifiziert: {row.email_verified ? 'ja' : 'nein'}
Portal-Rolle
setPortalDraft((prev) => ({
...prev,
[row.id]: { ...prev[row.id], role: e.target.value, tier: prev[row.id]?.tier ?? row.tier },
}))
}
>
{portalRoleChoices.map((r) => (
{ROLE_LABEL[r] || r}
))}
Tier
setPortalDraft((prev) => ({
...prev,
[row.id]: {
...prev[row.id],
tier: e.target.value,
role: prev[row.id]?.role ?? row.role,
},
}))
}
>
{tierChoices.map((t) => (
{t}
))}
savePortal(row.id)}>
Portal speichern
{
if (!clubs.length) return
setAssignRoles(['trainer'])
setAssignModal({
profileId: row.id,
profileLabel: row.name || row.email || `#${row.id}`,
clubId: clubs[0]?.id ?? '',
})
}}
>
Verein zuweisen
Vereinsmitgliedschaften
{!row.clubs?.length ? (
Keine Zuordnung.
) : (
{row.clubs.map((c) => (
{c.name}
{c.abbreviation ? ` (${c.abbreviation})` : ''} —{' '}
{(c.roles || []).join(', ') || '—'}
{c.membership_status === 'inactive' ? (
(inaktiv)
) : null}{' '}
setClubEditModal({
clubId: c.id,
clubName: c.name,
profileId: row.id,
profileLabel: row.name || row.email,
roles: [...(c.roles || [])],
status: (c.membership_status || 'active').toLowerCase(),
})
}
>
bearbeiten
))}
)}
)
})}
)}
{assignModal && (
Verein zuweisen
{assignModal.profileLabel}
Verein
setAssignModal((prev) =>
prev ? { ...prev, clubId: e.target.value ? parseInt(e.target.value, 10) : '' } : prev
)
}
>
{clubs.map((c) => (
{c.name}
))}
Zuweisen
setAssignModal(null)}
>
Abbrechen
)}
{clubEditModal && (
Vereinsmitgliedschaft
{clubEditModal.profileLabel} → {clubEditModal.clubName}
Status
setClubEditModal((prev) => (prev ? { ...prev, status: e.target.value } : prev))
}
>
aktiv
inaktiv
Speichern
Aus Verein entfernen
setClubEditModal(null)}>
Schließen
)}
)
}
export default AdminUsersPage