zioinfo-mail/manager/frontend/src/App.tsx
DESKTOP-TKLFCPR\ython 8fbb64a12a feat(ui): Manager DR·네트워크·CSAP 관제 + Messenger DR·네트워크 화면 구현
## GUARDiA Manager (frontend)
- pages/DrConsole.tsx — DR 재해복구 관제 (시나리오/RTO-RPO/테스트 실행)
- pages/NetworkConsole.tsx — 네트워크 장비 관제 (백업/diff/상태)
- pages/CsapConsole.tsx — CSAP 준수율 대시보드 (점검/Excel 다운로드)
- App.tsx — 3개 라우트 추가 (/dr, /network, /csap)
- Sidebar.tsx — '운영 관제' 그룹 메뉴 추가
- AppLayout.tsx — 페이지 타이틀 3개 추가

## GUARDiA Messenger (React Native)
- app/(tabs)/dr.tsx — DR 모니터링 화면 (M-01)
- app/(tabs)/network.tsx — 네트워크 장비 현황 화면 (M-02)
- app/(tabs)/_layout.tsx — DR·네트워크 탭 추가
- services/api.ts — DR/네트워크/CSAP API 함수 추가
- hooks/useBiometric.ts — 생체인증 훅 (M-03)
- hooks/useOfflineCache.ts — 오프라인 캐시 훅 (M-04)

## 매뉴얼
- 16_API_명세서.md — v2.2.0 업데이트
- 39_DR_네트워크장비_CSAP_운영가이드.md — Manager/Messenger UI 연동 현황 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 09:53:17 +09:00

68 lines
3.2 KiB
TypeScript

import { lazy, Suspense } from 'react'
import { Routes, Route, Navigate } from 'react-router-dom'
import { AppLayout } from './components/layout/AppLayout'
import { ProtectedRoute } from './components/common/ProtectedRoute'
const Login = lazy(() => import('./pages/Login'))
const Dashboard = lazy(() => import('./pages/Dashboard'))
const Servers = lazy(() => import('./pages/Servers'))
const CMDB = lazy(() => import('./pages/CMDB'))
const Deployments = lazy(() => import('./pages/Deployments'))
const Repos = lazy(() => import('./pages/Repos'))
const Users = lazy(() => import('./pages/Users'))
const Institutions = lazy(() => import('./pages/Institutions'))
const ApiKeys = lazy(() => import('./pages/ApiKeys'))
const AuditLog = lazy(() => import('./pages/AuditLog'))
const LLMManager = lazy(() => import('./pages/LLMManager'))
const ConfigEnv = lazy(() => import('./pages/ConfigEnv'))
const ConfigNginx = lazy(() => import('./pages/ConfigNginx'))
const Notifications = lazy(() => import('./pages/Notifications'))
const Licenses = lazy(() => import('./pages/Licenses'))
const ExportImport = lazy(() => import('./pages/ExportImport'))
const DrConsole = lazy(() => import('./pages/DrConsole'))
const NetworkConsole = lazy(() => import('./pages/NetworkConsole'))
const CsapConsole = lazy(() => import('./pages/CsapConsole'))
function Loading() {
return (
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center',
height: '60vh', color: '#94a3b8', gap: 10 }}>
<span style={{ width: 16, height: 16, border: '2px solid #4f6ef7',
borderTopColor: 'transparent', borderRadius: '50%',
animation: 'spin .6s linear infinite', display: 'inline-block' }} />
...
</div>
)
}
export default function App() {
return (
<Suspense fallback={<Loading />}>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/" element={<ProtectedRoute><AppLayout /></ProtectedRoute>}>
<Route index element={<Dashboard />} />
<Route path="servers" element={<Servers />} />
<Route path="cmdb" element={<CMDB />} />
<Route path="deployments" element={<Deployments />} />
<Route path="repos" element={<Repos />} />
<Route path="users" element={<Users />} />
<Route path="institutions" element={<Institutions />} />
<Route path="api-keys" element={<ApiKeys />} />
<Route path="audit" element={<AuditLog />} />
<Route path="llm" element={<LLMManager />} />
<Route path="config/env" element={<ConfigEnv />} />
<Route path="config/nginx" element={<ConfigNginx />} />
<Route path="notifications" element={<Notifications />} />
<Route path="licenses" element={<Licenses />} />
<Route path="export-import" element={<ExportImport />} />
<Route path="dr" element={<DrConsole />} />
<Route path="network" element={<NetworkConsole />} />
<Route path="csap" element={<CsapConsole />} />
</Route>
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</Suspense>
)
}