Initial commit: SAPIENS Stock service

This commit is contained in:
jungwoo choi
2025-10-22 09:31:15 +09:00
commit f0c0f3b8d6
93 changed files with 8369 additions and 0 deletions

362
components/financials.tsx Normal file
View File

@ -0,0 +1,362 @@
"use client"
import { useState } from "react"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Download, ChevronLeft, ChevronRight, TrendingUp, Minus, TrendingDown } from "lucide-react"
const financialTabs = [
{ id: "key-stats", label: "Key Stats" },
{ id: "income-statement", label: "Income Statement" },
{ id: "balance-sheet", label: "Balance Sheet" },
{ id: "cash-flow", label: "Cash Flow" },
]
const financialData = {
years: ["12/31/2025", "12/31/2024", "12/31/2023", "12/31/2022", "12/31/2021"],
metrics: [
{
label: "Market Cap",
values: ["-", "$1,291,076", "$788,551", "$385,553", "$1,042,337"],
type: "currency",
},
{
label: "- Cash",
values: ["-", "16,139", "16,398", "16,253", "17,576"],
type: "number",
indent: true,
},
{
label: "+ Debt",
values: ["-", "13,623", "9,573", "5,748", "8,873"],
type: "number",
indent: true,
},
{
label: "Enterprise Value",
values: ["-", "1,288,560", "781,726", "375,048", "1,033,634"],
type: "currency",
highlight: true,
},
{
label: "Revenue",
values: ["92,915", "97,690", "96,773", "81,462", "53,823"],
type: "currency",
},
{
label: "% Growth",
values: ["-4.9%", "0.9%", "18.8%", "51.4%", "-"],
type: "percentage",
indent: true,
italic: true,
},
{
label: "Gross Profit",
values: ["15,912", "17,450", "17,660", "20,853", "13,606"],
type: "currency",
},
{
label: "% Margin",
values: ["17.1%", "17.9%", "18.2%", "25.6%", "25.3%"],
type: "percentage",
indent: true,
italic: true,
},
{
label: "EBITDA",
values: ["13,428", "14,708", "14,796", "17,657", "9,625"],
type: "currency",
},
{
label: "% Margin",
values: ["14.5%", "15.1%", "15.3%", "21.7%", "17.9%"],
type: "percentage",
indent: true,
italic: true,
},
{
label: "Net Income",
values: ["5,018", "7,130", "14,999", "12,583", "5,524"],
type: "currency",
},
{
label: "% Margin",
values: ["5.4%", "7.3%", "15.5%", "15.4%", "10.3%"],
type: "percentage",
indent: true,
italic: true,
},
{
label: "EPS Diluted",
values: ["3.84", "2.04", "4.31", "3.62", "1.63"],
type: "number",
},
{
label: "% Growth",
values: ["88.0%", "-52.7%", "19.1%", "122.1%", "-"],
type: "percentage",
indent: true,
italic: true,
},
{
label: "Operating Cash Flow",
values: ["12,484", "14,923", "13,256", "14,724", "11,497"],
type: "currency",
},
{
label: "Capital Expenditures",
values: ["-9,714", "-11,342", "-8,899", "-7,172", "-8,014"],
type: "currency",
},
{
label: "Free Cash Flow",
values: ["4,011", "3,581", "4,357", "7,552", "3,483"],
type: "currency",
highlight: true,
},
],
}
const allInsights = [
{
title: "Strong EV Market Leadership Position",
content:
"Tesla maintains its position as the world's leading electric vehicle manufacturer with consistent delivery growth and expanding global market presence, particularly in key markets like China and Europe.",
signal: "bullish",
},
{
title: "Autonomous Driving Technology Advancement",
content:
"Significant progress in Full Self-Driving capabilities and neural network improvements position Tesla ahead of traditional automakers in the autonomous vehicle race.",
signal: "bullish",
},
{
title: "Energy Business Expansion",
content:
"Tesla's energy storage and solar business continues to grow, providing diversification beyond automotive and creating additional revenue streams with higher margins.",
signal: "bullish",
},
{
title: "Market Capitalization Volatility amid Industry Events",
content:
"Tesla's market capitalization fluctuated dramatically from $1.04 trillion in 2021 to a low of $385.6 billion in 2022, before rebounding to over $1.29 trillion by the end of 2024.",
signal: "neutral",
},
{
title: "Revenue Growth Stabilization",
content:
"Revenue growth has stabilized after the rapid expansion phase, with modest growth rates indicating market maturation in core segments.",
signal: "neutral",
},
{
title: "Production Capacity Utilization",
content:
"Current production facilities are operating at high capacity, requiring significant capital investment for further expansion to meet growing demand.",
signal: "neutral",
},
{
title: "Compressed Gross Margins Post-2022",
content:
"Gross profit margins declined significantly from a peak of 25.6% in 2022 to 17.9% in 2024, indicating aggressive pricing cuts and increased production costs.",
signal: "bearish",
},
{
title: "Increased Competition in EV Market",
content:
"Traditional automakers and new EV startups are rapidly expanding their electric vehicle offerings, intensifying competition and potentially impacting Tesla's market share.",
signal: "bearish",
},
{
title: "Regulatory and Policy Uncertainty",
content:
"Changes in government EV incentives and regulations across different markets could impact demand and profitability in key regions.",
signal: "bearish",
},
]
export function Financials() {
const [activeFinancialTab, setActiveFinancialTab] = useState("key-stats")
const [period, setPeriod] = useState("annual")
const [currency, setCurrency] = useState("M")
const [currentInsightIndex, setCurrentInsightIndex] = useState(0)
const insightsPerPage = 3
const totalPages = Math.ceil(allInsights.length / insightsPerPage)
const currentInsights = allInsights.slice(currentInsightIndex, currentInsightIndex + insightsPerPage)
const nextInsights = () => {
if (currentInsightIndex + insightsPerPage < allInsights.length) {
setCurrentInsightIndex(currentInsightIndex + insightsPerPage)
}
}
const prevInsights = () => {
if (currentInsightIndex > 0) {
setCurrentInsightIndex(Math.max(0, currentInsightIndex - insightsPerPage))
}
}
const getSignalStyle = (signal: string) => {
switch (signal) {
case "bullish":
return {
icon: TrendingUp,
color: "text-green-500",
bg: "bg-green-500/10",
label: "Bullish Signal",
}
case "bearish":
return {
icon: TrendingDown,
color: "text-red-500",
bg: "bg-red-500/10",
label: "Bearish Signal",
}
default:
return {
icon: Minus,
color: "text-gray-500",
bg: "bg-gray-500/10",
label: "Neutral Effect",
}
}
}
return (
<div className="space-y-4">
<Card>
<CardHeader className="pb-4">
<div className="flex items-center justify-between">
<div className="flex space-x-1">
{financialTabs.map((tab) => (
<Button
key={tab.id}
variant={activeFinancialTab === tab.id ? "default" : "ghost"}
size="sm"
onClick={() => setActiveFinancialTab(tab.id)}
className="text-sm"
>
{tab.label}
</Button>
))}
</div>
<div className="flex items-center space-x-2">
<Select value={period} onValueChange={setPeriod}>
<SelectTrigger className="w-20">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="annual">Annual</SelectItem>
<SelectItem value="quarterly">Quarterly</SelectItem>
</SelectContent>
</Select>
<Select value={currency} onValueChange={setCurrency}>
<SelectTrigger className="w-12">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="M">M</SelectItem>
<SelectItem value="B">B</SelectItem>
</SelectContent>
</Select>
<Button size="sm" variant="outline">
<Download className="h-4 w-4" />
</Button>
</div>
</div>
</CardHeader>
<CardContent>
<div className="overflow-x-auto">
<table className="w-full">
<thead>
<tr className="border-b border-border">
<th className="text-left py-1 text-sm font-medium text-muted-foreground leading-tight"></th>
{financialData.years.map((year) => (
<th
key={year}
className="text-right py-1 px-4 text-sm font-medium text-muted-foreground leading-tight"
>
{year}
</th>
))}
</tr>
</thead>
<tbody>
{financialData.metrics.map((metric, index) => (
<tr key={index} className="border-b border-border/50">
<td
className={`py-1 text-sm leading-tight ${metric.indent ? "pl-6 text-muted-foreground" : "font-medium"} ${metric.italic ? "italic" : ""} ${metric.highlight ? "font-semibold" : ""}`}
>
{metric.label}
</td>
{metric.values.map((value, valueIndex) => (
<td
key={valueIndex}
className={`text-right py-1 px-4 text-sm leading-tight ${metric.highlight ? "font-semibold" : ""}`}
>
{value}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<div className="flex items-center justify-between">
<CardTitle className="text-lg flex items-center space-x-2">
<span className="text-muted-foreground">💡</span>
<span>Insights</span>
</CardTitle>
<div className="flex items-center space-x-2 text-sm text-muted-foreground">
<span>{allInsights.length} insights</span>
<div className="flex space-x-1">
<div className="w-2 h-2 bg-green-500 rounded-full"></div>
<div className="w-2 h-2 bg-gray-500 rounded-full"></div>
<div className="w-2 h-2 bg-red-500 rounded-full"></div>
</div>
<Button variant="ghost" size="sm" onClick={prevInsights} disabled={currentInsightIndex === 0}>
<ChevronLeft className="h-4 w-4" />
</Button>
<span className="text-xs">
{Math.floor(currentInsightIndex / insightsPerPage) + 1} / {totalPages}
</span>
<Button
variant="ghost"
size="sm"
onClick={nextInsights}
disabled={currentInsightIndex + insightsPerPage >= allInsights.length}
>
<ChevronRight className="h-4 w-4" />
</Button>
</div>
</div>
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{currentInsights.map((insight, index) => {
const signalStyle = getSignalStyle(insight.signal)
const IconComponent = signalStyle.icon
return (
<div key={index} className={`p-4 rounded-lg border ${signalStyle.bg} space-y-3`}>
<div className="flex items-center space-x-2">
<IconComponent className={`h-4 w-4 ${signalStyle.color}`} />
<span className={`text-xs font-medium ${signalStyle.color}`}>{signalStyle.label}</span>
</div>
<h4 className="font-medium text-sm">{insight.title}</h4>
<p className="text-sm text-muted-foreground leading-relaxed">{insight.content}</p>
</div>
)
})}
</div>
</CardContent>
</Card>
</div>
)
}