mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-24 13:44:54 +00:00
Generated by Spark: half the app is gone, it was a code gen
This commit is contained in:
368
PRD.md
368
PRD.md
@@ -1,131 +1,237 @@
|
||||
# Planning Guide
|
||||
|
||||
**Experience Qualities**:
|
||||
|
||||
|
||||
This is a diagnostic tool with log parsing, error highlighting, and solution generation - more than a single-pu
|
||||
## Essential Features
|
||||
### Log Parser & Error Highlighter
|
||||
|
||||
**Complexity Level**: Light Application (multiple features with basic state)
|
||||
This is a diagnostic tool with log parsing, error highlighting, and solution generation - more than a single-purpose tool but not a complex multi-view application.
|
||||
|
||||
## Essential Features
|
||||
|
||||
### Log Parser & Error Highlighter
|
||||
- **Functionality**: Paste Docker build logs and automatically extract error information
|
||||
- **Purpose**: Make sense of lengthy, unformatted build output
|
||||
- **Trigger**: User pastes log text into a text area
|
||||
|
||||
- **Functionality**: Common Docker build errors with explanations and fixes
|
||||
|
||||
- **Success criteria**: Cove
|
||||
### Fix Code Generator
|
||||
- **Purpose**: Speed up fixing by providing exact code changes needed
|
||||
- **Progression**: Solution shown → Click "Generate Fix
|
||||
|
||||
|
||||
|
||||
- **Empty Input**: Show
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- **Foreground/Backgro
|
||||
- Card (`oklch(0.19 0.02 265)`): Light text `oklch(0.95 0.01 265)` - Ratio 9.8:1 ✓
|
||||
- Destructive/Error (`oklch(0.60 0.25 25)`): White text `oklch(1 0
|
||||
## Font Selection
|
||||
Monospace for code and logs, clean sans-serif for explanations - reflecting the technical nature while remaining reada
|
||||
- **Typographic Hierarchy**:
|
||||
|
||||
- Code/Logs: JetBra
|
||||
|
||||
|
||||
|
||||
- Solutions expand/collapse smoothly (300ms ease-out)
|
||||
- Log parsing shows subtle progress indicator during processing
|
||||
|
||||
|
||||
- Textarea (custo
|
||||
|
||||
- Button (primary for actions, secondary for copy operations)
|
||||
|
||||
|
||||
|
||||
- Monospace code blocks with line numbers for generated fixes
|
||||
|
||||
- Input: Focused state has bright accent border with subtle glow
|
||||
|
||||
- Terminal (for log input)
|
||||
- CheckCircle (for solutions)
|
||||
- MagnifyingGlass (for search in knowledge base)
|
||||
- Stack (for Docker layers)
|
||||
- **Spacing**:
|
||||
- Section gaps: gap-8 for major sections, gap-4 for related content
|
||||
|
||||
- **Mobile**:
|
||||
|
||||
- Collapsible sections for solutions to save space
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Planning Guide
|
||||
|
||||
CodeForge is a comprehensive low-code development platform that enables developers to rapidly build, test, and deploy full-stack applications through visual builders and intelligent code generation.
|
||||
|
||||
**Experience Qualities**:
|
||||
|
||||
1. **Powerful** - A complete development toolkit with visual designers for models, components, workflows, APIs, and testing
|
||||
2. **Efficient** - Keyboard shortcuts, intelligent search, and streamlined navigation accelerate development
|
||||
3. **Intelligent** - AI-assisted code generation, auto-repair, and context-aware suggestions
|
||||
|
||||
**Complexity Level**: Complex Application (advanced functionality with multiple views)
|
||||
|
||||
This is a sophisticated development platform with router-based navigation, multiple specialized views, state persistence, real-time preview, and comprehensive project management capabilities.
|
||||
|
||||
## Essential Features
|
||||
|
||||
### Dashboard & Project Overview
|
||||
- **Functionality**: Central hub displaying project metrics, file counts, component stats, and quick actions
|
||||
- **Purpose**: Provide at-a-glance project health and rapid access to common tasks
|
||||
- **Trigger**: Loaded on app initialization or via navigation
|
||||
- **Progression**: Load project state → Calculate metrics → Render cards → Enable quick actions
|
||||
- **Success criteria**: All metrics display correctly, navigation works, GitHub build status shows
|
||||
|
||||
### Code Editor with File Explorer
|
||||
- **Functionality**: Monaco-based code editor with syntax highlighting and file tree navigation
|
||||
- **Purpose**: Edit project files with professional IDE-like experience
|
||||
- **Trigger**: Navigate to Code Editor tab or select file from explorer
|
||||
- **Progression**: Mount editor → Load file content → Enable editing → Auto-save changes → Update file tree
|
||||
- **Success criteria**: Files open instantly, syntax highlighting works, changes persist
|
||||
|
||||
### Model Designer (Prisma Schema)
|
||||
- **Functionality**: Visual interface for designing database models with fields, relations, and constraints
|
||||
- **Purpose**: Create database schemas without writing raw Prisma syntax
|
||||
- **Trigger**: Navigate to Models tab
|
||||
- **Progression**: Display existing models → Add/edit models → Define fields → Set relations → Generate schema
|
||||
- **Success criteria**: Models create correctly, relations validate, Prisma schema generates
|
||||
|
||||
### Component Tree Builder
|
||||
- **Functionality**: Drag-and-drop interface for building React component hierarchies
|
||||
- **Purpose**: Visually compose component structures with props and styling
|
||||
- **Trigger**: Navigate to Components tab
|
||||
- **Progression**: Show component palette → Drag to canvas → Configure props → Set styling → Generate JSX
|
||||
- **Success criteria**: Components nest properly, props configure, code generates
|
||||
|
||||
### Workflow Designer
|
||||
- **Functionality**: Node-based workflow editor for defining application logic
|
||||
- **Purpose**: Create complex business logic visually using nodes and connections
|
||||
- **Trigger**: Navigate to Workflows tab
|
||||
- **Progression**: Place nodes → Connect nodes → Configure logic → Validate flow → Generate code
|
||||
- **Success criteria**: Flows connect correctly, validation prevents errors, code executes
|
||||
|
||||
### Lambda/Function Designer
|
||||
- **Functionality**: Code editor for serverless functions with runtime configuration
|
||||
- **Purpose**: Write and configure backend functions quickly
|
||||
- **Trigger**: Navigate to Lambdas tab
|
||||
- **Progression**: Create function → Write code → Set environment → Configure triggers → Test execution
|
||||
- **Success criteria**: Functions save, environments configure, testing works
|
||||
|
||||
### Style Designer (Theme Configuration)
|
||||
- **Functionality**: Visual theme editor for colors, typography, spacing, and design tokens
|
||||
- **Purpose**: Customize application appearance without editing CSS files
|
||||
- **Trigger**: Navigate to Styling tab
|
||||
- **Progression**: Select variant → Adjust colors → Configure typography → Preview changes → Generate CSS
|
||||
- **Success criteria**: Changes preview instantly, CSS variables update, theme persists
|
||||
|
||||
### Favicon Designer
|
||||
- **Functionality**: Visual icon designer with shapes, colors, and SVG export
|
||||
- **Purpose**: Create custom favicons without external tools
|
||||
- **Trigger**: Navigate to Favicon Designer tab
|
||||
- **Progression**: Add shapes → Customize colors → Position elements → Preview → Export SVG
|
||||
- **Success criteria**: Icons render correctly, SVG exports, preview updates in real-time
|
||||
|
||||
### Flask API Designer
|
||||
- **Functionality**: Configure Flask backend with routes, blueprints, and settings
|
||||
- **Purpose**: Set up Python backend API without manual configuration
|
||||
- **Trigger**: Navigate to Flask API tab
|
||||
- **Progression**: Configure settings → Define routes → Add blueprints → Set CORS → Generate config
|
||||
- **Success criteria**: Configuration valid, routes define properly, Flask app generates
|
||||
|
||||
### Test Designers (Playwright, Unit Tests, Storybook)
|
||||
- **Functionality**: Create and manage tests through visual interfaces
|
||||
- **Purpose**: Build comprehensive test coverage without boilerplate
|
||||
- **Trigger**: Navigate to respective test tabs
|
||||
- **Progression**: Define test → Set assertions → Configure steps → Run tests → View results
|
||||
- **Success criteria**: Tests create correctly, run successfully, results display
|
||||
|
||||
### Error Panel with Auto-Repair
|
||||
- **Functionality**: Display build/runtime errors with AI-powered fix suggestions
|
||||
- **Purpose**: Quickly identify and resolve issues
|
||||
- **Trigger**: Navigate to Errors tab or click error indicator
|
||||
- **Progression**: Parse errors → Categorize → Generate fixes → Apply suggestions → Re-validate
|
||||
- **Success criteria**: Errors display clearly, fixes apply correctly, issues resolve
|
||||
|
||||
### Feature Ideas Cloud
|
||||
- **Functionality**: Interactive tag cloud of feature suggestions with voting
|
||||
- **Purpose**: Crowdsource and prioritize new features
|
||||
- **Trigger**: Navigate to Feature Ideas tab
|
||||
- **Progression**: Display ideas → Click to vote → Add new ideas → Sort by votes → Track implementation
|
||||
- **Success criteria**: Voting works, ideas persist, sorting updates
|
||||
|
||||
### Docker Build Debugger
|
||||
- **Functionality**: Paste Docker build logs and get AI-powered error analysis with fixes
|
||||
- **Purpose**: Quickly diagnose and resolve Docker build failures
|
||||
- **Trigger**: Navigate to Docker Debugger tab from menu
|
||||
- **Progression**: Paste logs → Parse errors → Query knowledge base → Generate solutions → Copy fixes
|
||||
- **Success criteria**: Errors extract correctly, solutions relevant, fixes work
|
||||
|
||||
### Global Search (Ctrl+K)
|
||||
- **Functionality**: Fast fuzzy search across files, components, models, workflows, and navigation
|
||||
- **Purpose**: Instant access to any project artifact
|
||||
- **Trigger**: Press Ctrl+K or click search icon
|
||||
- **Progression**: Open dialog → Type query → Filter results → Select item → Navigate/open
|
||||
- **Success criteria**: Search < 100ms, results accurate, navigation works
|
||||
|
||||
### Keyboard Shortcuts
|
||||
- **Functionality**: Comprehensive keyboard shortcuts for all major actions
|
||||
- **Purpose**: Expert-level productivity without mouse
|
||||
- **Trigger**: Press configured shortcut or Ctrl+/ to view all
|
||||
- **Progression**: Press shortcut → Execute action → Show visual feedback
|
||||
- **Success criteria**: All shortcuts work, dialog lists current mappings
|
||||
|
||||
### Project Export/Import
|
||||
- **Functionality**: Export entire project as JSON, import projects from files
|
||||
- **Purpose**: Share projects, backup, or migrate between environments
|
||||
- **Trigger**: Click export/import in header menu
|
||||
- **Progression**: Serialize state → Download JSON → Upload JSON → Deserialize → Restore state
|
||||
- **Success criteria**: Export complete, import restores fully, no data loss
|
||||
|
||||
### PWA Support
|
||||
- **Functionality**: Progressive Web App with offline support, install prompts, and update notifications
|
||||
- **Purpose**: Desktop-like experience with offline capability
|
||||
- **Trigger**: Automatic service worker registration
|
||||
- **Progression**: Register SW → Cache assets → Show install prompt → Handle updates → Enable offline
|
||||
- **Success criteria**: Offline mode works, install succeeds, updates apply
|
||||
|
||||
## Edge Case Handling
|
||||
|
||||
- **No Project Data**: Show onboarding with sample project option
|
||||
- **Large Files**: Monaco editor lazy-loads only visible content
|
||||
- **Network Failures**: All state persists to KV storage, works offline
|
||||
- **Invalid JSON**: Schema validation with helpful error messages
|
||||
- **Circular References**: Workflow and component tree validation prevents cycles
|
||||
- **Conflicting Changes**: Last-write-wins with timestamp tracking
|
||||
- **Browser Compatibility**: Graceful degradation for older browsers
|
||||
- **Memory Limits**: Lazy loading and code splitting for large projects
|
||||
|
||||
## Design Direction
|
||||
|
||||
The design should feel like a professional development tool - powerful yet approachable, with emphasis on speed, clarity, and focused workspaces. Think VS Code meets Figma: clean, minimal chrome with rich, context-specific editing surfaces.
|
||||
|
||||
## Color Selection
|
||||
|
||||
**Technical Elegance** - Dark theme with vibrant purple accents
|
||||
|
||||
- **Primary Color**: `oklch(0.58 0.24 265)` - Vibrant purple for actions and focus
|
||||
- **Secondary Colors**:
|
||||
- Background: `oklch(0.15 0.02 265)` - Deep blue-black for immersive coding
|
||||
- Card: `oklch(0.19 0.02 265)` - Elevated surfaces
|
||||
- Muted: `oklch(0.25 0.03 265)` - Borders and subtle dividers
|
||||
- **Accent Color**: `oklch(0.75 0.20 145)` - Bright teal for success and completion
|
||||
- **Foreground/Background Pairings**:
|
||||
- Background (`oklch(0.15 0.02 265)`): Light text `oklch(0.95 0.01 265)` - Ratio 13.2:1 ✓
|
||||
- Primary (`oklch(0.58 0.24 265)`): White text `oklch(1 0 0)` - Ratio 5.1:1 ✓
|
||||
- Card (`oklch(0.19 0.02 265)`): Light text `oklch(0.95 0.01 265)` - Ratio 11.8:1 ✓
|
||||
- Accent (`oklch(0.75 0.20 145)`): Dark text `oklch(0.15 0.02 265)` - Ratio 7.9:1 ✓
|
||||
|
||||
## Font Selection
|
||||
|
||||
Developer-focused typography with monospace for code and clean sans-serif for UI
|
||||
|
||||
- **Typographic Hierarchy**:
|
||||
- H1 (Page Titles): JetBrains Mono Bold / 24px / tight letter spacing
|
||||
- H2 (Section Headers): JetBrains Mono Bold / 20px
|
||||
- H3 (Subsection Headers): JetBrains Mono Medium / 16px
|
||||
- Body Text: IBM Plex Sans Regular / 14px / 1.5 line height
|
||||
- Code/Logs: JetBrains Mono Regular / 14px / 1.4 line height
|
||||
- Labels: IBM Plex Sans Medium / 12px / uppercase tracking
|
||||
|
||||
## Animations
|
||||
|
||||
Purposeful motion for state changes, navigation, and feedback - never decorative
|
||||
|
||||
- Tab switching: 200ms crossfade
|
||||
- Panel transitions: 300ms slide with ease-out
|
||||
- Hover states: 150ms color/scale transitions
|
||||
- Loading states: Subtle pulse on relevant area
|
||||
- Success actions: Quick scale + color flash (200ms)
|
||||
- Drag-and-drop: Smooth follow with snap-to-grid
|
||||
|
||||
## Component Selection
|
||||
|
||||
**Core Components**:
|
||||
- **Tabs** (shadcn): Primary navigation with active indicators
|
||||
- **Sheet** (shadcn): Side panels for settings and auxiliary content
|
||||
- **Dialog** (shadcn): Modal overlays for search, shortcuts, and confirmations
|
||||
- **Card** (shadcn): Content containers with hover states
|
||||
- **Button** (shadcn): All variants - primary for actions, ghost for navigation
|
||||
- **Textarea/Input** (shadcn): Form controls with focus rings
|
||||
- **Select/Combobox** (shadcn): Dropdowns with search
|
||||
- **Separator** (shadcn): Visual dividers between sections
|
||||
- **Skeleton** (shadcn): Loading placeholders
|
||||
- **Switch/Checkbox** (shadcn): Boolean controls
|
||||
|
||||
**Custom Components**:
|
||||
- Monaco Editor wrapper with theme integration
|
||||
- ReactFlow workflow canvas with custom nodes
|
||||
- Tree view for file explorer and component hierarchy
|
||||
- Drag-and-drop canvas for component builder
|
||||
- Tag cloud with physics simulation
|
||||
- Resizable panel groups for split views
|
||||
|
||||
**States**:
|
||||
- Buttons: Default → Hover → Active → Disabled
|
||||
- Inputs: Empty → Focused → Filled → Error → Success
|
||||
- Panels: Collapsed → Expanding → Expanded → Collapsing
|
||||
- Files: Unselected → Hover → Active → Modified → Saved
|
||||
|
||||
**Icon Selection**: @phosphor-icons/react with bold weight for emphasis
|
||||
- Navigation: House, Code, Database, Tree, GitBranch, etc.
|
||||
- Actions: Plus, Trash, Copy, Download, Upload
|
||||
- Status: Check, X, Warning, Info, CircleNotch (loading)
|
||||
|
||||
**Spacing**:
|
||||
- Page padding: p-6
|
||||
- Section gaps: gap-8
|
||||
- Card padding: p-6
|
||||
- Button padding: px-4 py-2
|
||||
- Input padding: px-3 py-2
|
||||
- Tight spacing: gap-2 for related items
|
||||
|
||||
**Mobile**:
|
||||
- Collapsible sidebar navigation
|
||||
- Stacked layouts instead of side-by-side
|
||||
- Full-width panels
|
||||
- Touch-optimized button sizes (min 44px)
|
||||
- Simplified feature set (hide advanced tools)
|
||||
- Focused single-panel view instead of split panes
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>DevTools Hub</title>
|
||||
<title>CodeForge - Low-Code Development Platform</title>
|
||||
|
||||
<meta name="description" content="Your developer toolkit - Docker debugger and more">
|
||||
<meta name="description" content="Comprehensive low-code platform for rapid application development">
|
||||
<meta name="theme-color" content="#8b5cf6">
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
|
||||
517
src/App.tsx
517
src/App.tsx
@@ -1,138 +1,403 @@
|
||||
import { useState } from 'react'
|
||||
import { useKV } from '@github/spark/hooks'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '@/components/ui/sheet'
|
||||
import { List, Stack, House, Wrench } from '@phosphor-icons/react'
|
||||
import { DockerBuildDebugger } from '@/components/DockerBuildDebugger'
|
||||
import { motion } from 'framer-motion'
|
||||
console.log('[APP_ROUTER] 🚀 App.router.tsx loading - BEGIN')
|
||||
console.time('[APP_ROUTER] Component initialization')
|
||||
|
||||
type View = 'home' | 'docker-debugger'
|
||||
import { useState, Suspense, useEffect } from 'react'
|
||||
console.log('[APP_ROUTER] ✅ React hooks imported')
|
||||
|
||||
function App() {
|
||||
const [currentView, setCurrentView] = useKV<View>('current-view', 'home')
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false)
|
||||
import { BrowserRouter, useLocation } from 'react-router-dom'
|
||||
console.log('[APP_ROUTER] ✅ React Router imported')
|
||||
|
||||
const handleNavigation = (view: View) => {
|
||||
setCurrentView(view)
|
||||
setIsMenuOpen(false)
|
||||
import { AppHeader } from '@/components/organisms'
|
||||
console.log('[APP_ROUTER] ✅ Header components imported')
|
||||
|
||||
import { LoadingFallback } from '@/components/molecules'
|
||||
console.log('[APP_ROUTER] ✅ LoadingFallback imported')
|
||||
|
||||
import { useProjectState } from '@/hooks/use-project-state'
|
||||
import { useFileOperations } from '@/hooks/use-file-operations'
|
||||
import { useKeyboardShortcuts } from '@/hooks/use-keyboard-shortcuts'
|
||||
import { useSeedData } from '@/hooks/data/use-seed-data'
|
||||
import { useRouterNavigation } from '@/hooks/use-router-navigation'
|
||||
console.log('[APP_ROUTER] ✅ Custom hooks imported')
|
||||
|
||||
import { getPageShortcuts } from '@/config/page-loader'
|
||||
console.log('[APP_ROUTER] ✅ Page config imported')
|
||||
|
||||
import { toast } from 'sonner'
|
||||
console.log('[APP_ROUTER] ✅ Toast imported')
|
||||
|
||||
import { DialogRegistry, PWARegistry, preloadCriticalComponents } from '@/lib/component-registry'
|
||||
console.log('[APP_ROUTER] ✅ Component registry imported')
|
||||
|
||||
import { RouterProvider } from '@/router'
|
||||
console.log('[APP_ROUTER] ✅ Router provider imported')
|
||||
|
||||
const { GlobalSearch, KeyboardShortcutsDialog, PreviewDialog } = DialogRegistry
|
||||
const { PWAInstallPrompt, PWAUpdatePrompt, PWAStatusBar } = PWARegistry
|
||||
console.log('[APP_ROUTER] ✅ Dialog and PWA components registered')
|
||||
|
||||
console.log('[APP_ROUTER] 🎯 App component function executing')
|
||||
|
||||
function AppLayout() {
|
||||
console.log('[APP_ROUTER] 🏗️ AppLayout component rendering')
|
||||
const location = useLocation()
|
||||
const { currentPage, navigateToPage } = useRouterNavigation()
|
||||
|
||||
console.log('[APP_ROUTER] 📍 Current location:', location.pathname)
|
||||
console.log('[APP_ROUTER] 📄 Current page:', currentPage)
|
||||
|
||||
console.log('[APP_ROUTER] 📊 Initializing project state hook')
|
||||
const projectState = useProjectState()
|
||||
console.log('[APP_ROUTER] ✅ Project state initialized')
|
||||
|
||||
const {
|
||||
files,
|
||||
models,
|
||||
components,
|
||||
componentTrees,
|
||||
workflows,
|
||||
lambdas,
|
||||
theme,
|
||||
playwrightTests,
|
||||
storybookStories,
|
||||
unitTests,
|
||||
flaskConfig,
|
||||
nextjsConfig,
|
||||
npmSettings,
|
||||
featureToggles,
|
||||
setFiles,
|
||||
setModels,
|
||||
setComponents,
|
||||
setComponentTrees,
|
||||
setWorkflows,
|
||||
setLambdas,
|
||||
setTheme,
|
||||
setPlaywrightTests,
|
||||
setStorybookStories,
|
||||
setUnitTests,
|
||||
setFlaskConfig,
|
||||
setNextjsConfig,
|
||||
setNpmSettings,
|
||||
setFeatureToggles,
|
||||
} = projectState
|
||||
|
||||
console.log('[APP_ROUTER] 📁 Initializing file operations')
|
||||
const fileOps = useFileOperations(files, setFiles)
|
||||
console.log('[APP_ROUTER] ✅ File operations initialized')
|
||||
|
||||
const { activeFileId, setActiveFileId, handleFileChange, handleFileAdd, handleFileClose } = fileOps
|
||||
|
||||
console.log('[APP_ROUTER] 💾 Initializing state variables')
|
||||
const [searchOpen, setSearchOpen] = useState(false)
|
||||
const [shortcutsOpen, setShortcutsOpen] = useState(false)
|
||||
const [previewOpen, setPreviewOpen] = useState(false)
|
||||
const [lastSaved] = useState<number | null>(Date.now())
|
||||
const [errorCount] = useState(0)
|
||||
console.log('[APP_ROUTER] ✅ State variables initialized')
|
||||
|
||||
const shortcuts = getPageShortcuts(featureToggles)
|
||||
console.log('[APP_ROUTER] ⌨️ Keyboard shortcuts configured:', shortcuts.length)
|
||||
|
||||
console.log('[APP_ROUTER] ⌨️ Setting up keyboard shortcuts')
|
||||
useKeyboardShortcuts([
|
||||
...shortcuts.map(s => ({
|
||||
key: s.key,
|
||||
ctrl: s.ctrl,
|
||||
shift: s.shift,
|
||||
description: s.description,
|
||||
action: () => {
|
||||
console.log('[APP_ROUTER] ⌨️ Shortcut triggered, navigating to:', s.action)
|
||||
navigateToPage(s.action)
|
||||
}
|
||||
})),
|
||||
{
|
||||
key: 'k',
|
||||
ctrl: true,
|
||||
description: 'Search',
|
||||
action: () => {
|
||||
console.log('[APP_ROUTER] ⌨️ Search shortcut triggered')
|
||||
setSearchOpen(true)
|
||||
}
|
||||
},
|
||||
{
|
||||
key: '/',
|
||||
ctrl: true,
|
||||
description: 'Shortcuts',
|
||||
action: () => {
|
||||
console.log('[APP_ROUTER] ⌨️ Shortcuts dialog triggered')
|
||||
setShortcutsOpen(true)
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'p',
|
||||
ctrl: true,
|
||||
description: 'Preview',
|
||||
action: () => {
|
||||
console.log('[APP_ROUTER] ⌨️ Preview shortcut triggered')
|
||||
setPreviewOpen(true)
|
||||
}
|
||||
},
|
||||
])
|
||||
console.log('[APP_ROUTER] ✅ Keyboard shortcuts configured')
|
||||
|
||||
const getCurrentProject = () => ({
|
||||
name: nextjsConfig.appName,
|
||||
files,
|
||||
models,
|
||||
components,
|
||||
componentTrees,
|
||||
workflows,
|
||||
lambdas,
|
||||
theme,
|
||||
playwrightTests,
|
||||
storybookStories,
|
||||
unitTests,
|
||||
flaskConfig,
|
||||
nextjsConfig,
|
||||
npmSettings,
|
||||
featureToggles,
|
||||
})
|
||||
|
||||
const handleProjectLoad = (project: any) => {
|
||||
console.log('[APP_ROUTER] 📦 Loading project:', project.name)
|
||||
if (project.files) setFiles(project.files)
|
||||
if (project.models) setModels(project.models)
|
||||
if (project.components) setComponents(project.components)
|
||||
if (project.componentTrees) setComponentTrees(project.componentTrees)
|
||||
if (project.workflows) setWorkflows(project.workflows)
|
||||
if (project.lambdas) setLambdas(project.lambdas)
|
||||
if (project.theme) setTheme(project.theme)
|
||||
if (project.playwrightTests) setPlaywrightTests(project.playwrightTests)
|
||||
if (project.storybookStories) setStorybookStories(project.storybookStories)
|
||||
if (project.unitTests) setUnitTests(project.unitTests)
|
||||
if (project.flaskConfig) setFlaskConfig(project.flaskConfig)
|
||||
if (project.nextjsConfig) setNextjsConfig(project.nextjsConfig)
|
||||
if (project.npmSettings) setNpmSettings(project.npmSettings)
|
||||
if (project.featureToggles) setFeatureToggles(project.featureToggles)
|
||||
toast.success('Project loaded')
|
||||
console.log('[APP_ROUTER] ✅ Project loaded successfully')
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log('[APP_ROUTER] 📍 Route changed to:', location.pathname, '- Page:', currentPage)
|
||||
}, [location, currentPage])
|
||||
|
||||
console.log('[APP_ROUTER] 🎨 Rendering AppLayout UI')
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<div className="relative overflow-hidden">
|
||||
<div className="absolute inset-0 bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-primary/20 via-background to-background" />
|
||||
<div className="absolute inset-0 bg-[linear-gradient(to_right,#4f4f4f12_1px,transparent_1px),linear-gradient(to_bottom,#4f4f4f12_1px,transparent_1px)] bg-[size:4rem_4rem]" />
|
||||
|
||||
<div className="relative">
|
||||
<header className="border-b border-border/40 backdrop-blur-sm sticky top-0 z-40">
|
||||
<div className="container mx-auto px-4 sm:px-6 py-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="p-2 rounded-lg bg-primary/10 border border-primary/20">
|
||||
<Stack size={28} weight="bold" className="text-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-xl sm:text-2xl font-bold tracking-tight">DevTools Hub</h1>
|
||||
<p className="text-xs sm:text-sm text-muted-foreground">Your developer toolkit</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Sheet open={isMenuOpen} onOpenChange={setIsMenuOpen}>
|
||||
<SheetTrigger asChild>
|
||||
<Button variant="outline" size="icon" className="gap-2">
|
||||
<List size={20} weight="bold" />
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent>
|
||||
<SheetHeader>
|
||||
<SheetTitle>Navigation</SheetTitle>
|
||||
</SheetHeader>
|
||||
<nav className="mt-6 space-y-2">
|
||||
<Button
|
||||
variant={currentView === 'home' ? 'secondary' : 'ghost'}
|
||||
className="w-full justify-start gap-3"
|
||||
onClick={() => handleNavigation('home')}
|
||||
>
|
||||
<House size={20} weight="bold" />
|
||||
Home
|
||||
</Button>
|
||||
<Button
|
||||
variant={currentView === 'docker-debugger' ? 'secondary' : 'ghost'}
|
||||
className="w-full justify-start gap-3"
|
||||
onClick={() => handleNavigation('docker-debugger')}
|
||||
>
|
||||
<Wrench size={20} weight="bold" />
|
||||
Docker Build Debugger
|
||||
</Button>
|
||||
</nav>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="container mx-auto px-4 sm:px-6 py-8">
|
||||
{currentView === 'home' && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="space-y-6"
|
||||
>
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold mb-2">Welcome to DevTools Hub</h2>
|
||||
<p className="text-muted-foreground">
|
||||
Select a tool from the menu to get started
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
<Card
|
||||
className="border-border/50 bg-card/50 backdrop-blur-sm cursor-pointer hover:border-accent/50 hover:shadow-lg hover:shadow-accent/5 transition-all"
|
||||
onClick={() => handleNavigation('docker-debugger')}
|
||||
>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<div className="p-2 rounded-lg bg-accent/10 border border-accent/20">
|
||||
<Wrench size={24} weight="bold" className="text-accent" />
|
||||
</div>
|
||||
<CardTitle>Docker Build Debugger</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Analyze Docker build errors and get instant solutions with an intelligent knowledge base
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Paste your build logs and get detailed error analysis with recommended fixes
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
{currentView === 'docker-debugger' && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<div className="mb-6">
|
||||
<h2 className="text-2xl font-bold mb-2">Docker Build Debugger</h2>
|
||||
<p className="text-muted-foreground">
|
||||
Analyze errors and get instant solutions
|
||||
</p>
|
||||
</div>
|
||||
<DockerBuildDebugger />
|
||||
</motion.div>
|
||||
)}
|
||||
</main>
|
||||
</div>
|
||||
<div className="h-screen flex flex-col bg-background">
|
||||
<Suspense fallback={<div className="h-1 bg-primary animate-pulse" />}>
|
||||
<PWAStatusBar />
|
||||
</Suspense>
|
||||
<Suspense fallback={null}>
|
||||
<PWAUpdatePrompt />
|
||||
</Suspense>
|
||||
<AppHeader
|
||||
activeTab={currentPage}
|
||||
onTabChange={navigateToPage}
|
||||
featureToggles={featureToggles}
|
||||
errorCount={errorCount}
|
||||
lastSaved={lastSaved}
|
||||
currentProject={getCurrentProject()}
|
||||
onProjectLoad={handleProjectLoad}
|
||||
onSearch={() => {
|
||||
console.log('[APP_ROUTER] 🔍 Search opened')
|
||||
setSearchOpen(true)
|
||||
}}
|
||||
onShowShortcuts={() => {
|
||||
console.log('[APP_ROUTER] ⌨️ Shortcuts dialog opened')
|
||||
setShortcutsOpen(true)
|
||||
}}
|
||||
onGenerateAI={() => {
|
||||
console.log('[APP_ROUTER] 🤖 AI generation requested')
|
||||
toast.info('AI generation coming soon')
|
||||
}}
|
||||
onExport={() => {
|
||||
console.log('[APP_ROUTER] 📤 Export requested')
|
||||
toast.info('Export coming soon')
|
||||
}}
|
||||
onPreview={() => {
|
||||
console.log('[APP_ROUTER] 👁️ Preview opened')
|
||||
setPreviewOpen(true)
|
||||
}}
|
||||
onShowErrors={() => {
|
||||
console.log('[APP_ROUTER] ⚠️ Navigating to errors page')
|
||||
navigateToPage('errors')
|
||||
}}
|
||||
/>
|
||||
<div className="flex-1 overflow-hidden">
|
||||
<RouterProvider
|
||||
featureToggles={featureToggles}
|
||||
stateContext={{
|
||||
files,
|
||||
models,
|
||||
components,
|
||||
componentTrees,
|
||||
workflows,
|
||||
lambdas,
|
||||
theme,
|
||||
playwrightTests,
|
||||
storybookStories,
|
||||
unitTests,
|
||||
flaskConfig,
|
||||
nextjsConfig,
|
||||
npmSettings,
|
||||
featureToggles,
|
||||
activeFileId,
|
||||
}}
|
||||
actionContext={{
|
||||
handleFileChange,
|
||||
setActiveFileId,
|
||||
handleFileClose,
|
||||
handleFileAdd,
|
||||
setModels,
|
||||
setComponents,
|
||||
setComponentTrees,
|
||||
setWorkflows,
|
||||
setLambdas,
|
||||
setTheme,
|
||||
setPlaywrightTests,
|
||||
setStorybookStories,
|
||||
setUnitTests,
|
||||
setFlaskConfig,
|
||||
setNextjsConfig,
|
||||
setNpmSettings,
|
||||
setFeatureToggles,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Suspense fallback={null}>
|
||||
<GlobalSearch
|
||||
open={searchOpen}
|
||||
onOpenChange={setSearchOpen}
|
||||
files={files}
|
||||
models={models}
|
||||
components={components}
|
||||
componentTrees={componentTrees}
|
||||
workflows={workflows}
|
||||
lambdas={lambdas}
|
||||
playwrightTests={playwrightTests}
|
||||
storybookStories={storybookStories}
|
||||
unitTests={unitTests}
|
||||
onNavigate={(page) => {
|
||||
console.log('[APP_ROUTER] 🔍 Search navigation to:', page)
|
||||
navigateToPage(page)
|
||||
}}
|
||||
onFileSelect={(fileId) => {
|
||||
console.log('[APP_ROUTER] 📄 File selected from search:', fileId)
|
||||
setActiveFileId(fileId)
|
||||
navigateToPage('code')
|
||||
}}
|
||||
/>
|
||||
</Suspense>
|
||||
|
||||
<Suspense fallback={null}>
|
||||
<KeyboardShortcutsDialog open={shortcutsOpen} onOpenChange={setShortcutsOpen} />
|
||||
</Suspense>
|
||||
<Suspense fallback={null}>
|
||||
<PreviewDialog open={previewOpen} onOpenChange={setPreviewOpen} />
|
||||
</Suspense>
|
||||
<Suspense fallback={null}>
|
||||
<PWAInstallPrompt />
|
||||
</Suspense>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function App() {
|
||||
console.log('[APP_ROUTER] 🔧 Initializing App component')
|
||||
console.time('[APP_ROUTER] App render')
|
||||
|
||||
console.log('[APP_ROUTER] 🌱 Initializing seed data hook')
|
||||
const { loadSeedData } = useSeedData()
|
||||
const projectState = useProjectState()
|
||||
const { featureToggles, files, setFiles, ...restState } = projectState
|
||||
console.log('[APP_ROUTER] ✅ Hooks initialized')
|
||||
|
||||
console.log('[APP_ROUTER] 📁 Initializing file operations for router context')
|
||||
const fileOps = useFileOperations(files, setFiles)
|
||||
|
||||
const [appReady, setAppReady] = useState(false)
|
||||
console.log('[APP_ROUTER] 💾 App ready state:', appReady)
|
||||
|
||||
console.log('[APP_ROUTER] ⏰ Setting up initialization effect')
|
||||
useEffect(() => {
|
||||
console.log('[APP_ROUTER] 🚀 Initialization effect triggered')
|
||||
console.time('[APP_ROUTER] Seed data loading')
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
console.log('[APP_ROUTER] ⏱️ Fallback timer triggered (100ms)')
|
||||
setAppReady(true)
|
||||
}, 100)
|
||||
|
||||
console.log('[APP_ROUTER] 📥 Starting seed data load')
|
||||
loadSeedData()
|
||||
.then(() => {
|
||||
console.log('[APP_ROUTER] ✅ Seed data loaded successfully')
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('[APP_ROUTER] ❌ Seed data loading failed:', err)
|
||||
})
|
||||
.finally(() => {
|
||||
console.log('[APP_ROUTER] 🏁 Seed data loading complete')
|
||||
clearTimeout(timer)
|
||||
setAppReady(true)
|
||||
console.timeEnd('[APP_ROUTER] Seed data loading')
|
||||
console.log('[APP_ROUTER] ✅ App marked as ready')
|
||||
|
||||
console.log('[APP_ROUTER] 🚀 Preloading critical components')
|
||||
preloadCriticalComponents()
|
||||
})
|
||||
|
||||
return () => {
|
||||
console.log('[APP_ROUTER] 🧹 Cleaning up initialization effect')
|
||||
clearTimeout(timer)
|
||||
}
|
||||
}, [loadSeedData])
|
||||
|
||||
const stateContext = {
|
||||
files,
|
||||
...restState,
|
||||
activeFileId: fileOps.activeFileId,
|
||||
}
|
||||
|
||||
const actionContext = {
|
||||
handleFileChange: fileOps.handleFileChange,
|
||||
setActiveFileId: fileOps.setActiveFileId,
|
||||
handleFileClose: fileOps.handleFileClose,
|
||||
handleFileAdd: fileOps.handleFileAdd,
|
||||
setFiles,
|
||||
...Object.fromEntries(
|
||||
Object.entries(restState).filter(([key]) => key.startsWith('set'))
|
||||
),
|
||||
}
|
||||
|
||||
console.log('[APP_ROUTER] 🎨 Rendering App component UI')
|
||||
console.log('[APP_ROUTER] App state - appReady:', appReady)
|
||||
console.timeEnd('[APP_ROUTER] App render')
|
||||
|
||||
if (!appReady) {
|
||||
console.log('[APP_ROUTER] ⏳ App not ready, showing loading screen')
|
||||
return (
|
||||
<div className="fixed inset-0 bg-background z-50 flex items-center justify-center">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="w-12 h-12 border-4 border-primary border-t-transparent rounded-full animate-spin" />
|
||||
<p className="text-sm text-muted-foreground">Loading CodeForge...</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
console.log('[APP_ROUTER] ✅ App ready, rendering router')
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<AppLayout />
|
||||
</BrowserRouter>
|
||||
)
|
||||
}
|
||||
|
||||
console.log('[APP_ROUTER] ✅ App component defined')
|
||||
console.timeEnd('[APP_ROUTER] Component initialization')
|
||||
|
||||
export default App
|
||||
|
||||
@@ -355,6 +355,16 @@
|
||||
"shortcut": "ctrl+shift+d",
|
||||
"order": 24,
|
||||
"props": {}
|
||||
},
|
||||
{
|
||||
"id": "docker-debugger",
|
||||
"title": "Docker Debugger",
|
||||
"icon": "Wrench",
|
||||
"component": "DockerBuildDebugger",
|
||||
"enabled": true,
|
||||
"toggleKey": "dockerDebugger",
|
||||
"order": 25,
|
||||
"props": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -151,6 +151,11 @@ export const ComponentRegistry = {
|
||||
() => import('@/components/DataBindingDesigner').then(m => ({ default: m.DataBindingDesigner })),
|
||||
'DataBindingDesigner'
|
||||
),
|
||||
|
||||
DockerBuildDebugger: lazyWithPreload(
|
||||
() => import('@/components/DockerBuildDebugger').then(m => ({ default: m.DockerBuildDebugger })),
|
||||
'DockerBuildDebugger'
|
||||
),
|
||||
} as const
|
||||
|
||||
export const DialogRegistry = {
|
||||
|
||||
Reference in New Issue
Block a user