mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-24 13:44:54 +00:00
Generated by Spark: Load more of UI from JSON declarations and break up large components into atomic and create hooks as needed
This commit is contained in:
117
docs/COMPONENT_SIZE_GUIDE.md
Normal file
117
docs/COMPONENT_SIZE_GUIDE.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# Component Size Guidelines
|
||||
|
||||
All components must be under 150 lines of code (LOC). This refactor follows atomic design principles.
|
||||
|
||||
## Component Categories
|
||||
|
||||
### Atoms (< 50 LOC)
|
||||
Single-purpose, highly reusable components:
|
||||
- DataList
|
||||
- StatCard
|
||||
- ActionButton
|
||||
- LoadingState
|
||||
- EmptyState
|
||||
- StatusBadge
|
||||
- IconButton
|
||||
|
||||
### Molecules (50-100 LOC)
|
||||
Combinations of atoms for specific use cases:
|
||||
- SearchBar (Input + Icon)
|
||||
- DataCard (Card + Content + Actions)
|
||||
- FormField (Label + Input + Error)
|
||||
- FilterBar (Multiple filters)
|
||||
|
||||
### Organisms (100-150 LOC)
|
||||
Complex components combining molecules:
|
||||
- DataTable (with sorting, filtering, pagination)
|
||||
- Dashboard (multiple stat cards and charts)
|
||||
- FormBuilder (dynamic form generation)
|
||||
|
||||
## Refactoring Large Components
|
||||
|
||||
### Before (200+ LOC):
|
||||
```typescript
|
||||
function ProjectDashboard() {
|
||||
// 50 lines of state and logic
|
||||
// 150 lines of JSX with embedded components
|
||||
return <div>...</div>
|
||||
}
|
||||
```
|
||||
|
||||
### After (< 50 LOC):
|
||||
```typescript
|
||||
function ProjectDashboard(props) {
|
||||
return (
|
||||
<JSONPageRenderer
|
||||
schema={dashboardSchema}
|
||||
data={props}
|
||||
functions={{ calculateCompletionScore }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Hook Extraction
|
||||
|
||||
Move logic out of components into hooks:
|
||||
|
||||
### Before:
|
||||
```typescript
|
||||
function MyComponent() {
|
||||
const [items, setItems] = useState([])
|
||||
const [search, setSearch] = useState('')
|
||||
const filtered = items.filter(i => i.name.includes(search))
|
||||
const [page, setPage] = useState(1)
|
||||
const paginated = filtered.slice((page-1)*10, page*10)
|
||||
// ... more logic
|
||||
return <div>...</div>
|
||||
}
|
||||
```
|
||||
|
||||
### After:
|
||||
```typescript
|
||||
function MyComponent() {
|
||||
const [items, setItems] = useKV('items', [])
|
||||
const { filtered } = useSearchFilter({ items, searchFields: ['name'] })
|
||||
const { items: page } = usePagination({ items: filtered, pageSize: 10 })
|
||||
return <DataList items={page} renderItem={...} />
|
||||
}
|
||||
```
|
||||
|
||||
## JSON-Driven Pages
|
||||
|
||||
For data-heavy pages, use JSON configuration:
|
||||
|
||||
1. Create JSON schema in `/src/config/pages/`
|
||||
2. Define data bindings and layout
|
||||
3. Implement computed functions
|
||||
4. Use JSONPageRenderer
|
||||
|
||||
This reduces component size from 200+ LOC to < 50 LOC.
|
||||
|
||||
## Composition Over Inheritance
|
||||
|
||||
Build complex UIs by composing simple components:
|
||||
|
||||
```typescript
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<Heading level={2}>Title</Heading>
|
||||
<StatusBadge status="active" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<DataList items={data} renderItem={renderItem} />
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<ActionButton label="Add" onClick={handleAdd} />
|
||||
</CardFooter>
|
||||
</Card>
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Easier to Test**: Small components = simple tests
|
||||
2. **Easier to Understand**: Clear, focused responsibility
|
||||
3. **Easier to Reuse**: Composable building blocks
|
||||
4. **Easier to Maintain**: Changes are localized
|
||||
5. **Better Performance**: Smaller re-render boundaries
|
||||
219
docs/HOOKS_REFERENCE.md
Normal file
219
docs/HOOKS_REFERENCE.md
Normal file
@@ -0,0 +1,219 @@
|
||||
# Hook Library Reference
|
||||
|
||||
## Data Management Hooks
|
||||
|
||||
### useDataSource
|
||||
Unified data source manager supporting KV storage, static data, and computed values.
|
||||
|
||||
```typescript
|
||||
import { useDataSource } from '@/hooks/data'
|
||||
|
||||
const { data, setData, isLoading } = useDataSource({
|
||||
id: 'myData',
|
||||
type: 'kv',
|
||||
key: 'app-data',
|
||||
defaultValue: []
|
||||
})
|
||||
```
|
||||
|
||||
**Config Options:**
|
||||
- `type`: 'kv' | 'static' | 'computed'
|
||||
- `key`: KV storage key (for type='kv')
|
||||
- `defaultValue`: Initial value
|
||||
- `compute`: Function for computed data
|
||||
- `dependencies`: Array of dependency IDs
|
||||
|
||||
---
|
||||
|
||||
### useCRUD
|
||||
Complete CRUD operations for any data type with functional updates.
|
||||
|
||||
```typescript
|
||||
import { useCRUD } from '@/hooks/data'
|
||||
import { useKV } from '@github/spark/hooks'
|
||||
|
||||
const [items, setItems] = useKV('todos', [])
|
||||
const crud = useCRUD({ items, setItems, idField: 'id' })
|
||||
|
||||
crud.create({ id: Date.now(), title: 'New task' })
|
||||
const item = crud.read(123)
|
||||
crud.update(123, { completed: true })
|
||||
crud.delete(123)
|
||||
const all = crud.list()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### useSearchFilter
|
||||
Search and filter with multiple fields support.
|
||||
|
||||
```typescript
|
||||
import { useSearchFilter } from '@/hooks/data'
|
||||
|
||||
const {
|
||||
searchQuery,
|
||||
setSearchQuery,
|
||||
filters,
|
||||
setFilter,
|
||||
clearFilters,
|
||||
filtered,
|
||||
count
|
||||
} = useSearchFilter({
|
||||
items: myData,
|
||||
searchFields: ['name', 'description'],
|
||||
filterFn: (item, filters) => item.status === filters.status
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### useSort
|
||||
Sortable list with direction toggle.
|
||||
|
||||
```typescript
|
||||
import { useSort } from '@/hooks/data'
|
||||
|
||||
const {
|
||||
sorted,
|
||||
sortField,
|
||||
sortDirection,
|
||||
toggleSort,
|
||||
resetSort
|
||||
} = useSort({
|
||||
items: myData,
|
||||
defaultField: 'name',
|
||||
defaultDirection: 'asc'
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### usePagination
|
||||
Full pagination logic with navigation.
|
||||
|
||||
```typescript
|
||||
import { usePagination } from '@/hooks/data'
|
||||
|
||||
const {
|
||||
items: paginatedItems,
|
||||
currentPage,
|
||||
totalPages,
|
||||
goToPage,
|
||||
nextPage,
|
||||
prevPage,
|
||||
hasNext,
|
||||
hasPrev,
|
||||
startIndex,
|
||||
endIndex
|
||||
} = usePagination({
|
||||
items: myData,
|
||||
pageSize: 10,
|
||||
initialPage: 1
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### useSelection
|
||||
Multi/single selection with bulk operations.
|
||||
|
||||
```typescript
|
||||
import { useSelection } from '@/hooks/data'
|
||||
|
||||
const {
|
||||
selected,
|
||||
toggle,
|
||||
select,
|
||||
deselect,
|
||||
selectAll,
|
||||
deselectAll,
|
||||
isSelected,
|
||||
getSelected,
|
||||
count,
|
||||
hasSelection
|
||||
} = useSelection({
|
||||
items: myData,
|
||||
multiple: true,
|
||||
idField: 'id'
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Form Hooks
|
||||
|
||||
### useFormField
|
||||
Individual field validation and state management.
|
||||
|
||||
```typescript
|
||||
import { useFormField } from '@/hooks/forms'
|
||||
|
||||
const field = useFormField({
|
||||
name: 'email',
|
||||
defaultValue: '',
|
||||
rules: [
|
||||
{
|
||||
validate: (val) => val.includes('@'),
|
||||
message: 'Must be valid email'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
<input
|
||||
value={field.value}
|
||||
onChange={(e) => field.onChange(e.target.value)}
|
||||
onBlur={field.onBlur}
|
||||
/>
|
||||
{field.touched && field.error && <span>{field.error}</span>}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### useForm
|
||||
Form submission with async support.
|
||||
|
||||
```typescript
|
||||
import { useForm } from '@/hooks/forms'
|
||||
|
||||
const { submit, isSubmitting } = useForm({
|
||||
fields: { email: {...}, password: {...} },
|
||||
onSubmit: async (values) => {
|
||||
await api.submit(values)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always use functional updates with useCRUD:**
|
||||
```typescript
|
||||
// ✅ CORRECT
|
||||
crud.create(newItem)
|
||||
crud.update(id, updates)
|
||||
|
||||
// ❌ WRONG - Never manually modify items
|
||||
setItems([...items, newItem]) // Can cause data loss!
|
||||
```
|
||||
|
||||
2. **Combine hooks for complex scenarios:**
|
||||
```typescript
|
||||
const [items, setItems] = useKV('data', [])
|
||||
const crud = useCRUD({ items, setItems })
|
||||
const { filtered } = useSearchFilter({ items })
|
||||
const { sorted } = useSort({ items: filtered })
|
||||
const { items: page } = usePagination({ items: sorted })
|
||||
```
|
||||
|
||||
3. **Use computed data sources for derived state:**
|
||||
```typescript
|
||||
useDataSource({
|
||||
type: 'computed',
|
||||
compute: (data) => ({
|
||||
total: data.items?.length || 0,
|
||||
completed: data.items?.filter(i => i.done).length || 0
|
||||
}),
|
||||
dependencies: ['items']
|
||||
})
|
||||
```
|
||||
270
docs/JSON_PAGES_GUIDE.md
Normal file
270
docs/JSON_PAGES_GUIDE.md
Normal file
@@ -0,0 +1,270 @@
|
||||
# JSON Page Configuration Guide
|
||||
|
||||
## Overview
|
||||
Define entire pages using JSON configuration instead of writing React components.
|
||||
|
||||
## Page Schema Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "my-page",
|
||||
"layout": {
|
||||
"type": "vertical",
|
||||
"spacing": "6",
|
||||
"sections": [...]
|
||||
},
|
||||
"dataBindings": ["prop1", "prop2"],
|
||||
"components": [...]
|
||||
}
|
||||
```
|
||||
|
||||
## Layout Types
|
||||
|
||||
### Vertical Layout
|
||||
```json
|
||||
{
|
||||
"type": "vertical",
|
||||
"spacing": "6",
|
||||
"sections": [
|
||||
{ "type": "header", "title": "Page Title", "description": "Description" },
|
||||
{ "type": "grid", "items": "statCards", "columns": { "md": 2, "lg": 3 } },
|
||||
{ "type": "cards", "items": "dashboardCards" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Grid Layout
|
||||
```json
|
||||
{
|
||||
"type": "grid",
|
||||
"items": "myItems",
|
||||
"columns": {
|
||||
"sm": 1,
|
||||
"md": 2,
|
||||
"lg": 3,
|
||||
"xl": 4
|
||||
},
|
||||
"gap": "4"
|
||||
}
|
||||
```
|
||||
|
||||
## Data Binding
|
||||
|
||||
### Simple Bindings
|
||||
```json
|
||||
{
|
||||
"dataBinding": "files.length"
|
||||
}
|
||||
```
|
||||
|
||||
### Complex Expressions
|
||||
```json
|
||||
{
|
||||
"dataBinding": "flaskConfig.blueprints.reduce((acc, bp) => acc + bp.endpoints.length, 0)"
|
||||
}
|
||||
```
|
||||
|
||||
### Computed Data Sources
|
||||
```json
|
||||
{
|
||||
"dataSource": {
|
||||
"type": "computed",
|
||||
"compute": "calculateCompletionScore"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Component Types
|
||||
|
||||
### Stat Cards
|
||||
```json
|
||||
{
|
||||
"id": "code-files",
|
||||
"icon": "Code",
|
||||
"title": "Code Files",
|
||||
"dataBinding": "files.length",
|
||||
"description": "files in your project",
|
||||
"color": "text-blue-500"
|
||||
}
|
||||
```
|
||||
|
||||
### Gradient Cards
|
||||
```json
|
||||
{
|
||||
"id": "completion",
|
||||
"type": "gradient-card",
|
||||
"title": "Project Completeness",
|
||||
"icon": "CheckCircle",
|
||||
"gradient": "from-primary/10 to-accent/10",
|
||||
"dataSource": {
|
||||
"type": "computed",
|
||||
"compute": "calculateScore"
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"type": "metric",
|
||||
"binding": "score",
|
||||
"format": "percentage",
|
||||
"size": "large"
|
||||
},
|
||||
{
|
||||
"type": "progress",
|
||||
"binding": "score"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Custom React Components
|
||||
```json
|
||||
{
|
||||
"id": "build-status",
|
||||
"type": "card",
|
||||
"title": "Build Status",
|
||||
"component": "GitHubBuildStatus",
|
||||
"props": {}
|
||||
}
|
||||
```
|
||||
|
||||
## Sub-Components
|
||||
|
||||
### Metric Display
|
||||
```json
|
||||
{
|
||||
"type": "metric",
|
||||
"binding": "completionScore",
|
||||
"format": "percentage",
|
||||
"size": "large"
|
||||
}
|
||||
```
|
||||
|
||||
### Badge
|
||||
```json
|
||||
{
|
||||
"type": "badge",
|
||||
"binding": "status",
|
||||
"variants": {
|
||||
"ready": { "label": "Ready", "variant": "default" },
|
||||
"pending": { "label": "Pending", "variant": "secondary" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Progress Bar
|
||||
```json
|
||||
{
|
||||
"type": "progress",
|
||||
"binding": "completionScore"
|
||||
}
|
||||
```
|
||||
|
||||
### Text
|
||||
```json
|
||||
{
|
||||
"type": "text",
|
||||
"binding": "message",
|
||||
"className": "text-sm text-muted-foreground"
|
||||
}
|
||||
```
|
||||
|
||||
## Icons
|
||||
Use Phosphor icon names:
|
||||
```json
|
||||
{
|
||||
"icon": "Code" // <Code size={24} weight="duotone" />
|
||||
"icon": "Database" // <Database size={24} weight="duotone" />
|
||||
"icon": "Cube" // <Cube size={24} weight="duotone" />
|
||||
}
|
||||
```
|
||||
|
||||
## Complete Example
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "project-overview",
|
||||
"layout": {
|
||||
"type": "vertical",
|
||||
"spacing": "6",
|
||||
"sections": [
|
||||
{
|
||||
"type": "header",
|
||||
"title": "Project Overview",
|
||||
"description": "Key metrics and status"
|
||||
},
|
||||
{
|
||||
"type": "grid",
|
||||
"items": "metrics",
|
||||
"columns": { "md": 2, "lg": 4 },
|
||||
"gap": "4"
|
||||
}
|
||||
]
|
||||
},
|
||||
"metrics": [
|
||||
{
|
||||
"id": "total-files",
|
||||
"icon": "FileText",
|
||||
"title": "Total Files",
|
||||
"dataBinding": "files.length",
|
||||
"description": "source files",
|
||||
"color": "text-blue-500"
|
||||
},
|
||||
{
|
||||
"id": "test-coverage",
|
||||
"icon": "Shield",
|
||||
"title": "Test Coverage",
|
||||
"dataBinding": "tests.coverage",
|
||||
"description": "of code tested",
|
||||
"color": "text-green-500"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Usage in React
|
||||
|
||||
```typescript
|
||||
import { JSONPageRenderer } from '@/components/JSONPageRenderer'
|
||||
import pageSchema from '@/config/pages/my-page.json'
|
||||
|
||||
function MyPage(props) {
|
||||
const functions = {
|
||||
calculateScore: (data) => {
|
||||
// Custom calculation logic
|
||||
return Math.round((data.completed / data.total) * 100)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<JSONPageRenderer
|
||||
schema={pageSchema}
|
||||
data={props}
|
||||
functions={functions}
|
||||
/>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **No Code Deployment**: Update UI without code changes
|
||||
2. **Consistent Design**: Enforced design patterns
|
||||
3. **Rapid Prototyping**: Build pages in minutes
|
||||
4. **Easy Maintenance**: Clear structure and readability
|
||||
5. **Type Safety**: Still benefits from TypeScript
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
1. Start with simple stat-heavy pages (dashboards)
|
||||
2. Define JSON schema for page
|
||||
3. Implement custom functions for computed data
|
||||
4. Replace React component with JSONPageRenderer
|
||||
5. Test and iterate
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- [ ] Actions and event handlers in JSON
|
||||
- [ ] Conditional rendering
|
||||
- [ ] Animations and transitions
|
||||
- [ ] Form definitions
|
||||
- [ ] Table configurations
|
||||
- [ ] Visual JSON schema editor
|
||||
353
docs/README.md
353
docs/README.md
@@ -1,269 +1,158 @@
|
||||
# CodeForge Documentation
|
||||
# Refactoring Documentation Index
|
||||
|
||||
This directory contains comprehensive documentation for the CodeForge low-code application builder.
|
||||
## Overview Documents
|
||||
- [REFACTOR_SUMMARY.md](../REFACTOR_SUMMARY.md) - High-level overview of the refactor
|
||||
- [COMPONENT_SIZE_GUIDE.md](./COMPONENT_SIZE_GUIDE.md) - Guidelines for keeping components under 150 LOC
|
||||
- [architecture.json](../architecture.json) - System architecture configuration
|
||||
|
||||
## 🚀 Quick Start
|
||||
## Hook Library
|
||||
- [HOOKS_REFERENCE.md](./HOOKS_REFERENCE.md) - Complete hook library reference
|
||||
|
||||
### New Features
|
||||
- **[Lazy Loading Charts](./LAZY_LOADING_CHARTS.md)** - Lazy-load recharts, d3, three.js (NEW!)
|
||||
- **[Hover-Based Preloading](./hover-preloading.md)** - Instant page navigation
|
||||
- **[Preloading Quick Reference](./preloading-quick-reference.md)** - Quick start guide
|
||||
- **[Router Quick Start](./ROUTER_QUICK_START.md)** - Enable React Router in 2 minutes
|
||||
- **[React Router Integration](./REACT_ROUTER_INTEGRATION.md)** - Full router documentation
|
||||
### Available Hooks
|
||||
|
||||
## 📚 Documentation Structure
|
||||
#### Data Management (`@/hooks/data`)
|
||||
- `useDataSource` - Unified data source (KV, static, computed)
|
||||
- `useCRUD` - Create, Read, Update, Delete operations
|
||||
- `useSearchFilter` - Search and filter with multiple fields
|
||||
- `useSort` - Sortable lists with direction toggle
|
||||
- `usePagination` - Page navigation and item slicing
|
||||
- `useSelection` - Multi/single selection management
|
||||
|
||||
### Getting Started
|
||||
- **[Router Quick Start](./ROUTER_QUICK_START.md)** - Enable route-based code splitting
|
||||
- **[PRD](./PRD.md)** - Product Requirements Document
|
||||
#### Form Management (`@/hooks/forms`)
|
||||
- `useFormField` - Individual field validation and state
|
||||
- `useForm` - Form submission with async support
|
||||
|
||||
### Performance & Optimization
|
||||
- **[Lazy Loading Charts](./LAZY_LOADING_CHARTS.md)** - Lazy-load recharts, d3, three.js (NEW!)
|
||||
- **[Bundle Optimization (Monaco Editor)](./bundle-optimization.md)** - Lazy-load heavy components
|
||||
- **[Hover-Based Preloading](./hover-preloading.md)** - Instant navigation with preloading
|
||||
- **[Preloading Quick Reference](./preloading-quick-reference.md)** - Quick start
|
||||
- **[React Router Integration](./REACT_ROUTER_INTEGRATION.md)** - Route-based code splitting
|
||||
- **[Router vs Tabs Comparison](./ROUTER_VS_TABS_COMPARISON.md)** - Performance benchmarks
|
||||
- **[Router Quick Start](./ROUTER_QUICK_START.md)** - Enable router in 2 minutes
|
||||
- **[Bundle Optimization](./BUNDLE_OPTIMIZATION.md)** - Bundle size and performance optimization
|
||||
#### UI State (`@/hooks/ui`)
|
||||
- `useDialog` - Dialog open/close state
|
||||
- `useToggle` - Boolean toggle with callbacks
|
||||
- `useKeyboardShortcuts` - Global keyboard shortcuts
|
||||
|
||||
### Error Fixes & Troubleshooting
|
||||
- **[502 Error Fix](./502_ERROR_FIX.md)** - Fix 502 Bad Gateway errors
|
||||
- **[CI/CD Fixes](./CI_CD_FIXES.md)** - Continuous integration fixes
|
||||
## JSON-Driven UI
|
||||
- [JSON_PAGES_GUIDE.md](./JSON_PAGES_GUIDE.md) - Building pages from JSON configuration
|
||||
- [JSON_UI_GUIDE.md](../JSON_UI_GUIDE.md) - Original JSON UI documentation
|
||||
|
||||
### Architecture & Organization
|
||||
- **[Documentation Reorganization](./DOCUMENTATION_REORGANIZATION.md)** - Docs structure
|
||||
- **[Cleanup Complete](./CLEANUP_COMPLETE.md)** - Code cleanup summary
|
||||
- **[Changes Summary](./CHANGES_SUMMARY.md)** - Recent changes
|
||||
- **[Organization Plan](./ORGANIZATION_PLAN.md)** - Project organization
|
||||
### Page Schemas
|
||||
- `/src/config/pages/dashboard.json` - Dashboard page configuration
|
||||
- More schemas can be added for other pages
|
||||
|
||||
### Detailed Sections
|
||||
- **[API Documentation](./api/)** - API reference
|
||||
- **[Architecture](./architecture/)** - System architecture
|
||||
- **[Deployment](./deployment/)** - Deployment guides
|
||||
- **[Guides](./guides/)** - How-to guides
|
||||
- **[Testing](./testing/)** - Testing documentation
|
||||
- **[Reference](./reference/)** - Technical reference
|
||||
## Component Library
|
||||
|
||||
## 🆕 Recent Additions
|
||||
### Atomic Components (`@/components/atoms`)
|
||||
All under 50 LOC:
|
||||
- `DataList` - List rendering with empty states
|
||||
- `StatCard` - Metric display cards
|
||||
- `ActionButton` - Buttons with tooltips
|
||||
- `LoadingState` - Loading spinners
|
||||
- `EmptyState` - Empty state displays
|
||||
- `StatusBadge` - Status indicators
|
||||
- Plus 15+ more existing atoms
|
||||
|
||||
### Chart Library Lazy Loading (Latest)
|
||||
Optimized bundle size by lazy-loading heavy chart libraries:
|
||||
### Molecules (`@/components/molecules`)
|
||||
50-100 LOC components combining atoms
|
||||
|
||||
**Benefits:**
|
||||
- ~1.5MB+ reduction in initial bundle size
|
||||
- Charts load only when needed
|
||||
- Automatic preloading with hover support
|
||||
- Retry logic for network failures
|
||||
### Organisms (`@/components/organisms`)
|
||||
100-150 LOC complex components
|
||||
|
||||
**Libraries optimized:**
|
||||
- Recharts (~450KB)
|
||||
- D3 (~500KB)
|
||||
- Three.js (~600KB)
|
||||
- ReactFlow (~300KB)
|
||||
### Page Renderers
|
||||
- `JSONPageRenderer` - Renders pages from JSON schemas
|
||||
|
||||
**Learn more:**
|
||||
- [Full Documentation](./LAZY_LOADING_CHARTS.md) - Complete guide
|
||||
- [Library Loader API](../src/lib/README.md#library-loaderts) - Technical reference
|
||||
## Migration Examples
|
||||
|
||||
### Monaco Editor Lazy Loading
|
||||
Optimized bundle size by lazy-loading Monaco Editor (2.5MB+):
|
||||
|
||||
**Benefits:**
|
||||
- ~2.5MB reduction in initial bundle size
|
||||
- Faster initial page load for all users
|
||||
- Monaco Editor loads only when needed
|
||||
- Automatic preloading when editor pages are accessed
|
||||
|
||||
**Components optimized:**
|
||||
- CodeEditor (main file editor)
|
||||
- LambdaDesigner (lambda function editor)
|
||||
- WorkflowDesigner (inline script editors)
|
||||
|
||||
**Learn more:**
|
||||
- [Full Documentation](./bundle-optimization.md) - Complete optimization guide
|
||||
- [Implementation Details](./bundle-optimization.md#optimization-strategy) - Technical details
|
||||
|
||||
### Hover-Based Route Preloading
|
||||
Instant page navigation with intelligent preloading:
|
||||
|
||||
**Benefits:**
|
||||
- Instant navigation on hover-preloaded routes
|
||||
- Adjacent route preloading for smooth sequential navigation
|
||||
- Popular routes preloaded in background
|
||||
- Visual feedback with preload indicator
|
||||
|
||||
**Features:**
|
||||
- Hover detection with 100ms delay
|
||||
- Smart concurrency control (max 3 concurrent)
|
||||
- Automatic adjacent and popular route preloading
|
||||
- Cache management and status tracking
|
||||
|
||||
**Learn more:**
|
||||
- [Full Documentation](./hover-preloading.md) - Complete guide
|
||||
- [Quick Reference](./preloading-quick-reference.md) - Quick start
|
||||
|
||||
### React Router Integration
|
||||
We've added full React Router support with route-based code splitting:
|
||||
|
||||
**Benefits:**
|
||||
- 52% smaller initial bundle (1.2MB vs 2.5MB)
|
||||
- 50% faster time to interactive
|
||||
- URL-based navigation
|
||||
- Browser back/forward support
|
||||
- Better code organization
|
||||
|
||||
**Enable it:**
|
||||
### Before: Traditional React Component (200+ LOC)
|
||||
```typescript
|
||||
// src/config/app.config.ts
|
||||
export const APP_CONFIG = {
|
||||
useRouter: true, // Change this!
|
||||
function ProjectDashboard({ files, models, ...rest }) {
|
||||
// State management
|
||||
const [filter, setFilter] = useState('')
|
||||
const [sort, setSort] = useState('name')
|
||||
|
||||
// Calculations
|
||||
const totalFiles = files.length
|
||||
const completionScore = calculateScore(...)
|
||||
|
||||
// Render
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* 150+ lines of JSX */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
**Learn more:**
|
||||
- [Quick Start Guide](./ROUTER_QUICK_START.md) - Get started in 2 minutes
|
||||
- [Full Documentation](./REACT_ROUTER_INTEGRATION.md) - Complete guide
|
||||
|
||||
## Available Guides
|
||||
|
||||
### [502 Bad Gateway Error Fix](./502_ERROR_FIX.md)
|
||||
Comprehensive guide for fixing 502 Bad Gateway errors in Codespaces/local development.
|
||||
|
||||
**Quick Fix:**
|
||||
```bash
|
||||
# Run the diagnostic script
|
||||
bash scripts/diagnose-502.sh
|
||||
|
||||
# Then restart the dev server
|
||||
npm run kill
|
||||
npm run dev
|
||||
### After: JSON-Driven (< 50 LOC)
|
||||
```typescript
|
||||
function ProjectDashboard(props) {
|
||||
return (
|
||||
<JSONPageRenderer
|
||||
schema={dashboardSchema}
|
||||
data={props}
|
||||
functions={{ calculateCompletionScore }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
**Key Changes Made:**
|
||||
- ✅ Updated `vite.config.ts` to use port 5000 (was 5173)
|
||||
- ✅ Server already configured to bind to `0.0.0.0`
|
||||
- ✅ Updated CI/CD workflows to use `npm install` instead of `npm ci`
|
||||
## Best Practices
|
||||
|
||||
## Common Issues
|
||||
1. **Extract Logic to Hooks**
|
||||
- Keep components focused on rendering
|
||||
- Move state management to custom hooks
|
||||
- Use data hooks for CRUD operations
|
||||
|
||||
### 1. Port Mismatch
|
||||
**Symptom**: 502 errors when accessing Codespaces URL
|
||||
**Cause**: Vite running on different port than forwarded
|
||||
**Fix**: Ensure vite.config.ts uses port 5000
|
||||
2. **Use JSON for Data-Heavy Pages**
|
||||
- Dashboards with multiple metrics
|
||||
- Settings pages
|
||||
- Status displays
|
||||
|
||||
### 2. Workspace Dependencies
|
||||
**Symptom**: CI/CD fails with `EUNSUPPORTEDPROTOCOL`
|
||||
**Cause**: `npm ci` doesn't support workspace protocol
|
||||
**Fix**: Use `npm install` or switch to pnpm
|
||||
3. **Compose Small Components**
|
||||
- Build complex UIs from atomic pieces
|
||||
- Each component has single responsibility
|
||||
- Maximum 150 LOC per component
|
||||
|
||||
### 3. Server Not Accessible
|
||||
**Symptom**: 502 errors even when server is running
|
||||
**Cause**: Server bound to localhost only
|
||||
**Fix**: Use `host: '0.0.0.0'` in vite.config.ts (already done)
|
||||
|
||||
### 4. MIME Type Errors
|
||||
**Symptom**: Resources refused as wrong content type
|
||||
**Cause**: Usually secondary to 502 errors
|
||||
**Fix**: Fix 502 errors first, MIME issues resolve automatically
|
||||
|
||||
## Quick Commands
|
||||
|
||||
```bash
|
||||
# Check if server is running
|
||||
lsof -i :5000
|
||||
|
||||
# Kill server on port 5000
|
||||
npm run kill
|
||||
|
||||
# Start dev server
|
||||
npm run dev
|
||||
|
||||
# Run diagnostics
|
||||
bash scripts/diagnose-502.sh
|
||||
|
||||
# Check Codespaces ports
|
||||
gh codespace ports
|
||||
|
||||
# Install dependencies (with workspace support)
|
||||
npm install
|
||||
```
|
||||
|
||||
## File Changes Made
|
||||
|
||||
| File | Change | Status |
|
||||
|------|--------|--------|
|
||||
| `vite.config.ts` | Port 5173 → 5000 | ✅ Fixed |
|
||||
| `.github/workflows/ci.yml` | `npm ci` → `npm install` (4 places) | ✅ Fixed |
|
||||
| `.github/workflows/e2e-tests.yml` | `npm ci` → `npm install` | ✅ Fixed |
|
||||
| `scripts/diagnose-502.sh` | Created diagnostic script | ✅ New |
|
||||
| `docs/502_ERROR_FIX.md` | Created comprehensive guide | ✅ New |
|
||||
|
||||
## Next Steps After Fixes
|
||||
|
||||
1. **Restart Development Server**
|
||||
```bash
|
||||
npm run kill # Kill existing processes
|
||||
npm run dev # Start fresh
|
||||
4. **Always Use Functional Updates**
|
||||
```typescript
|
||||
// ✅ CORRECT
|
||||
setItems(current => [...current, newItem])
|
||||
|
||||
// ❌ WRONG - Can cause data loss
|
||||
setItems([...items, newItem])
|
||||
```
|
||||
|
||||
2. **Verify in Browser**
|
||||
- Open Codespaces forwarded URL for port 5000
|
||||
- Should see React app load without errors
|
||||
- Check browser console - no 502s
|
||||
## Quick Start
|
||||
|
||||
3. **Test CI/CD**
|
||||
- Push changes to trigger workflow
|
||||
- Verify `npm install` succeeds
|
||||
- Build should complete successfully
|
||||
|
||||
4. **Long-term Improvements**
|
||||
- Consider migrating to pnpm for better workspace support
|
||||
- Add health check endpoint for monitoring
|
||||
- Document port configuration for team
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If issues persist after applying fixes:
|
||||
|
||||
1. **Check the diagnostic output**:
|
||||
```bash
|
||||
bash scripts/diagnose-502.sh
|
||||
1. **Use existing hooks:**
|
||||
```typescript
|
||||
import { useCRUD, useSearchFilter } from '@/hooks/data'
|
||||
```
|
||||
|
||||
2. **Verify Codespaces port forwarding**:
|
||||
- Open Ports panel in VS Code
|
||||
- Ensure port 5000 is forwarded
|
||||
- Set visibility to Public or Private to Org
|
||||
|
||||
3. **Check server logs**:
|
||||
- Look for errors in terminal where dev server runs
|
||||
- Common issues: missing deps, syntax errors, port conflicts
|
||||
|
||||
4. **Clear Vite cache**:
|
||||
```bash
|
||||
rm -rf node_modules/.vite
|
||||
npm run dev
|
||||
2. **Create JSON page schema:**
|
||||
```json
|
||||
{
|
||||
"id": "my-page",
|
||||
"layout": { ... },
|
||||
"statCards": [ ... ]
|
||||
}
|
||||
```
|
||||
|
||||
5. **Rebuild dependencies**:
|
||||
```bash
|
||||
rm -rf node_modules package-lock.json
|
||||
npm install
|
||||
npm run dev
|
||||
3. **Render with JSONPageRenderer:**
|
||||
```typescript
|
||||
<JSONPageRenderer schema={mySchema} data={props} />
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
## Future Enhancements
|
||||
|
||||
- [Vite Configuration Guide](https://vitejs.dev/config/)
|
||||
- [GitHub Codespaces Docs](https://docs.github.com/en/codespaces)
|
||||
- [pnpm Workspace Guide](https://pnpm.io/workspaces)
|
||||
- [ ] Visual JSON schema editor
|
||||
- [ ] Action handlers in JSON
|
||||
- [ ] Form definitions in JSON
|
||||
- [ ] Conditional rendering support
|
||||
- [ ] Animation configurations
|
||||
- [ ] More atomic components
|
||||
- [ ] Component library storybook
|
||||
|
||||
## Support
|
||||
## Contributing
|
||||
|
||||
If you continue experiencing issues:
|
||||
|
||||
1. Check existing documentation in `docs/` directory
|
||||
2. Review browser console for specific error messages
|
||||
3. Check server terminal logs for backend errors
|
||||
4. Verify all file changes were applied correctly
|
||||
When adding new features:
|
||||
1. Keep components under 150 LOC
|
||||
2. Extract logic to hooks
|
||||
3. Document new hooks in HOOKS_REFERENCE.md
|
||||
4. Add examples to guides
|
||||
5. Update this index
|
||||
|
||||
Reference in New Issue
Block a user