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) => (
))}
)}
);
}