diff --git a/README.md b/README.md
index c6ab06b..d58a33a 100644
--- a/README.md
+++ b/README.md
@@ -277,6 +277,20 @@ src/
└── utils/ # Pure utility functions
```
+### Dashboard routes
+
+`/dashboard` is the single primary prediction terminal. It now includes the
+high-value panels that previously lived only on the legacy `/play` view: the
+price chart, the round lifecycle timeline, round-update connection status, the
+end-round modal, and opt-in community chat (toggled from the dashboard header so
+the default terminal stays uncluttered).
+
+`/play` is **deprecated** and permanently redirects to `/dashboard`. The
+`LegacyDashboard` component is retained only for reference and is no longer
+routed. Chat and notifications are available via the in-dashboard toggle; further
+social/notification consolidation is tracked in issue
+[#130](https://github.com/TevaLabs/Xelma-Frontend/issues/130).
+
---
## Testing
diff --git a/src/App.tsx b/src/App.tsx
index 3ab4074..9c817ae 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,5 +1,5 @@
import { lazy, Suspense } from 'react';
-import { Routes, Route, useLocation } from 'react-router-dom';
+import { Routes, Route, Navigate, useLocation } from 'react-router-dom';
import { Toaster } from 'sonner';
import Navbar from './components/Navbar';
import PageSkeleton from './components/PageSkeleton';
@@ -14,7 +14,6 @@ import { Trophy } from 'lucide-react';
import { ENTER } from './utils/motion';
const Dashboard = lazy(() => import(/* webpackChunkName: "dashboard" */ './pages/Dashboard'));
-const LegacyDashboard = lazy(() => import(/* webpackChunkName: "legacy-dashboard" */ './pages/LegacyDashboard'));
const Leaderboard = lazy(() => import(/* webpackChunkName: "leaderboard" */ './components/Leaderboard'));
const LearnPage = lazy(() => import(/* webpackChunkName: "learn" */ './pages/Learn'));
const Connect = lazy(() => import('./pages/Connect'));
@@ -40,28 +39,28 @@ function App() {
}>
-
-
- } />
- }>} />
- }>} />
- }>} />
- }>} />
- } />
- } />
-
- }
- />
- } />
-
-
+
+ } />
+ }>} />
+ {/* /play is deprecated: its high-value panels (price chart, round
+ timeline, chat, end-round modal) now live in /dashboard. */}
+ } />
+ }>} />
+ }>} />
+ } />
+ } />
+
+ }
+ />
+ } />
+
diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx
index a12997f..462fcf9 100644
--- a/src/pages/Dashboard.tsx
+++ b/src/pages/Dashboard.tsx
@@ -5,6 +5,10 @@ import PredictionHistory from "../components/PredictionHistory";
import type { PredictionData } from "../components/PredictionControls";
import BetModal from "../components/BetModal";
import EndRoundModal from "../components/EndRoundModal";
+import RoundTimeline from "../components/RoundTimeline";
+import { ChatSidebar } from "../components/ChatSidebar";
+import { ConnectionStatus } from "../components/ConnectionStatus";
+import { useConnectionStatus } from "../hooks/useConnectionStatus";
import { useRoundStore } from "../store/useRoundStore";
import type { Round } from "../lib/api-client";
import { educationApi } from "../lib/api-client";
@@ -90,6 +94,7 @@ const DailyTip = () => {
const Dashboard = () => {
const isRoundActive = useRoundStore((state) => state.isRoundActive);
const isLoading = useRoundStore((state) => state.isLoading);
+ const sseConnection = useRoundStore((state) => state.sseConnection);
const isWalletConnected = useWalletStore(selectIsWalletConnected);
const isWalletConnecting = useWalletStore(
(s) => s.status === "connecting" || s.status === "checking"
@@ -97,9 +102,12 @@ const Dashboard = () => {
const resolvedRound = useRoundStore((state) => state.resolvedRound);
const dismissResolvedRound = useRoundStore((state) => state.dismissResolvedRound);
const publicKey = useWalletStore((s) => s.publicKey);
- const balance = useWalletStore((s) => s.balance);
+ const { isConnected: isSocketConnected } = useConnectionStatus();
const [isBetModalOpen, setIsBetModalOpen] = useState(false);
const [pendingPrediction, setPendingPrediction] = useState(null);
+ // Community chat is opt-in so the default terminal stays uncluttered.
+ const [isChatOpen, setIsChatOpen] = useState(false);
+ const timeoutRef = useRef(null);
useEffect(() => {
const { fetchActiveRound, subscribeToRoundEvents } = useRoundStore.getState();
@@ -151,9 +159,51 @@ const Dashboard = () => {
return (
+ {/* Opt-in community chat (ported from the legacy /play view). Self-positions
+ as a fixed slide-over, so mounting it does not shift the terminal layout. */}
+ {isChatOpen && }
+