Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m14s
CI/CD Pipeline / Security Scanning (push) Successful in 2m34s
CI/CD Pipeline / Lint and Format (push) Failing after 40s
CI/CD Pipeline / Terraform Validation (push) Failing after 24s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 26s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 37s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 22s
Validation / validate-genesis (push) Successful in 24s
Validation / validate-terraform (push) Failing after 24s
Validation / validate-kubernetes (push) Failing after 9s
Validation / validate-smart-contracts (push) Failing after 10s
Validation / validate-security (push) Failing after 1m22s
Validation / validate-documentation (push) Failing after 17s
Verify Deployment / Verify Deployment (push) Failing after 47s
Add VITE_ECOSYSTEM build profiles, Z-only nginx vhosts, standalone Z production stack script, and remove Z Chain from OMNL registry. Co-authored-by: Cursor <cursoragent@cursor.com>
93 lines
4.2 KiB
TypeScript
93 lines
4.2 KiB
TypeScript
import { Link, Outlet, useLocation } from 'react-router-dom';
|
|
import { useRef, useState } from 'react';
|
|
import WalletConnect from '../wallet/WalletConnect';
|
|
import WalletDisconnectNotice from '../wallet/WalletDisconnectNotice';
|
|
import NasaIcon, { type NasaIconName } from '../icons/NasaIcon';
|
|
import MobileNavDrawer from './MobileNavDrawer';
|
|
import MobileBottomNav from './MobileBottomNav';
|
|
|
|
const PRODUCTS: { path: string; label: string; icon: NasaIconName }[] = [
|
|
{ path: '/hub', label: 'DBIS Dashboard', icon: 'dashboard' },
|
|
{ path: '/central-bank', label: 'Central Bank', icon: 'central-bank' },
|
|
{ path: '/office-24', label: 'O24 Central Bank', icon: 'office' },
|
|
{ path: '/trade', label: 'Trade', icon: 'trade' },
|
|
{ path: '/swap', label: 'Swap', icon: 'swap' },
|
|
];
|
|
|
|
export default function OmnlProductLayout() {
|
|
const location = useLocation();
|
|
const userInitiatedDisconnectRef = useRef(false);
|
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
|
|
const isActive = (path: string) =>
|
|
path === '/hub' ? location.pathname === '/hub' : location.pathname.startsWith(path);
|
|
|
|
const drawerItems = [
|
|
...PRODUCTS.map((p) => ({ to: p.path, label: p.label, active: isActive(p.path) })),
|
|
{ to: '/bridge', label: 'Bridge', active: location.pathname === '/bridge' },
|
|
{ to: '/admin', label: 'Admin', active: location.pathname === '/admin' },
|
|
{ to: '/wallets', label: 'Wallets', active: location.pathname === '/wallets' },
|
|
];
|
|
|
|
const isBanking = location.pathname === '/central-bank';
|
|
|
|
return (
|
|
<div className={`omnl-app min-h-screen flex flex-col dbis-has-bottom-nav${isBanking ? ' omnl-banking-theme' : ''}`}>
|
|
<WalletDisconnectNotice userInitiatedDisconnectRef={userInitiatedDisconnectRef} />
|
|
<header className="omnl-app-header mobile-nav-bar sticky top-0 z-50 border-b border-green-500/20 safe-area-top bg-[#1a241c]">
|
|
<div className="max-w-[1600px] mx-auto px-3 sm:px-4 h-14 flex items-center gap-2 sm:gap-4">
|
|
<button
|
|
type="button"
|
|
className="md:hidden shrink-0 text-white p-2 min-h-[44px] min-w-[44px] rounded-lg hover:bg-white/10"
|
|
aria-label="Open menu"
|
|
aria-expanded={menuOpen}
|
|
onClick={() => setMenuOpen(true)}
|
|
>
|
|
☰
|
|
</button>
|
|
<Link to="/hub" className="flex items-center gap-2 shrink-0 min-w-0">
|
|
<span className="w-8 h-8 rounded-lg bg-green-600 text-white font-bold flex items-center justify-center text-sm shrink-0">
|
|
<NasaIcon name="central-bank" size={16} />
|
|
</span>
|
|
<span className="font-semibold hidden sm:inline text-sm truncate text-white">DBIS OMNL</span>
|
|
</Link>
|
|
|
|
<nav className="hidden md:flex items-center gap-1 flex-1 overflow-x-auto min-w-0" aria-label="OMNL products">
|
|
{PRODUCTS.map(({ path, label, icon }) => (
|
|
<Link
|
|
key={path}
|
|
to={path}
|
|
className={`px-3 py-2 rounded-lg text-sm font-medium transition-colors whitespace-nowrap min-h-[40px] flex items-center gap-1.5 ${
|
|
isActive(path) ? 'bg-green-600 text-white' : 'text-[#848e9c] hover:text-white hover:bg-white/5'
|
|
}`}
|
|
>
|
|
<NasaIcon name={icon} size={14} />
|
|
<span className="hidden lg:inline">{label}</span>
|
|
<span className="lg:hidden">{label.split(' ')[0]}</span>
|
|
</Link>
|
|
))}
|
|
</nav>
|
|
|
|
<Link
|
|
to="/bridge"
|
|
className="hidden lg:inline-flex items-center gap-1.5 px-3 py-2 rounded-lg text-sm font-medium text-[#848e9c] hover:text-white hover:bg-white/5 min-h-[40px]"
|
|
>
|
|
<NasaIcon name="bridge" size={14} />
|
|
Bridge
|
|
</Link>
|
|
<div className="shrink-0 max-w-[45%] sm:max-w-none ml-auto">
|
|
<WalletConnect onBeforeDisconnect={() => { userInitiatedDisconnectRef.current = true; }} />
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<MobileNavDrawer open={menuOpen} onClose={() => setMenuOpen(false)} title="DBIS OMNL" items={drawerItems} />
|
|
<MobileBottomNav onOpenMenu={() => setMenuOpen(true)} />
|
|
|
|
<main className="flex-1 w-full min-w-0 overflow-x-hidden">
|
|
<Outlet />
|
|
</main>
|
|
</div>
|
|
);
|
|
}
|