core/panel/routes/admin.tsx

211 lines
6.8 KiB
TypeScript
Raw Normal View History

2025-05-16 06:23:48 +00:00
/**
* Компонент страницы администратора
* @module AdminPage
*/
2025-06-30 18:25:26 +00:00
import { useNavigate, useParams } from '@solidjs/router'
import { Component, createEffect, createSignal, onMount, Show } from 'solid-js'
2025-07-02 19:30:21 +00:00
import publyLogo from '../assets/publy.svg?url'
import { logout } from '../context/auth'
import styles from '../styles/Admin.module.css'
import Button from '../ui/Button'
import CommunitySelector from '../ui/CommunitySelector'
import LanguageSwitcher from '../ui/LanguageSwitcher'
2025-06-30 18:25:26 +00:00
// Прямой импорт компонентов вместо ленивой загрузки
2025-07-02 19:30:21 +00:00
import AuthorsRoute from './authors'
import CollectionsRoute from './collections'
import CommunitiesRoute from './communities'
import EnvRoute from './env'
import InvitesRoute from './invites'
2025-07-04 09:39:41 +00:00
import ReactionsRoute from './reactions'
2025-07-02 19:30:21 +00:00
import ShoutsRoute from './shouts'
import { Topics as TopicsRoute } from './topics'
2025-06-28 10:47:08 +00:00
2025-05-20 22:34:02 +00:00
/**
* Интерфейс свойств компонента AdminPage
*/
2025-06-30 18:25:26 +00:00
export interface AdminPageProps {
2025-05-20 22:34:02 +00:00
apiUrl: string
2025-05-16 07:30:02 +00:00
onLogout?: () => void
}
2025-05-16 06:23:48 +00:00
/**
* Компонент страницы администратора
*/
2025-05-16 07:30:02 +00:00
const AdminPage: Component<AdminPageProps> = (props) => {
2025-06-30 18:25:26 +00:00
console.log('[AdminPage] Initializing...')
const navigate = useNavigate()
const params = useParams()
2025-05-16 06:23:48 +00:00
const [error, setError] = createSignal<string | null>(null)
const [successMessage, setSuccessMessage] = createSignal<string | null>(null)
2025-06-30 18:25:26 +00:00
const [currentTab, setCurrentTab] = createSignal<string>('authors')
2025-05-20 22:34:02 +00:00
2025-06-30 18:25:26 +00:00
onMount(() => {
console.log('[AdminPage] Component mounted')
console.log('[AdminPage] Initial params:', params)
// Если мы на корневом пути /admin, редиректим на /admin/authors
if (!params.tab) {
navigate('/admin/authors', { replace: true })
} else {
setCurrentTab(params.tab)
}
2025-05-16 06:23:48 +00:00
})
2025-06-30 18:25:26 +00:00
// Отслеживаем изменения параметров роута
createEffect(() => {
console.log('[AdminPage] Params changed:', params)
console.log('[AdminPage] Current tab param:', params.tab)
const newTab = params.tab || 'authors'
setCurrentTab(newTab)
console.log('[AdminPage] Updated currentTab to:', newTab)
2025-06-28 10:47:08 +00:00
})
2025-05-16 06:23:48 +00:00
/**
2025-05-20 22:34:02 +00:00
* Обрабатывает выход из системы
2025-05-16 06:23:48 +00:00
*/
2025-05-20 22:34:02 +00:00
const handleLogout = async () => {
try {
await logout()
2025-05-16 07:30:02 +00:00
if (props.onLogout) {
props.onLogout()
}
2025-06-30 18:25:26 +00:00
navigate('/login')
2025-05-20 22:34:02 +00:00
} catch (error) {
2025-06-30 18:25:26 +00:00
setError(`Ошибка при выходе: ${(error as Error).message}`)
2025-05-20 22:34:02 +00:00
}
}
/**
2025-06-30 18:25:26 +00:00
* Обработчик ошибок
2025-05-20 22:34:02 +00:00
*/
2025-06-30 18:25:26 +00:00
const handleError = (error: string) => {
setError(error)
// Скрываем ошибку через 5 секунд
setTimeout(() => setError(null), 5000)
2025-05-20 22:34:02 +00:00
}
/**
2025-06-30 18:25:26 +00:00
* Обработчик успешных операций
2025-05-20 22:34:02 +00:00
*/
2025-06-30 18:25:26 +00:00
const handleSuccess = (message: string) => {
setSuccessMessage(message)
// Скрываем сообщение через 3 секунды
setTimeout(() => setSuccessMessage(null), 3000)
2025-06-28 11:52:46 +00:00
}
2025-05-16 06:23:48 +00:00
return (
2025-06-30 18:25:26 +00:00
<div class={styles['admin-panel']}>
2025-05-16 06:23:48 +00:00
<header>
2025-06-30 18:25:26 +00:00
<div class={styles['header-container']}>
<div class={styles['header-left']}>
<img src={publyLogo} alt="Logo" class={styles.logo} />
2025-07-02 19:30:21 +00:00
</div>
<div class={styles['header-right']}>
<CommunitySelector />
<LanguageSwitcher />
<button class={styles['logout-button']} onClick={handleLogout}>
Выйти
</button>
2025-06-30 18:25:26 +00:00
</div>
2025-05-16 06:23:48 +00:00
</div>
2025-06-30 18:25:26 +00:00
<nav class={styles['admin-tabs']}>
<Button
2025-07-02 19:30:21 +00:00
variant={currentTab() === 'authors' ? 'primary' : 'secondary'}
2025-06-30 18:25:26 +00:00
onClick={() => navigate('/admin/authors')}
>
Авторы
</Button>
<Button
2025-07-02 19:30:21 +00:00
variant={currentTab() === 'shouts' ? 'primary' : 'secondary'}
2025-06-30 18:25:26 +00:00
onClick={() => navigate('/admin/shouts')}
>
2025-06-28 10:47:08 +00:00
Публикации
2025-06-30 18:25:26 +00:00
</Button>
<Button
2025-07-02 19:30:21 +00:00
variant={currentTab() === 'topics' ? 'primary' : 'secondary'}
2025-06-30 18:25:26 +00:00
onClick={() => navigate('/admin/topics')}
>
Темы
</Button>
<Button
2025-07-02 19:30:21 +00:00
variant={currentTab() === 'communities' ? 'primary' : 'secondary'}
2025-06-30 18:25:26 +00:00
onClick={() => navigate('/admin/communities')}
>
Сообщества
</Button>
2025-06-30 18:46:53 +00:00
<Button
2025-07-02 19:30:21 +00:00
variant={currentTab() === 'collections' ? 'primary' : 'secondary'}
2025-06-30 18:46:53 +00:00
onClick={() => navigate('/admin/collections')}
>
Коллекции
</Button>
2025-06-30 19:19:46 +00:00
<Button
2025-07-02 19:30:21 +00:00
variant={currentTab() === 'invites' ? 'primary' : 'secondary'}
2025-06-30 19:19:46 +00:00
onClick={() => navigate('/admin/invites')}
>
Приглашения
</Button>
2025-07-04 09:39:41 +00:00
<Button
variant={currentTab() === 'reactions' ? 'primary' : 'secondary'}
onClick={() => navigate('/admin/reactions')}
>
Реакции
</Button>
2025-06-30 18:25:26 +00:00
<Button
2025-07-02 19:30:21 +00:00
variant={currentTab() === 'env' ? 'primary' : 'secondary'}
2025-06-30 18:25:26 +00:00
onClick={() => navigate('/admin/env')}
>
2025-05-20 22:34:02 +00:00
Переменные среды
2025-06-30 18:25:26 +00:00
</Button>
2025-05-16 06:23:48 +00:00
</nav>
</header>
<main>
<Show when={error()}>
2025-06-30 18:25:26 +00:00
<div class={styles['error-message']}>{error()}</div>
2025-05-16 06:23:48 +00:00
</Show>
<Show when={successMessage()}>
2025-06-30 18:25:26 +00:00
<div class={styles['success-message']}>{successMessage()}</div>
2025-05-16 06:23:48 +00:00
</Show>
2025-06-30 18:25:26 +00:00
{/* Используем Show компоненты для каждой вкладки */}
2025-07-02 19:30:21 +00:00
<Show when={currentTab() === 'authors'}>
2025-06-30 18:25:26 +00:00
<AuthorsRoute onError={handleError} onSuccess={handleSuccess} />
2025-05-20 22:34:02 +00:00
</Show>
2025-07-02 19:30:21 +00:00
<Show when={currentTab() === 'shouts'}>
2025-06-30 18:25:26 +00:00
<ShoutsRoute onError={handleError} onSuccess={handleSuccess} />
</Show>
2025-06-28 10:47:08 +00:00
2025-07-02 19:30:21 +00:00
<Show when={currentTab() === 'topics'}>
2025-06-30 18:25:26 +00:00
<TopicsRoute onError={handleError} onSuccess={handleSuccess} />
</Show>
2025-06-28 10:47:08 +00:00
2025-07-02 19:30:21 +00:00
<Show when={currentTab() === 'communities'}>
2025-06-30 18:25:26 +00:00
<CommunitiesRoute onError={handleError} onSuccess={handleSuccess} />
2025-06-28 10:47:08 +00:00
</Show>
2025-07-02 19:30:21 +00:00
<Show when={currentTab() === 'collections'}>
2025-06-30 18:46:53 +00:00
<CollectionsRoute onError={handleError} onSuccess={handleSuccess} />
</Show>
2025-07-02 19:30:21 +00:00
<Show when={currentTab() === 'invites'}>
2025-06-30 19:19:46 +00:00
<InvitesRoute onError={handleError} onSuccess={handleSuccess} />
</Show>
2025-07-04 09:39:41 +00:00
<Show when={currentTab() === 'reactions'}>
<ReactionsRoute onError={handleError} onSuccess={handleSuccess} />
</Show>
2025-07-02 19:30:21 +00:00
<Show when={currentTab() === 'env'}>
2025-06-30 18:25:26 +00:00
<EnvRoute onError={handleError} onSuccess={handleSuccess} />
2025-05-16 06:23:48 +00:00
</Show>
</main>
</div>
)
}
export default AdminPage