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:
57
frontend/src/api/trees.ts
Normal file
57
frontend/src/api/trees.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import apiClient from './client'
|
||||
import type { Tree, TreeListItem, TreeCreate, TreeUpdate } from '@/types'
|
||||
|
||||
export interface TreeListParams {
|
||||
page?: number
|
||||
size?: number
|
||||
category?: string
|
||||
include_inactive?: boolean
|
||||
}
|
||||
|
||||
export interface TreeListResponse {
|
||||
items: TreeListItem[]
|
||||
total: number
|
||||
page: number
|
||||
size: number
|
||||
pages: number
|
||||
}
|
||||
|
||||
export const treesApi = {
|
||||
async list(params?: TreeListParams): Promise<TreeListItem[]> {
|
||||
const response = await apiClient.get<TreeListItem[]>('/trees', { params })
|
||||
return response.data
|
||||
},
|
||||
|
||||
async get(id: string): Promise<Tree> {
|
||||
const response = await apiClient.get<Tree>(`/trees/${id}`)
|
||||
return response.data
|
||||
},
|
||||
|
||||
async create(data: TreeCreate): Promise<Tree> {
|
||||
const response = await apiClient.post<Tree>('/trees', data)
|
||||
return response.data
|
||||
},
|
||||
|
||||
async update(id: string, data: TreeUpdate): Promise<Tree> {
|
||||
const response = await apiClient.put<Tree>(`/trees/${id}`, data)
|
||||
return response.data
|
||||
},
|
||||
|
||||
async delete(id: string): Promise<void> {
|
||||
await apiClient.delete(`/trees/${id}`)
|
||||
},
|
||||
|
||||
async categories(): Promise<string[]> {
|
||||
const response = await apiClient.get<string[]>('/trees/categories')
|
||||
return response.data
|
||||
},
|
||||
|
||||
async search(query: string, category?: string): Promise<TreeListItem[]> {
|
||||
const response = await apiClient.get<TreeListItem[]>('/trees/search', {
|
||||
params: { q: query, category },
|
||||
})
|
||||
return response.data
|
||||
},
|
||||
}
|
||||
|
||||
export default treesApi
|
||||
Reference in New Issue
Block a user