diff --git a/src/components/ErrorPanel.tsx b/src/components/ErrorPanel.tsx index ecaca1e..6e59f26 100644 --- a/src/components/ErrorPanel.tsx +++ b/src/components/ErrorPanel.tsx @@ -3,10 +3,7 @@ import { CodeError } from '@/types/errors' import { ProjectFile } from '@/types/project' import { ErrorRepairService } from '@/lib/error-repair-service' import { Card } from '@/components/ui/card' -import { Button } from '@/components/ui/button' -import { Badge } from '@/components/ui/badge' import { ScrollArea } from '@/components/ui/scroll-area' -import { Separator } from '@/components/ui/separator' import { Warning, X, @@ -23,6 +20,19 @@ import { CollapsibleContent, CollapsibleTrigger, } from '@/components/ui/collapsible' +import { + Badge, + ActionButton, + Stack, + Flex, + Heading, + Text, + EmptyState, + IconText, + Code, + StatusIcon, + PanelHeader +} from '@/components/atoms' interface ErrorPanelProps { files: ProjectFile[] @@ -210,14 +220,13 @@ export function ErrorPanel({ files, onFileChange, onFileSelect }: ErrorPanelProp return (
-
-
-
- -

Error Detection & Repair

-
+ + + }> + Error Detection & Repair + {errors.length > 0 && ( -
+ {errorCount > 0 && ( {errorCount} {errorCount === 1 ? 'Error' : 'Errors'} @@ -228,85 +237,81 @@ export function ErrorPanel({ files, onFileChange, onFileSelect }: ErrorPanelProp {warningCount} {warningCount === 1 ? 'Warning' : 'Warnings'} )} -
+
)} -
-
- - -
-
+ variant="default" + /> + +
{errors.length === 0 && !isScanning && ( - - -

No Issues Found

-

- All files are looking good! Click "Scan" to check again. -

-
+ } + title="No Issues Found" + description="All files are looking good! Click 'Scan' to check again." + /> )} {isScanning && ( - - -

Scanning Files...

-

- Analyzing your code for errors and issues -

-
+ } + title="Scanning Files..." + description="Analyzing your code for errors and issues" + /> )} {errors.length > 0 && ( -
+ {Object.entries(errorsByFile).map(([fileId, fileErrors]) => { const file = files.find(f => f.id === fileId) if (!file) return null return ( -
-
- - {file.name} - - {fileErrors.length} {fileErrors.length === 1 ? 'issue' : 'issues'} - -
-
- - -
+
+ + + + {file.name} + + {fileErrors.length} {fileErrors.length === 1 ? 'issue' : 'issues'} + + + + } + label="Open" + onClick={() => onFileSelect(fileId)} + variant="outline" + size="sm" + /> + } + label="Repair" + onClick={() => repairFileWithContext(fileId)} + disabled={isRepairing} + variant="default" + size="sm" + /> + +
@@ -317,48 +322,46 @@ export function ErrorPanel({ files, onFileChange, onFileSelect }: ErrorPanelProp {getSeverityIcon(error.severity)}
-
- + + {error.type} {error.line && ( - + Line {error.line} - + )} {error.isFixed && ( - + Fixed )} -
-

{error.message}

+ + {error.message} {error.code && ( - + )}
- + variant="outline" + size="sm" + />
{error.code && ( -
- {error.code} +
+ {error.code}
)} @@ -368,7 +371,7 @@ export function ErrorPanel({ files, onFileChange, onFileSelect }: ErrorPanelProp ) })} -
+
)}
diff --git a/src/components/NotFoundPage.tsx b/src/components/NotFoundPage.tsx index 2f2ff50..3efb852 100644 --- a/src/components/NotFoundPage.tsx +++ b/src/components/NotFoundPage.tsx @@ -1,5 +1,4 @@ import { useNavigate } from 'react-router-dom' -import { Button } from '@/components/ui/button' import { Card } from '@/components/ui/card' import { House, @@ -11,6 +10,18 @@ import { Lightning, ChartBar } from '@phosphor-icons/react' +import { + EmptyState, + ActionButton, + Stack, + Heading, + Text, + Kbd, + IconWrapper, + GlowCard, + ResponsiveGrid, + Container +} from '@/components/atoms' export function NotFoundPage() { const navigate = useNavigate() @@ -24,92 +35,89 @@ export function NotFoundPage() { return (
-
-
-
- + + +
+
+ +
+ + 404 + Page Not Found + + The page you're looking for doesn't exist or may have been moved. +
- -

404

-

Page Not Found

-

- The page you're looking for doesn't exist or may have been moved. -

-
-
- - - - - -
+ + } + label="Go Back" + onClick={() => navigate(-1)} + variant="outline" + size="lg" + /> + + } + label="Home" + onClick={() => navigate('/')} + variant="default" + size="lg" + /> + + } + label="Search" + onClick={() => { + const searchBtn = document.querySelector('[data-search-trigger]') as HTMLElement + searchBtn?.click() + }} + variant="outline" + size="lg" + /> + -
-

- Quick Links -

-
- {quickLinks.map((link) => { - const Icon = link.icon - return ( - navigate(link.path)} - > -
-
- -
-
-

{link.label}

-

- {link.description} -

-
-
-
- ) - })} + + + Quick Links + + + {quickLinks.map((link) => { + const Icon = link.icon + return ( + navigate(link.path)} + className="cursor-pointer" + > + +
+ +
+ + {link.label} + + {link.description} + + +
+
+ ) + })} +
+
+ +
+ + Need help? Check the keyboard shortcuts with{' '} + Ctrl + {' + '} + / +
-
- -
-

- Need help? Check the keyboard shortcuts with{' '} - Ctrl - {' + '} - / -

-
-
+ +
) } diff --git a/src/components/atoms/EmptyState.tsx b/src/components/atoms/EmptyState.tsx index 1955d2e..60c3365 100644 --- a/src/components/atoms/EmptyState.tsx +++ b/src/components/atoms/EmptyState.tsx @@ -10,6 +10,7 @@ export interface EmptyStateProps { label: string onClick: () => void } + children?: ReactNode className?: string } @@ -18,6 +19,7 @@ export function EmptyState({ title, description, action, + children, className, }: EmptyStateProps) { return ( @@ -43,6 +45,7 @@ export function EmptyState({ {action.label} )} + {children}
) } diff --git a/src/components/organisms/DataSourceManager.tsx b/src/components/organisms/DataSourceManager.tsx index e694460..8357f27 100644 --- a/src/components/organisms/DataSourceManager.tsx +++ b/src/components/organisms/DataSourceManager.tsx @@ -1,6 +1,11 @@ import { useState } from 'react' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Button } from '@/components/ui/button' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from '@/components/ui/dropdown-menu' import { DataSourceCard } from '@/components/molecules/DataSourceCard' import { DataSourceEditorDialog } from '@/components/molecules/DataSourceEditorDialog' import { useDataSourceManager } from '@/hooks/data/use-data-source-manager' @@ -8,11 +13,14 @@ import { DataSource, DataSourceType } from '@/types/json-ui' import { Plus, Database, Function, FileText } from '@phosphor-icons/react' import { toast } from 'sonner' import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger -} from '@/components/ui/dropdown-menu' + EmptyState, + ActionButton, + Heading, + Text, + IconText, + Stack, + Section +} from '@/components/atoms' interface DataSourceManagerProps { dataSources: DataSource[] @@ -76,18 +84,22 @@ export function DataSourceManager({ dataSources, onChange }: DataSourceManagerPr
-
- Data Sources - + + Data Sources + Manage KV storage, computed values, and static data - -
+ + - +
+ } + label="Add Data Source" + variant="default" + onClick={() => {}} + /> +
handleAddDataSource('kv')}> @@ -108,24 +120,22 @@ export function DataSourceManager({ dataSources, onChange }: DataSourceManagerPr {localSources.length === 0 ? ( -
-
- -
-

No data sources yet

-

- Create your first data source to start binding data to components -

-
+ } + title="No data sources yet" + description="Create your first data source to start binding data to components" + /> ) : ( -
+ {groupedSources.kv.length > 0 && ( -
-

- +
+ } + className="text-sm font-semibold mb-3" + > KV Store ({groupedSources.kv.length}) -

-
+ + {groupedSources.kv.map(ds => ( ))} -
-
+
+ )} {groupedSources.static.length > 0 && ( -
-

- +
+ } + className="text-sm font-semibold mb-3" + > Static Data ({groupedSources.static.length}) -

-
+ + {groupedSources.static.map(ds => ( ))} -
-
+ + )} {groupedSources.computed.length > 0 && ( -
-

- +
+ } + className="text-sm font-semibold mb-3" + > Computed Values ({groupedSources.computed.length}) -

-
+ + {groupedSources.computed.map(ds => ( ))} -
-
+ + )} -
+ )}
diff --git a/src/components/organisms/EmptyCanvasState.tsx b/src/components/organisms/EmptyCanvasState.tsx index dddeb70..c80e4b0 100644 --- a/src/components/organisms/EmptyCanvasState.tsx +++ b/src/components/organisms/EmptyCanvasState.tsx @@ -1,5 +1,5 @@ -import { Button } from '@/components/ui/button' import { Plus, Folder } from '@phosphor-icons/react' +import { EmptyState, ActionButton, Stack } from '@/components/atoms' interface EmptyCanvasStateProps { onAddFirstComponent?: () => void @@ -8,32 +8,31 @@ interface EmptyCanvasStateProps { export function EmptyCanvasState({ onAddFirstComponent, onImportSchema }: EmptyCanvasStateProps) { return ( -
-
-
- -
-
- -

Empty Canvas

-

- Start building your UI by dragging components from the left panel, or import an existing schema. -

- -
- {onImportSchema && ( - - )} - {onAddFirstComponent && ( - - )} -
+
+ } + title="Empty Canvas" + description="Start building your UI by dragging components from the left panel, or import an existing schema." + > + + {onImportSchema && ( + } + label="Import Schema" + onClick={onImportSchema} + variant="outline" + /> + )} + {onAddFirstComponent && ( + } + label="Add Component" + onClick={onAddFirstComponent} + variant="default" + /> + )} + +
) } diff --git a/src/components/organisms/SchemaCodeViewer.tsx b/src/components/organisms/SchemaCodeViewer.tsx index 5bbff67..db138a5 100644 --- a/src/components/organisms/SchemaCodeViewer.tsx +++ b/src/components/organisms/SchemaCodeViewer.tsx @@ -1,8 +1,8 @@ -import { Button } from '@/components/ui/button' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' import { ScrollArea } from '@/components/ui/scroll-area' import { Code, Eye } from '@phosphor-icons/react' import { UIComponent } from '@/types/json-ui' +import { PanelHeader, Text, Code as CodeAtom, Stack, IconText } from '@/components/atoms' interface SchemaCodeViewerProps { components: UIComponent[] @@ -14,14 +14,7 @@ export function SchemaCodeViewer({ components, schema }: SchemaCodeViewerProps) return (
-
-
-
- -

Schema Output

-
-
-
+ } /> @@ -39,9 +32,9 @@ export function SchemaCodeViewer({ components, schema }: SchemaCodeViewerProps)
-

+ Live preview coming soon -

+
diff --git a/src/components/organisms/SchemaEditorStatusBar.tsx b/src/components/organisms/SchemaEditorStatusBar.tsx index b718dad..989b7d8 100644 --- a/src/components/organisms/SchemaEditorStatusBar.tsx +++ b/src/components/organisms/SchemaEditorStatusBar.tsx @@ -1,5 +1,5 @@ -import { Badge } from '@/components/ui/badge' import { cn } from '@/lib/utils' +import { Badge, Chip, Text, Flex } from '@/components/atoms' interface SchemaEditorStatusBarProps { componentCount: number @@ -16,31 +16,35 @@ export function SchemaEditorStatusBar({ }: SchemaEditorStatusBarProps) { return (
-
- + + {componentCount} component{componentCount !== 1 ? 's' : ''} - + {selectedComponentType && ( -
- Selected: - + + Selected: + {selectedComponentType} - -
+ + )} -
+ -
+ {hasUnsavedChanges && ( - + Unsaved changes )} -
+
) } diff --git a/src/components/organisms/SchemaEditorToolbar.tsx b/src/components/organisms/SchemaEditorToolbar.tsx index df22c32..536db53 100644 --- a/src/components/organisms/SchemaEditorToolbar.tsx +++ b/src/components/organisms/SchemaEditorToolbar.tsx @@ -1,5 +1,3 @@ -import { Button } from '@/components/ui/button' -import { Separator } from '@/components/ui/separator' import { Download, Upload, @@ -7,6 +5,9 @@ import { Trash, Copy, } from '@phosphor-icons/react' +import { Heading, TextGradient, Text, Separator, Stack } from '@/components/atoms' +import { ActionBar } from '@/components/molecules' +import { ActionButton } from '@/components/atoms' interface SchemaEditorToolbarProps { onImport: () => void @@ -26,58 +27,56 @@ export function SchemaEditorToolbar({ return (
-
-

+ + Schema Editor -

-

+ + Build JSON UI schemas with drag-and-drop -

-
+ +
- - - + variant="outline" + size="sm" + /> - - + variant="destructive" + size="sm" + />