Files
CurrenciCombo/src/components/TitleBar.tsx
T
Devin AIandNakamoto, S <[email protected]> 52676016fb 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 <[email protected]>
2026-04-18 17:20:13 +00:00

167 lines
6.5 KiB
TypeScript

import { useState } from 'react';
import {
Search, Bell, ChevronDown, Play, FlaskConical, ShieldCheck, Zap,
Command, User, LogOut, Settings, Shield
} from 'lucide-react';
import type { SessionMode } from '../types';
import { sampleNotifications } from '../data/sampleData';
const modeColors: Record<SessionMode, string> = {
Sandbox: '#eab308',
Simulate: '#3b82f6',
Live: '#22c55e',
'Compliance Review': '#a855f7',
};
interface TitleBarProps {
mode: SessionMode;
onModeChange: (mode: SessionMode) => void;
onToggleCommandPalette: () => void;
onValidate: () => void;
onSimulate: () => void;
onExecute: () => void;
}
export default function TitleBar({ mode, onModeChange, onToggleCommandPalette, onValidate, onSimulate, onExecute }: TitleBarProps) {
const [showModeMenu, setShowModeMenu] = useState(false);
const [showNotifications, setShowNotifications] = useState(false);
const [showUserMenu, setShowUserMenu] = useState(false);
const [notifications, setNotifications] = useState(sampleNotifications);
const modes: SessionMode[] = ['Sandbox', 'Simulate', 'Live', 'Compliance Review'];
const unreadCount = notifications.filter(n => !n.read).length;
const markAllRead = () => {
setNotifications(prev => prev.map(n => ({ ...n, read: true })));
};
const notifTypeColors: Record<string, string> = {
info: '#3b82f6',
success: '#22c55e',
warning: '#eab308',
error: '#ef4444',
};
return (
<div className="title-bar">
<div className="title-bar-left">
<div className="title-bar-logo">
<Zap size={18} color="#3b82f6" />
<span className="title-bar-name">TransactFlow</span>
</div>
<div className="title-bar-separator" />
<span className="title-bar-workspace">Institutional Workspace</span>
<div className="title-bar-separator" />
<div className="mode-selector" onClick={() => setShowModeMenu(!showModeMenu)}>
<div className="mode-dot" style={{ background: modeColors[mode] }} />
<span>{mode}</span>
<ChevronDown size={12} />
{showModeMenu && (
<div className="mode-dropdown">
{modes.map(m => (
<div
key={m}
className={`mode-option ${m === mode ? 'active' : ''}`}
onClick={(e) => { e.stopPropagation(); onModeChange(m); setShowModeMenu(false); }}
>
<div className="mode-dot" style={{ background: modeColors[m] }} />
{m}
</div>
))}
</div>
)}
</div>
</div>
<div className="title-bar-center">
<button className="title-bar-search" onClick={onToggleCommandPalette}>
<Search size={13} />
<span>Search or run command...</span>
<kbd>Ctrl+K</kbd>
</button>
</div>
<div className="title-bar-right">
<button className="title-bar-action validate" title="Validate (Ctrl+Shift+V)" onClick={onValidate}>
<ShieldCheck size={15} />
<span>Validate</span>
</button>
<button className="title-bar-action simulate" title="Simulate (Ctrl+Shift+S)" onClick={onSimulate}>
<FlaskConical size={15} />
<span>Simulate</span>
</button>
<button className="title-bar-action execute" title="Execute (Ctrl+Shift+E)" onClick={onExecute}>
<Play size={15} />
<span>Execute</span>
</button>
<div className="title-bar-separator" />
{/* Notification bell with dropdown */}
<div className="notification-wrapper">
<button className="icon-btn" title="Notifications" onClick={() => { setShowNotifications(!showNotifications); setShowUserMenu(false); }}>
<Bell size={16} />
{unreadCount > 0 && <span className="notification-badge">{unreadCount}</span>}
</button>
{showNotifications && (
<div className="notification-dropdown">
<div className="notification-dropdown-header">
<span>Notifications</span>
{unreadCount > 0 && (
<button className="mark-read-btn" onClick={markAllRead}>Mark all read</button>
)}
</div>
{notifications.map(n => (
<div key={n.id} className={`notification-item ${n.read ? 'read' : ''}`} onClick={() => setNotifications(prev => prev.map(x => x.id === n.id ? { ...x, read: true } : x))}>
<div className="notification-dot" style={{ background: notifTypeColors[n.type] }} />
<div className="notification-content">
<span className="notification-title">{n.title}</span>
<span className="notification-message">{n.message}</span>
<span className="notification-time">{n.timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</span>
</div>
</div>
))}
</div>
)}
</div>
<button className="icon-btn" title="Command Palette" onClick={onToggleCommandPalette}>
<Command size={16} />
</button>
{/* User menu with dropdown */}
<div className="user-menu-wrapper">
<button className="icon-btn user-btn" title="User Settings" onClick={() => { setShowUserMenu(!showUserMenu); setShowNotifications(false); }}>
<User size={16} />
</button>
{showUserMenu && (
<div className="user-menu-dropdown">
<div className="user-menu-profile">
<div className="user-avatar">JD</div>
<div>
<div className="user-name">Jane Doe</div>
<div className="user-role">Admin · Compliance Officer</div>
</div>
</div>
<div className="user-menu-divider" />
<div className="user-menu-item">
<User size={13} /> <span>Profile</span>
</div>
<div className="user-menu-item">
<Settings size={13} /> <span>Settings</span>
</div>
<div className="user-menu-item">
<Shield size={13} /> <span>Permissions</span>
<span className="user-menu-badge">Admin</span>
</div>
<div className="user-menu-divider" />
<div className="user-menu-item logout">
<LogOut size={13} /> <span>Sign Out</span>
</div>
</div>
)}
</div>
</div>
</div>
);
}