Deploy Phase 4.7: AI & Tech Special Silo and create QUANT_ROADMAP.md
This commit is contained in:
525
components/modules/tech/AiSpecialSilo.tsx
Normal file
525
components/modules/tech/AiSpecialSilo.tsx
Normal file
@@ -0,0 +1,525 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { LineChart, Line, ResponsiveContainer } from 'recharts';
|
||||
import 'katex/dist/katex.min.css';
|
||||
import TechMathModal from './TechMathModal';
|
||||
import {
|
||||
Cpu, AlertCircle, BookOpen, Activity, Zap, TrendingUp, TrendingDown,
|
||||
ArrowUpRight, ArrowDownRight, Minus, Server, Wallet
|
||||
} from 'lucide-react';
|
||||
|
||||
interface TickerMetricData {
|
||||
quarter: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
interface SupplyChainDataPoint {
|
||||
quarter: string;
|
||||
nvdaInvTurnover: number;
|
||||
aggregateObligations: number;
|
||||
velocityIndex: number;
|
||||
}
|
||||
|
||||
interface Payload {
|
||||
dates: string[];
|
||||
liveDataAvailable: boolean;
|
||||
timestamp: number;
|
||||
metrics: {
|
||||
monetizationGap: {
|
||||
name: string;
|
||||
tickers: Record<string, {
|
||||
current: number;
|
||||
previous: number;
|
||||
trend: 'UP' | 'DOWN' | 'FLAT';
|
||||
segmentRevenueGrowth: number;
|
||||
capexGrowth: number;
|
||||
roiToCapex: number;
|
||||
data: {
|
||||
quarter: string;
|
||||
monetizationGap: number;
|
||||
roiToCapex: number;
|
||||
segmentRevenueGrowth: number;
|
||||
capexGrowth: number;
|
||||
}[];
|
||||
}>;
|
||||
};
|
||||
supplyChain: {
|
||||
name: string;
|
||||
unit: string;
|
||||
currentVelocity: number;
|
||||
previousVelocity: number;
|
||||
currentTurnover: number;
|
||||
currentObligations: number;
|
||||
trend: 'UP' | 'DOWN' | 'FLAT';
|
||||
data: SupplyChainDataPoint[];
|
||||
};
|
||||
infrastructure: {
|
||||
name: string;
|
||||
tickers: Record<string, {
|
||||
currentDE: number;
|
||||
currentCapExDep: number;
|
||||
trendDE: 'UP' | 'DOWN' | 'FLAT';
|
||||
data: {
|
||||
quarter: string;
|
||||
de: number;
|
||||
capexDep: number;
|
||||
debt: number;
|
||||
equity: number;
|
||||
}[];
|
||||
}>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default function AiSpecialSilo() {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [payload, setPayload] = useState<Payload | null>(null);
|
||||
const [isMathModalOpen, setIsMathModalOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const response = await fetch('/api/tech/ai');
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
setPayload(data);
|
||||
} else {
|
||||
setError('Error fetching AI Tech Hyper-Leverage metrics.');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Fetch tech metrics error:', err);
|
||||
setError('Network error loading AI Special Silo data.');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-8 text-slate-100 shadow-xl min-h-[450px] flex flex-col items-center justify-center space-y-4">
|
||||
<div className="w-10 h-10 rounded-full border-2 border-teal-400 border-t-transparent animate-spin" />
|
||||
<div className="text-slate-400 text-sm font-mono animate-pulse">Ingesting quarterly balance sheets & tech indicators...</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (error || !payload) {
|
||||
return (
|
||||
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-6 text-slate-100 shadow-xl min-h-[400px] flex items-center justify-center">
|
||||
<div className="text-rose-400 font-semibold flex items-center gap-2">
|
||||
<AlertCircle className="w-5 h-5" /> {error || 'Error loading data.'}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const { monetizationGap, supplyChain, infrastructure } = payload.metrics;
|
||||
|
||||
// HSL Status Colors based on metric thresholds
|
||||
const getMonetizationStatus = () => {
|
||||
const gaps = Object.values(monetizationGap.tickers).map(t => t.current);
|
||||
const minGap = Math.min(...gaps);
|
||||
if (minGap < -15) return 'RED';
|
||||
if (minGap < 0) return 'AMBER';
|
||||
return 'GREEN';
|
||||
};
|
||||
|
||||
const getSupplyChainStatus = () => {
|
||||
const vel = supplyChain.currentVelocity;
|
||||
if (vel < 1.8 || supplyChain.trend === 'DOWN') return 'RED';
|
||||
if (vel < 3.0) return 'AMBER';
|
||||
return 'GREEN';
|
||||
};
|
||||
|
||||
const getInfrastructureStatus = () => {
|
||||
const ratios = Object.values(infrastructure.tickers).map(t => t.currentCapExDep);
|
||||
const maxRatio = Math.max(...ratios);
|
||||
const des = Object.values(infrastructure.tickers).map(t => t.currentDE);
|
||||
const maxDE = Math.max(...des);
|
||||
|
||||
if (maxRatio > 4.0 || maxDE > 1.2) return 'RED';
|
||||
if (maxRatio > 2.5 || maxDE > 0.8) return 'AMBER';
|
||||
return 'GREEN';
|
||||
};
|
||||
|
||||
const monetizationStatus = getMonetizationStatus();
|
||||
const supplyStatus = getSupplyChainStatus();
|
||||
const infraStatus = getInfrastructureStatus();
|
||||
|
||||
// Helper for trend icons
|
||||
const renderTrendIcon = (trend: 'UP' | 'DOWN' | 'FLAT', isDangerUp = false) => {
|
||||
const baseClass = "w-3.5 h-3.5 inline-block align-middle";
|
||||
if (trend === 'UP') {
|
||||
return <ArrowUpRight className={`${baseClass} ${isDangerUp ? 'text-rose-400' : 'text-emerald-400'}`} />;
|
||||
}
|
||||
if (trend === 'DOWN') {
|
||||
return <ArrowDownRight className={`${baseClass} ${isDangerUp ? 'text-emerald-400' : 'text-rose-400'}`} />;
|
||||
}
|
||||
return <Minus className={`${baseClass} text-slate-500`} />;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
|
||||
{/* ⚠️ Dynamic Rate-Limit Fallback Banner */}
|
||||
{!payload.liveDataAvailable && (
|
||||
<div className="bg-rose-955/40 border border-rose-800/80 text-rose-400 text-xs rounded-xl p-4 flex items-center gap-3 shadow-[0_0_15px_rgba(244,63,94,0.15)] animate-pulse">
|
||||
<AlertCircle className="w-5 h-5 text-rose-400 shrink-0" />
|
||||
<div className="flex-1">
|
||||
<span className="font-bold font-mono uppercase tracking-wider block mb-0.5">[⚠️ API Limit - Fallback Archive Active]</span>
|
||||
Real-time API balance sheet fetches are rate-limited (FMP HTTP 429). The workstation has initialized fallback calculations using the high-fidelity historical archive.
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* HEADER SECTION */}
|
||||
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-6 text-slate-100 shadow-xl relative overflow-hidden">
|
||||
<div className="absolute top-0 right-0 w-32 h-32 bg-teal-500/10 rounded-full blur-3xl -z-10" />
|
||||
|
||||
<div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
|
||||
<div className="space-y-1">
|
||||
<span className="text-teal-400 text-xs font-semibold uppercase tracking-wider">AI & Tech Silo</span>
|
||||
<h2 className="text-2xl font-extrabold text-white flex items-center gap-2">
|
||||
<Zap className="text-teal-400 w-6 h-6" /> AI Hyper-Leverage & CapEx Matrix
|
||||
</h2>
|
||||
<p className="text-xs text-slate-400">
|
||||
Monitors Big Tech capital expenditures, segment revenues, and inventory velocities to diagnose infrastructure bubbles.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-3 w-full md:w-auto justify-end">
|
||||
<button
|
||||
onClick={() => setIsMathModalOpen(true)}
|
||||
className="flex items-center gap-1.5 px-4 py-2.5 rounded-xl bg-slate-955/80 hover:bg-slate-900 border border-slate-800 hover:border-slate-700 transition-all font-semibold text-xs tracking-wider text-teal-400 w-full md:w-auto justify-center h-11 cursor-pointer"
|
||||
>
|
||||
<BookOpen className="w-4 h-4" />
|
||||
<span>📖 Modulerklärung</span>
|
||||
</button>
|
||||
|
||||
<div className="bg-slate-955/80 border border-slate-800 rounded-xl px-4 py-2 text-right shrink-0 h-11 flex flex-col justify-center">
|
||||
<div className="text-[9px] text-slate-500 uppercase font-mono">Archive State</div>
|
||||
<div className="font-mono text-xs text-slate-300">
|
||||
{new Date(payload.timestamp).toLocaleTimeString()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 🚥 3 LARGE GLOWING NEON-AMPEL CARDS */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
|
||||
{/* CARD 1: ROI-to-CapEx & Monetization Gap */}
|
||||
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-850 rounded-2xl p-5 relative overflow-hidden shadow-lg flex flex-col justify-between min-h-[140px]">
|
||||
<div className="absolute top-0 right-0 w-24 h-24 bg-gradient-to-br from-indigo-500/10 to-transparent rounded-full blur-2xl pointer-events-none" />
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="space-y-1">
|
||||
<div className="text-[10px] text-indigo-400 uppercase font-bold tracking-widest font-mono">1. ROI-to-CapEx & Monetization Gap</div>
|
||||
<div className="text-lg font-black text-white leading-tight">Monetization Gap</div>
|
||||
<div className="text-[10px] text-slate-400">YoY Segment Rev Growth minus CapEx Growth</div>
|
||||
</div>
|
||||
|
||||
<span className={`w-3.5 h-3.5 rounded-full ${
|
||||
monetizationStatus === 'GREEN' ? 'bg-emerald-500 shadow-[0_0_10px_#10b981]' :
|
||||
monetizationStatus === 'AMBER' ? 'bg-amber-500 shadow-[0_0_10px_#fbbf24]' :
|
||||
'bg-rose-500 shadow-[0_0_10px_#f43f5e] animate-pulse'
|
||||
}`} />
|
||||
</div>
|
||||
|
||||
<div className="mt-4 pt-4 border-t border-slate-850 flex justify-between items-end">
|
||||
<div>
|
||||
<div className="text-[9px] uppercase font-mono text-slate-500">Max Divergence</div>
|
||||
<div className="font-mono text-xl font-bold text-slate-200">
|
||||
{Math.min(...Object.values(monetizationGap.tickers).map(t => t.current)).toFixed(1)}%
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-[9px] uppercase font-mono text-slate-500">Global Trend</div>
|
||||
<div className="text-xs font-semibold text-slate-300 flex items-center gap-1 justify-end">
|
||||
{renderTrendIcon(monetizationStatus === 'GREEN' ? 'UP' : 'DOWN')}
|
||||
<span>{monetizationStatus === 'GREEN' ? 'Stable' : monetizationStatus === 'AMBER' ? 'Diverging' : 'Bubble Risk'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* CARD 2: Nvidia Supply-Chain Velocity */}
|
||||
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-850 rounded-2xl p-5 relative overflow-hidden shadow-lg flex flex-col justify-between min-h-[140px]">
|
||||
<div className="absolute top-0 right-0 w-24 h-24 bg-gradient-to-br from-teal-500/10 to-transparent rounded-full blur-2xl pointer-events-none" />
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="space-y-1">
|
||||
<div className="text-[10px] text-teal-400 uppercase font-bold tracking-widest font-mono">2. Supply-Chain Commitments</div>
|
||||
<div className="text-lg font-black text-white leading-tight">Nvidia SC Velocity</div>
|
||||
<div className="text-[10px] text-slate-400">Buyer commitments relative to NVDA inventory</div>
|
||||
</div>
|
||||
|
||||
<span className={`w-3.5 h-3.5 rounded-full ${
|
||||
supplyStatus === 'GREEN' ? 'bg-emerald-500 shadow-[0_0_10px_#10b981]' :
|
||||
supplyStatus === 'AMBER' ? 'bg-amber-500 shadow-[0_0_10px_#fbbf24]' :
|
||||
'bg-rose-500 shadow-[0_0_10px_#f43f5e] animate-pulse'
|
||||
}`} />
|
||||
</div>
|
||||
|
||||
<div className="mt-4 pt-4 border-t border-slate-850 flex justify-between items-end">
|
||||
<div>
|
||||
<div className="text-[9px] uppercase font-mono text-slate-500">Velocity Index</div>
|
||||
<div className="font-mono text-xl font-bold text-slate-200">
|
||||
{supplyChain.currentVelocity}x
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-[9px] uppercase font-mono text-slate-500">NVDA Inv Turnover</div>
|
||||
<div className="font-mono text-xs font-bold text-slate-355">
|
||||
{supplyChain.currentTurnover}x
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* CARD 3: Tech Infrastructure Leverage */}
|
||||
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-850 rounded-2xl p-5 relative overflow-hidden shadow-lg flex flex-col justify-between min-h-[140px]">
|
||||
<div className="absolute top-0 right-0 w-24 h-24 bg-gradient-to-br from-purple-500/10 to-transparent rounded-full blur-2xl pointer-events-none" />
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="space-y-1">
|
||||
<div className="text-[10px] text-purple-400 uppercase font-bold tracking-widest font-mono">3. Cluster Construction Leverage</div>
|
||||
<div className="text-lg font-black text-white leading-tight">Infrastructure Leverage</div>
|
||||
<div className="text-[10px] text-slate-400">Aggressive CapEx-to-Depreciation ratios</div>
|
||||
</div>
|
||||
|
||||
<span className={`w-3.5 h-3.5 rounded-full ${
|
||||
infraStatus === 'GREEN' ? 'bg-emerald-500 shadow-[0_0_10px_#10b981]' :
|
||||
infraStatus === 'AMBER' ? 'bg-amber-500 shadow-[0_0_10px_#fbbf24]' :
|
||||
'bg-rose-500 shadow-[0_0_10px_#f43f5e] animate-pulse'
|
||||
}`} />
|
||||
</div>
|
||||
|
||||
<div className="mt-4 pt-4 border-t border-slate-850 flex justify-between items-end">
|
||||
<div>
|
||||
<div className="text-[9px] uppercase font-mono text-slate-500">Max CapEx/Dep</div>
|
||||
<div className="font-mono text-xl font-bold text-slate-200">
|
||||
{Math.max(...Object.values(infrastructure.tickers).map(t => t.currentCapExDep)).toFixed(1)}x
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-[9px] uppercase font-mono text-slate-500">Structural Debt</div>
|
||||
<div className="font-mono text-xs font-bold text-slate-355">
|
||||
Max D/E: {Math.max(...Object.values(infrastructure.tickers).map(t => t.currentDE)).toFixed(2)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* DETAILED LEDGER GRID */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
|
||||
{/* PANEL A: ROI-TO-CAPEX & MONETIZATION GAPS */}
|
||||
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-6 shadow-xl space-y-4">
|
||||
<div className="space-y-0.5">
|
||||
<h3 className="text-sm font-bold text-white flex items-center gap-2">
|
||||
<Activity className="w-4 h-4 text-indigo-400" /> Monetization Gap & Segment Returns
|
||||
</h3>
|
||||
<p className="text-[10px] text-slate-400">
|
||||
Compares quarterly segment revenue growth trends against CapEx growth.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
{Object.entries(monetizationGap.tickers).map(([ticker, metrics]) => {
|
||||
const currentGap = metrics.current;
|
||||
|
||||
const gapColorClass = currentGap >= 0
|
||||
? 'text-emerald-400'
|
||||
: currentGap >= -15
|
||||
? 'text-amber-400 font-semibold'
|
||||
: 'text-rose-400 font-bold animate-pulse';
|
||||
|
||||
const strokeColor = currentGap >= 0
|
||||
? '#10b981'
|
||||
: currentGap >= -15
|
||||
? '#fbbf24'
|
||||
: '#f43f5e';
|
||||
|
||||
return (
|
||||
<div key={ticker} className="bg-slate-950/40 border border-slate-850 rounded-xl p-3 flex justify-between items-center hover:bg-slate-955/60 transition-colors">
|
||||
<div className="space-y-0.5 w-1/4">
|
||||
<div className="text-xs font-bold text-slate-200">{ticker}</div>
|
||||
<div className="text-[9px] text-slate-500 font-mono">
|
||||
Seg Rev QoQ: {metrics.segmentRevenueGrowth > 0 ? '+' : ''}{metrics.segmentRevenueGrowth}%
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Sparkline for Monetization Gap */}
|
||||
<div className="w-1/3 h-8">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<LineChart data={metrics.data}>
|
||||
<Line
|
||||
type="monotone"
|
||||
dataKey="monetizationGap"
|
||||
stroke={strokeColor}
|
||||
strokeWidth={1.5}
|
||||
dot={false}
|
||||
/>
|
||||
</LineChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
|
||||
<div className="text-right w-1/3 space-y-0.5">
|
||||
<div className="text-xs font-mono text-slate-400">
|
||||
ROI: <span className="font-semibold text-slate-200">{metrics.roiToCapex}%</span>
|
||||
</div>
|
||||
<div className={`font-mono text-sm font-bold ${gapColorClass}`}>
|
||||
Gap: {currentGap > 0 ? '+' : ''}{currentGap}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* PANEL B: TECH INFRASTRUCTURE LEVERAGE & CLUSTER HEALTH */}
|
||||
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-6 shadow-xl space-y-4">
|
||||
<div className="space-y-0.5">
|
||||
<h3 className="text-sm font-bold text-white flex items-center gap-2">
|
||||
<Server className="w-4 h-4 text-purple-400" /> Cluster Construction & Leverage Ratios
|
||||
</h3>
|
||||
<p className="text-[10px] text-slate-400">
|
||||
Tracks structural debt loads and CapEx spending compared to depreciation rate vectors.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
{Object.entries(infrastructure.tickers).map(([ticker, metrics]) => {
|
||||
const currentCapExDep = metrics.currentCapExDep;
|
||||
|
||||
const highlightClass = currentCapExDep > 4.0
|
||||
? 'text-rose-400 font-bold animate-pulse'
|
||||
: currentCapExDep > 2.5
|
||||
? 'text-amber-400 font-semibold'
|
||||
: 'text-emerald-400';
|
||||
|
||||
const strokeColor = currentCapExDep > 4.0
|
||||
? '#f43f5e'
|
||||
: currentCapExDep > 2.5
|
||||
? '#fbbf24'
|
||||
: '#10b981';
|
||||
|
||||
return (
|
||||
<div key={ticker} className="bg-slate-955/40 border border-slate-850 rounded-xl p-3 flex justify-between items-center hover:bg-slate-955/60 transition-colors">
|
||||
<div className="space-y-0.5 w-1/4">
|
||||
<div className="text-xs font-bold text-slate-200">{ticker}</div>
|
||||
<div className="text-[9px] text-slate-500 font-mono">
|
||||
D/E: {metrics.currentDE.toFixed(2)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Sparkline for D/E Ratio */}
|
||||
<div className="w-1/3 h-8">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<LineChart data={metrics.data}>
|
||||
<Line
|
||||
type="monotone"
|
||||
dataKey="de"
|
||||
stroke={strokeColor}
|
||||
strokeWidth={1.5}
|
||||
dot={false}
|
||||
/>
|
||||
</LineChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
|
||||
<div className="text-right w-1/3">
|
||||
<div className="text-[9px] text-slate-500 uppercase font-mono">CapEx/Depreciation</div>
|
||||
<div className={`font-mono text-sm font-bold ${highlightClass}`}>
|
||||
{currentCapExDep.toFixed(1)}x
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* PANEL C: SUPPLY CHAIN FLOW DETAILS */}
|
||||
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-6 shadow-xl space-y-4">
|
||||
<div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4 border-b border-slate-850 pb-4">
|
||||
<div className="space-y-0.5">
|
||||
<h3 className="text-sm font-bold text-white flex items-center gap-2">
|
||||
<Cpu className="w-4 h-4 text-teal-400" /> Nvidia Supply-Chain Velocity Timeline
|
||||
</h3>
|
||||
<p className="text-[10px] text-slate-400">
|
||||
Tracks the velocity of purchase commitments from top buyers (MSFT, GOOGL, META) relative to Nvidia's inventories.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4 text-xs font-mono text-slate-400 bg-slate-955/80 border border-slate-850 px-3 py-1.5 rounded-xl">
|
||||
<div>
|
||||
NVDA Inventory: <span className="text-slate-200 font-semibold">{supplyChain.data[supplyChain.data.length - 1].aggregateObligations / 1000}B$</span>
|
||||
</div>
|
||||
<div className="border-l border-slate-800 pl-4">
|
||||
Commitments: <span className="text-slate-200 font-semibold">{supplyChain.currentObligations / 1000}B$</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full border-collapse text-left text-xs text-slate-400 font-mono">
|
||||
<thead>
|
||||
<tr className="border-b border-slate-850 text-[10px] text-slate-555 uppercase">
|
||||
<th className="py-2">Quarter</th>
|
||||
<th className="py-2 text-right">Nvidia Inventory Turnover</th>
|
||||
<th className="py-2 text-right">Top Buyer Commitments</th>
|
||||
<th className="py-2 text-right">Velocity Index</th>
|
||||
<th className="py-2 text-center">Trend Indicator</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-slate-850">
|
||||
{supplyChain.data.map((row, idx) => {
|
||||
const prevRow = idx > 0 ? supplyChain.data[idx - 1] : row;
|
||||
const rowTrend = row.velocityIndex > prevRow.velocityIndex
|
||||
? 'UP'
|
||||
: row.velocityIndex < prevRow.velocityIndex
|
||||
? 'DOWN'
|
||||
: 'FLAT';
|
||||
|
||||
const velocityClass = row.velocityIndex < 2.0
|
||||
? 'text-rose-400 font-semibold font-bold'
|
||||
: row.velocityIndex < 3.0
|
||||
? 'text-amber-400'
|
||||
: 'text-emerald-400';
|
||||
|
||||
return (
|
||||
<tr key={row.quarter} className="hover:bg-slate-955/20 transition-colors">
|
||||
<td className="py-3 font-semibold text-slate-300">{row.quarter}</td>
|
||||
<td className="py-3 text-right text-slate-300">{row.nvdaInvTurnover.toFixed(2)}x</td>
|
||||
<td className="py-3 text-right text-slate-355">{(row.aggregateObligations / 1000).toFixed(1)}B$</td>
|
||||
<td className="py-3 text-right"><span className={velocityClass}>{row.velocityIndex.toFixed(2)}x</span></td>
|
||||
<td className="py-3 text-center">{renderTrendIcon(rowTrend, row.velocityIndex < 2.5)}</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Modulerklärung Modal */}
|
||||
<TechMathModal
|
||||
isOpen={isMathModalOpen}
|
||||
onClose={() => setIsMathModalOpen(false)}
|
||||
/>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user