feat: implement My Trees, admin UI, rating modal, and bundle optimization (Issues #15, #18, #19, #31)
Frontend features: - My Trees personal dashboard with fork tracking (Issue #15) - Tree sharing UI with token generation and copy (Issue #16) - Draft tree badges and validation UI (Issue #25) - Save session as tree modal (Issue #17) - Rate/review modal with localStorage tracking (Issue #19) - Admin category management with drag-and-drop (Issue #18) - Bundle size optimization with code splitting (Issue #31) Components created: - MyTreesPage: Personal tree organization - AdminCategoriesPage: Category CRUD with @dnd-kit - ShareTreeModal: Tree sharing interface - SaveSessionAsTreeModal: Session conversion UI - StepRatingModal: Post-session rating with stars - StarRating: Reusable rating component - PageLoader: Loading fallback for lazy routes - CreateCategoryModal, EditCategoryModal: Admin modals Bundle optimization: - Reduced from 892 KB to 221 KB (75% reduction) - Dynamic imports for 9 heavy pages - Vendor chunk splitting for optimal caching - 6 separate vendor chunks (react, markdown, utils, dnd, icons, state) Dependencies added: - @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities API clients: - stepCategories: Full CRUD for admin - Enhanced sessions: saveAsTree endpoint - Enhanced trees: share, fork, canPublish endpoints Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -81,3 +81,16 @@ export interface SessionNavigationState {
|
||||
isLoading: boolean
|
||||
error: string | null
|
||||
}
|
||||
|
||||
// Save session as tree
|
||||
export interface SaveAsTreeRequest {
|
||||
tree_name?: string
|
||||
description?: string
|
||||
status: 'draft' | 'published'
|
||||
}
|
||||
|
||||
export interface SaveAsTreeResponse {
|
||||
tree_id: string
|
||||
tree_name: string
|
||||
message: string
|
||||
}
|
||||
|
||||
@@ -60,6 +60,28 @@ export interface StepCategory {
|
||||
is_active: boolean
|
||||
}
|
||||
|
||||
export interface StepCategoryListItem {
|
||||
id: string
|
||||
name: string
|
||||
description?: string
|
||||
display_order: number
|
||||
is_active: boolean
|
||||
}
|
||||
|
||||
export interface StepCategoryCreate {
|
||||
name: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
export interface StepCategoryUpdate {
|
||||
name?: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
export interface StepCategoryListParams {
|
||||
include_inactive?: boolean
|
||||
}
|
||||
|
||||
export interface StepListParams {
|
||||
visibility?: 'private' | 'team' | 'public'
|
||||
category_id?: string
|
||||
@@ -97,7 +119,9 @@ export interface StepUpdate {
|
||||
export interface RatingCreate {
|
||||
rating: number
|
||||
review_text?: string
|
||||
verified_use: boolean
|
||||
was_helpful?: boolean
|
||||
session_id?: string
|
||||
is_verified_use?: boolean
|
||||
}
|
||||
|
||||
export interface RatingUpdate {
|
||||
|
||||
@@ -57,6 +57,8 @@ export interface TreeStructure {
|
||||
}
|
||||
|
||||
// API response types
|
||||
export type TreeStatus = 'draft' | 'published'
|
||||
|
||||
export interface Tree {
|
||||
id: string
|
||||
name: string
|
||||
@@ -71,6 +73,7 @@ export interface Tree {
|
||||
is_active: boolean
|
||||
is_public: boolean
|
||||
is_default: boolean
|
||||
status: TreeStatus
|
||||
version: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
@@ -90,6 +93,7 @@ export interface TreeListItem {
|
||||
is_active: boolean
|
||||
is_public: boolean
|
||||
is_default: boolean
|
||||
status: TreeStatus
|
||||
version: number
|
||||
usage_count: number
|
||||
created_at: string
|
||||
@@ -105,6 +109,7 @@ export interface TreeCreate {
|
||||
tree_structure: TreeStructure
|
||||
is_public?: boolean
|
||||
is_default?: boolean
|
||||
status?: TreeStatus
|
||||
}
|
||||
|
||||
export interface TreeUpdate {
|
||||
@@ -116,6 +121,7 @@ export interface TreeUpdate {
|
||||
tree_structure?: TreeStructure
|
||||
is_active?: boolean
|
||||
is_public?: boolean
|
||||
status?: TreeStatus
|
||||
}
|
||||
|
||||
// Filter params for tree listing
|
||||
@@ -127,7 +133,55 @@ export interface TreeFilters {
|
||||
is_active?: boolean
|
||||
author_id?: string
|
||||
is_public?: boolean
|
||||
include_drafts?: boolean
|
||||
sort_by?: 'usage_count' | 'updated_at' | 'created_at' | 'name' | 'name_desc' | 'version'
|
||||
skip?: number
|
||||
limit?: number
|
||||
}
|
||||
|
||||
// Tree sharing types
|
||||
export type TreeVisibility = 'private' | 'team' | 'link' | 'public'
|
||||
|
||||
export interface TreeShareCreate {
|
||||
allow_forking?: boolean
|
||||
expires_at?: string | null
|
||||
}
|
||||
|
||||
export interface TreeShare {
|
||||
id: string
|
||||
tree_id: string
|
||||
share_token: string
|
||||
share_url: string
|
||||
allow_forking: boolean
|
||||
created_by: string
|
||||
created_at: string
|
||||
expires_at: string | null
|
||||
}
|
||||
|
||||
export interface TreeVisibilityUpdate {
|
||||
visibility: TreeVisibility
|
||||
}
|
||||
|
||||
export interface SharedTree {
|
||||
id: string
|
||||
name: string
|
||||
description: string | null
|
||||
category: string | null
|
||||
tree_structure: TreeStructure
|
||||
tags: string[]
|
||||
version: number
|
||||
allow_forking: boolean
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
// Tree validation types
|
||||
export interface ValidationError {
|
||||
field: string
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface TreeValidationResponse {
|
||||
can_publish: boolean
|
||||
errors: ValidationError[]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user