This commit establishes the foundation for the BlackRoad OS web application, the primary SaaS product for human-AI collaboration. 1. Authentication System - Login and signup pages with email/password - Zustand state management for auth - Workspace-based user model - Protected route handling 2. App Shell - Sidebar navigation (Conversations, Agents, Governance, Account) - App header with workspace and user info - Layout with authentication guards - Responsive design with Tailwind CSS 3. Conversation Interface - Chat UI with message bubbles - User and assistant message rendering - Real-time timestamp display - Loading states and animations - Placeholder for WebSocket integration 4. Core Dependencies - Next.js 16 with App Router - Zustand for state management - TanStack Query (ready for API calls) - Lucide React icons - Tailwind CSS 4 with custom utilities 5. Workspace Management - Multi-tenant workspace structure - Workspace store with Zustand - Plan-based workspace model (Free, Pro, Enterprise) Structure: app/ ├── (auth)/ # Authentication routes │ ├── login/ │ └── signup/ ├── (app)/ # Protected app routes │ ├── conversations/[id]/ │ ├── workspace/ │ └── layout.tsx └── page.tsx # Redirects to login components/ ├── Sidebar.tsx # Main navigation └── AppHeader.tsx # Workspace header stores/ ├── auth-store.ts # Authentication state └── workspace-store.ts lib/ └── cn.ts # Tailwind merge utility Next Steps: - Integrate WebSocket streaming for real-time AI responses - Connect to BlackRoad OS backend API - Add agent management interface - Build governance center UI - Deploy to app.blackroad.io Phase 1 Alpha Target: Jan 25, 2026 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
79 lines
1.7 KiB
TypeScript
79 lines
1.7 KiB
TypeScript
import { create } from 'zustand';
|
|
import { persist } from 'zustand/middleware';
|
|
|
|
interface User {
|
|
id: string;
|
|
email: string;
|
|
name: string;
|
|
workspaceId: string;
|
|
role: 'admin' | 'member';
|
|
}
|
|
|
|
interface AuthState {
|
|
user: User | null;
|
|
token: string | null;
|
|
isAuthenticated: boolean;
|
|
login: (email: string, password: string) => Promise<void>;
|
|
logout: () => void;
|
|
signup: (email: string, password: string, name: string) => Promise<void>;
|
|
}
|
|
|
|
export const useAuthStore = create<AuthState>()(
|
|
persist(
|
|
(set) => ({
|
|
user: null,
|
|
token: null,
|
|
isAuthenticated: false,
|
|
|
|
login: async (email: string, password: string) => {
|
|
// TODO: Replace with actual API call
|
|
const mockUser: User = {
|
|
id: '1',
|
|
email,
|
|
name: email.split('@')[0],
|
|
workspaceId: 'default-workspace',
|
|
role: 'admin',
|
|
};
|
|
|
|
const mockToken = 'mock-jwt-token';
|
|
|
|
set({
|
|
user: mockUser,
|
|
token: mockToken,
|
|
isAuthenticated: true,
|
|
});
|
|
},
|
|
|
|
logout: () => {
|
|
set({
|
|
user: null,
|
|
token: null,
|
|
isAuthenticated: false,
|
|
});
|
|
},
|
|
|
|
signup: async (email: string, password: string, name: string) => {
|
|
// TODO: Replace with actual API call
|
|
const mockUser: User = {
|
|
id: '1',
|
|
email,
|
|
name,
|
|
workspaceId: 'default-workspace',
|
|
role: 'admin',
|
|
};
|
|
|
|
const mockToken = 'mock-jwt-token';
|
|
|
|
set({
|
|
user: mockUser,
|
|
token: mockToken,
|
|
isAuthenticated: true,
|
|
});
|
|
},
|
|
}),
|
|
{
|
|
name: 'auth-storage',
|
|
}
|
|
)
|
|
);
|