import { Component, createEffect, createSignal, For } from 'solid-js' import type { AdminUserInfo } from '../graphql/generated/schema' import formStyles from '../styles/Form.module.css' import Button from '../ui/Button' import Modal from '../ui/Modal' // Список администраторских email const ADMIN_EMAILS = ['welcome@discours.io'] export interface UserEditModalProps { user: AdminUserInfo isOpen: boolean onClose: () => void onSave: (userData: { id: number email?: string name?: string slug?: string roles: string }) => Promise } // Доступные роли в системе const AVAILABLE_ROLES = [ { id: 'admin', name: 'Системный администратор', description: 'Администраторы определяются автоматически по настройкам сервера', emoji: '🪄' }, { id: 'editor', name: 'Редактор', description: 'Редактирование публикаций и управление сообществом', emoji: '✒️' }, { id: 'expert', name: 'Эксперт', description: 'Добавление доказательств и опровержений, управление темами', emoji: '🔬' }, { id: 'author', name: 'Автор', description: 'Создание и редактирование своих публикаций', emoji: '📝' }, { id: 'reader', name: 'Читатель', description: 'Чтение и комментирование', emoji: '📖' } ] const UserEditModal: Component = (props) => { const [formData, setFormData] = createSignal({ id: props.user.id, email: props.user.email || '', name: props.user.name || '', slug: props.user.slug || '', roles: props.user.roles || [] }) const [errors, setErrors] = createSignal>({}) const [loading, setLoading] = createSignal(false) // Проверяем, является ли пользователь администратором по ролям, которые приходят с сервера const isAdmin = () => { const roles = formData().roles return roles.includes('admin') || (props.user.email ? ADMIN_EMAILS.includes(props.user.email) : false) } // Получаем информацию о роли по ID const getRoleInfo = (roleId: string) => { return AVAILABLE_ROLES.find((role) => role.id === roleId) || { name: roleId, emoji: '👤' } } // Обновляем поле формы const updateField = (field: keyof ReturnType, value: string) => { setFormData((prev) => ({ ...prev, [field]: value })) if (errors()[field]) { setErrors((prev) => { const newErrors = { ...prev } delete newErrors[field] return newErrors }) } } // Обновляем форму при изменении пользователя createEffect(() => { if (props.user) { setFormData({ id: props.user.id, email: props.user.email || '', name: props.user.name || '', slug: props.user.slug || '', roles: props.user.roles || [] }) setErrors({}) } }) const handleRoleToggle = (roleId: string) => { if (roleId === 'admin') { return } setFormData((prev) => { const currentRoles = prev.roles || [] const newRoles = currentRoles.includes(roleId) ? currentRoles.filter((r: string) => r !== roleId) : [...currentRoles, roleId] return { ...prev, roles: newRoles } }) if (errors().roles) { setErrors((prev) => { const newErrors = { ...prev } delete newErrors.roles return newErrors }) } } const validateForm = (): boolean => { const newErrors: Record = {} const data = formData() if (!data.email.trim() || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email.trim())) { newErrors.email = 'Неверный формат email' } if (!data.name.trim() || data.name.trim().length < 2) { newErrors.name = 'Имя должно содержать минимум 2 символа' } if (!data.slug.trim() || !/^[a-z0-9_-]+$/.test(data.slug.trim())) { newErrors.slug = 'Slug может содержать только латинские буквы, цифры, дефисы и подчеркивания' } if (!isAdmin() && (data.roles || []).filter((role: string) => role !== 'admin').length === 0) { newErrors.roles = 'Выберите хотя бы одну роль' } setErrors(newErrors) return Object.keys(newErrors).length === 0 } const handleSave = async () => { if (!validateForm()) { return } setLoading(true) try { await props.onSave({ ...formData(), roles: (formData().roles || []).join(',') }) props.onClose() } catch (error) { console.error('Ошибка при сохранении пользователя:', error) setErrors({ general: 'Ошибка при сохранении пользователя' }) } finally { setLoading(false) } } return (
{/* Основные данные */}
updateField('email', e.currentTarget.value)} disabled={loading()} placeholder="user@example.com" /> {errors().email && (
⚠️ {errors().email}
)}
updateField('name', e.currentTarget.value)} disabled={loading()} placeholder="Иван Иванов" /> {errors().name && (
⚠️ {errors().name}
)}
updateField('slug', e.currentTarget.value.toLowerCase())} disabled={loading()} placeholder="ivan-ivanov" /> {errors().slug && (
⚠️ {errors().slug}
)}
{/* Роли */}
{(role) => { const isAdminRole = role.id === 'admin' const isSelected = (formData().roles || []).includes(role.id) const isDisabled = isAdminRole const roleInfo = getRoleInfo(role.id) return ( ) }}
{!isAdmin() && errors().roles && (
⚠️ {errors().roles}
)}
💡 Системные роли (администратор) назначаются автоматически и не могут быть изменены вручную. {!isAdmin() && ' Выберите дополнительные роли для пользователя - минимум одна роль обязательна.'}
{/* Общая ошибка */} {errors().general && (
⚠️ {errors().general}
)} {/* Компактные кнопки действий */}
) } export default UserEditModal