Closes #011 - Refactor Smart Money tab and extend DEV_MODE shield
This commit is contained in:
16
DEV_LOG.md
16
DEV_LOG.md
@@ -73,5 +73,21 @@ This document tracks all modifications, npm packages, active compilation states,
|
|||||||
* **Active Bugs**: None.
|
* **Active Bugs**: None.
|
||||||
* **Type Checker Status**: Verified clean compilation (`npx tsc --noEmit` returns exit code 0).
|
* **Type Checker Status**: Verified clean compilation (`npx tsc --noEmit` returns exit code 0).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [2026-06-12] - Smart-Money Refactoring, Visual Consolidation & Security Shield (#ISSUE-011)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
* **Insider API Outbound Interception Layer**: Configured [/api/insider/route.ts](file:///c:/Users/jannr/.gemini/antigravity/scratch/investment-sandbox/app/api/insider/route.ts) to intercept requests when `process.env.DEV_MODE === 'true'`, short-circuiting live FMP calls and returning high-fidelity mock streams with `isShieldActive: true`.
|
||||||
|
* **Insider UI Workstation badge**: Upgraded [InsiderDemo.tsx](file:///c:/Users/jannr/.gemini/antigravity/scratch/investment-sandbox/components/modules/insider/InsiderDemo.tsx) to read the shield state and render the glowing amber status badge `🟡 DEV-ARCHIV AKTIV (0 CALLS)` when active.
|
||||||
|
|
||||||
|
### Modified
|
||||||
|
* **`app/page.tsx`**: Consolidated the separate `Insider` and `Whale Screener` tabs under a single `Smart Money` tab (activeTab `'smart-money'`). Implemented an interactive sub-tab selector toggle in the layout switcher. Removed bracket labels from the `⚡ AI Special Silo` navigation button.
|
||||||
|
* **`QUANT_ROADMAP.md`**: Updated Section 1 and Section 3 to document the Smart Money visual consolidation.
|
||||||
|
|
||||||
|
### Active Bugs / Compile Status
|
||||||
|
* **Active Bugs**: None.
|
||||||
|
* **Type Checker Status**: Verified clean compilation (`npx tsc --noEmit` returns exit code 0).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ This document serves as the permanent, centralized system architecture design an
|
|||||||
* **Phase 3.0: Real FRED Macro Ingestion**
|
* **Phase 3.0: Real FRED Macro Ingestion**
|
||||||
* *Features*: Real-time server-side API integration with Federal Reserve Economic Data (FRED). Ingests Personal Savings Rates, Credit Card Delinquencies, Housing Starts, and Case-Shiller indices.
|
* *Features*: Real-time server-side API integration with Federal Reserve Economic Data (FRED). Ingests Personal Savings Rates, Credit Card Delinquencies, Housing Starts, and Case-Shiller indices.
|
||||||
* *Status*: **Fully Operational (Production Lock)**.
|
* *Status*: **Fully Operational (Production Lock)**.
|
||||||
* **Phase 3.0: Whale Satellite-Screener**
|
* **Phase 3.0: Smart Money & Whale Satellite-Screener**
|
||||||
* *Features*: Track high-conviction institutional shifts (SEC Form 13F filings) for Scion (Michael Burry), Akre Capital, and Mairs & Power. Calculates Velocity of Conviction (VoC) weight deltas, integrated with `DEV_MODE` offline protection shield.
|
* *Features*: Track high-conviction institutional shifts (SEC Form 13F filings) for Scion (Michael Burry), Akre Capital, and Mairs & Power. Calculates Velocity of Conviction (VoC) weight deltas, integrated with `DEV_MODE` offline protection shield. Consolidated under the unified 'Smart Money' workstation with a sub-tab switcher alongside broad corporate and congressional flows.
|
||||||
* *Status*: **Fully Operational (Production Lock)**.
|
* *Status*: **Fully Operational (Production Lock)**.
|
||||||
* **Phase 4.7: AI & Tech Hyper-Leverage Silo**
|
* **Phase 4.7: AI & Tech Hyper-Leverage Silo**
|
||||||
* *Features*: Track the AI CapEx-Overinvestment Cycle for NVDA, MSFT, GOOGL, META, and AMD. Calculates ROI-to-CapEx (Monetization Gap), Nvidia Supply-Chain Velocity Index, and Tech Infrastructure Leverage with a 60-minute caching layer.
|
* *Features*: Track the AI CapEx-Overinvestment Cycle for NVDA, MSFT, GOOGL, META, and AMD. Calculates ROI-to-CapEx (Monetization Gap), Nvidia Supply-Chain Velocity Index, and Tech Infrastructure Leverage with a 60-minute caching layer.
|
||||||
@@ -97,6 +97,7 @@ graph TD
|
|||||||
### Implemented Architecture
|
### Implemented Architecture
|
||||||
- **API Endpoint**: [/api/whale/screener](file:///c:/Users/jannr/.gemini/antigravity/scratch/investment-sandbox/app/api/whale/screener/route.ts) fetches SEC Form 13F filings for Scion Asset Management (Michael Burry: `0001649339`), Akre Capital Management (`0001483348`), and Mairs & Power Small Cap Fund (`0001099684`).
|
- **API Endpoint**: [/api/whale/screener](file:///c:/Users/jannr/.gemini/antigravity/scratch/investment-sandbox/app/api/whale/screener/route.ts) fetches SEC Form 13F filings for Scion Asset Management (Michael Burry: `0001649339`), Akre Capital Management (`0001483348`), and Mairs & Power Small Cap Fund (`0001099684`).
|
||||||
- **Offline Fallback**: Respects `DEV_MODE=true` environment configurations, completely bypassing outbound FMP requests and serving structured `MOCK_WHALE_DATA` with `isShieldActive: true`.
|
- **Offline Fallback**: Respects `DEV_MODE=true` environment configurations, completely bypassing outbound FMP requests and serving structured `MOCK_WHALE_DATA` with `isShieldActive: true`.
|
||||||
|
- **Visual Interface**: Consolidated under the 'Smart Money' tab (`app/page.tsx`) with a sub-tab selection toggle to switch between broad corporate/congressional flows and whale conviction screeners.
|
||||||
- **Velocity of Conviction**:
|
- **Velocity of Conviction**:
|
||||||
$$\text{VoC}_i = w_{i, t} - w_{i, t-1}$$
|
$$\text{VoC}_i = w_{i, t} - w_{i, t-1}$$
|
||||||
$$w_{i, t} = \frac{V_{i, t}}{\sum_{j} V_{j, t}} \times 100$$
|
$$w_{i, t} = \frac{V_{i, t}}{\sum_{j} V_{j, t}} \times 100$$
|
||||||
|
|||||||
@@ -2,6 +2,128 @@ import { NextResponse } from 'next/server';
|
|||||||
|
|
||||||
export const dynamic = 'force-dynamic';
|
export const dynamic = 'force-dynamic';
|
||||||
|
|
||||||
|
const MOCK_EXECUTIVES = [
|
||||||
|
{
|
||||||
|
id: 'mock_exec_1',
|
||||||
|
ticker: 'PLTR',
|
||||||
|
insiderName: 'Karp Alexander C.',
|
||||||
|
relation: 'CEO / Director',
|
||||||
|
type: 'SELL',
|
||||||
|
shares: 250000,
|
||||||
|
value: 9250000,
|
||||||
|
date: '2026-06-10',
|
||||||
|
insight: 'Verkauf durch CEO/CFO. Häufig automatisiert (10b5-1 Plan) zur Portfoliodiversifikation.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'mock_exec_2',
|
||||||
|
ticker: 'NVDA',
|
||||||
|
insiderName: 'Huang Jen Hsun',
|
||||||
|
relation: 'CEO / President',
|
||||||
|
type: 'SELL',
|
||||||
|
shares: 120000,
|
||||||
|
value: 15400000,
|
||||||
|
date: '2026-06-09',
|
||||||
|
insight: 'Regulärer Verkauf im Rahmen eines vorab festgelegten 10b5-1 Handelsplans.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'mock_exec_3',
|
||||||
|
ticker: 'AAPL',
|
||||||
|
insiderName: 'Maestri Luca',
|
||||||
|
relation: 'CFO / Senior VP',
|
||||||
|
type: 'BUY',
|
||||||
|
shares: 15000,
|
||||||
|
value: 2850000,
|
||||||
|
date: '2026-06-08',
|
||||||
|
insight: 'Starkes Conviction-Signal: CFO kauft eigene Aktien aus freien Mitteln.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'mock_exec_4',
|
||||||
|
ticker: 'TSLA',
|
||||||
|
insiderName: 'Taneja Vaibhav',
|
||||||
|
relation: 'Chief Accounting Officer',
|
||||||
|
type: 'BUY',
|
||||||
|
shares: 5000,
|
||||||
|
value: 950000,
|
||||||
|
date: '2026-06-07',
|
||||||
|
insight: 'Opportunistischer Conviction-Kauf mit positivem Signal für den Markt.'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const MOCK_CONGRESS = [
|
||||||
|
{
|
||||||
|
id: 'mock_cong_1',
|
||||||
|
ticker: 'MSFT',
|
||||||
|
representative: 'Nancy Pelosi',
|
||||||
|
chamber: 'HOUSE',
|
||||||
|
type: 'BUY',
|
||||||
|
valueRange: '$1,000,001 - $5,000,000',
|
||||||
|
transactionDate: '2026-05-20',
|
||||||
|
filingDate: '2026-06-05',
|
||||||
|
lagDays: 16,
|
||||||
|
insight: 'Politisches Conviction-Signal (Nancy Pelosi). Möglicher Informationsvorsprung.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'mock_cong_2',
|
||||||
|
ticker: 'NVIDIA',
|
||||||
|
representative: 'Tommy Tuberville',
|
||||||
|
chamber: 'SENATE',
|
||||||
|
type: 'SELL',
|
||||||
|
valueRange: '$100,001 - $250,000',
|
||||||
|
transactionDate: '2026-05-15',
|
||||||
|
filingDate: '2026-06-02',
|
||||||
|
lagDays: 18,
|
||||||
|
insight: 'Taktische Reduzierung der Position im Rahmen von Compliance-Richtlinien.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'mock_cong_3',
|
||||||
|
ticker: 'LMT',
|
||||||
|
representative: 'Mark Green',
|
||||||
|
chamber: 'HOUSE',
|
||||||
|
type: 'BUY',
|
||||||
|
valueRange: '$50,001 - $100,000',
|
||||||
|
transactionDate: '2026-05-18',
|
||||||
|
filingDate: '2026-06-01',
|
||||||
|
lagDays: 14,
|
||||||
|
insight: 'Akkumulation im Rüstungssektor. Zeitliche Nähe zu Haushaltsbeschlüssen.'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const MOCK_WHALES = [
|
||||||
|
{
|
||||||
|
id: 'mock_whale_1',
|
||||||
|
ticker: 'AMZN',
|
||||||
|
institution: 'Scion Asset Management (Michael Burry)',
|
||||||
|
type: 'BUY',
|
||||||
|
sharesTraded: 50000,
|
||||||
|
sharesHeld: 150000,
|
||||||
|
filingDate: '2026-05-15',
|
||||||
|
estimatedValue: 9150000,
|
||||||
|
insight: 'Institutionelle Akkumulation durch Scion Asset Management. Aufbau einer strategischen Position.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'mock_whale_2',
|
||||||
|
ticker: 'GOOGL',
|
||||||
|
institution: 'Akre Capital Management',
|
||||||
|
type: 'BUY',
|
||||||
|
sharesTraded: 250000,
|
||||||
|
sharesHeld: 1250000,
|
||||||
|
filingDate: '2026-05-15',
|
||||||
|
estimatedValue: 43250000,
|
||||||
|
insight: 'Aufbau/Verstärkung einer langfristigen Kernposition durch Akre Capital.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'mock_whale_3',
|
||||||
|
ticker: 'TSLA',
|
||||||
|
institution: 'Renaissance Technologies LLC',
|
||||||
|
type: 'SELL',
|
||||||
|
sharesTraded: 450000,
|
||||||
|
sharesHeld: 2100000,
|
||||||
|
filingDate: '2026-05-14',
|
||||||
|
estimatedValue: 85500000,
|
||||||
|
insight: 'Taktische Gewinnmitnahme / Quantitative Portfolio-Rebalancierung.'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
function getStrategicInsight(trade: { type: string; relation: string; value: number; ticker: string }) {
|
function getStrategicInsight(trade: { type: string; relation: string; value: number; ticker: string }) {
|
||||||
const isBuy = trade.type === 'BUY';
|
const isBuy = trade.type === 'BUY';
|
||||||
const relation = (trade.relation || '').toUpperCase();
|
const relation = (trade.relation || '').toUpperCase();
|
||||||
@@ -42,6 +164,22 @@ export async function GET(request: Request) {
|
|||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
const type = searchParams.get('type') || 'executives';
|
const type = searchParams.get('type') || 'executives';
|
||||||
const apiKey = process.env.FMP_API_KEY;
|
const apiKey = process.env.FMP_API_KEY;
|
||||||
|
const isDevMode = process.env.DEV_MODE === 'true';
|
||||||
|
|
||||||
|
if (isDevMode) {
|
||||||
|
let mockResults: any[] = [];
|
||||||
|
if (type === 'executives') mockResults = MOCK_EXECUTIVES;
|
||||||
|
else if (type === 'congress') mockResults = MOCK_CONGRESS;
|
||||||
|
else if (type === 'whales') mockResults = MOCK_WHALES;
|
||||||
|
|
||||||
|
const res = NextResponse.json(
|
||||||
|
{ results: mockResults, liveDataAvailable: false, isShieldActive: true },
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
res.headers.set('Cache-Control', 'no-store, max-age=0, must-revalidate');
|
||||||
|
res.headers.set('X-Shield-Active', 'true');
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
if (!apiKey) {
|
if (!apiKey) {
|
||||||
console.error("====== CRITICAL INSIDER ROUTE FAILURE ======", new Error("FMP_API_KEY is not configured in environment variables."));
|
console.error("====== CRITICAL INSIDER ROUTE FAILURE ======", new Error("FMP_API_KEY is not configured in environment variables."));
|
||||||
|
|||||||
38
app/page.tsx
38
app/page.tsx
@@ -12,7 +12,8 @@ import WhaleScreener from '@/components/modules/whale/WhaleScreener';
|
|||||||
import { BarChart3, TrendingUp, ShieldAlert, Radio, Landmark, RefreshCw, Activity, Cpu, Compass } from 'lucide-react';
|
import { BarChart3, TrendingUp, ShieldAlert, Radio, Landmark, RefreshCw, Activity, Cpu, Compass } from 'lucide-react';
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const [activeTab, setActiveTab] = useState<'sandbox' | 'scanner' | 'insider' | 'crypto' | 'events' | 'macro' | 'tech' | 'whale'>('sandbox');
|
const [activeTab, setActiveTab] = useState<'sandbox' | 'scanner' | 'smart-money' | 'crypto' | 'events' | 'macro' | 'tech'>('sandbox');
|
||||||
|
const [smartMoneySubTab, setSmartMoneySubTab] = useState<'flows' | 'screener'>('flows');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-[#070b13] text-slate-100 flex flex-col font-sans selection:bg-teal-500/30 selection:text-teal-200">
|
<div className="min-h-screen bg-[#070b13] text-slate-100 flex flex-col font-sans selection:bg-teal-500/30 selection:text-teal-200">
|
||||||
@@ -78,10 +79,10 @@ export default function Home() {
|
|||||||
<ShieldAlert className="w-4 h-4" /> Scanner
|
<ShieldAlert className="w-4 h-4" /> Scanner
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab('insider')}
|
onClick={() => setActiveTab('smart-money')}
|
||||||
className={`flex-1 lg:flex-none px-4 py-2.5 rounded-xl text-xs font-semibold flex items-center justify-center gap-2 transition-all ${activeTab === 'insider' ? 'bg-gradient-to-r from-purple-500 to-indigo-500 text-white font-bold shadow-lg shadow-purple-500/25' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-900/50'}`}
|
className={`flex-1 lg:flex-none px-4 py-2.5 rounded-xl text-xs font-semibold flex items-center justify-center gap-2 transition-all ${activeTab === 'smart-money' ? 'bg-gradient-to-r from-purple-500 to-indigo-500 text-white font-bold shadow-lg shadow-purple-500/25' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-900/50'}`}
|
||||||
>
|
>
|
||||||
<Radio className="w-4 h-4" /> Insider
|
<Radio className="w-4 h-4" /> Smart Money
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab('crypto')}
|
onClick={() => setActiveTab('crypto')}
|
||||||
@@ -105,13 +106,7 @@ export default function Home() {
|
|||||||
onClick={() => setActiveTab('tech')}
|
onClick={() => setActiveTab('tech')}
|
||||||
className={`flex-1 lg:flex-none px-4 py-2.5 rounded-xl text-xs font-semibold flex items-center justify-center gap-2 transition-all ${activeTab === 'tech' ? 'bg-gradient-to-r from-teal-500 to-indigo-500 text-white font-bold shadow-lg shadow-teal-500/25' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-900/50'}`}
|
className={`flex-1 lg:flex-none px-4 py-2.5 rounded-xl text-xs font-semibold flex items-center justify-center gap-2 transition-all ${activeTab === 'tech' ? 'bg-gradient-to-r from-teal-500 to-indigo-500 text-white font-bold shadow-lg shadow-teal-500/25' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-900/50'}`}
|
||||||
>
|
>
|
||||||
<Cpu className="w-4 h-4" /> [⚡ AI Special Silo]
|
<Cpu className="w-4 h-4" /> ⚡ AI Special Silo
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => setActiveTab('whale')}
|
|
||||||
className={`flex-1 lg:flex-none px-4 py-2.5 rounded-xl text-xs font-semibold flex items-center justify-center gap-2 transition-all ${activeTab === 'whale' ? 'bg-gradient-to-r from-blue-500 to-teal-500 text-slate-950 font-bold shadow-lg shadow-blue-500/25' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-900/50'}`}
|
|
||||||
>
|
|
||||||
<Compass className="w-4 h-4" /> [🐋 Whale Screener]
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -124,12 +119,29 @@ export default function Home() {
|
|||||||
<div className="transition-all duration-300 transform opacity-100 translate-y-0">
|
<div className="transition-all duration-300 transform opacity-100 translate-y-0">
|
||||||
{activeTab === 'sandbox' && <SandboxDemo />}
|
{activeTab === 'sandbox' && <SandboxDemo />}
|
||||||
{activeTab === 'scanner' && <ScannerDemo />}
|
{activeTab === 'scanner' && <ScannerDemo />}
|
||||||
{activeTab === 'insider' && <InsiderDemo />}
|
{activeTab === 'smart-money' && (
|
||||||
|
<div className="space-y-6">
|
||||||
|
<div className="flex bg-slate-950/80 p-1.5 rounded-xl border border-slate-800/80 max-w-lg mx-auto">
|
||||||
|
<button
|
||||||
|
onClick={() => setSmartMoneySubTab('flows')}
|
||||||
|
className={`flex-1 py-2 rounded-lg text-xs font-semibold font-sans transition-all flex items-center justify-center gap-1.5 ${smartMoneySubTab === 'flows' ? 'bg-purple-500 text-white font-bold shadow-lg shadow-purple-500/25' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-900/50'}`}
|
||||||
|
>
|
||||||
|
<Radio className="w-3.5 h-3.5" /> Broad Insider & Congressional Flows
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setSmartMoneySubTab('screener')}
|
||||||
|
className={`flex-1 py-2 rounded-lg text-xs font-semibold font-sans transition-all flex items-center justify-center gap-1.5 ${smartMoneySubTab === 'screener' ? 'bg-purple-500 text-white font-bold shadow-lg shadow-purple-500/25' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-900/50'}`}
|
||||||
|
>
|
||||||
|
<Compass className="w-3.5 h-3.5" /> Whale Conviction Screener (VoC)
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{smartMoneySubTab === 'flows' ? <InsiderDemo /> : <WhaleScreener />}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{activeTab === 'crypto' && <CryptoDemo />}
|
{activeTab === 'crypto' && <CryptoDemo />}
|
||||||
{activeTab === 'events' && <EventsDemo />}
|
{activeTab === 'events' && <EventsDemo />}
|
||||||
{activeTab === 'macro' && <MacroIndicatorsDemo />}
|
{activeTab === 'macro' && <MacroIndicatorsDemo />}
|
||||||
{activeTab === 'tech' && <AiSpecialSilo />}
|
{activeTab === 'tech' && <AiSpecialSilo />}
|
||||||
{activeTab === 'whale' && <WhaleScreener />}
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ export default function InsiderDemo() {
|
|||||||
}[] | null>(null);
|
}[] | null>(null);
|
||||||
const [showMathAccordion, setShowMathAccordion] = useState(false);
|
const [showMathAccordion, setShowMathAccordion] = useState(false);
|
||||||
const [isMathModalOpen, setIsMathModalOpen] = useState(false);
|
const [isMathModalOpen, setIsMathModalOpen] = useState(false);
|
||||||
|
const [isShieldActive, setIsShieldActive] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [errorMsg, setErrorMsg] = useState<string | null>(null);
|
const [errorMsg, setErrorMsg] = useState<string | null>(null);
|
||||||
|
|
||||||
@@ -105,6 +106,7 @@ export default function InsiderDemo() {
|
|||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
if (active) {
|
if (active) {
|
||||||
|
setIsShieldActive(!!execRes.isShieldActive || !!congRes.isShieldActive || !!whaleRes.isShieldActive);
|
||||||
const unavailable: string[] = [];
|
const unavailable: string[] = [];
|
||||||
if (execRes.liveDataAvailable === false) unavailable.push('Executives (Form 4)');
|
if (execRes.liveDataAvailable === false) unavailable.push('Executives (Form 4)');
|
||||||
if (congRes.liveDataAvailable === false) unavailable.push('Congress (Stock Act)');
|
if (congRes.liveDataAvailable === false) unavailable.push('Congress (Stock Act)');
|
||||||
@@ -247,8 +249,19 @@ export default function InsiderDemo() {
|
|||||||
<div className="flex flex-col lg:flex-row justify-between items-start lg:items-center gap-4 border-b border-slate-800 pb-4 mb-6">
|
<div className="flex flex-col lg:flex-row justify-between items-start lg:items-center gap-4 border-b border-slate-800 pb-4 mb-6">
|
||||||
<div>
|
<div>
|
||||||
<span className="text-purple-400 text-xs font-semibold uppercase tracking-wider">Element 3</span>
|
<span className="text-purple-400 text-xs font-semibold uppercase tracking-wider">Element 3</span>
|
||||||
<h2 className="text-2xl font-bold bg-gradient-to-r from-purple-400 to-indigo-200 bg-clip-text text-transparent">
|
<h2 className="text-2xl font-bold bg-gradient-to-r from-purple-400 to-indigo-200 bg-clip-text text-transparent flex flex-wrap items-center gap-2">
|
||||||
Institutional & Insider Flow Tracker
|
<span>Institutional & Insider Flow Tracker</span>
|
||||||
|
{isShieldActive ? (
|
||||||
|
<span className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-[10px] font-bold bg-amber-500/10 text-amber-400 border border-amber-500/20 shadow-[0_0_10px_rgba(245,158,11,0.15)] animate-pulse">
|
||||||
|
<span className="w-1.5 h-1.5 rounded-full bg-amber-500" />
|
||||||
|
DEV-ARCHIV AKTIV (0 CALLS)
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-[10px] font-bold bg-emerald-500/10 text-emerald-400 border border-emerald-500/20 shadow-[0_0_10px_rgba(16,185,129,0.15)]">
|
||||||
|
<span className="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-ping" />
|
||||||
|
LIVE-API ENDPUNKT (FMP CORPO)
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-wrap items-center gap-3">
|
<div className="flex flex-wrap items-center gap-3">
|
||||||
|
|||||||
Reference in New Issue
Block a user