QuantHive / ui /src /App.jsx
ARKAISW's picture
Final manual tweaks to server imports
5b8d71e
import React from 'react';
import { Play, SkipForward, Square } from 'lucide-react';
import { BalancePanel } from './components/BalancePanel';
import { MarketPanel } from './components/MarketPanel';
import { MetricsPanel } from './components/MetricsPanel';
import { OfficeScene } from './components/OfficeScene';
import { useSimulationStore } from './store';
function App() {
const {
simState,
portfolioHistory,
priceHistory,
lastPortfolioDelta,
lastPriceDelta,
lastError,
toggleSimulation,
fetchState,
stepSimulation,
} = useSimulationStore();
React.useEffect(() => {
fetchState();
const interval = window.setInterval(() => {
fetchState();
}, 600);
return () => window.clearInterval(interval);
}, [fetchState]);
return (
<div className="min-h-screen bg-[linear-gradient(180deg,#f9eadb_0%,#f6ddc6_42%,#ecd0bb_100%)] px-6 py-8 text-stone-800 md:px-8">
<div className="mx-auto max-w-[1500px]">
<div className="mb-8 flex flex-col gap-5 rounded-[2.2rem] border border-[#7d5a4f]/15 bg-[#fff8ef]/78 px-6 py-6 shadow-[0_24px_55px_rgba(77,44,26,0.12)] backdrop-blur md:flex-row md:items-end md:justify-between">
<div className="max-w-3xl">
<div className="inline-flex items-center gap-2 rounded-full bg-white/80 px-4 py-1 text-[11px] font-semibold uppercase tracking-[0.32em] text-stone-500">
<span className={`h-2.5 w-2.5 rounded-full ${simState.is_running ? 'bg-emerald-500' : 'bg-stone-400'}`} />
Wild Card Demo
</div>
<h1 className="mt-4 text-4xl font-semibold tracking-tight text-stone-900 md:text-5xl">
Indie quant floor with live agent choreography
</h1>
<p className="mt-3 max-w-2xl text-sm leading-7 text-stone-600 md:text-base">
The scene updates off the running trading environment: signals travel desk to desk, the trader fires orders, and the balance reacts to the trades in real time.
</p>
</div>
<div className="flex flex-wrap items-center gap-3">
{lastError ? (
<div className="rounded-full border border-rose-200 bg-rose-50 px-4 py-2 text-[11px] font-semibold uppercase tracking-[0.18em] text-rose-600 shadow-sm">
Demo error: {lastError}
</div>
) : null}
<div className="rounded-full bg-white/85 px-4 py-2 text-[11px] font-semibold uppercase tracking-[0.24em] text-stone-500 shadow-sm">
Step {simState.current_step}
</div>
<div className="rounded-full bg-white/85 px-4 py-2 text-[11px] font-semibold uppercase tracking-[0.24em] text-stone-500 shadow-sm">
{simState.engine?.mode}
</div>
<button
onClick={() => stepSimulation()}
className="inline-flex items-center gap-2 rounded-full border border-[#7d5a4f]/15 bg-white px-5 py-3 text-sm font-semibold text-stone-700 shadow-sm transition hover:bg-stone-50"
>
<SkipForward size={16} />
Step
</button>
<button
onClick={() => toggleSimulation(simState.is_running)}
className={`inline-flex items-center gap-2 rounded-full px-5 py-3 text-sm font-semibold shadow-sm transition ${
simState.is_running
? 'bg-rose-500 text-white hover:bg-rose-600'
: 'bg-emerald-500 text-white hover:bg-emerald-600'
}`}
>
{simState.is_running ? <Square size={16} /> : <Play size={16} />}
{simState.is_running ? 'Stop Demo' : 'Run Demo'}
</button>
</div>
</div>
<div className="grid gap-6 xl:grid-cols-[minmax(0,1fr)_360px]">
<OfficeScene
agents={simState.agents}
flow={simState.flow}
trade={simState.trade}
currentStep={simState.current_step}
isRunning={simState.is_running}
engine={simState.engine}
/>
<div className="flex flex-col gap-6">
<BalancePanel
portfolio={simState.portfolio}
history={portfolioHistory}
lastDelta={lastPortfolioDelta}
trade={simState.trade}
/>
<MarketPanel
chart={simState.chart}
history={priceHistory}
trade={simState.trade}
engine={simState.engine}
lastPriceDelta={lastPriceDelta}
/>
</div>
</div>
<div className="mt-6">
<MetricsPanel metrics={simState.metrics} trade={simState.trade} agents={simState.agents} />
</div>
</div>
</div>
);
}
export default App;