import { Component, createEffect, createSignal, For } from 'solid-js' import type { AdminUserInfo } from '../graphql/generated/schema' import styles from '../styles/Form.module.css' import Button from '../ui/Button' import Modal from '../ui/Modal' 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: 'Полный доступ к системе' }, { id: 'editor', name: 'Редактор', description: 'Редактирование публикаций и управление сообществом' }, { id: 'expert', name: 'Эксперт', description: 'Добавление доказательств и опровержений, управление темами' }, { id: 'author', name: 'Автор', description: 'Создание и редактирование своих публикаций' }, { id: 'reader', name: 'Читатель', description: 'Чтение и комментирование' } ] const UserEditModal: Component = (props) => { const [formData, setFormData] = createSignal({ email: props.user.email || '', name: props.user.name || '', slug: props.user.slug || '', roles: props.user.roles || [] }) const [loading, setLoading] = createSignal(false) const [errors, setErrors] = createSignal>({}) // Сброс формы при открытии модалки createEffect(() => { if (props.isOpen) { setFormData({ email: props.user.email || '', name: props.user.name || '', slug: props.user.slug || '', roles: props.user.roles || [] }) setErrors({}) } }) const validateForm = () => { const newErrors: Record = {} const data = formData() // Валидация email if (!data.email.trim()) { newErrors.email = 'Email обязателен' } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) { newErrors.email = 'Некорректный формат email' } // Валидация имени if (!data.name.trim()) { newErrors.name = 'Имя обязательно' } // Валидация slug if (!data.slug.trim()) { newErrors.slug = 'Slug обязателен' } else if (!/^[a-z0-9-_]+$/.test(data.slug)) { newErrors.slug = 'Slug может содержать только латинские буквы, цифры, дефисы и подчеркивания' } // Валидация ролей if (data.roles.length === 0) { newErrors.roles = 'Выберите хотя бы одну роль' } setErrors(newErrors) return Object.keys(newErrors).length === 0 } const updateField = (field: string, value: string) => { setFormData((prev) => ({ ...prev, [field]: value })) // Очищаем ошибку для поля при изменении setErrors((prev) => ({ ...prev, [field]: '' })) } const handleRoleToggle = (roleId: string) => { const current = formData().roles const newRoles = current.includes(roleId) ? current.filter((r) => r !== roleId) : [...current, roleId] setFormData((prev) => ({ ...prev, roles: newRoles })) setErrors((prev) => ({ ...prev, roles: '' })) } const handleSave = async () => { if (!validateForm()) { return } setLoading(true) try { await props.onSave({ id: props.user.id, email: formData().email, name: formData().name, slug: formData().slug, roles: formData().roles }) props.onClose() } catch (error) { console.error('Error saving user:', error) setErrors({ general: 'Ошибка при сохранении данных пользователя' }) } finally { setLoading(false) } } const formatDate = (timestamp?: number | null) => { if (!timestamp) return '—' return new Date(timestamp * 1000).toLocaleString('ru-RU') } const footer = ( <> ) return (
{errors().general && (
{errors().general}
)} {/* Информационная секция */}

Системная информация

ID: {props.user.id}
Дата регистрации: {formatDate(props.user.created_at)}
Последняя активность: {formatDate(props.user.last_seen)}
{/* Основные данные */}

Основные данные

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" />
Используется в URL профиля. Только латинские буквы, цифры, дефисы и подчеркивания.
{errors().slug &&
{errors().slug}
}
{/* Роли */}

Роли *

{(role) => ( )}
{errors().roles &&
{errors().roles}
}
) } export default UserEditModal