diff --git a/json-components-registry.json b/json-components-registry.json index 1a55800..20184f7 100644 --- a/json-components-registry.json +++ b/json-components-registry.json @@ -3984,6 +3984,11 @@ "type": "AppLayout", "source": "app", "jsonCompatible": true + }, + { + "type": "AppRouterLayout", + "source": "app", + "jsonCompatible": true } ], "statistics": { diff --git a/src/components/json-definitions/app-router-layout.json b/src/components/json-definitions/app-router-layout.json new file mode 100644 index 0000000..d54d0b7 --- /dev/null +++ b/src/components/json-definitions/app-router-layout.json @@ -0,0 +1,51 @@ +{ + "id": "app-router-layout", + "type": "div", + "className": "h-screen flex flex-col bg-background", + "children": [ + { + "id": "main-panel", + "type": "AppMainPanel", + "bindings": { + "currentPage": { "source": "hookData.currentPage" }, + "navigateToPage": { "source": "hookData.navigateToPage" }, + "featureToggles": { "source": "hookData.featureToggles" }, + "errorCount": { "source": "hookData.errorCount" }, + "lastSaved": { "source": "hookData.lastSaved" }, + "currentProject": { "source": "hookData.currentProject" }, + "onProjectLoad": { "source": "hookData.handleProjectLoad" }, + "onSearch": { "source": "hookData.setSearchOpen", "transform": "() => setSearchOpen(true)" }, + "onShowShortcuts": { "source": "hookData.setShortcutsOpen", "transform": "() => setShortcutsOpen(true)" }, + "onGenerateAI": { "source": "hookData.onGenerateAI" }, + "onExport": { "source": "hookData.onExport" }, + "onPreview": { "source": "hookData.setPreviewOpen", "transform": "() => setPreviewOpen(true)" }, + "onShowErrors": { "source": "hookData.navigateToPage", "transform": "() => navigateToPage('errors')" }, + "stateContext": { "source": "hookData.stateContext" }, + "actionContext": { "source": "hookData.actionContext" } + } + }, + { + "id": "dialogs-container", + "type": "AppDialogs", + "bindings": { + "searchOpen": { "source": "hookData.searchOpen" }, + "onSearchOpenChange": { "source": "hookData.setSearchOpen" }, + "shortcutsOpen": { "source": "hookData.shortcutsOpen" }, + "onShortcutsOpenChange": { "source": "hookData.setShortcutsOpen" }, + "previewOpen": { "source": "hookData.previewOpen" }, + "onPreviewOpenChange": { "source": "hookData.setPreviewOpen" }, + "files": { "source": "hookData.files" }, + "models": { "source": "hookData.models" }, + "components": { "source": "hookData.components" }, + "componentTrees": { "source": "hookData.componentTrees" }, + "workflows": { "source": "hookData.workflows" }, + "lambdas": { "source": "hookData.lambdas" }, + "playwrightTests": { "source": "hookData.playwrightTests" }, + "storybookStories": { "source": "hookData.storybookStories" }, + "unitTests": { "source": "hookData.unitTests" }, + "onNavigate": { "source": "hookData.navigateToPage" }, + "onFileSelect": { "source": "hookData.onFileSelect" } + } + } + ] +} diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 061efbb..f39323b 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -38,3 +38,4 @@ export * from './use-file-upload' export * from './use-accordion' export * from './use-binding-editor' export { useAppLayout } from './use-app-layout' +export { useAppRouterLayout } from './use-app-router-layout' diff --git a/src/hooks/use-app-router-layout.ts b/src/hooks/use-app-router-layout.ts new file mode 100644 index 0000000..6eb8f70 --- /dev/null +++ b/src/hooks/use-app-router-layout.ts @@ -0,0 +1,72 @@ +import { useState } from 'react' +import useAppNavigation from './use-app-navigation' +import useAppProject from './use-app-project' +import useAppShortcuts from './use-app-shortcuts' + +export function useAppRouterLayout() { + const { currentPage, navigateToPage } = useAppNavigation() + const { + files, + models, + components, + componentTrees, + workflows, + lambdas, + playwrightTests, + storybookStories, + unitTests, + featureToggles, + fileOps, + currentProject, + handleProjectLoad, + stateContext, + actionContext, + } = useAppProject() + const { searchOpen, setSearchOpen, shortcutsOpen, setShortcutsOpen, previewOpen, setPreviewOpen } = + useAppShortcuts({ featureToggles, navigateToPage }) + const [lastSaved] = useState(() => Date.now()) + const [errorCount] = useState(0) + + // Create inline callback handlers for JSON binding + const onGenerateAI = () => { + // This will be defined via toast.info from appStrings + } + const onExport = () => { + // This will be defined via toast.info from appStrings + } + const onFileSelect = (fileId: string) => { + fileOps.setActiveFileId(fileId) + navigateToPage('code') + } + + return { + currentPage, + navigateToPage, + files, + models, + components, + componentTrees, + workflows, + lambdas, + playwrightTests, + storybookStories, + unitTests, + featureToggles, + fileOps, + currentProject, + handleProjectLoad, + stateContext, + actionContext, + searchOpen, + setSearchOpen, + shortcutsOpen, + setShortcutsOpen, + previewOpen, + setPreviewOpen, + lastSaved, + errorCount, + onGenerateAI, + onExport, + onFileSelect, + } +} diff --git a/src/lib/json-ui/hooks-registry.ts b/src/lib/json-ui/hooks-registry.ts index 353d388..483c3e8 100644 --- a/src/lib/json-ui/hooks-registry.ts +++ b/src/lib/json-ui/hooks-registry.ts @@ -16,6 +16,7 @@ import { useFileUpload } from '@/hooks/use-file-upload' import { useAccordion } from '@/hooks/use-accordion' import { useBindingEditor } from '@/hooks/use-binding-editor' import { useAppLayout } from '@/hooks/use-app-layout' +import { useAppRouterLayout } from '@/hooks/use-app-router-layout' export interface HookRegistry { [key: string]: (...args: any[]) => any @@ -39,6 +40,7 @@ export const hooksRegistry: HookRegistry = { useAccordion, useBindingEditor, useAppLayout, + useAppRouterLayout, // Add more hooks here as needed } diff --git a/src/lib/json-ui/interfaces/app-router-layout.ts b/src/lib/json-ui/interfaces/app-router-layout.ts new file mode 100644 index 0000000..4b0c310 --- /dev/null +++ b/src/lib/json-ui/interfaces/app-router-layout.ts @@ -0,0 +1,4 @@ +export interface AppRouterLayoutProps { + // Props passed from parent + // Most state comes from hooks, not props +} diff --git a/src/lib/json-ui/interfaces/index.ts b/src/lib/json-ui/interfaces/index.ts index c84d113..eee867f 100644 --- a/src/lib/json-ui/interfaces/index.ts +++ b/src/lib/json-ui/interfaces/index.ts @@ -23,3 +23,6 @@ export * from './file-upload' export * from './accordion' export * from './binding-editor' export * from './app-layout' +export * from './app-router-layout' +export * from './app-main-panel' +export * from './app-dialogs' diff --git a/src/lib/json-ui/json-components.ts b/src/lib/json-ui/json-components.ts index 6dcb746..5d7a1ab 100644 --- a/src/lib/json-ui/json-components.ts +++ b/src/lib/json-ui/json-components.ts @@ -31,6 +31,9 @@ import type { AccordionProps, BindingEditorProps, AppLayoutProps, + AppRouterLayoutProps, + AppMainPanelProps, + AppDialogsProps, } from './interfaces' // Import JSON definitions @@ -57,6 +60,8 @@ import fileUploadDef from '@/components/json-definitions/file-upload.json' import accordionDef from '@/components/json-definitions/accordion.json' import bindingEditorDef from '@/components/json-definitions/binding-editor.json' import appLayoutDef from '@/components/json-definitions/app-layout.json' +import appRouterLayoutDef from '@/components/json-definitions/app-router-layout.json' +import appMainPanelDef from '@/components/json-definitions/app-main-panel.json' // Create pure JSON components (no hooks) export const LoadingFallback = createJsonComponent(loadingFallbackDef) @@ -197,4 +202,15 @@ export const AppLayout = createJsonComponentWithHooks(appLayoutD } }) +export const AppRouterLayout = createJsonComponentWithHooks(appRouterLayoutDef, { + hooks: { + hookData: { + hookName: 'useAppRouterLayout', + args: (props) => [props] + } + } +}) + +export const AppMainPanel = createJsonComponent(appMainPanelDef) + // All components converted to pure JSON! 🎉