import { Component, createSignal, For, onMount, Show } from 'solid-js' import type { AuthorsSortField } from '../context/sort' import { AUTHORS_SORT_CONFIG } from '../context/sortConfig' import { query } from '../graphql' import type { Query, AdminUserInfo as User } from '../graphql/generated/schema' import { ADMIN_GET_USERS_QUERY } from '../graphql/queries' import { ADMIN_UPDATE_USER_MUTATION } from '../graphql/mutations' import UserEditModal from '../modals/RolesModal' import styles from '../styles/Admin.module.css' import Pagination from '../ui/Pagination' import SortableHeader from '../ui/SortableHeader' import TableControls from '../ui/TableControls' import { formatDateRelative } from '../utils/date' export interface AuthorsRouteProps { onError?: (error: string) => void onSuccess?: (message: string) => void } const AuthorsRoute: Component = (props) => { const [users, setUsers] = createSignal([]) const [loading, setLoading] = createSignal(true) const [selectedUser, setSelectedUser] = createSignal(null) const [showEditModal, setShowEditModal] = createSignal(false) // Pagination state const [pagination, setPagination] = createSignal({ page: 1, limit: 20, total: 0, totalPages: 1 }) // Search state const [searchQuery, setSearchQuery] = createSignal('') /** * Загрузка списка пользователей с учетом пагинации и поиска */ async function loadUsers() { try { setLoading(true) const data = await query<{ adminGetUsers: Query['adminGetUsers'] }>( `${location.origin}/graphql`, ADMIN_GET_USERS_QUERY, { search: searchQuery(), limit: pagination().limit, offset: (pagination().page - 1) * pagination().limit } ) if (data?.adminGetUsers?.authors) { setUsers(data.adminGetUsers.authors) setPagination((prev) => ({ ...prev, total: data.adminGetUsers.total || 0, totalPages: data.adminGetUsers.totalPages || 1 })) } } catch (error) { console.error('[AuthorsRoute] Failed to load authors:', error) props.onError?.(error instanceof Error ? error.message : 'Не удалось загрузить список пользователей') } finally { setLoading(false) } } /** * Обновляет данные пользователя (профиль и роли) */ const updateUser = async (userData: { id: number email?: string name?: string slug?: string roles: string }) => { try { const result = await query<{ adminUpdateUser: { success: boolean; error?: string } }>(`${location.origin}/graphql`, ADMIN_UPDATE_USER_MUTATION, { user: { id: userData.id, email: userData.email, name: userData.name, slug: userData.slug, roles: userData.roles.split(',').map(role => role.trim()).filter(role => role.length > 0) } }) if (result.adminUpdateUser.success) { // Перезагружаем список пользователей await loadUsers() // Закрываем модальное окно setShowEditModal(false) props.onSuccess?.('Пользователь успешно обновлен') } else { props.onError?.(result.adminUpdateUser.error || 'Не удалось обновить пользователя') } } catch (error) { console.error('Ошибка при обновлении пользователя:', error) props.onError?.(error instanceof Error ? error.message : 'Не удалось обновить пользователя') } } // Pagination handlers function handlePageChange(page: number) { setPagination((prev) => ({ ...prev, page })) void loadUsers() } function handlePerPageChange(limit: number) { setPagination((prev) => ({ ...prev, page: 1, limit })) void loadUsers() } function handleSearch() { setPagination((prev) => ({ ...prev, page: 1 })) void loadUsers() } // Load authors on mount onMount(() => { void loadUsers() }) /** * Компонент для отображения роли с эмоджи и тултипом */ const RoleBadge: Component<{ role: string }> = (props) => { const getRoleIcon = (role: string): string => { switch (role.toLowerCase().trim()) { case 'admin': return '🔧' case 'editor': return '✒️' case 'expert': return '🔬' case 'artist': return '🎨' case 'author': return '📝' case 'reader': return '📖' default: return '👤' } } return {getRoleIcon(props.role)} } return (
Загрузка данных...
Нет данных для отображения
0}> ID Email Имя Создан {(user) => ( { setSelectedUser(user) setShowEditModal(true) }} > )}
Роли
{user.id} {user.email} {user.name || '-'} {formatDateRelative(user.created_at || Date.now())()}
{(role) => } {(!user.roles || user.roles.length === 0) && ( Нет ролей )}
setShowEditModal(false)} onSave={updateUser} />
) } export default AuthorsRoute