import { useState, useEffect, useCallback } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { useAuth } from '../context/AuthContext' import { useAlert } from '../context/AlertContext' import ConfirmModal from '../components/ConfirmModal' import FormField from '../components/FormField' import Forbidden from '../components/Forbidden' import useModalLock from '../hooks/useModalLock' import apiFetch from '../utils/api' const API_BASE = '/api/admin' export default function Users() { const { user: currentUser, updateUser, hasPermission } = useAuth() const alert = useAlert() const [users, setUsers] = useState([]) const [roles, setRoles] = useState([]) const [loading, setLoading] = useState(true) const [showModal, setShowModal] = useState(false) const [editingUser, setEditingUser] = useState(null) const [deleteModal, setDeleteModal] = useState({ isOpen: false, user: null }) const [deleting, setDeleting] = useState(false) const [formData, setFormData] = useState({ username: '', email: '', password: '', first_name: '', last_name: '', role_id: '', is_active: true }) useModalLock(showModal) const fetchUsers = useCallback(async () => { try { const response = await apiFetch(`${API_BASE}/users.php`, { }) const data = await response.json() if (data.success) { setUsers(data.data.users || []) setRoles(data.data.roles || []) } else { alert.error(data.error || 'Nepodařilo se načíst uživatele') } } catch { alert.error('Chyba připojení') } finally { setLoading(false) } }, []) // eslint-disable-line react-hooks/exhaustive-deps useEffect(() => { fetchUsers() }, [fetchUsers]) if (!hasPermission('users.view')) return const openCreateModal = () => { setEditingUser(null) setFormData({ username: '', email: '', password: '', first_name: '', last_name: '', role_id: roles[0]?.id || '', is_active: true }) setShowModal(true) } const openEditModal = (user) => { setEditingUser(user) setFormData({ username: user.username, email: user.email, password: '', first_name: user.first_name, last_name: user.last_name, role_id: user.role_id, is_active: user.is_active }) setShowModal(true) } const closeModal = () => { setShowModal(false) setEditingUser(null) } const handleSubmit = async (e) => { e?.preventDefault() const dataToSave = { ...formData } const wasEditing = editingUser const editingId = editingUser?.id try { const url = wasEditing ? `${API_BASE}/users.php?id=${editingId}` : `${API_BASE}/users.php` const method = wasEditing ? 'PUT' : 'POST' const response = await apiFetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(dataToSave) }) const data = await response.json() if (data.success) { if (wasEditing && currentUser && Number(editingId) === Number(currentUser.id)) { updateUser({ username: dataToSave.username, email: dataToSave.email, fullName: `${dataToSave.first_name} ${dataToSave.last_name}`.trim() }) } closeModal() await new Promise(resolve => setTimeout(resolve, 300)) alert.success(wasEditing ? 'Uživatel byl upraven' : 'Uživatel byl vytvořen') fetchUsers() } else { alert.error(data.error || 'Nepodařilo se uložit uživatele') } } catch { alert.error('Chyba připojení') } } const openDeleteModal = (user) => { setDeleteModal({ isOpen: true, user }) } const closeDeleteModal = () => { setDeleteModal({ isOpen: false, user: null }) } const handleDelete = async () => { if (!deleteModal.user) return setDeleting(true) try { const response = await apiFetch(`${API_BASE}/users.php?id=${deleteModal.user.id}`, { method: 'DELETE', }) const data = await response.json() if (data.success) { closeDeleteModal() fetchUsers() alert.success('Uživatel byl smazán') } else { alert.error(data.error || 'Nepodařilo se smazat uživatele') } } catch { alert.error('Chyba připojení') } finally { setDeleting(false) } } const toggleActive = async (user) => { try { const response = await apiFetch(`${API_BASE}/users.php?id=${user.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ is_active: !user.is_active }) }) const data = await response.json() if (data.success) { fetchUsers() alert.success(user.is_active ? 'Uživatel byl deaktivován' : 'Uživatel byl aktivován') } else { alert.error(data.error || 'Nepodařilo se změnit stav uživatele') } } catch { alert.error('Chyba připojení') } } const getRoleBadgeClass = (roleName) => { switch (roleName) { case 'admin': return 'admin-badge admin-badge-admin' default: return 'admin-badge admin-badge-viewer' } } if (loading) { return (
{[0, 1, 2, 3, 4].map(i => (
))}
) } return (

Uživatelé

Správa uživatelských účtů a oprávnění

{users.map((user) => ( ))}
Uživatel E-mail Role Stav Akce
{(user.first_name || user.username).charAt(0).toUpperCase()}
{user.first_name} {user.last_name}
@{user.username}
{user.email} {user.role_display_name || user.role_name}
{user.id !== currentUser?.id && ( )}
{showModal && (

{editingUser ? 'Upravit uživatele' : 'Přidat nového uživatele'}

setFormData({ ...formData, first_name: e.target.value })} required className="admin-form-input" /> setFormData({ ...formData, last_name: e.target.value })} required className="admin-form-input" />
setFormData({ ...formData, username: e.target.value })} required className="admin-form-input" /> setFormData({ ...formData, email: e.target.value })} required className="admin-form-input" /> setFormData({ ...formData, password: e.target.value })} required={!editingUser} className="admin-form-input" />
)}
) }