import React, { useState } from 'react' import { useNavigate } from 'react-router-dom' import { useTranslation } from 'react-i18next' import { Box, Heading, Button, Table, Flex, Input, HStack, Text, Badge, } from '@chakra-ui/react' import { useGetChainsQuery, useDeleteChainMutation, useUpdateChainMutation } from '../../__data__/api/api' import { URLs } from '../../__data__/urls' import { LoadingSpinner } from '../../components/LoadingSpinner' import { ErrorAlert } from '../../components/ErrorAlert' import { EmptyState } from '../../components/EmptyState' import { DuplicateChainDialog } from '../../components/DuplicateChainDialog' import { ClearSubmissionsDialog } from '../../components/ClearSubmissionsDialog' import type { ChallengeChain } from '../../types/challenge' import { toaster } from '../../components/ui/toaster' export const ChainsListPage: React.FC = () => { const navigate = useNavigate() const { t } = useTranslation() const { data: chains, isLoading, error, refetch } = useGetChainsQuery() const [deleteChain] = useDeleteChainMutation() const [searchQuery, setSearchQuery] = useState('') const [chainToDuplicate, setChainToDuplicate] = useState(null) const [chainToClearSubmissions, setChainToClearSubmissions] = useState(null) const [updatingChainId, setUpdatingChainId] = useState(null) const [updateChain] = useUpdateChainMutation() const handleDeleteChain = async (chain: ChallengeChain) => { const confirmed = window.confirm( t('challenge.admin.chains.delete.confirm.message', { name: chain.name }) ) if (!confirmed) return try { await deleteChain(chain.id).unwrap() toaster.create({ title: t('challenge.admin.common.success'), description: t('challenge.admin.chains.deleted'), type: 'success', }) } catch (err) { toaster.create({ title: t('challenge.admin.common.error'), description: t('challenge.admin.chains.delete.error'), type: 'error', }) } } const handleToggleActive = async (chain: ChallengeChain, nextValue: boolean) => { setUpdatingChainId(chain.id) try { await updateChain({ id: chain.id, data: { isActive: nextValue }, }).unwrap() toaster.create({ title: t('challenge.admin.common.success'), description: t('challenge.admin.chains.updated'), type: 'success', }) } catch { toaster.create({ title: t('challenge.admin.common.error'), description: t('challenge.admin.chains.save.error'), type: 'error', }) } finally { setUpdatingChainId(null) } } if (isLoading) { return } if (error || !chains) { return } const filteredChains = chains.filter((chain) => chain.name.toLowerCase().includes(searchQuery.toLowerCase()) ) const formatDate = (dateStr: string) => { return new Date(dateStr).toLocaleDateString('ru-RU', { year: 'numeric', month: 'short', day: 'numeric', }) } return ( {t('challenge.admin.chains.list.title')} {chains.length > 0 && ( setSearchQuery(e.target.value)} maxW="400px" /> )} {filteredChains.length === 0 && chains.length === 0 ? ( navigate(URLs.chainNew)} /> ) : filteredChains.length === 0 ? ( ) : ( {t('challenge.admin.chains.list.table.name')} {t('challenge.admin.chains.list.table.tasks.count')} {t('challenge.admin.chains.list.table.created')} {t('challenge.admin.chains.list.table.status')} {t('challenge.admin.chains.list.table.actions')} {filteredChains.map((chain) => ( {chain.name} {chain.tasks.length} {t('challenge.admin.chains.list.badge.tasks')} {formatDate(chain.createdAt)} {chain.isActive ? t('challenge.admin.chains.list.status.active') : t('challenge.admin.chains.list.status.inactive')} ))} )} setChainToDuplicate(null)} chain={chainToDuplicate} /> setChainToClearSubmissions(null)} chain={chainToClearSubmissions} /> ) }