chore: add build artifacts, map assets, and routing data

This commit is contained in:
Hamza-Ayed
2026-09-19 12:34:24 +03:00
parent aa2b9f131f
commit 43ad2e0ad4
327 changed files with 52421 additions and 1810 deletions
+194 -78
View File
@@ -6,7 +6,6 @@ import CompareView from './pages/CompareView'
import IntelligenceDashboard from './pages/IntelligenceDashboard'
import { ExecutiveShowcase } from './pages/ExecutiveShowcase'
import { TacticalDefenseView } from './pages/TacticalDefenseView'
import { SiroStrategicReport } from './pages/SiroStrategicReport'
import './index.css'
maplibregl.setRTLTextPlugin(
@@ -15,62 +14,175 @@ maplibregl.setRTLTextPlugin(
true
);
// Lightweight hash router
// Lightweight hash router with Sovereign Executive Styling
const NAV = [
{ hash: '#siro', label: 'تقرير المركز الجغرافي (سيرو)', icon: '🏛️' },
{ hash: '#tactical', label: 'المنظومة التكتيكية العسكرية', icon: '🎖️' },
{ hash: '#map', label: 'الخريطة والطقس والملاحة', icon: '🗺️' },
{ hash: '#compare', label: 'مقارنة العمالقة والأسعار', icon: '⚖️' },
{ hash: '#review', label: 'تدقيق الطرق الذكي', icon: '🔍' },
]
function ViewNav({ hash }: { hash: string }) {
const currentHash = hash || '#siro'
function MasterHeader({ hash }: { hash: string }) {
const currentHash = hash || '#tactical'
const [isFullscreen, setIsFullscreen] = useState(false);
const toggleFullscreen = () => {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen().catch(() => {});
setIsFullscreen(true);
} else {
document.exitFullscreen().catch(() => {});
setIsFullscreen(false);
}
};
return (
<div style={{
<header style={{
position: 'fixed',
top: 12,
left: '50%',
transform: 'translateX(-50%)',
top: 0,
left: 0,
right: 0,
height: 52,
zIndex: 9999,
display: 'flex',
alignItems: 'center',
gap: 4,
background: 'rgba(255, 255, 255, 0.88)',
backdropFilter: 'blur(20px)',
border: '1px solid rgba(0, 0, 0, 0.1)',
boxShadow: '0 4px 20px rgba(0, 0, 0, 0.08)',
borderRadius: 999,
padding: '4px 6px',
justifyContent: 'space-between',
padding: '0 16px',
background: 'rgba(9, 14, 26, 0.94)',
backdropFilter: 'blur(24px)',
WebkitBackdropFilter: 'blur(24px)',
borderBottom: '1px solid rgba(255, 255, 255, 0.08)',
boxShadow: '0 4px 20px rgba(0, 0, 0, 0.4)',
fontFamily: "'IBM Plex Sans Arabic', Inter, system-ui, sans-serif",
direction: 'rtl',
maxWidth: 'calc(100vw - 24px)',
overflowX: 'auto'
userSelect: 'none'
}}>
{NAV.map(n => {
const active = currentHash === n.hash
return (
<a key={n.hash} href={n.hash}
style={{
textDecoration: 'none',
fontSize: 12,
fontWeight: 700,
color: active ? '#fff' : '#64748b',
background: active ? 'linear-gradient(135deg, #0071e3, #4f46e5)' : 'transparent',
boxShadow: active ? '0 2px 8px rgba(0, 113, 227, 0.35)' : 'none',
padding: '6px 14px',
borderRadius: 999,
{/* Right Section: Brand & Sovereign Security Clearance */}
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
<a href="#tactical" style={{ textDecoration: 'none', display: 'flex', alignItems: 'center', gap: 8 }}>
<div style={{
width: 32,
height: 32,
borderRadius: 9,
background: 'linear-gradient(135deg, #0071e3, #6366f1)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
boxShadow: '0 0 14px rgba(0, 113, 227, 0.5)'
}}>
<span style={{ fontSize: 16 }}>⚡</span>
</div>
<div>
<div style={{
color: '#ffffff',
fontSize: '0.85rem',
fontWeight: 800,
letterSpacing: '-0.02em',
display: 'flex',
alignItems: 'center',
gap: 6,
transition: 'all 0.15s ease'
gap: 6
}}>
<span>{n.icon}</span>
<span>{n.label}</span>
</a>
)
})}
</div>
<span>منظومة انطلاق المكانية</span>
<span style={{
fontSize: '9.5px',
background: 'rgba(0, 113, 227, 0.25)',
border: '1px solid rgba(0, 113, 227, 0.5)',
color: '#38bdf8',
padding: '1px 5px',
borderRadius: 4,
fontWeight: 700
}}>
Sovereign Cloud v3.2
</span>
</div>
</div>
</a>
</div>
{/* Center Section: Master Navigation Segmented Controller */}
<nav style={{
display: 'flex',
alignItems: 'center',
gap: 3,
background: 'rgba(255, 255, 255, 0.05)',
border: '1px solid rgba(255, 255, 255, 0.1)',
padding: '3px 4px',
borderRadius: 12,
boxShadow: 'inset 0 1px 4px rgba(0, 0, 0, 0.3)'
}}>
{NAV.map(n => {
const active = currentHash === n.hash
return (
<a key={n.hash} href={n.hash}
style={{
textDecoration: 'none',
fontSize: 12,
fontWeight: active ? 800 : 600,
color: active ? '#ffffff' : '#94a3b8',
background: active
? 'linear-gradient(135deg, #0071e3, #4f46e5)'
: 'transparent',
boxShadow: active ? '0 2px 10px rgba(0, 113, 227, 0.45)' : 'none',
padding: '6px 12px',
borderRadius: 9,
display: 'flex',
alignItems: 'center',
gap: 6,
transition: 'all 0.15s ease'
}}>
<span style={{ fontSize: 13 }}>{n.icon}</span>
<span>{n.label}</span>
</a>
)
})}
</nav>
{/* Left Section: Live Sovereign Telemetry & Fullscreen */}
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
<div style={{
display: 'flex',
alignItems: 'center',
gap: 6,
background: 'rgba(34, 197, 94, 0.12)',
border: '1px solid rgba(34, 197, 94, 0.3)',
color: '#4ade80',
padding: '4px 10px',
borderRadius: 8,
fontSize: '0.72rem',
fontWeight: 700
}}>
<span style={{
display: 'inline-block',
width: 7,
height: 7,
borderRadius: '50%',
background: '#22c55e',
boxShadow: '0 0 8px #22c55e'
}} />
<span>السحابة السيادية متصلة</span>
</div>
<button
onClick={toggleFullscreen}
title="ملء الشاشة"
style={{
background: 'rgba(255, 255, 255, 0.06)',
border: '1px solid rgba(255, 255, 255, 0.12)',
color: '#cbd5e1',
padding: '5px 9px',
borderRadius: 8,
fontSize: '0.75rem',
cursor: 'pointer',
fontWeight: 600,
display: 'flex',
alignItems: 'center',
gap: 4
}}
>
<span>{isFullscreen ? '🗗' : '🗖'}</span>
</button>
</div>
</header>
)
}
@@ -97,8 +209,8 @@ class ErrorBoundary extends React.Component<{ children: React.ReactNode }, { has
alignItems: 'center',
justifyContent: 'center',
height: '100vh',
background: '#f8fafc',
color: '#1d1d1f',
background: '#090e1a',
color: '#ffffff',
fontFamily: 'system-ui, sans-serif',
direction: 'rtl',
padding: 24,
@@ -106,7 +218,7 @@ class ErrorBoundary extends React.Component<{ children: React.ReactNode }, { has
}}>
<div style={{ fontSize: '3rem', marginBottom: 16 }}>⚠️</div>
<h2 style={{ fontSize: '1.4rem', fontWeight: 700, marginBottom: 8 }}>حدث خطأ أثناء تحميل الواجهة</h2>
<p style={{ color: '#64748b', fontSize: '0.9rem', maxWidth: 450, marginBottom: 20 }}>
<p style={{ color: '#94a3b8', fontSize: '0.9rem', maxWidth: 450, marginBottom: 20 }}>
{this.state.error?.message || 'تعذر تحميل أحد مكونات الخريطة'}
</p>
<button
@@ -132,11 +244,11 @@ class ErrorBoundary extends React.Component<{ children: React.ReactNode }, { has
}
function Root() {
const [hash, setHash] = useState(window.location.hash || '#executive');
const [hash, setHash] = useState(window.location.hash || '#tactical');
useEffect(() => {
const on = () => {
const h = window.location.hash || '#executive';
const h = window.location.hash || '#tactical';
setHash(h);
setTimeout(() => {
window.dispatchEvent(new Event('resize'));
@@ -146,8 +258,7 @@ function Root() {
return () => window.removeEventListener('hashchange', on);
}, []);
const isSiro = hash === '#siro' || hash === '#report' || hash === '' || hash === '#executive';
const isTactical = hash === '#tactical' || hash === '#military';
const isTactical = hash === '#tactical' || hash === '#military' || hash === '' || hash === '#siro';
const isExecutive = hash === '#showcase' || hash === '#pitch';
const isCompare = hash === '#compare';
const isReview = hash === '#review';
@@ -155,43 +266,48 @@ function Root() {
return (
<ErrorBoundary>
<ViewNav hash={hash} />
<MasterHeader hash={hash} />
{isSiro && (
<div style={{ width: '100vw', height: '100vh', position: 'absolute', top: 0, left: 0, overflowY: 'auto', overflowX: 'hidden' }}>
<SiroStrategicReport />
</div>
)}
<main style={{
position: 'absolute',
top: 52,
bottom: 0,
left: 0,
right: 0,
width: '100vw',
height: 'calc(100vh - 52px)',
overflow: 'hidden'
}}>
{isTactical && (
<div style={{ width: '100%', height: '100%' }}>
<TacticalDefenseView />
</div>
)}
{isTactical && (
<div style={{ width: '100vw', height: '100vh', position: 'absolute', top: 0, left: 0 }}>
<TacticalDefenseView />
</div>
)}
{isExecutive && (
<div style={{ width: '100%', height: '100%', overflowY: 'auto', overflowX: 'hidden' }}>
<ExecutiveShowcase />
</div>
)}
{isExecutive && (
<div style={{ width: '100vw', height: '100vh', position: 'absolute', top: 0, left: 0, overflowY: 'auto', overflowX: 'hidden' }}>
<ExecutiveShowcase />
</div>
)}
{isCompare && (
<div style={{ width: '100%', height: '100%' }}>
<CompareView />
</div>
)}
{isCompare && (
<div style={{ width: '100vw', height: '100vh', position: 'absolute', top: 0, left: 0 }}>
<CompareView />
</div>
)}
{isReview && (
<div style={{ width: '100%', height: '100%' }}>
<IntelligenceDashboard />
</div>
)}
{isReview && (
<div style={{ width: '100vw', height: '100vh', position: 'absolute', top: 0, left: 0 }}>
<IntelligenceDashboard />
</div>
)}
{isMap && (
<div style={{ width: '100vw', height: '100vh', position: 'absolute', top: 0, left: 0 }}>
<App />
</div>
)}
{isMap && (
<div style={{ width: '100%', height: '100%' }}>
<App />
</div>
)}
</main>
</ErrorBoundary>
);
}