@ramme-io/create-app 1.2.1 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/package.json +9 -15
  2. package/template/package.json +41 -0
  3. package/template/pkg.json +9 -7
  4. package/template/src/App.tsx +72 -31
  5. package/template/src/components/AIChatWidget.tsx +2 -2
  6. package/template/src/components/AppHeader.tsx +12 -12
  7. package/template/src/components/AutoForm.tsx +13 -0
  8. package/template/src/{pages/styleguide → components}/NotFound.tsx +1 -1
  9. package/template/src/components/PageTitleUpdater.tsx +2 -2
  10. package/template/src/components/ProtectedRoute.tsx +18 -1
  11. package/template/src/components/ScrollToTop.tsx +19 -0
  12. package/template/src/components/dashboard/ChartLine.tsx +28 -0
  13. package/template/src/components/dashboard/StatCard.tsx +61 -0
  14. package/template/src/config/app.manifest.ts +3 -1
  15. package/template/src/config/component-registry.tsx +69 -0
  16. package/template/src/config/navigation.ts +1 -1
  17. package/template/src/data/mock-charts.ts +32 -28
  18. package/template/src/{components → engine/renderers}/DynamicBlock.tsx +28 -8
  19. package/template/src/engine/renderers/DynamicPage.tsx +150 -0
  20. package/template/src/engine/runtime/ManifestContext.tsx +79 -0
  21. package/template/src/{contexts → engine/runtime}/MqttContext.tsx +23 -14
  22. package/template/src/{contexts → engine/runtime}/SitemapContext.tsx +1 -1
  23. package/template/src/engine/runtime/data-seeder.ts +47 -0
  24. package/template/src/{hooks → engine/runtime}/useAction.ts +11 -14
  25. package/template/src/{hooks → engine/runtime}/useCrudLocalStorage.ts +27 -8
  26. package/template/src/{hooks → engine/runtime}/useDataQuery.ts +15 -1
  27. package/template/src/engine/runtime/useDynamicSitemap.tsx +43 -0
  28. package/template/src/engine/runtime/useJustInTimeSeeder.ts +76 -0
  29. package/template/src/engine/runtime/useLiveBridge.ts +44 -0
  30. package/template/src/engine/runtime/useSignal.ts +40 -0
  31. package/template/src/{generated/hooks.ts → engine/runtime/useSignalStore.ts} +35 -8
  32. package/template/src/engine/runtime/useWorkflowEngine.ts +89 -0
  33. package/template/src/{core → engine/types}/manifest-types.ts +35 -3
  34. package/template/src/{types → engine/validation}/schema.ts +17 -0
  35. package/template/src/{pages → features/ai/pages}/AiChat.tsx +1 -1
  36. package/template/src/features/auth/AuthContext.tsx +118 -0
  37. package/template/src/features/auth/pages/AuthLayout.tsx +55 -0
  38. package/template/src/features/auth/pages/LoginPage.tsx +106 -0
  39. package/template/src/features/auth/pages/SignupPage.tsx +96 -0
  40. package/template/src/{blocks → features/datagrid}/SmartTable.tsx +41 -25
  41. package/template/src/features/developer/GhostOverlay.tsx +114 -0
  42. package/template/src/{pages → features/onboarding/pages}/Welcome.tsx +0 -1
  43. package/template/src/features/overview/index.ts +1 -0
  44. package/template/src/features/overview/pages/OverviewPage.tsx +127 -0
  45. package/template/src/{pages → features/playground/pages}/AccountingLedgerPage.tsx +1 -1
  46. package/template/src/{pages/prototypes → features/playground/pages}/ItemSelectorPage.tsx +1 -1
  47. package/template/src/{pages/settings → features/settings/pages}/BillingPage.tsx +1 -1
  48. package/template/src/features/settings/pages/ProfilePage.tsx +153 -0
  49. package/template/src/{pages/settings → features/settings/pages}/TeamPage.tsx +1 -1
  50. package/template/src/features/styleguide/Styleguide.tsx +75 -0
  51. package/template/src/features/users/components/UserDrawer.tsx +138 -0
  52. package/template/src/features/users/index.ts +2 -0
  53. package/template/src/features/users/pages/UsersPage.tsx +151 -0
  54. package/template/src/features/visualizations/SmartChart.tsx +178 -0
  55. package/template/src/index.css +1 -1
  56. package/template/src/main.tsx +27 -15
  57. package/template/src/templates/dashboard/DashboardLayout.tsx +77 -107
  58. package/template/src/templates/dashboard/dashboard.sitemap.ts +19 -22
  59. package/template/src/templates/docs/DocsLayout.tsx +49 -38
  60. package/template/src/templates/docs/docs.sitemap.ts +22 -34
  61. package/template/src/templates/settings/SettingsLayout.tsx +83 -143
  62. package/template/src/templates/settings/settings.sitemap.ts +6 -6
  63. package/template/tailwind.config.cjs +10 -9
  64. package/template/vite.config.ts +0 -11
  65. package/template/src/adaptors/.gitkeep +0 -0
  66. package/template/src/components/LocalSideNav.tsx +0 -120
  67. package/template/src/components/PageWithSideNav.tsx +0 -69
  68. package/template/src/components/dev/GhostOverlay.tsx +0 -68
  69. package/template/src/config/dashboard.layout.ts +0 -110
  70. package/template/src/contexts/AuthContext.tsx +0 -64
  71. package/template/src/core/component-registry.tsx +0 -56
  72. package/template/src/core/data-seeder.ts +0 -35
  73. package/template/src/data/mockUsers.ts +0 -18
  74. package/template/src/hooks/useSignal.ts +0 -83
  75. package/template/src/hooks/useWorkflowEngine.ts +0 -123
  76. package/template/src/layouts/DataLayout.tsx +0 -37
  77. package/template/src/layouts/SideNavLayout.tsx +0 -28
  78. package/template/src/pages/Dashboard.tsx +0 -60
  79. package/template/src/pages/DataGridPage.tsx +0 -184
  80. package/template/src/pages/DynamicPage.tsx +0 -95
  81. package/template/src/pages/LoginPage.tsx +0 -58
  82. package/template/src/pages/settings/ProfilePage.tsx +0 -10
  83. package/template/src/pages/styleguide/Styleguide.tsx +0 -40
  84. package/template/src/templates/docs/pages/Introduction.tsx +0 -13
  85. package/template/src/types/signal.ts +0 -23
  86. /package/template/src/{core → engine/renderers}/route-generator.tsx +0 -0
  87. /package/template/src/{core → engine/types}/sitemap-entry.ts +0 -0
  88. /package/template/src/{pages → features}/GenericContentPage.tsx +0 -0
  89. /package/template/src/{hooks → features/assistant}/useMockChat.ts +0 -0
  90. /package/template/src/{hooks → features/developer}/useDevTools.ts +0 -0
  91. /package/template/src/{pages → features}/styleguide/sections/charts/ChartsSection.tsx +0 -0
  92. /package/template/src/{pages → features}/styleguide/sections/colors/ColorsSection.tsx +0 -0
  93. /package/template/src/{pages → features}/styleguide/sections/elements/ElementsSection.tsx +0 -0
  94. /package/template/src/{pages → features}/styleguide/sections/feedback/FeedbackSection.tsx +0 -0
  95. /package/template/src/{pages → features}/styleguide/sections/forms/FormsSection.tsx +0 -0
  96. /package/template/src/{pages → features}/styleguide/sections/icons/IconsSection.tsx +0 -0
  97. /package/template/src/{pages → features}/styleguide/sections/layout/LayoutSection.tsx +0 -0
  98. /package/template/src/{pages → features}/styleguide/sections/navigation/NavigationSection.tsx +0 -0
  99. /package/template/src/{pages → features}/styleguide/sections/tables/TablesSection.tsx +0 -0
  100. /package/template/src/{pages → features}/styleguide/sections/templates/TemplatesSection.tsx +0 -0
  101. /package/template/src/{pages → features}/styleguide/sections/theming/ThemingSection.tsx +0 -0
  102. /package/template/src/{pages → features}/styleguide/sections/utilities/UtilitiesSection.tsx +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ramme-io/create-app",
3
- "version": "1.2.1",
3
+ "version": "1.2.5",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "create-ramme-app": "./index.js"
@@ -9,16 +9,7 @@
9
9
  "index.js",
10
10
  "template"
11
11
  ],
12
- "scripts": {
13
- "dev": "cd template && vite",
14
- "build": "cd template && tsc && vite build",
15
- "preview": "cd template && vite preview",
16
- "pack-tarball": "npm pack",
17
- "bundle:ai": "repomix --ignore '**/*.lock,**/dist/**,**/template/dist/**,**/template/node_modules/**' --output 'ramme-starter-context.txt'",
18
- "zip:builder": "cd template && zip -r ../base.zip . -x \"node_modules/*\" \"dist/*\" \".DS_Store\" && mv ../base.zip ../../ramme-app-builder/public/base.zip && echo '✅ base.zip updated in Builder!'"
19
- },
20
12
  "dependencies": {
21
- "@ramme-io/ui": "^1.1.5",
22
13
  "ag-grid-community": "^34.1.2",
23
14
  "ag-grid-enterprise": "^34.1.2",
24
15
  "ag-grid-react": "^34.1.2",
@@ -40,9 +31,12 @@
40
31
  "typescript": "^5.2.2",
41
32
  "vite": "^5.2.0"
42
33
  },
43
- "pnpm": {
44
- "overrides": {
45
- "react-router-dom": "6.30.1"
46
- }
34
+ "scripts": {
35
+ "dev": "cd template && vite",
36
+ "build": "cd template && tsc && vite build",
37
+ "preview": "cd template && vite preview",
38
+ "pack-tarball": "npm pack",
39
+ "bundle:ai": "repomix --ignore '**/*.lock,**/dist/**,**/template/dist/**,**/template/node_modules/**' --output 'ramme-starter-context.txt'",
40
+ "zip:builder": "cd template && zip -r ../base.zip . -x \"node_modules/*\" \"dist/*\" \".DS_Store\" && mv ../base.zip ../../ramme-app-builder/public/base.zip && echo '✅ base.zip updated in Builder!'"
47
41
  }
48
- }
42
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "ramme-app",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "tsc && vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "@ai-sdk/google": "^0.0.10",
13
+ "@ramme-io/ui": "^1.2.3",
14
+ "ag-grid-community": "^31.3.1",
15
+ "ag-grid-enterprise": "^31.3.1",
16
+ "ag-grid-react": "^31.3.1",
17
+ "ai": "^3.0.0",
18
+ "framer-motion": "^11.0.0",
19
+ "fs-extra": "^11.2.0",
20
+ "mqtt": "^5.3.5",
21
+ "react": "^18.2.0",
22
+ "react-dom": "^18.2.0",
23
+ "react-resizable-panels": "^2.0.9",
24
+ "react-router-dom": "^6.22.0",
25
+ "uuid": "^13.0.0",
26
+ "zod": "^3.22.0",
27
+ "zustand": "^4.5.7"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^20.11.0",
31
+ "@types/react": "^18.2.0",
32
+ "@types/react-dom": "^18.2.0",
33
+ "@types/uuid": "^10.0.0",
34
+ "@vitejs/plugin-react": "^4.2.0",
35
+ "autoprefixer": "^10.4.19",
36
+ "postcss": "^8.4.38",
37
+ "tailwindcss": "^3.4.3",
38
+ "typescript": "^5.2.0",
39
+ "vite": "^5.2.0"
40
+ }
41
+ }
package/template/pkg.json CHANGED
@@ -9,26 +9,28 @@
9
9
  "preview": "vite preview"
10
10
  },
11
11
  "dependencies": {
12
- "@ramme-io/ui": "^1.1.5",
13
- "mqtt": "^5.3.5",
14
- "zustand": "^4.5.0",
12
+ "@ai-sdk/google": "^0.0.10",
13
+ "@ramme-io/ui": "^1.2.3",
15
14
  "ag-grid-community": "^31.3.1",
16
15
  "ag-grid-enterprise": "^31.3.1",
17
16
  "ag-grid-react": "^31.3.1",
17
+ "ai": "^3.0.0",
18
18
  "framer-motion": "^11.0.0",
19
19
  "fs-extra": "^11.2.0",
20
+ "mqtt": "^5.3.5",
20
21
  "react": "^18.2.0",
21
22
  "react-dom": "^18.2.0",
22
- "react-router-dom": "^6.22.0",
23
23
  "react-resizable-panels": "^2.0.9",
24
- "ai": "^3.0.0",
25
- "@ai-sdk/google": "^0.0.10",
26
- "zod": "^3.22.0"
24
+ "react-router-dom": "^6.22.0",
25
+ "uuid": "^13.0.0",
26
+ "zod": "^3.22.0",
27
+ "zustand": "^4.5.7"
27
28
  },
28
29
  "devDependencies": {
29
30
  "@types/node": "^20.11.0",
30
31
  "@types/react": "^18.2.0",
31
32
  "@types/react-dom": "^18.2.0",
33
+ "@types/uuid": "^10.0.0",
32
34
  "@vitejs/plugin-react": "^4.2.0",
33
35
  "autoprefixer": "^10.4.19",
34
36
  "postcss": "^8.4.38",
@@ -1,10 +1,20 @@
1
- import { Routes, Route, Navigate } from 'react-router-dom';
2
- import { generateRoutes } from './core/route-generator';
3
1
  import { useEffect } from 'react';
2
+ import { Routes, Route, Navigate } from 'react-router-dom';
3
+ import { generateRoutes } from './engine/renderers/route-generator';
4
+ import { ThemeProvider } from '@ramme-io/ui';
5
+ import { AuthProvider } from './features/auth/AuthContext';
6
+ import { MqttProvider } from './engine/runtime/MqttContext';
7
+
8
+
9
+ // --- 1. IMPORT AUTH CLUSTER ---
10
+ import { AuthLayout } from './features/auth/pages/AuthLayout';
11
+ import LoginPage from './features/auth/pages/LoginPage';
12
+ import SignupPage from './features/auth/pages/SignupPage';
4
13
 
5
- // --- 1. IMPORT ALL THREE TEMPLATES ---
14
+ // --- 2. IMPORT TEMPLATES ---
6
15
  import DashboardLayout from './templates/dashboard/DashboardLayout';
7
16
  import { dashboardSitemap } from './templates/dashboard/dashboard.sitemap';
17
+ import { useDynamicSitemap } from './engine/runtime/useDynamicSitemap';
8
18
  import DocsLayout from './templates/docs/DocsLayout';
9
19
  import { docsSitemap } from './templates/docs/docs.sitemap';
10
20
  import SettingsLayout from './templates/settings/SettingsLayout';
@@ -12,43 +22,74 @@ import { settingsSitemap } from './templates/settings/settings.sitemap';
12
22
 
13
23
  // Other Imports
14
24
  import ProtectedRoute from './components/ProtectedRoute';
15
- import LoginPage from './pages/LoginPage';
16
- import NotFound from './pages/styleguide/NotFound';
25
+ import NotFound from './components/NotFound';
26
+
27
+ // --- 3. DATA SEEDER ---
28
+ import { initializeDataLake } from './engine/runtime/data-seeder';
29
+
30
+ import ScrollToTop from './components/ScrollToTop';
31
+ import HashLinkScroll from './components/HashLinkScroll';
17
32
 
18
- // --- 2. IMPORT THE SEEDER ---
19
- import { initializeDataLake } from './core/data-seeder';
20
33
 
21
34
  function App() {
22
35
 
23
- // 3. TRIGGER DATA SEEDING ON MOUNT
36
+ // Trigger data seeding on mount
24
37
  useEffect(() => {
25
38
  initializeDataLake();
26
39
  }, []);
27
40
 
41
+ const liveDashboardRoutes = useDynamicSitemap(dashboardSitemap);
42
+
43
+ console.log("🗺️ ROUTER MAP:", liveDashboardRoutes.map(r => ({ path: r.path, id: r.id })));
44
+
45
+
28
46
  return (
29
- <Routes>
30
- <Route path="/login" element={<LoginPage />} />
31
- <Route element={<ProtectedRoute />}>
32
- {/* ✅ FIX: Redirect root to the new Welcome page */}
33
- <Route path="/" element={<Navigate to="/dashboard/welcome" replace />} />
34
-
35
- {/* Dashboard Template Routes */}
36
- <Route path="/dashboard/*" element={<DashboardLayout />}>
37
- {generateRoutes(dashboardSitemap)}
38
- </Route>
39
-
40
- {/* Docs Template Routes */}
41
- <Route path="/docs/*" element={<DocsLayout />}>
42
- {generateRoutes(docsSitemap)}
43
- </Route>
44
-
45
- {/* Settings Layout Route */}
46
- <Route path="/settings/*" element={<SettingsLayout />}>
47
- {generateRoutes(settingsSitemap)}
48
- </Route>
49
- </Route>
50
- <Route path="*" element={<NotFound />} />
51
- </Routes>
47
+ <ThemeProvider>
48
+
49
+ <AuthProvider>
50
+ <MqttProvider>
51
+ <ScrollToTop />
52
+ <HashLinkScroll />
53
+ <Routes>
54
+ {/* --- NEW AUTH CLUSTER --- */}
55
+ {/* This handles the layout and background for all auth pages */}
56
+ <Route path="/auth" element={<AuthLayout />}>
57
+ <Route index element={<Navigate to="/auth/login" replace />} />
58
+ <Route path="login" element={<LoginPage />} />
59
+ <Route path="signup" element={<SignupPage />} />
60
+ </Route>
61
+
62
+ {/* Fallback for legacy /login access */}
63
+ <Route path="/login" element={<Navigate to="/auth/login" replace />} />
64
+
65
+ {/* --- PROTECTED APP ROUTES --- */}
66
+ <Route element={<ProtectedRoute />}>
67
+ <Route path="/" element={<Navigate to="/dashboard/welcome" replace />} />
68
+
69
+ {/* Dashboard Template */}
70
+ <Route path="/dashboard/*" element={<DashboardLayout />}>
71
+ <Route index element={<Navigate to="welcome" replace />} />
72
+ {generateRoutes(liveDashboardRoutes)}
73
+ </Route>
74
+
75
+ {/* Docs Template */}
76
+ <Route path="/docs/*" element={<DocsLayout />}>
77
+ {generateRoutes(docsSitemap)}
78
+ </Route>
79
+
80
+ {/* Settings Template */}
81
+ <Route path="/settings/*" element={<SettingsLayout />}>
82
+ {generateRoutes(settingsSitemap)}
83
+ </Route>
84
+ </Route>
85
+
86
+ {/* 404 Handler */}
87
+ <Route path="*" element={<NotFound />} />
88
+ </Routes>
89
+ </MqttProvider>
90
+ </AuthProvider>
91
+
92
+ </ThemeProvider>
52
93
  );
53
94
  }
54
95
 
@@ -7,7 +7,7 @@ import {
7
7
  Button,
8
8
  Icon,
9
9
  } from '@ramme-io/ui';
10
- import { useMockChat } from '../hooks/useMockChat';
10
+ import { useMockChat } from '../features/assistant/useMockChat';
11
11
 
12
12
  interface AIChatWidgetProps {
13
13
  onClose: () => void;
@@ -31,7 +31,7 @@ export const AIChatWidget: React.FC<AIChatWidgetProps> = ({ onClose }) => {
31
31
  <div className="p-4 border-b flex justify-between items-center bg-muted/50 rounded-t-lg">
32
32
  <div className="flex items-center gap-2">
33
33
  <div className="w-2 h-2 rounded-full bg-green-500 animate-pulse" />
34
- <span className="font-semibold text-sm">Bodewell AI</span>
34
+ <span className="font-semibold text-sm">AI Chat</span>
35
35
  </div>
36
36
  <Button variant="ghost" size="icon" onClick={onClose} className="h-6 w-6">
37
37
  <Icon name="x" size={16} />
@@ -4,9 +4,9 @@
4
4
  * @description This is the global application header.
5
5
  *
6
6
  * @developer_notes
7
- * STRATEGIC REFACTOR (10/21/2025):
8
- * 1. Updated logo to include both the `orange.png` image and "Ramme" text.
9
- * 2. Kept all A.D.A.P.T. manifest, asChild, and z-index fixes.
7
+ * STRATEGIC REFACTOR:
8
+ * 1. Cleaned up Ghost Bridge telemetry for production feel.
9
+ * 2. Kept all A.D.A.P.T. navigation and z-index fixes.
10
10
  */
11
11
  import React from 'react';
12
12
  import { Link } from 'react-router-dom';
@@ -19,13 +19,13 @@ import {
19
19
  useTheme,
20
20
  type ThemeName,
21
21
  } from '@ramme-io/ui';
22
- import { useAuth } from '../contexts/AuthContext';
22
+ import { useAuth } from '../features/auth/AuthContext';
23
23
 
24
24
  // --- STRATEGIC IMPORTS ---
25
25
  import { appManifest } from '../config/navigation';
26
- import type { ManifestLink } from '../core/manifest-types';
26
+ import type { ManifestLink } from '../engine/types/manifest-types';
27
27
  import TemplateSwitcher from './TemplateSwitcher';
28
- import rammeLogo from '../assets/orange.png'; // <-- 1. IMPORT THE LOGO
28
+ import rammeLogo from '../assets/orange.png';
29
29
 
30
30
  const AppHeader: React.FC = () => {
31
31
  const { theme, availableThemes, setTheme } = useTheme();
@@ -47,13 +47,13 @@ const AppHeader: React.FC = () => {
47
47
  // Z-INDEX FIX: Set to z-50 to render above the z-40 sidebar.
48
48
  <header className="flex items-center justify-between p-4 bg-card border-b border-border shadow-sm sticky top-0 z-50">
49
49
 
50
- {/* --- 2. UPDATED LOGO BLOCK --- */}
51
- {/* Logo - links to dashboard home */}
50
+ {/* --- 1. LOGO BLOCK --- */}
52
51
  <Link to="/dashboard" className="flex items-center gap-2">
53
52
  <img src={rammeLogo} alt="Ramme Logo" className="h-8 w-auto" />
54
53
  <h1 className="text-2xl font-bold text-text">Ramme</h1>
55
54
  </Link>
56
55
 
56
+ {/* --- 2. USER ACTIONS --- */}
57
57
  <div className="flex items-center gap-4">
58
58
  <TemplateSwitcher />
59
59
  {user && (
@@ -64,14 +64,14 @@ const AppHeader: React.FC = () => {
64
64
  </button>
65
65
  }
66
66
  >
67
- {/* 1. User Info (Static) */}
67
+ {/* User Info */}
68
68
  <div className="p-2 text-sm text-muted-foreground">
69
69
  <p className="font-semibold text-text">{user.name}</p>
70
70
  <p>{user.email}</p>
71
71
  </div>
72
72
  <MenuDivider />
73
73
 
74
- {/* 2. Designer-Controlled Nav Links */}
74
+ {/* Navigation Links */}
75
75
  {userNavLinks.map((link: ManifestLink) => (
76
76
  <MenuItem
77
77
  key={link.id}
@@ -83,7 +83,7 @@ const AppHeader: React.FC = () => {
83
83
  ))}
84
84
  <MenuDivider />
85
85
 
86
- {/* 3. App-Specific: Theme Switcher */}
86
+ {/* Theme Switcher */}
87
87
  <div className="p-2 text-sm text-muted-foreground">
88
88
  <p>
89
89
  Active Theme:{' '}
@@ -100,7 +100,7 @@ const AppHeader: React.FC = () => {
100
100
  ))}
101
101
  <MenuDivider />
102
102
 
103
- {/* 4. App-Specific: Actions */}
103
+ {/* Actions */}
104
104
  <MenuItem onClick={handleResetData} icon={<Icon name="refresh-cw" />}>
105
105
  Reset Data
106
106
  </MenuItem>
@@ -1,6 +1,19 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { Drawer, FormTemplate, Button, type FormField } from '@ramme-io/ui';
3
3
 
4
+ /**
5
+ * @file AutoForm.tsx
6
+ * @description The "Zero-Boilerplate" Form Engine.
7
+ * * ARCHITECTURAL ROLE:
8
+ * This component acts as the bridge between your data schema (JSON) and the UI.
9
+ * Instead of writing manual form code for every resource (Users, Products, Orders),
10
+ * this component dynamically generates the correct inputs based on the field type.
11
+ * * KEY FEATURES:
12
+ * 1. **Smart Mapping:** Automatically converts 'boolean' -> Toggle, 'date' -> DatePicker, etc.
13
+ * 2. **Context Aware:** Auto-detects "Create" vs "Edit" mode based on `initialData`.
14
+ * 3. **Safety Logic:** Automatically hides primary keys during creation and locks them during editing.
15
+ */
16
+
4
17
  interface AutoFormProps {
5
18
  isOpen: boolean;
6
19
  onClose: () => void;
@@ -13,7 +13,7 @@ const NotFound: React.FC = () => {
13
13
  </p>
14
14
  {/* Wrap the Button with the Link component */}
15
15
  <Link to="/">
16
- <Button size="lg">Return to Style Guide</Button>
16
+ <Button size="lg">Return to Dashboard</Button>
17
17
  </Link>
18
18
  </div>
19
19
  );
@@ -6,8 +6,8 @@
6
6
  */
7
7
  import React, { useEffect } from 'react';
8
8
  import { useLocation } from 'react-router-dom';
9
- import { useSitemap } from '../contexts/SitemapContext'; // Import our context hook
10
- import type { SitemapEntry } from '../core/sitemap-entry';
9
+ import { useSitemap } from '../engine/runtime/SitemapContext'; // Import our context hook
10
+ import type { SitemapEntry } from '../engine/types/sitemap-entry';
11
11
 
12
12
  // Helper function to recursively find a route by path
13
13
  const findRouteByPath = (
@@ -1,8 +1,25 @@
1
1
  import React from 'react';
2
2
  import { Navigate, Outlet } from 'react-router-dom';
3
- import { useAuth } from '../contexts/AuthContext';
3
+ import { useAuth } from '../features/auth/AuthContext';
4
4
  import { Icon } from '@ramme-io/ui';
5
5
 
6
+ /**
7
+ * @file ProtectedRoute.tsx
8
+ * @description The "Security Gatekeeper" for the application.
9
+ *
10
+ * ARCHITECTURAL ROLE:
11
+ * This component wraps all private routes (Dashboard, Settings, Docs) in `App.tsx`.
12
+ * It acts as a middleware that checks the user's authentication status before
13
+ * allowing access to the child components (Outlet).
14
+ *
15
+ * KEY FEATURES:
16
+ * 1. **Auth Verification:** Automatically redirects unauthenticated users to `/login`.
17
+ * 2. **Loading State:** Displays a spinner while the Auth Provider is initializing,
18
+ * preventing "flash of login screen" bugs.
19
+ * 3. **History Management:** Uses `replace` on redirect to ensure the browser
20
+ * back button works correctly (skips the restricted page).
21
+ */
22
+
6
23
  const ProtectedRoute: React.FC = () => {
7
24
  const { user, isLoading } = useAuth();
8
25
 
@@ -0,0 +1,19 @@
1
+ import { useEffect } from 'react';
2
+ import { useLocation } from 'react-router-dom';
3
+
4
+ const ScrollToTop = () => {
5
+ const { pathname } = useLocation();
6
+
7
+ useEffect(() => {
8
+ // "instant" prevents the user from seeing the page scroll up
9
+ window.scrollTo({
10
+ top: 0,
11
+ left: 0,
12
+ behavior: 'instant',
13
+ });
14
+ }, [pathname]);
15
+
16
+ return null;
17
+ };
18
+
19
+ export default ScrollToTop;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { Card } from '@ramme-io/ui';
3
+
4
+ export const ChartLine: React.FC<{ title: string; description?: string }> = ({ title, description }) => {
5
+ return (
6
+ <Card className="p-6 h-full min-h-[300px] flex flex-col">
7
+ <div className="mb-6">
8
+ <h3 className="font-semibold text-lg">{title}</h3>
9
+ {description && <p className="text-sm text-muted-foreground">{description}</p>}
10
+ </div>
11
+
12
+ {/* Visual Mockup of a Chart */}
13
+ <div className="flex-1 flex items-end justify-between gap-2 px-2 pb-2 mt-4 border-b border-l border-border/50">
14
+ {[40, 70, 45, 90, 65, 85, 55, 95, 75, 60, 90, 100].map((h, i) => (
15
+ <div key={i} className="w-full flex flex-col items-center gap-2 group">
16
+ <div
17
+ className="w-full bg-primary/20 group-hover:bg-primary/80 transition-all rounded-t-sm"
18
+ style={{ height: `${h}%` }}
19
+ />
20
+ </div>
21
+ ))}
22
+ </div>
23
+ <div className="flex justify-between mt-2 text-xs text-muted-foreground px-2">
24
+ <span>Mon</span><span>Tue</span><span>Wed</span><span>Thu</span><span>Fri</span><span>Sat</span><span>Sun</span>
25
+ </div>
26
+ </Card>
27
+ );
28
+ };
@@ -0,0 +1,61 @@
1
+ import React from 'react';
2
+ import { Card } from '@ramme-io/ui';
3
+ import { ArrowUpRight, ArrowDownRight, Activity, Users, DollarSign, CreditCard } from 'lucide-react';
4
+
5
+ interface StatCardProps {
6
+ title: string;
7
+ value: string | number;
8
+ trend?: string;
9
+ status?: 'positive' | 'negative' | 'neutral' | 'offline';
10
+ }
11
+
12
+ export const StatCard: React.FC<StatCardProps> = ({
13
+ title,
14
+ value,
15
+ trend,
16
+ status = 'neutral'
17
+ }) => {
18
+ const statusColors = {
19
+ positive: 'text-green-600 bg-green-100',
20
+ negative: 'text-red-600 bg-red-100',
21
+ neutral: 'text-blue-600 bg-blue-100',
22
+ offline: 'text-gray-400 bg-gray-100',
23
+ };
24
+
25
+ const getIcon = () => {
26
+ switch(title?.toLowerCase()) {
27
+ case 'active users': return <Users size={20} />;
28
+ case 'revenue': return <DollarSign size={20} />;
29
+ case 'sales': return <CreditCard size={20} />;
30
+ default: return <Activity size={20} />;
31
+ }
32
+ };
33
+
34
+ return (
35
+ <Card className="p-6 flex flex-col justify-between h-full border-border/60 hover:shadow-md transition-all">
36
+ <div className="flex justify-between items-start mb-4">
37
+ <div>
38
+ <p className="text-sm font-medium text-muted-foreground">{title}</p>
39
+ <h3 className="text-2xl font-bold mt-1 tracking-tight">{value || '--'}</h3>
40
+ </div>
41
+ <div className={`p-2 rounded-lg ${statusColors[status] || statusColors.neutral}`}>
42
+ {getIcon()}
43
+ </div>
44
+ </div>
45
+
46
+ {trend && (
47
+ <div className="flex items-center gap-1 text-xs font-medium">
48
+ {trend.startsWith('+') ? (
49
+ <ArrowUpRight size={14} className="text-green-600" />
50
+ ) : (
51
+ <ArrowDownRight size={14} className="text-red-600" />
52
+ )}
53
+ <span className={trend.startsWith('+') ? 'text-green-600' : 'text-red-600'}>
54
+ {trend}
55
+ </span>
56
+ <span className="text-muted-foreground ml-1">from last month</span>
57
+ </div>
58
+ )}
59
+ </Card>
60
+ );
61
+ };
@@ -1,4 +1,6 @@
1
- import type { AppSpecification } from '../types/schema';
1
+ import type { AppSpecification } from '../engine/validation/schema';
2
+
3
+
2
4
 
3
5
  export const appManifest: AppSpecification = {
4
6
  meta: {
@@ -0,0 +1,69 @@
1
+ import React from 'react';
2
+ // ✅ 1. Import the Master Registry from the UI Library (Tier 1: Atoms)
3
+ // This instantly pulls in Button, Card, Inputs, Layouts, Navigation, etc.
4
+ import { AUTO_REGISTRY } from '@ramme-io/ui';
5
+
6
+ // ✅ 2. Import Local "Smart Blocks" (Tier 2: Logic)
7
+ // These exist only in the App (Starter), not the UI library.
8
+ import { SmartTable } from '../features/datagrid/SmartTable';
9
+ import { SmartChart } from '../features/visualizations/SmartChart';
10
+
11
+ // ✅ 3. MERGE EVERYTHING
12
+ export const COMPONENT_REGISTRY: Record<string, React.FC<any>> = {
13
+ // A. The Entire UI Library (~50+ components)
14
+ ...AUTO_REGISTRY,
15
+
16
+ // B. The Smart Blocks (Data-Connected)
17
+ SmartTable,
18
+ SmartChart,
19
+
20
+ // C. Legacy Aliases (For older AI prompts/manifests)
21
+ 'smart_table': SmartTable,
22
+ 'smart_chart': SmartChart,
23
+ 'stat_card': AUTO_REGISTRY['StatCard'],
24
+ 'chart_line': AUTO_REGISTRY['LineChart'],
25
+ 'chart_bar': AUTO_REGISTRY['BarChart'],
26
+ 'chart_pie': AUTO_REGISTRY['PieChart'],
27
+ };
28
+
29
+ // --- COMPONENT RESOLVER ENGINE ---
30
+ export const getComponent = (name: string) => {
31
+ // 1. Normalize the key to handle case-insensitivity and snake_case
32
+ // e.g. "page_header" -> "PageHeader", "button" -> "Button"
33
+ const normalizedName = name.replace(/_/g, '').toLowerCase();
34
+
35
+ // 2. Lookup Strategy
36
+ // We check the exact name, then the lowercase version, then the normalized version
37
+ const Component =
38
+ COMPONENT_REGISTRY[name] ||
39
+ COMPONENT_MAP_LOWER[name.toLowerCase()] ||
40
+ COMPONENT_MAP_NORMALIZED[normalizedName];
41
+
42
+ // 3. Safety Net (Ghost Placeholder)
43
+ if (!Component) {
44
+ console.warn(`[Registry] ❌ Unknown component: "${name}"`);
45
+
46
+ return ({ ...props }) => (
47
+ <div className="p-4 border-2 border-dashed border-red-200 bg-red-50 rounded-lg flex flex-col items-center justify-center text-red-400 min-h-[100px] h-full w-full animate-in fade-in">
48
+ <span className="text-xs font-mono font-bold uppercase tracking-wider">{name}</span>
49
+ <span className="text-[10px] mt-1 opacity-75">Component Missing</span>
50
+ {/* Hidden debug data for developers */}
51
+ <div className="hidden">{JSON.stringify(props)}</div>
52
+ </div>
53
+ );
54
+ }
55
+ return Component;
56
+ };
57
+
58
+ // --- OPTIMIZATION: PRE-CALCULATED LOOKUP MAPS ---
59
+ // We generate these once on startup so we don't map/reduce on every render.
60
+
61
+ const COMPONENT_MAP_LOWER = Object.keys(COMPONENT_REGISTRY).reduce((acc, key) => {
62
+ acc[key.toLowerCase()] = COMPONENT_REGISTRY[key];
63
+ return acc;
64
+ }, {} as Record<string, React.FC<any>>);
65
+
66
+ const COMPONENT_MAP_NORMALIZED = Object.keys(COMPONENT_REGISTRY).reduce((acc, key) => {
67
+ acc[key.replace(/_/g, '').toLowerCase()] = COMPONENT_REGISTRY[key];
68
+ return acc;
69
+ }, {} as Record<string, React.FC<any>>);
@@ -5,7 +5,7 @@
5
5
  * This is the central manifest for all GLOBAL, shared navigation elements.
6
6
  * Corrected paths to point within the /settings layout.
7
7
  */
8
- import type { ManifestLink } from '../core/manifest-types';
8
+ import type { ManifestLink } from '../engine/types/manifest-types';
9
9
 
10
10
  interface AppManifest {
11
11
  userMenu: ManifestLink[];