import { createEffect, createSignal, Show } from 'solid-js' import { useData } from '../context/data' import type { Role } from '../graphql/generated/schema' import { GET_COMMUNITY_ROLE_SETTINGS_QUERY, GET_COMMUNITY_ROLES_QUERY, UPDATE_COMMUNITY_ROLE_SETTINGS_MUTATION } from '../graphql/queries' import formStyles from '../styles/Form.module.css' import styles from '../styles/Modal.module.css' import Button from '../ui/Button' import Modal from '../ui/Modal' import RoleManager from '../ui/RoleManager' interface Community { id: number name: string slug: string desc?: string pic?: string } interface CommunityEditModalProps { isOpen: boolean community: Community | null onClose: () => void onSave: (communityData: Partial) => Promise } interface RoleSettings { default_roles: string[] available_roles: string[] } interface CustomRole { id: string name: string description: string icon: string } const STANDARD_ROLES = [ { id: 'reader', name: 'Читатель', description: 'Может читать и комментировать', icon: '👁️' }, { id: 'author', name: 'Автор', description: 'Может создавать публикации', icon: '✍️' }, { id: 'artist', name: 'Художник', description: 'Может быть credited artist', icon: '🎨' }, { id: 'expert', name: 'Эксперт', description: 'Может добавлять доказательства', icon: '🧠' }, { id: 'editor', name: 'Редактор', description: 'Может модерировать контент', icon: '📝' }, { id: 'admin', name: 'Администратор', description: 'Полные права', icon: '👑' } ] const CommunityEditModal = (props: CommunityEditModalProps) => { const { queryGraphQL } = useData() const [formData, setFormData] = createSignal>({}) const [roleSettings, setRoleSettings] = createSignal({ default_roles: ['reader'], available_roles: ['reader', 'author', 'artist', 'expert', 'editor', 'admin'] }) const [customRoles, setCustomRoles] = createSignal([]) const [errors, setErrors] = createSignal>({}) const [activeTab, setActiveTab] = createSignal<'basic' | 'roles'>('basic') const [loading, setLoading] = createSignal(false) // Инициализация формы при открытии createEffect(() => { if (props.isOpen) { if (props.community) { setFormData({ name: props.community.name || '', slug: props.community.slug || '', desc: props.community.desc || '', pic: props.community.pic || '' }) void loadRoleSettings() } else { setFormData({ name: '', slug: '', desc: '', pic: '' }) setRoleSettings({ default_roles: ['reader'], available_roles: ['reader', 'author', 'artist', 'expert', 'editor', 'admin'] }) } setErrors({}) setActiveTab('basic') setCustomRoles([]) } }) const loadRoleSettings = async () => { if (!props.community?.id) return try { const data = await queryGraphQL(GET_COMMUNITY_ROLE_SETTINGS_QUERY, { community_id: props.community.id }) if (data?.adminGetCommunityRoleSettings && !data.adminGetCommunityRoleSettings.error) { setRoleSettings({ default_roles: data.adminGetCommunityRoleSettings.default_roles, available_roles: data.adminGetCommunityRoleSettings.available_roles }) } // Загружаем все роли сообщества для получения произвольных const rolesData = await queryGraphQL(GET_COMMUNITY_ROLES_QUERY, { community: props.community.id }) if (rolesData?.adminGetRoles) { // Фильтруем только произвольные роли (не стандартные) const standardRoleIds = STANDARD_ROLES.map((r) => r.id) const customRolesList = rolesData.adminGetRoles .filter((role: Role) => !standardRoleIds.includes(role.id)) .map((role: Role) => ({ id: role.id, name: role.name, description: role.description || '', icon: '🔖' // Пока иконки не хранятся в БД })) setCustomRoles(customRolesList) } } catch (error) { console.error('Ошибка загрузки настроек ролей:', error) } } const validateForm = (): boolean => { const newErrors: Record = {} const data = formData() if (!data.name?.trim()) { newErrors.name = 'Название обязательно' } if (!data.slug?.trim()) { newErrors.slug = 'Слаг обязательный' } else if (!/^[a-z0-9-]+$/.test(data.slug)) { newErrors.slug = 'Слаг может содержать только латинские буквы, цифры и дефисы' } // Валидация ролей const roleSet = roleSettings() if (roleSet.default_roles.length === 0) { newErrors.roles = 'Должна быть хотя бы одна дефолтная роль' } const invalidDefaults = roleSet.default_roles.filter((role) => !roleSet.available_roles.includes(role)) if (invalidDefaults.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 handleSave = async () => { if (!validateForm()) { return } setLoading(true) try { // Сохраняем основные данные сообщества await props.onSave(formData()) // Если редактируем существующее сообщество, сохраняем настройки ролей if (props.community?.id) { const roleData = await queryGraphQL(UPDATE_COMMUNITY_ROLE_SETTINGS_MUTATION, { community_id: props.community.id, default_roles: roleSettings().default_roles, available_roles: roleSettings().available_roles }) if (!roleData?.adminUpdateCommunityRoleSettings?.success) { console.error( 'Ошибка сохранения настроек ролей:', roleData?.adminUpdateCommunityRoleSettings?.error ) } } } catch (error) { console.error('Ошибка сохранения:', error) } finally { setLoading(false) } } const isCreating = () => props.community === null const modalTitle = () => isCreating() ? 'Создание нового сообщества' : `Редактирование сообщества: ${props.community?.name || ''}` return (
{/* Табы */}
{/* Контент табов */}
updateField('name', e.currentTarget.value)} placeholder="Введите название сообщества" /> ⚠️ {errors().name}
updateField('slug', e.currentTarget.value)} placeholder="community-slug" disabled={!isCreating()} /> ⚠️ {errors().slug} 💡 Слаг нельзя изменить после создания