Complete Phase 2: Frontend implementation with React + TypeScript
Frontend Features: - React 18 + Vite + TypeScript + Tailwind CSS + Zustand - JWT authentication with automatic token refresh - Tree library with search and category filtering - Full tree navigation (decision/action/solution nodes) - Session management with notes and completion - Session history with export (Markdown/Text/HTML) - ErrorBoundary for graceful error handling Backend Fixes: - CORS: Added port 5174 to allowed origins - Sessions: Fixed JSONB datetime serialization (mode='json') Documentation: - Updated PROGRESS.md with Phase 2 completion - Updated 03-DEVELOPMENT-ROADMAP.md with checked items - Added PHASE-2.5-PERSONAL-BRANCHING.md spec Seed Data: - Added backend/scripts/seed_data.py with Password Reset tree Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
12
frontend/src/types/auth.ts
Normal file
12
frontend/src/types/auth.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export interface Token {
|
||||
access_token: string
|
||||
refresh_token: string
|
||||
token_type: string
|
||||
}
|
||||
|
||||
export interface AuthState {
|
||||
user: import('./user').User | null
|
||||
token: Token | null
|
||||
isAuthenticated: boolean
|
||||
isLoading: boolean
|
||||
}
|
||||
17
frontend/src/types/index.ts
Normal file
17
frontend/src/types/index.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
export * from './user'
|
||||
export * from './auth'
|
||||
export * from './tree'
|
||||
export * from './session'
|
||||
|
||||
// API response wrapper types
|
||||
export interface PaginatedResponse<T> {
|
||||
items: T[]
|
||||
total: number
|
||||
page: number
|
||||
size: number
|
||||
pages: number
|
||||
}
|
||||
|
||||
export interface ApiError {
|
||||
detail: string
|
||||
}
|
||||
55
frontend/src/types/session.ts
Normal file
55
frontend/src/types/session.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import type { TreeStructure } from './tree'
|
||||
|
||||
export interface DecisionRecord {
|
||||
node_id: string
|
||||
question: string | null
|
||||
answer: string | null
|
||||
action_performed: string | null
|
||||
notes: string | null
|
||||
automation_used: boolean
|
||||
timestamp: string
|
||||
attachments: string[]
|
||||
}
|
||||
|
||||
export interface Session {
|
||||
id: string
|
||||
tree_id: string
|
||||
user_id: string
|
||||
tree_snapshot: TreeStructure
|
||||
path_taken: string[]
|
||||
decisions: DecisionRecord[]
|
||||
started_at: string
|
||||
completed_at: string | null
|
||||
ticket_number: string | null
|
||||
client_name: string | null
|
||||
exported: boolean
|
||||
}
|
||||
|
||||
export interface SessionCreate {
|
||||
tree_id: string
|
||||
ticket_number?: string
|
||||
client_name?: string
|
||||
}
|
||||
|
||||
export interface SessionUpdate {
|
||||
path_taken?: string[]
|
||||
decisions?: DecisionRecord[]
|
||||
ticket_number?: string
|
||||
client_name?: string
|
||||
}
|
||||
|
||||
export interface SessionExport {
|
||||
format: 'text' | 'markdown' | 'html'
|
||||
include_timestamps?: boolean
|
||||
include_tree_info?: boolean
|
||||
}
|
||||
|
||||
// Navigation state for active session
|
||||
export interface SessionNavigationState {
|
||||
activeSession: Session | null
|
||||
currentNodeId: string
|
||||
pathTaken: string[]
|
||||
decisions: DecisionRecord[]
|
||||
isLoading: boolean
|
||||
error: string | null
|
||||
}
|
||||
98
frontend/src/types/tree.ts
Normal file
98
frontend/src/types/tree.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
// Tree node types
|
||||
export type NodeType = 'decision' | 'action' | 'solution'
|
||||
|
||||
export interface TreeOption {
|
||||
id: string
|
||||
label: string
|
||||
next_node_id: string
|
||||
}
|
||||
|
||||
export interface TreeNodeBase {
|
||||
id: string
|
||||
type: NodeType
|
||||
}
|
||||
|
||||
export interface DecisionNode extends TreeNodeBase {
|
||||
type: 'decision'
|
||||
question: string
|
||||
help_text?: string
|
||||
options: TreeOption[]
|
||||
children: TreeNode[]
|
||||
}
|
||||
|
||||
export interface ActionNode extends TreeNodeBase {
|
||||
type: 'action'
|
||||
title: string
|
||||
description: string
|
||||
commands?: string[]
|
||||
expected_outcome?: string
|
||||
next_node_id?: string
|
||||
children?: TreeNode[]
|
||||
}
|
||||
|
||||
export interface SolutionNode extends TreeNodeBase {
|
||||
type: 'solution'
|
||||
title: string
|
||||
description: string
|
||||
resolution_steps?: string[]
|
||||
}
|
||||
|
||||
export type TreeNode = DecisionNode | ActionNode | SolutionNode
|
||||
|
||||
export interface TreeStructure {
|
||||
id: string
|
||||
type: NodeType
|
||||
question?: string
|
||||
title?: string
|
||||
description?: string
|
||||
help_text?: string
|
||||
options?: TreeOption[]
|
||||
commands?: string[]
|
||||
expected_outcome?: string
|
||||
next_node_id?: string
|
||||
resolution_steps?: string[]
|
||||
children?: TreeStructure[]
|
||||
}
|
||||
|
||||
// API response types
|
||||
export interface Tree {
|
||||
id: string
|
||||
name: string
|
||||
description: string | null
|
||||
category: string | null
|
||||
tree_structure: TreeStructure
|
||||
author_id: string | null
|
||||
team_id: string | null
|
||||
is_active: boolean
|
||||
version: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
usage_count: number
|
||||
}
|
||||
|
||||
export interface TreeListItem {
|
||||
id: string
|
||||
name: string
|
||||
description: string | null
|
||||
category: string | null
|
||||
is_active: boolean
|
||||
version: number
|
||||
usage_count: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface TreeCreate {
|
||||
name: string
|
||||
description?: string
|
||||
category?: string
|
||||
tree_structure: TreeStructure
|
||||
}
|
||||
|
||||
export interface TreeUpdate {
|
||||
name?: string
|
||||
description?: string
|
||||
category?: string
|
||||
tree_structure?: TreeStructure
|
||||
is_active?: boolean
|
||||
}
|
||||
28
frontend/src/types/user.ts
Normal file
28
frontend/src/types/user.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
export type UserRole = 'admin' | 'engineer' | 'viewer'
|
||||
|
||||
export interface User {
|
||||
id: string
|
||||
email: string
|
||||
name: string
|
||||
role: UserRole
|
||||
team_id: string | null
|
||||
created_at: string
|
||||
last_login: string | null
|
||||
}
|
||||
|
||||
export interface UserCreate {
|
||||
email: string
|
||||
password: string
|
||||
name: string
|
||||
role?: UserRole
|
||||
}
|
||||
|
||||
export interface UserLogin {
|
||||
email: string
|
||||
password: string
|
||||
}
|
||||
|
||||
export interface UserUpdate {
|
||||
name?: string
|
||||
email?: string
|
||||
}
|
||||
Reference in New Issue
Block a user