import { useCallback, useState, memo } from 'react'; import { useNavigate } from 'react-router'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { infoPagesApi } from '../api/infoPages'; import { AdminBackButton } from '../components/admin'; import { Toggle } from '../components/admin/Toggle'; import { useHapticFeedback } from '../platform/hooks/useHaptic'; import { useDestructiveConfirm } from '../platform/hooks/useNativeDialog'; import { cn } from '../lib/utils'; import { FileTextIcon, PencilIcon, PlusIcon, RefreshIcon, TrashIcon } from '@/components/icons'; import type { InfoPageListItem, InfoPageType } from '../api/infoPages'; type FilterTab = 'all' | 'page' | 'faq'; // --- Page Row --- const PageRow = memo(function PageRow({ page, locale, onEdit, onDelete, onToggleActive, }: { page: InfoPageListItem; locale: string; onEdit: () => void; onDelete: () => void; onToggleActive: () => void; }) { const { t } = useTranslation(); const resolvedTitle = page.title[locale] || page.title['ru'] || page.title['en'] || ''; return (
{page.icon && {page.icon}} /{page.slug} {page.page_type === 'faq' ? 'FAQ' : t('admin.infoPages.typePage')} {page.is_active ? t('admin.infoPages.active') : t('admin.infoPages.inactive')} {page.replaces_tab && ( {t(`admin.infoPages.replacesTabOptions.${page.replaces_tab}`)} )} #{page.id}

{resolvedTitle}

{t('admin.infoPages.fields.sortOrder')}: {page.sort_order} {page.updated_at && {new Date(page.updated_at).toLocaleDateString()}}
); }); // --- Row Wrapper (stable callbacks for memo) --- interface PageRowWrapperProps { page: InfoPageListItem; locale: string; onNavigate: (path: string) => void; onDelete: (id: number) => void; onToggleActive: (id: number) => void; } const PageRowWrapper = memo(function PageRowWrapper({ page, locale, onNavigate, onDelete, onToggleActive, }: PageRowWrapperProps) { const handleEdit = useCallback( () => onNavigate(`/admin/info-pages/${page.id}/edit`), [page.id, onNavigate], ); const handleDelete = useCallback(() => onDelete(page.id), [page.id, onDelete]); const handleToggleActive = useCallback(() => onToggleActive(page.id), [page.id, onToggleActive]); return ( ); }); export default function AdminInfoPages() { const { t, i18n } = useTranslation(); const navigate = useNavigate(); const queryClient = useQueryClient(); const haptic = useHapticFeedback(); const confirm = useDestructiveConfirm(); const currentLocale = i18n.language.split('-')[0]; const [activeFilter, setActiveFilter] = useState('all'); const filterParam: InfoPageType | undefined = activeFilter === 'all' ? undefined : activeFilter; const { data: pages, isLoading, refetch, } = useQuery({ queryKey: ['admin', 'info-pages', 'list', activeFilter], queryFn: () => infoPagesApi.getAdminPages(filterParam), staleTime: 30_000, }); const items = pages ?? []; const deleteMutation = useMutation({ mutationFn: infoPagesApi.deletePage, onSuccess: () => { haptic.success(); queryClient.invalidateQueries({ queryKey: ['admin', 'info-pages'] }); queryClient.invalidateQueries({ queryKey: ['info-pages'] }); }, }); const toggleActiveMutation = useMutation({ mutationFn: infoPagesApi.toggleActive, onSuccess: () => { haptic.success(); queryClient.invalidateQueries({ queryKey: ['admin', 'info-pages'] }); queryClient.invalidateQueries({ queryKey: ['info-pages'] }); }, }); const handleDelete = useCallback( async (id: number) => { const confirmed = await confirm(t('admin.infoPages.confirmDelete')); if (confirmed) { deleteMutation.mutate(id); } }, [confirm, deleteMutation, t], ); const handleToggleActive = useCallback( (id: number) => { toggleActiveMutation.mutate(id); }, [toggleActiveMutation], ); return (
{/* Header */}

{t('admin.infoPages.title')}

{items.length > 0 && ( {items.length} )}
{/* Filter tabs */}
{(['all', 'page', 'faq'] as const).map((tab) => ( ))}
{/* Pages list */} {isLoading ? (
{Array.from({ length: 3 }).map((_, i) => (
))}
) : items.length === 0 ? (

{t('admin.infoPages.noPages')}

) : (
{items.map((page) => ( ))}
)}
); }