Phase 1 MVP: gateway, CRUD handlers, frontend components
Backend: - WebSocket gateway (hub, client, events) with fanout broadcast - Server CRUD handlers (create, list, get, update, delete) - Channel CRUD handlers (create, list, get, update, delete) - Message CRUD handlers (list with cursor pagination, create, update, delete) - cmd/migrate standalone migration CLI (up/down) - cmd/server wired to all handlers + WebSocket + static file serving Frontend: - Zustand stores: auth, server, channel, message, websocket - API client with fetch wrapper - Terminal-styled components: Layout, LoginForm, ChatArea, ChannelList, ServerBar, MemberList - React Router with login and main routes - Gruvbox dark palette throughout Ops: - Docker Compose with app service (multi-stage build) - Caddyfile with WebSocket upgrade support - Makefile for common tasks
This commit is contained in:
+31
-15
@@ -1,17 +1,33 @@
|
||||
function App() {
|
||||
return (
|
||||
<div className="h-full w-full flex flex-col items-center justify-center bg-gb-bg text-gb-fg">
|
||||
<div className="terminal-border p-6 bg-gb-bg-h">
|
||||
<pre className="text-gb-orange font-mono text-lg mb-4">
|
||||
{"┌─ DUMPSTER ─┐"}
|
||||
</pre>
|
||||
<p className="text-gb-fg-s mb-4">The server is running. Frontend coming soon.</p>
|
||||
<button className="terminal-button">
|
||||
[LOGIN]
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
|
||||
import { LoginForm } from './components/LoginForm.tsx';
|
||||
import { Layout } from './components/Layout.tsx';
|
||||
import { ChatArea } from './components/ChatArea.tsx';
|
||||
import { useAuthStore } from './stores/auth.ts';
|
||||
|
||||
function ProtectedRoute({ children }: { children: React.ReactNode }) {
|
||||
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
|
||||
return isAuthenticated ? <>{children}</> : <Navigate to="/login" replace />;
|
||||
}
|
||||
|
||||
export default App
|
||||
function App() {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="/login" element={<LoginForm />} />
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout />
|
||||
</ProtectedRoute>
|
||||
}
|
||||
>
|
||||
<Route index element={<ChatArea />} />
|
||||
<Route path="channels/:channelId" element={<ChatArea />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
Reference in New Issue
Block a user