/** * Интеграция ФГИС РЭВС — Федеральная ГИС реестра эксплуатантов ВС. * ВК РФ ст. 33, 36, 37.2; Приказ Росавиации № 180-П; ФАП-148. */ 'use client'; import { useState, useCallback } from 'react'; import { PageLayout, DataTable, StatusBadge, EmptyState } from '@/components/ui'; type Tab = 'aircraft' | 'certificates' | 'operators' | 'directives' | 'maint-orgs' | 'sync' | 'connection'; export default function FGISPage() { const [tab, setTab] = useState('aircraft'); const [data, setData] = useState(null); const [loading, setLoading] = useState(false); const [syncing, setSyncing] = useState(false); const [syncResults, setSyncResults] = useState(null); const api = useCallback(async (ep: string, method = 'GET') => { setLoading(true); try { const opts: RequestInit = { method }; const r = await fetch(`/api/v1/fgis-revs/${ep}`, opts); const d = await r.json(); setData(d); return d; } finally { setLoading(false); } }, []); const loadTab = useCallback((t: Tab) => { setTab(t); setData(null); switch (t) { case 'aircraft': api('aircraft-registry'); break; case 'certificates': api('certificates'); break; case 'operators': api('operators'); break; case 'directives': api('directives'); break; case 'maint-orgs': api('maintenance-organizations'); break; case 'sync': api('sync/status'); break; case 'connection': api('connection-status'); break; } }, [api]); const runSync = async (type: string) => { setSyncing(true); try { const r = await fetch(`/api/v1/fgis-revs/sync/${type}`, { method: 'POST' }); const d = await r.json(); setSyncResults(d); if (type === 'all') loadTab('sync'); } finally { setSyncing(false); } }; const tabs: { id: Tab; label: string; icon: string }[] = [ { id: 'aircraft', label: 'Реестр ВС', icon: '✈️' }, { id: 'certificates', label: 'СЛГ', icon: '📜' }, { id: 'operators', label: 'Эксплуатанты', icon: '🏢' }, { id: 'directives', label: 'Директивы ЛГ', icon: '⚠️' }, { id: 'maint-orgs', label: 'Орг. по ТО', icon: '🔧' }, { id: 'sync', label: 'Синхронизация', icon: '🔄' }, { id: 'connection', label: 'Подключение', icon: '🔌' }, ]; return ( {/* Tabs */}
{tabs.map(t => ( ))}
{loading &&
⏳ Загрузка данных из ФГИС РЭВС...
} {/* Aircraft Registry */} {tab === 'aircraft' && data && !loading && (
📡 Источник: {data.source} | {data.legal_basis} | {data.total} записей
{(v||'').slice(0,30)} }, { key: 'year_manufactured', label: 'Год' }, { key: 'operator', label: 'Эксплуатант' }, { key: 'base_airport', label: 'Аэродром' }, { key: 'status', label: 'Статус', render: (v: string) => ( )}, ]} data={data.items || []} />
)} {/* Certificates */} {tab === 'certificates' && data && !loading && (
📡 {data.source} | {data.legal_basis}
({ standard: 'Стандартный', restricted: 'Ограниченный', special: 'Специальный', export: 'Экспортный' }[v] || v) }, { key: 'category', label: 'Категория' }, { key: 'issue_date', label: 'Выдан' }, { key: 'expiry_date', label: 'Действует до' }, { key: 'status', label: 'Статус', render: (v: string) => ( )}, ]} data={data.items || []} />
)} {/* Operators */} {tab === 'operators' && data && !loading && (
📡 {data.source} | {data.legal_basis}
{(data.items || []).map((op: any, i: number) => (

{op.name}

СЭ: {op.certificate_number} | ИНН: {op.inn} | ОГРН: {op.ogrn}
{(op.aircraft_types || []).map((t: string) => ( {t} ))}
Парк: {op.fleet_count} ВС | Действует: {op.issue_date} — {op.expiry_date}
))}
)} {/* Directives */} {tab === 'directives' && data && !loading && (
📡 {data.source} | {data.legal_basis}
(v || []).join(', ') }, { key: 'ata_chapter', label: 'ATA' }, { key: 'effective_date', label: 'С даты' }, { key: 'compliance_type', label: 'Тип', render: (v: string) => ( )}, ]} data={data.items || []} />
)} {/* Maintenance Organizations */} {tab === 'maint-orgs' && data && !loading && (
📡 {data.source} | {data.legal_basis}
{(data.items || []).map((org: any, i: number) => (

{org.name}

Сертификат: {org.certificate_number}
{(org.approval_scope || []).map((s: string) => ( {s} ))}
Действует: {org.issue_date} — {org.expiry_date}
))}
)} {/* Sync */} {tab === 'sync' && !loading && (
{[ { type: 'aircraft', label: '✈️ Реестр ВС', desc: 'Двунаправленная синх.' }, { type: 'certificates', label: '📜 СЛГ', desc: 'Pull из ФГИС' }, { type: 'directives', label: '⚠️ Директивы ЛГ', desc: 'Pull + auto-create AD' }, { type: 'all', label: '🔄 Полная синхр.', desc: 'Все реестры' }, ].map(s => ( ))}
{syncing &&
🔄 Синхронизация...
} {syncResults && (

✅ Результат синхронизации

{JSON.stringify(syncResults, null, 2)}
)} {data?.history?.length > 0 && (

📋 История синхронизаций

( )}, { key: 'records_synced', label: 'Синхр.' }, { key: 'records_failed', label: 'Ошибки' }, { key: 'started_at', label: 'Время', render: (v: string) => v ? new Date(v).toLocaleString('ru-RU') : '—' }, ]} data={data.history} />
)}
)} {/* Connection Status */} {tab === 'connection' && data && !loading && (

📡 ФГИС РЭВС (REST API)

URL:{data.fgis_revs?.url}
Статус:
{data.fgis_revs?.note}

🔐 СМЭВ 3.0 (SOAP)

URL:{data.smev_30?.url}
Статус:
{data.smev_30?.note}

⚙️ Конфигурация

{Object.entries(data.config || {}).map(([k, v]) => (
{k}:{String(v)}
))}
)} {!data && !loading && tab !== 'sync' && }
); }