Overview: regime to the nav bar, watchlist up top
The market regime banner took a full-width row on the dashboard for ambient context. It is now a subtle status in the top bar (colored dot + "neutral regime", full headline and the longs/shorts caution in the tooltip) linking to /regime - matching the mockup's nav. The watchlist strip moves from the bottom of the dashboard (where it got lost) into the freed spot right under the hero: a slim chip row with today's move per symbol and the full-watchlist link. The empty state is a one-line hint instead of a callout box. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,8 +6,6 @@ import { useTrades } from '../hooks/useTrades';
|
||||
import { useWatchlist } from '../hooks/useWatchlist';
|
||||
import { usePaperTrades } from '../hooks/usePaperTrades';
|
||||
import { useTickerNames } from '../hooks/useTickers';
|
||||
import { useMarketRegime } from '../hooks/useMarketRegime';
|
||||
import { regimeColor, regimeDot, regimeHeadline } from '../lib/regime';
|
||||
import { Callout } from '../components/ui/Callout';
|
||||
import { Section } from '../components/ui/Section';
|
||||
import { OpenTradesPanel } from '../components/dashboard/OpenTradesPanel';
|
||||
@@ -213,7 +211,6 @@ export default function DashboardPage() {
|
||||
const tickerNames = useTickerNames();
|
||||
const activation = useActivation();
|
||||
const openTrades = usePaperTrades('open');
|
||||
const regime = useMarketRegime();
|
||||
|
||||
const qualifiedSetups = useMemo(
|
||||
() =>
|
||||
@@ -342,21 +339,35 @@ export default function DashboardPage() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Market regime banner */}
|
||||
{regime.data && (
|
||||
<div className="glass-sm flex items-center gap-2.5 px-4 py-2.5">
|
||||
<span className={`inline-block h-2 w-2 rounded-full ${regimeDot(regime.data.label)}`} />
|
||||
<span className="text-sm text-gray-400">Market regime:</span>
|
||||
<span className={`text-sm font-semibold ${regimeColor(regime.data.label)}`}>
|
||||
{regimeHeadline(regime.data)}
|
||||
</span>
|
||||
{regime.data.label === 'bearish' && (
|
||||
<span className="text-xs text-gray-500">— be cautious on new longs</span>
|
||||
)}
|
||||
{regime.data.label === 'bullish' && (
|
||||
<span className="text-xs text-gray-500">— shorts are counter-trend</span>
|
||||
)}
|
||||
</div>
|
||||
{/* Watchlist — a slim glanceable strip right up top (regime moved to the nav bar) */}
|
||||
{watchlist.data && (
|
||||
topWatchlist.length > 0 ? (
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<span className="section-index mr-1">Watchlist</span>
|
||||
{topWatchlist.map((entry) => (
|
||||
<Link
|
||||
key={entry.symbol}
|
||||
to={`/ticker/${entry.symbol}`}
|
||||
className="inline-flex items-baseline gap-2 rounded-full border border-white/[0.09] px-3 py-1 text-[12.5px] transition-colors hover:border-blue-400/40 hover:bg-white/[0.03]"
|
||||
>
|
||||
<b className="font-semibold text-gray-200">{entry.symbol}</b>
|
||||
<span className={`num text-[11px] ${rColor(entry.change_pct)}`}>
|
||||
{entry.change_pct != null
|
||||
? `${entry.change_pct >= 0 ? '+' : ''}${entry.change_pct.toFixed(2)}%`
|
||||
: '—'}
|
||||
</span>
|
||||
</Link>
|
||||
))}
|
||||
<Link to="/market" className="ml-1 text-xs font-medium text-blue-300 transition-colors hover:text-blue-200">
|
||||
Full watchlist →
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-xs text-gray-600">
|
||||
<span className="section-index mr-2">Watchlist</span>
|
||||
empty — open any ticker and tap ☆ to add it.
|
||||
</p>
|
||||
)
|
||||
)}
|
||||
|
||||
{/* Focal setup */}
|
||||
@@ -496,37 +507,6 @@ export default function DashboardPage() {
|
||||
</Section>
|
||||
</div>
|
||||
|
||||
{/* Watchlist — compact chips, drill into any ticker */}
|
||||
<Section title="My Watchlist" hint="today's move">
|
||||
{watchlist.isLoading && <SkeletonTable rows={2} cols={4} />}
|
||||
{watchlist.isError && <Callout variant="error">Failed to load watchlist</Callout>}
|
||||
{watchlist.data && topWatchlist.length === 0 && (
|
||||
<Callout variant="empty">
|
||||
Your watchlist is empty — open any ticker and tap “☆ Add to watchlist”.
|
||||
</Callout>
|
||||
)}
|
||||
{topWatchlist.length > 0 && (
|
||||
<div className="flex flex-wrap items-center gap-2.5">
|
||||
{topWatchlist.map((entry) => (
|
||||
<Link
|
||||
key={entry.symbol}
|
||||
to={`/ticker/${entry.symbol}`}
|
||||
className="inline-flex items-baseline gap-2 rounded-full border border-white/[0.09] px-3.5 py-1.5 text-[13px] transition-colors hover:border-blue-400/40 hover:bg-white/[0.03]"
|
||||
>
|
||||
<b className="font-semibold text-gray-200">{entry.symbol}</b>
|
||||
<span className={`num text-[11.5px] ${rColor(entry.change_pct)}`}>
|
||||
{entry.change_pct != null
|
||||
? `${entry.change_pct >= 0 ? '+' : ''}${entry.change_pct.toFixed(2)}%`
|
||||
: '—'}
|
||||
</span>
|
||||
</Link>
|
||||
))}
|
||||
<Link to="/market" className="ml-1 text-xs font-medium text-blue-300 transition-colors hover:text-blue-200">
|
||||
Full watchlist →
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</Section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user