import { Component, createSignal, For, onMount, Show } from 'solid-js' import { CREATE_COLLECTION_MUTATION, DELETE_COLLECTION_MUTATION, UPDATE_COLLECTION_MUTATION } from '../graphql/mutations' import { GET_COLLECTIONS_QUERY } from '../graphql/queries' import styles from '../styles/Table.module.css' import Button from '../ui/Button' import Modal from '../ui/Modal' /** * Интерфейс для коллекции */ interface Collection { id: number slug: string title: string desc?: string pic: string amount: number created_at: number published_at?: number created_by: { id: number name: string email: string } } interface CollectionsRouteProps { onError: (error: string) => void onSuccess: (message: string) => void } /** * Компонент для управления коллекциями */ const CollectionsRoute: Component = (props) => { const [collections, setCollections] = createSignal([]) const [loading, setLoading] = createSignal(false) const [editModal, setEditModal] = createSignal<{ show: boolean; collection: Collection | null }>({ show: false, collection: null }) const [deleteModal, setDeleteModal] = createSignal<{ show: boolean; collection: Collection | null }>({ show: false, collection: null }) const [createModal, setCreateModal] = createSignal(false) // Форма для редактирования/создания const [formData, setFormData] = createSignal({ slug: '', title: '', desc: '', pic: '' }) /** * Загружает список всех коллекций */ const loadCollections = async () => { setLoading(true) try { const response = await fetch('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: GET_COLLECTIONS_QUERY }) }) const result = await response.json() if (result.errors) { throw new Error(result.errors[0].message) } setCollections(result.data.get_collections_all || []) } catch (error) { props.onError(`Ошибка загрузки коллекций: ${(error as Error).message}`) } finally { setLoading(false) } } /** * Форматирует дату */ const formatDate = (timestamp: number): string => { return new Date(timestamp * 1000).toLocaleDateString('ru-RU') } /** * Открывает модалку редактирования */ const openEditModal = (collection: Collection) => { setFormData({ slug: collection.slug, title: collection.title, desc: collection.desc || '', pic: collection.pic }) setEditModal({ show: true, collection }) } /** * Открывает модалку создания */ const openCreateModal = () => { setFormData({ slug: '', title: '', desc: '', pic: '' }) setCreateModal(true) } /** * Создает новую коллекцию */ const createCollection = async () => { try { const response = await fetch('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: CREATE_COLLECTION_MUTATION, variables: { collection_input: formData() } }) }) const result = await response.json() if (result.errors) { throw new Error(result.errors[0].message) } if (result.data.create_collection.error) { throw new Error(result.data.create_collection.error) } props.onSuccess('Коллекция успешно создана') setCreateModal(false) await loadCollections() } catch (error) { props.onError(`Ошибка создания коллекции: ${(error as Error).message}`) } } /** * Обновляет коллекцию */ const updateCollection = async () => { try { const response = await fetch('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: UPDATE_COLLECTION_MUTATION, variables: { collection_input: formData() } }) }) const result = await response.json() if (result.errors) { throw new Error(result.errors[0].message) } if (result.data.update_collection.error) { throw new Error(result.data.update_collection.error) } props.onSuccess('Коллекция успешно обновлена') setEditModal({ show: false, collection: null }) await loadCollections() } catch (error) { props.onError(`Ошибка обновления коллекции: ${(error as Error).message}`) } } /** * Удаляет коллекцию */ const deleteCollection = async (slug: string) => { try { const response = await fetch('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: DELETE_COLLECTION_MUTATION, variables: { slug } }) }) const result = await response.json() if (result.errors) { throw new Error(result.errors[0].message) } if (result.data.delete_collection.error) { throw new Error(result.data.delete_collection.error) } props.onSuccess('Коллекция успешно удалена') setDeleteModal({ show: false, collection: null }) await loadCollections() } catch (error) { props.onError(`Ошибка удаления коллекции: ${(error as Error).message}`) } } // Загружаем коллекции при монтировании компонента onMount(() => { void loadCollections() }) return (

Управление коллекциями

Загрузка коллекций...
} > {(collection) => ( openEditModal(collection)} style={{ cursor: 'pointer' }} class={styles['clickable-row']} > )}
ID Название Slug Описание Создатель Публикации Создано Опубликовано Действия
{collection.id} {collection.title} {collection.slug}
{collection.desc || '—'}
{collection.created_by.name || collection.created_by.email} {collection.amount} {formatDate(collection.created_at)} {collection.published_at ? formatDate(collection.published_at) : '—'} e.stopPropagation()}>
{/* Модальное окно создания */} setCreateModal(false)} title="Создание новой коллекции">
setFormData((prev) => ({ ...prev, slug: e.target.value }))} style={{ width: '100%', padding: '8px', border: '1px solid #ddd', 'border-radius': '4px' }} required placeholder="my-collection" />
setFormData((prev) => ({ ...prev, title: e.target.value }))} style={{ width: '100%', padding: '8px', border: '1px solid #ddd', 'border-radius': '4px' }} required placeholder="Моя коллекция" />