Files
CurrenciCombo/src/Portal.tsx
Devin AI e83107d71f feat: Solace Bank Group PLC Treasury Management Portal
- Web3 authentication with MetaMask, WalletConnect, Coinbase wallet options
- Demo mode for testing without wallet
- Overview dashboard with KPI cards, asset allocation, positions, accounts, alerts
- Transaction Builder module (full IDE-style drag-and-drop canvas with 28 gap fixes)
- Accounts module with multi-account/subaccount hierarchical structures
- Treasury Management module with positions table and 14-day cash forecast
- Financial Reporting module with IPSAS, US GAAP, IFRS compliance
- Compliance & Risk module with KYC/AML/Sanctions monitoring
- Settlement & Clearing module with DVP/FOP/PVP operations
- Settings with role-based permissions and enterprise controls
- Dark theme professional UI with Solace Bank branding
- HashRouter for static hosting compatibility

Co-Authored-By: Nakamoto, S <defi@defi-oracle.io>
2026-04-18 10:25:56 -07:00

244 lines
7.5 KiB
TypeScript

import { Routes, Route, Navigate } from 'react-router-dom';
import { useAuth } from './contexts/AuthContext';
import LoginPage from './pages/LoginPage';
import DashboardPage from './pages/DashboardPage';
import AccountsPage from './pages/AccountsPage';
import TreasuryPage from './pages/TreasuryPage';
import ReportingPage from './pages/ReportingPage';
import CompliancePage from './pages/CompliancePage';
import SettlementsPage from './pages/SettlementsPage';
import PortalLayout from './components/portal/PortalLayout';
import App from './App';
function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { isAuthenticated, loading } = useAuth();
if (loading) {
return (
<div className="portal-loading">
<div className="portal-loading-spinner" />
<span>Initializing secure session...</span>
</div>
);
}
if (!isAuthenticated) {
return <Navigate to="/login" replace />;
}
return <>{children}</>;
}
export default function Portal() {
const { isAuthenticated, loading } = useAuth();
if (loading) {
return (
<div className="portal-loading">
<div className="portal-loading-spinner" />
<span>Initializing secure session...</span>
</div>
);
}
return (
<Routes>
<Route
path="/login"
element={isAuthenticated ? <Navigate to="/dashboard" replace /> : <LoginPage />}
/>
<Route
path="/dashboard"
element={
<ProtectedRoute>
<PortalLayout>
<DashboardPage />
</PortalLayout>
</ProtectedRoute>
}
/>
<Route
path="/transaction-builder"
element={
<ProtectedRoute>
<PortalLayout>
<div className="transaction-builder-module">
<App />
</div>
</PortalLayout>
</ProtectedRoute>
}
/>
<Route
path="/accounts"
element={
<ProtectedRoute>
<PortalLayout>
<AccountsPage />
</PortalLayout>
</ProtectedRoute>
}
/>
<Route
path="/treasury"
element={
<ProtectedRoute>
<PortalLayout>
<TreasuryPage />
</PortalLayout>
</ProtectedRoute>
}
/>
<Route
path="/reporting"
element={
<ProtectedRoute>
<PortalLayout>
<ReportingPage />
</PortalLayout>
</ProtectedRoute>
}
/>
<Route
path="/compliance"
element={
<ProtectedRoute>
<PortalLayout>
<CompliancePage />
</PortalLayout>
</ProtectedRoute>
}
/>
<Route
path="/settlements"
element={
<ProtectedRoute>
<PortalLayout>
<SettlementsPage />
</PortalLayout>
</ProtectedRoute>
}
/>
<Route
path="/settings"
element={
<ProtectedRoute>
<PortalLayout>
<SettingsPage />
</PortalLayout>
</ProtectedRoute>
}
/>
<Route path="*" element={<Navigate to={isAuthenticated ? '/dashboard' : '/login'} replace />} />
</Routes>
);
}
function SettingsPage() {
const { user, wallet } = useAuth();
return (
<div className="settings-page">
<div className="page-header">
<h1>Settings</h1>
<p className="page-subtitle">Portal configuration and user preferences</p>
</div>
<div className="settings-grid">
<div className="dashboard-card">
<div className="card-header"><h3>Profile</h3></div>
<div className="settings-section">
<div className="setting-row">
<span className="setting-label">Display Name</span>
<span className="setting-value">{user?.displayName || '—'}</span>
</div>
<div className="setting-row">
<span className="setting-label">Role</span>
<span className="setting-value">{user?.role?.replace('_', ' ') || '—'}</span>
</div>
<div className="setting-row">
<span className="setting-label">Institution</span>
<span className="setting-value">{user?.institution || '—'}</span>
</div>
<div className="setting-row">
<span className="setting-label">Department</span>
<span className="setting-value">{user?.department || '—'}</span>
</div>
<div className="setting-row">
<span className="setting-label">Wallet Address</span>
<span className="setting-value mono">{wallet?.address || '—'}</span>
</div>
<div className="setting-row">
<span className="setting-label">Chain ID</span>
<span className="setting-value">{wallet?.chainId || '—'}</span>
</div>
</div>
</div>
<div className="dashboard-card">
<div className="card-header"><h3>Permissions</h3></div>
<div className="settings-section">
<div className="permissions-list">
{user?.permissions?.map(p => (
<span key={p} className="permission-badge">{p}</span>
)) || <span>No permissions</span>}
</div>
</div>
</div>
<div className="dashboard-card">
<div className="card-header"><h3>Reporting Preferences</h3></div>
<div className="settings-section">
<div className="setting-row">
<span className="setting-label">Default Standard</span>
<span className="setting-value">IFRS</span>
</div>
<div className="setting-row">
<span className="setting-label">Base Currency</span>
<span className="setting-value">USD</span>
</div>
<div className="setting-row">
<span className="setting-label">Fiscal Year End</span>
<span className="setting-value">December 31</span>
</div>
<div className="setting-row">
<span className="setting-label">Auto-generate Reports</span>
<span className="setting-value">Monthly</span>
</div>
</div>
</div>
<div className="dashboard-card">
<div className="card-header"><h3>Enterprise Controls</h3></div>
<div className="settings-section">
<div className="setting-row">
<span className="setting-label">Multi-signature Required</span>
<span className="setting-value">Yes (2-of-3)</span>
</div>
<div className="setting-row">
<span className="setting-label">Transaction Limit</span>
<span className="setting-value">$10,000,000</span>
</div>
<div className="setting-row">
<span className="setting-label">Approval Workflow</span>
<span className="setting-value">Dual Authorization</span>
</div>
<div className="setting-row">
<span className="setting-label">Session Timeout</span>
<span className="setting-value">30 minutes</span>
</div>
<div className="setting-row">
<span className="setting-label">Audit Logging</span>
<span className="setting-value">Enabled (Full)</span>
</div>
</div>
</div>
</div>
</div>
);
}