import { useState } from 'react'; import { Header } from '../components/Header'; import { AuthGuard } from '../components/AuthGuard'; import { UserFormData } from '../types/auth'; import { useUserManagement } from '../hooks/useUserManagement'; import { ImagePlus, X, UserPlus, Pencil } from 'lucide-react'; import { imageResolutions } from '../config/imageResolutions'; import { CategoryIds, CategoryTitles, CityIds, CityTitles } from "../types"; import axios from "axios"; import { useAuthStore } from "../stores/authStore"; //import { AuthorModal } from "./AuthorModal"; const initialFormData: UserFormData = { id: '', email: '', password: '', displayName: '', avatarUrl: '/images/avatar.jpg' }; export function UserManagementPage() { const { users, selectedUser, loading, error, setSelectedUser, handlePermissionChange, handleCityChange, createUser, updateUser, // deleteUser } = useUserManagement(); const [showCreateModal, setShowCreateModal] = useState(false); const [showEditModal, setShowEditModal] = useState(false); const [formData, setFormData] = useState(initialFormData); const [formError, setFormError] = useState(null); const { user } = useAuthStore(); const handleAvatarUpload = async (event: React.ChangeEvent, userId: string) => { const file = event.target.files?.[0]; if (!file) return; try { const resolution = imageResolutions.find(r => r.id === 'thumbnail'); if (!resolution) throw new Error('Invalid resolution'); const formData = new FormData(); formData.append('file', file); formData.append('resolutionId', resolution.id); formData.append('folder', 'users/' + userId); // Отправка запроса на сервер const response = await axios.post('/api/images/upload-url', formData, { headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${localStorage.getItem('token')}`, // Передача токена аутентификации }, }); setFormData(prev => ({ ...prev, avatarUrl: response.data?.fileUrl })); } catch (error) { setFormError('Ошибка загрузки аватара. Повторите попытку.'); console.error('Ошибка загрузки:', error); } }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setFormError(null); try { if (showCreateModal) { await createUser(formData); setShowCreateModal(false); } else if (showEditModal && selectedUser) { await updateUser(selectedUser.id, formData); setShowEditModal(false); } setFormData(initialFormData); } catch (error) { setFormError(error instanceof Error ? error.message : 'Произошла ошибка'); } }; if (loading) { return (
); } return (

Управление пользователями

{error && (
{error}
)}
{/* Users List */}

Пользователи

    {users.map((user) => (
  • {user.displayName}
    {user.displayName}
    {user.email}
  • ))}
{/* Permissions Editor */} {selectedUser && (

Редактирование прав пользователя "{selectedUser.displayName}"

{/* Categories Permissions */}

Права по категориям

{CategoryIds.map((categoryId) => (

{CategoryTitles[categoryId]}

{(['create', 'edit', 'delete'] as const).map((action) => ( ))}
))}
{/* Cities Access */}

Разрешения для города

{CityIds.map((city) => ( ))}
)}
{/* Create/Edit User Modal */} {((showCreateModal || showEditModal) && user?.permissions.isAdmin) && (

{showCreateModal ? 'Создание нового пользователя' : 'Редактирование'}

{formError && (
{formError}
)}
Аватар пользователя
setFormData(prev => ({ ...prev, displayName: e.target.value }))} autoComplete="off" className="px-2 py-1 mt-1 block w-full rounded-lg border border-gray-300 shadow-sm hover:border-blue-300 focus:border-blue-500 focus:ring-4 focus:ring-blue-100 transition-all duration-200" required />
setFormData(prev => ({ ...prev, email: e.target.value }))} autoComplete="off" className="px-2 py-1 mt-1 block w-full rounded-lg border border-gray-300 shadow-sm hover:border-blue-300 focus:border-blue-500 focus:ring-4 focus:ring-blue-100 transition-all duration-200" required />
setFormData(prev => ({ ...prev, password: e.target.value }))} autoComplete="new-password" placeholder={showEditModal ? 'Оставьте пустым, чтобы не менять' : ''} className="px-2 py-1 mt-1 block w-full rounded-lg border border-gray-300 shadow-sm hover:border-blue-300 focus:border-blue-500 focus:ring-4 focus:ring-blue-100 transition-all duration-200" required={!showEditModal} />
)}
); }