arm-web/src/layouts/DocumentPage.tsx

64 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Button, Empty, Result, Spin, Tag } from 'antd';
import { useCallback, useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { ApiError } from '../api/client';
import PageTitle from '../components/PageTitle';
import { fetchLegalEntity } from '../services/api/directories/company_groups';
import { getDocument } from '../services/api/documents';
import type { DocumentOut } from '../types/api';
import { documentStatusLabel, documentTypeLabel, periodLabel } from '../utils/labels';
import { OsvDocument } from '../widgets/DocumentReview/OsvDocument';
import { documentViewKind } from '../widgets/DocumentReview/viewKind';
export function DocumentPage() {
const { document_id } = useParams();
const navigate = useNavigate();
const [doc, setDoc] = useState<DocumentOut | null>(null);
const [entityName, setEntityName] = useState('');
const [error, setError] = useState<string | null>(null);
const load = useCallback(async () => {
if (!document_id) return;
try {
const d = await getDocument(document_id);
setDoc(d);
setError(null);
fetchLegalEntity(d.legal_entity_id)
.then((le) => setEntityName(le.name))
.catch(() => setEntityName(''));
} catch (e: unknown) {
setError(e instanceof ApiError ? e.message : 'Не удалось открыть документ');
}
}, [document_id]);
useEffect(() => {
void load();
}, [load]);
if (error) {
return <Result status='warning' title={error} extra={<Button onClick={() => navigate(-1)}>Назад</Button>} />;
}
if (!doc) {
return <Spin style={{ margin: 48 }} />;
}
const kind = documentViewKind(doc);
// Документ в статусе ERROR — данных формы/строк нет: показываем карточку и понятный текст, а не пустой экран.
const broken = doc.status === 'ERROR' && kind !== 'none';
return (
<div style={{ padding: 12, display: 'flex', flexDirection: 'column', height: '100vh', gap: 12 }}>
<PageTitle
backable
location={`Проверка документа${entityName ? ` › ${entityName}` : ''}`}
header={`${documentTypeLabel(doc.document_type, doc.osv_account_code)} · ${periodLabel(doc.period_year, doc.period_quarter, doc.is_cumulative)}`}
description={<Tag>{documentStatusLabel(doc.status)}</Tag>}
/>
<main style={{ flex: '1 1 auto', minHeight: 0, background: 'white', borderRadius: 12, padding: 12, overflow: 'auto' }}>
{broken && <Empty description='Документ не удалось распознать — данных для проверки нет' />}
{!broken && kind === 'osv' && <OsvDocument key={doc.id} document={doc} onChanged={load} />}
{!broken && kind === 'statement' && <Empty description='Проверка формы — в следующей задаче' />}
{kind === 'none' && <Empty description='Документ без данных для проверки' />}
</main>
</div>
);
}