diff --git a/frontend/components/dashboard/ScanTerminalDashboard.tsx b/frontend/components/dashboard/ScanTerminalDashboard.tsx
index 063830ce..79cdc9ee 100644
--- a/frontend/components/dashboard/ScanTerminalDashboard.tsx
+++ b/frontend/components/dashboard/ScanTerminalDashboard.tsx
@@ -19,6 +19,17 @@ import {
UserRound,
} from "lucide-react";
import { useEffect, useMemo, useState } from "react";
+import {
+ Area,
+ AreaChart,
+ Bar,
+ BarChart as ReBarChart,
+ CartesianGrid,
+ ResponsiveContainer,
+ Tooltip,
+ XAxis,
+ YAxis,
+} from "recharts";
import type { ProAccessState, ScanOpportunityRow } from "@/lib/dashboard-types";
import { getInitialLocaleFromNavigator } from "@/lib/i18n";
import { isBrowserLocalFullAccess } from "@/lib/local-dev-access";
@@ -114,23 +125,91 @@ function decisionClass(label: string) {
return "border-amber-200 bg-amber-50 text-amber-700";
}
-function MiniSparkline({ tone = "blue" }: { tone?: "blue" | "emerald" | "red" }) {
- const stroke =
- tone === "emerald" ? "#059669" : tone === "red" ? "#dc2626" : "#2563eb";
+function SparkArea({
+ color = "#2563eb",
+ data,
+}: {
+ color?: string;
+ data: { v: number }[];
+}) {
+ if (!data.length) {
+ return (
+
+ No data
+
+ );
+ }
return (
-
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+function ProbabilityDistributionChart({
+ points,
+}: {
+ points?: ScanOpportunityRow["distribution_preview"];
+}) {
+ if (!points?.length) {
+ return (
+
+ No distribution data
+
+ );
+ }
+ const chartData = points.map((p) => ({
+ label: p.label || "",
+ model: Number((p.model_probability ?? 0) * 100),
+ market: Number((p.market_probability ?? 0) * 100),
+ }));
+ return (
+
+
+
+
+ `${v}%`}
+ />
+
+ `${Number(value).toFixed(1)}%`
+ }
+ />
+
+
+
+
);
}
@@ -445,9 +524,23 @@ function KoyfinWeatherTerminal({
Intraday Performance
- = 0 ? "emerald" : "red"}
- />
+
+ = 0
+ ? "#059669"
+ : "#dc2626"
+ }
+ data={
+ selectedRow?.distribution_preview?.map((p) => ({
+ v:
+ typeof p === "number"
+ ? p
+ : p.model_probability ?? 0,
+ })) || []
+ }
+ />
+
Edge {pct(selectedRow?.edge_percent)}
@@ -460,21 +553,14 @@ function KoyfinWeatherTerminal({
-
-
- {[
- ["Model Probability", selectedRow?.model_probability ?? selectedRow?.model_event_probability, "blue"],
- ["Market Probability", selectedRow?.market_probability ?? selectedRow?.market_event_probability, "emerald"],
- ["Peak Probability", selectedRow?.peak_probability, "red"],
- ].map(([label, value, tone]) => (
-
-
- {label}
- {pct(value)}
-
-
-
- ))}
+
+
diff --git a/frontend/public/logo.png b/frontend/public/logo.png
new file mode 100644
index 00000000..db665596
Binary files /dev/null and b/frontend/public/logo.png differ