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 (
{activeSection === 'employees' && (
{createdCredential && (
Login wurde angelegtDiese Zugangsdaten jetzt sicher weitergeben.
)}
Mitarbeiterkonten
Aktive Logins für das Ticketsystem
{employeesError && }
{employeesLoading ? (
Mitarbeiter werden geladen …
) : employees.length === 0 ? (
Noch keine Mitarbeiter
Lege links den ersten Login an.
) : (
| Mitarbeiter | E-Mail | Kürzel | Rolle | User-ID | Aktionen |
{employees.map((employee) => (
| {employee.displayName || '–'} |
|
{employee.shortcode || '–'} |
{employee.isAdmin ? 'Admin' : 'Mitarbeiter'} |
|
{employee.userId !== user?.$id && }
|
))}
)}
)}
)
}