Spaces:
Sleeping
Sleeping
Add business details to Company Profile section
Browse files- Sector and Industry (combined display)
- Headquarters location
- Employee count
- Website (clickable link)
- SIC description
- Extract from SEC EDGAR and Yahoo Finance sources
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
frontend/src/components/MCPDataPanel.tsx
CHANGED
|
@@ -511,14 +511,48 @@ export function MCPDataPanel({ metrics, rawData, companyName, ticker, exchange,
|
|
| 511 |
const companyProfile = React.useMemo(() => {
|
| 512 |
if (!rawData) return null
|
| 513 |
|
| 514 |
-
// Try
|
| 515 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 516 |
return {
|
| 517 |
-
sector: profile.sector |
|
| 518 |
-
|
| 519 |
-
|
| 520 |
-
|
| 521 |
-
|
|
|
|
| 522 |
}
|
| 523 |
}, [rawData])
|
| 524 |
|
|
@@ -531,7 +565,7 @@ export function MCPDataPanel({ metrics, rawData, companyName, ticker, exchange,
|
|
| 531 |
|
| 532 |
return (
|
| 533 |
<div className="space-y-4">
|
| 534 |
-
{/* Company
|
| 535 |
{(companyName || ticker) && (
|
| 536 |
<div className="bg-card rounded-lg border border-border overflow-hidden">
|
| 537 |
<div className="px-3 py-2 bg-muted/50 border-b border-border">
|
|
@@ -556,6 +590,9 @@ export function MCPDataPanel({ metrics, rawData, companyName, ticker, exchange,
|
|
| 556 |
<div className="flex items-center gap-2">
|
| 557 |
<Briefcase className="h-4 w-4 text-muted-foreground" />
|
| 558 |
<span>{companyProfile.sector}</span>
|
|
|
|
|
|
|
|
|
|
| 559 |
</div>
|
| 560 |
)}
|
| 561 |
{companyProfile?.hqLocation && (
|
|
@@ -570,6 +607,24 @@ export function MCPDataPanel({ metrics, rawData, companyName, ticker, exchange,
|
|
| 570 |
<span>{Number(companyProfile.employees).toLocaleString()}</span>
|
| 571 |
</div>
|
| 572 |
)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 573 |
</div>
|
| 574 |
</div>
|
| 575 |
)}
|
|
|
|
| 511 |
const companyProfile = React.useMemo(() => {
|
| 512 |
if (!rawData) return null
|
| 513 |
|
| 514 |
+
// Try multiple sources for profile data
|
| 515 |
+
const multiSource = rawData.multi_source as Record<string, unknown> | undefined
|
| 516 |
+
const valAll = multiSource?.valuation_all as Record<string, unknown> | undefined
|
| 517 |
+
const fundsAll = multiSource?.fundamentals_all as Record<string, unknown> | undefined
|
| 518 |
+
|
| 519 |
+
// Yahoo Finance profile (most complete)
|
| 520 |
+
const yfValData = valAll?.yahoo_finance as Record<string, unknown> | undefined
|
| 521 |
+
const yfProfile = yfValData?.data as Record<string, unknown> | undefined
|
| 522 |
+
const yfProfileNested = yfProfile?.profile as Record<string, unknown> | undefined
|
| 523 |
+
|
| 524 |
+
// SEC EDGAR company info
|
| 525 |
+
const secData = fundsAll?.sec_edgar as Record<string, unknown> | undefined
|
| 526 |
+
const secInfo = secData?.data as Record<string, unknown> | undefined
|
| 527 |
+
const secCompanyInfo = secInfo?.company_info as Record<string, unknown> | undefined
|
| 528 |
+
|
| 529 |
+
// Legacy fallback
|
| 530 |
+
const legacyProfile = rawData.metrics?.valuation?.profile || rawData.company_info || {}
|
| 531 |
+
|
| 532 |
+
// Merge sources (Yahoo Finance primary, SEC secondary, legacy fallback)
|
| 533 |
+
const profile = { ...legacyProfile, ...secCompanyInfo, ...yfProfileNested, ...yfProfile }
|
| 534 |
+
|
| 535 |
+
// Build HQ location from available fields
|
| 536 |
+
let hqLocation = null
|
| 537 |
+
const city = profile.city as string | undefined
|
| 538 |
+
const state = profile.state as string | undefined
|
| 539 |
+
const stateOrCountry = profile.stateOrCountry as string | undefined
|
| 540 |
+
const country = profile.country as string | undefined
|
| 541 |
+
|
| 542 |
+
if (city && (state || stateOrCountry)) {
|
| 543 |
+
const stateVal = state || stateOrCountry
|
| 544 |
+
hqLocation = country && country !== 'United States' && country !== 'US'
|
| 545 |
+
? `${city}, ${stateVal}, ${country}`
|
| 546 |
+
: `${city}, ${stateVal}`
|
| 547 |
+
}
|
| 548 |
+
|
| 549 |
return {
|
| 550 |
+
sector: profile.sector as string | null || null,
|
| 551 |
+
industry: profile.industry as string | null || null,
|
| 552 |
+
hqLocation,
|
| 553 |
+
employees: profile.fullTimeEmployees as number | null || profile.employees as number | null || null,
|
| 554 |
+
website: profile.website as string | null || null,
|
| 555 |
+
sicDescription: profile.sicDescription as string | null || null,
|
| 556 |
}
|
| 557 |
}, [rawData])
|
| 558 |
|
|
|
|
| 565 |
|
| 566 |
return (
|
| 567 |
<div className="space-y-4">
|
| 568 |
+
{/* Company Profile */}
|
| 569 |
{(companyName || ticker) && (
|
| 570 |
<div className="bg-card rounded-lg border border-border overflow-hidden">
|
| 571 |
<div className="px-3 py-2 bg-muted/50 border-b border-border">
|
|
|
|
| 590 |
<div className="flex items-center gap-2">
|
| 591 |
<Briefcase className="h-4 w-4 text-muted-foreground" />
|
| 592 |
<span>{companyProfile.sector}</span>
|
| 593 |
+
{companyProfile?.industry && companyProfile.industry !== companyProfile.sector && (
|
| 594 |
+
<span className="text-muted-foreground">/ {companyProfile.industry}</span>
|
| 595 |
+
)}
|
| 596 |
</div>
|
| 597 |
)}
|
| 598 |
{companyProfile?.hqLocation && (
|
|
|
|
| 607 |
<span>{Number(companyProfile.employees).toLocaleString()}</span>
|
| 608 |
</div>
|
| 609 |
)}
|
| 610 |
+
{companyProfile?.website && (
|
| 611 |
+
<div className="flex items-center gap-2">
|
| 612 |
+
<ExternalLink className="h-4 w-4 text-muted-foreground" />
|
| 613 |
+
<a
|
| 614 |
+
href={companyProfile.website}
|
| 615 |
+
target="_blank"
|
| 616 |
+
rel="noopener noreferrer"
|
| 617 |
+
className="text-blue-400 hover:text-blue-300 hover:underline"
|
| 618 |
+
>
|
| 619 |
+
{companyProfile.website.replace(/^https?:\/\//, '').replace(/\/$/, '')}
|
| 620 |
+
</a>
|
| 621 |
+
</div>
|
| 622 |
+
)}
|
| 623 |
+
{companyProfile?.sicDescription && (
|
| 624 |
+
<div className="flex items-center gap-2 text-muted-foreground">
|
| 625 |
+
<span>SIC: {companyProfile.sicDescription}</span>
|
| 626 |
+
</div>
|
| 627 |
+
)}
|
| 628 |
</div>
|
| 629 |
</div>
|
| 630 |
)}
|