/* * ============================================================================= * VibeQuant (vquant) — AI-Powered Financial Intelligence Platform * ----------------------------------------------------------------------------- * File: client/src/components/explore/stock-header.tsx * * Author: Simon-Pierre Boucher * Contact: contact@spboucher.ai * Website: https://www.spboucher.ai * Demo: https://www.vquant.ai * License: MIT (see LICENSE) * * Copyright © 2026 Simon-Pierre Boucher. All rights reserved. * ============================================================================= */ import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { ArrowLeft, TrendingUp, TrendingDown, Building2, Globe, ExternalLink, DollarSign } from "lucide-react"; interface CompanyProfile { symbol: string; companyName: string; industry: string; sector: string; ceo: string; website: string; description: string; country: string; city: string; address: string; employees: number; marketCap: number; image: string; exchange: string; isin: string; cusip: string; phone: string; } interface StockQuote { symbol: string; price: number; change: number; changesPercentage: number; dayLow: number; dayHigh: number; yearHigh: number; yearLow: number; marketCap: number; priceAvg50: number; priceAvg200: number; volume: number; avgVolume: number; open: number; previousClose: number; eps: number; pe: number; earningsAnnouncement: string; sharesOutstanding: number; timestamp: number; } interface StockHeaderProps { ticker: string; companyProfile?: CompanyProfile; stockQuote?: StockQuote; onBack: () => void; } export function StockHeader({ ticker, companyProfile, stockQuote, onBack }: StockHeaderProps) { const isPositive = (stockQuote?.changesPercentage ?? 0) >= 0; const formatNumber = (num: number) => { if (num >= 1e12) return `$${(num / 1e12).toFixed(2)}T`; if (num >= 1e9) return `$${(num / 1e9).toFixed(2)}B`; if (num >= 1e6) return `$${(num / 1e6).toFixed(2)}M`; if (num >= 1e3) return `$${(num / 1e3).toFixed(2)}K`; return `$${num.toFixed(2)}`; }; const formatVolume = (vol: number) => { if (vol >= 1e9) return `${(vol / 1e9).toFixed(2)}B`; if (vol >= 1e6) return `${(vol / 1e6).toFixed(2)}M`; if (vol >= 1e3) return `${(vol / 1e3).toFixed(2)}K`; return vol.toString(); }; return (
{/* Back Button */} {/* Main Stock Header */}
{/* Company Info */}
{companyProfile?.image && (
{companyProfile.companyName}
)}

{companyProfile?.companyName || ticker}

{ticker} {companyProfile?.exchange && ( {companyProfile.exchange} )} {companyProfile?.sector && ( {companyProfile.sector} )} {companyProfile?.industry && ( {companyProfile.industry} )}
{companyProfile?.description && (

{companyProfile.description}

)} {companyProfile && (
{companyProfile.ceo && (
CEO:{" "} {companyProfile.ceo}
)} {companyProfile.employees && (
Employés:{" "} {companyProfile.employees.toLocaleString()}
)} {companyProfile.country && (
Pays:{" "} {companyProfile.country}
)} {companyProfile.website && ( Site Web )}
)}
{/* Live Quote */} {stockQuote && (
Prix Actuel
${stockQuote.price?.toFixed(2)}
{isPositive ? ( ) : ( )} {isPositive ? '+' : ''}{stockQuote.change?.toFixed(2)} ({isPositive ? '+' : ''}{stockQuote.changesPercentage?.toFixed(2)}%)
Ouverture
${stockQuote.open?.toFixed(2)}
Clôture Préc.
${stockQuote.previousClose?.toFixed(2)}
Jour Bas
${stockQuote.dayLow?.toFixed(2)}
Jour Haut
${stockQuote.dayHigh?.toFixed(2)}
52W Bas
${stockQuote.yearLow?.toFixed(2)}
52W Haut
${stockQuote.yearHigh?.toFixed(2)}
Volume {formatVolume(stockQuote.volume)}
Vol. Moyen {formatVolume(stockQuote.avgVolume)}
Cap. Boursière {formatNumber(stockQuote.marketCap)}
{stockQuote.pe && (
P/E Ratio {stockQuote.pe.toFixed(2)}
)} {stockQuote.eps && (
EPS ${stockQuote.eps.toFixed(2)}
)}
{stockQuote.earningsAnnouncement && (
Prochains Résultats
{new Date(stockQuote.earningsAnnouncement).toLocaleDateString('fr-FR', { year: 'numeric', month: 'long', day: 'numeric' })}
)}
)}
); }