import { useState } from 'react' import { FaFloppyDisk, FaPlus, FaSpinner, FaTrash, FaXmark, } from 'react-icons/fa6' import { FaEdit } from 'react-icons/fa' import CopyableCredential from '../components/CopyableCredential' import { useAuth } from '../context/AuthContext' import { useEmployees } from '../hooks/useEmployees' import './AdminPage.css' const EMPTY_EMPLOYEE = { displayName: '', email: '', password: '', shortcode: '', isAdmin: false, } function Notice({ notice }) { if (!notice?.text) return null return
{notice.text}
} export default function AdminPage() { const { user, isAdmin } = useAuth() const { employees, loading: employeesLoading, error: employeesError, createEmployee, updateEmployee, deleteEmployee, } = useEmployees() // Kunden werden unter "Kunden" gepflegt (Anlegen und Loeschen fuer Admins dort) const [activeSection, setActiveSection] = useState('employees') const [employeeForm, setEmployeeForm] = useState(EMPTY_EMPLOYEE) const [editingEmployee, setEditingEmployee] = useState(null) const [employeeBusy, setEmployeeBusy] = useState(false) const [createdCredential, setCreatedCredential] = useState(null) const [notice, setNotice] = useState(null) const showNotice = (type, text) => { setNotice({ type, text }) window.setTimeout(() => setNotice(null), 4500) } if (!isAdmin) { return (
403

Zugriff verweigert

Für diesen Bereich ist ein Admin-Account erforderlich.

) } const resetEmployeeForm = () => { setEmployeeForm(EMPTY_EMPLOYEE) setEditingEmployee(null) } const submitEmployee = async (event) => { event.preventDefault() if (!employeeForm.displayName.trim() || !employeeForm.email.trim()) { showNotice('error', 'Name und E-Mail sind erforderlich.') return } if (!editingEmployee && employeeForm.password.length < 8) { showNotice('error', 'Das Passwort muss mindestens 8 Zeichen haben.') return } if (editingEmployee && employeeForm.password && employeeForm.password.length < 8) { showNotice('error', 'Ein neues Passwort muss mindestens 8 Zeichen haben.') return } setEmployeeBusy(true) const result = editingEmployee ? await updateEmployee(editingEmployee, employeeForm) : await createEmployee(employeeForm) setEmployeeBusy(false) if (!result.success) { showNotice('error', result.error || 'Mitarbeiter konnte nicht gespeichert werden.') return } if (!editingEmployee) { setCreatedCredential({ email: employeeForm.email.trim(), password: employeeForm.password, }) } showNotice('success', editingEmployee ? 'Mitarbeiter aktualisiert.' : 'Mitarbeiter angelegt. Der Login ist sofort aktiv.') resetEmployeeForm() } const editEmployee = (employee) => { setEditingEmployee(employee.$id) setEmployeeForm({ displayName: employee.displayName || '', email: employee.email || '', password: '', shortcode: employee.shortcode || '', isAdmin: Boolean(employee.isAdmin), }) } const removeEmployee = async (employee) => { if (!window.confirm(`${employee.displayName || employee.email} und dessen Login wirklich löschen?`)) return const result = await deleteEmployee(employee.$id) showNotice( result.success ? 'success' : 'error', result.success ? 'Mitarbeiter und Login gelöscht.' : result.error ) } return (
Systemverwaltung

Admin

Mitarbeiter und ihre Zugänge verwalten. Kunden pflegst du unter „Kunden“.

Angemeldet als {user?.name || user?.email}
{activeSection === 'employees' && (
{createdCredential && (
Login wurde angelegtDiese Zugangsdaten jetzt sicher weitergeben.
)}

{editingEmployee ? 'Mitarbeiter bearbeiten' : 'Mitarbeiter anlegen'}

Die User-ID wird automatisch vergeben.
{editingEmployee && }

Mitarbeiterkonten

Aktive Logins für das Ticketsystem
{employeesError && } {employeesLoading ? (
Mitarbeiter werden geladen …
) : employees.length === 0 ? (

Noch keine Mitarbeiter

Lege links den ersten Login an.

) : (
{employees.map((employee) => ( ))}
MitarbeiterE-MailKürzelRolleUser-IDAktionen
{employee.displayName || '–'} {employee.shortcode || '–'} {employee.isAdmin ? 'Admin' : 'Mitarbeiter'} {employee.userId !== user?.$id && }
)}
)}
) }