@donotdev/cli 0.0.6 → 0.0.8

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 (87) hide show
  1. package/README.md +3 -18
  2. package/dependencies-matrix.json +64 -121
  3. package/dist/bin/commands/build.js +173 -161
  4. package/dist/bin/commands/bump.js +181 -156
  5. package/dist/bin/commands/cacheout.js +188 -171
  6. package/dist/bin/commands/create-app.js +213 -156
  7. package/dist/bin/commands/create-project.js +183 -154
  8. package/dist/bin/commands/deploy.js +491 -477
  9. package/dist/bin/commands/dev.js +176 -160
  10. package/dist/bin/commands/emu.js +181 -165
  11. package/dist/bin/commands/format.js +191 -174
  12. package/dist/bin/commands/lint.js +191 -171
  13. package/dist/bin/commands/preview.js +177 -161
  14. package/dist/bin/commands/sync-secrets.js +172 -158
  15. package/dist/bin/commands/wai.d.ts +11 -0
  16. package/dist/bin/commands/wai.d.ts.map +1 -0
  17. package/dist/bin/commands/wai.js +12 -0
  18. package/dist/bin/commands/wai.js.map +1 -0
  19. package/dist/bin/dndev.js +24 -24
  20. package/dist/bin/donotdev.js +24 -24
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +661 -669
  24. package/dist/index.js.map +1 -1
  25. package/package.json +1 -1
  26. package/templates/app-demo/src/config/app.ts.example +12 -0
  27. package/templates/app-next/src/config/app.ts.example +75 -48
  28. package/templates/app-vite/index.html.example +71 -37
  29. package/templates/app-vite/src/config/app.ts.example +75 -47
  30. package/templates/app-vite/src/pages/FormPageExample.tsx.example +152 -0
  31. package/templates/app-vite/src/pages/HomePage.tsx.example +81 -134
  32. package/templates/app-vite/src/pages/ListPageExample.tsx.example +88 -0
  33. package/templates/functions-firebase/build.mjs.example +8 -1
  34. package/templates/functions-firebase/functions-firebase/build.mjs.example +8 -1
  35. package/templates/functions-firebase/functions-firebase/src/index.ts.example +19 -25
  36. package/templates/functions-firebase/functions.config.js.example +35 -0
  37. package/templates/root-consumer/entities/ExampleEntity.ts.example +223 -0
  38. package/templates/root-consumer/entities/demo.ts.example +576 -0
  39. package/templates/root-consumer/entities/index.ts.example +15 -0
  40. package/templates/root-consumer/eslint.config.js.example +2 -80
  41. package/templates/root-consumer/guides/{AGENT_START_HERE.md.example → dndev/AGENT_START_HERE.md.example} +22 -0
  42. package/templates/root-consumer/guides/dndev/COMPONENTS_CRUD.md.example +231 -0
  43. package/templates/root-consumer/guides/{SETUP_AUTH.md.example → dndev/SETUP_AUTH.md.example} +30 -0
  44. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +539 -0
  45. package/templates/root-consumer/guides/dndev/SETUP_FUNCTIONS.md.example +116 -0
  46. package/templates/root-consumer/guides/{SETUP_I18N.md.example → dndev/SETUP_I18N.md.example} +46 -0
  47. package/templates/root-consumer/guides/wai-way/WAI_WAY_CLI.md.example +404 -0
  48. package/templates/root-consumer/guides/wai-way/agents/architect.md.example +78 -0
  49. package/templates/root-consumer/guides/wai-way/agents/builder.md.example +87 -0
  50. package/templates/root-consumer/guides/wai-way/agents/extractor.md.example +325 -0
  51. package/templates/root-consumer/guides/wai-way/agents/polisher.md.example +100 -0
  52. package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +281 -0
  53. package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +77 -0
  54. package/templates/root-consumer/guides/wai-way/blueprints/2_entities.md.example +104 -0
  55. package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +124 -0
  56. package/templates/root-consumer/guides/wai-way/blueprints/4_configure.md.example +165 -0
  57. package/templates/root-consumer/guides/wai-way/context_map.json.example +95 -0
  58. package/templates/root-consumer/guides/wai-way/entity_patterns.md.example +840 -0
  59. package/templates/root-consumer/guides/wai-way/page_patterns.md.example +686 -0
  60. package/templates/root-consumer/guides/wai-way/presets_guide.md.example +217 -0
  61. package/templates/root-consumer/guides/wai-way/spec_template.md.example +312 -0
  62. package/templates/functions-firebase/functions-firebase/src/crud/createEntity.ts.example +0 -19
  63. package/templates/functions-firebase/functions-firebase/src/crud/deleteEntity.ts.example +0 -14
  64. package/templates/functions-firebase/functions-firebase/src/crud/getEntity.ts.example +0 -14
  65. package/templates/functions-firebase/functions-firebase/src/crud/index.ts.example +0 -12
  66. package/templates/functions-firebase/functions-firebase/src/crud/listEntities.ts.example +0 -14
  67. package/templates/functions-firebase/functions-firebase/src/crud/updateEntity.ts.example +0 -14
  68. package/templates/root-consumer/guides/COMPONENTS_CRUD.md.example +0 -70
  69. package/templates/root-consumer/guides/SETUP_CRUD.md.example +0 -1244
  70. package/templates/root-consumer/guides/SETUP_FUNCTIONS.md.example +0 -114
  71. /package/templates/root-consumer/guides/{COMPONENTS_ADV.md.example → dndev/COMPONENTS_ADV.md.example} +0 -0
  72. /package/templates/root-consumer/guides/{COMPONENTS_ATOMIC.md.example → dndev/COMPONENTS_ATOMIC.md.example} +0 -0
  73. /package/templates/root-consumer/guides/{COMPONENTS_UI.md.example → dndev/COMPONENTS_UI.md.example} +0 -0
  74. /package/templates/root-consumer/guides/{ENV_SETUP.md.example → dndev/ENV_SETUP.md.example} +0 -0
  75. /package/templates/root-consumer/guides/{INDEX.md.example → dndev/INDEX.md.example} +0 -0
  76. /package/templates/root-consumer/guides/{SETUP_APP_CONFIG.md.example → dndev/SETUP_APP_CONFIG.md.example} +0 -0
  77. /package/templates/root-consumer/guides/{SETUP_BILLING.md.example → dndev/SETUP_BILLING.md.example} +0 -0
  78. /package/templates/root-consumer/guides/{SETUP_LAYOUTS.md.example → dndev/SETUP_LAYOUTS.md.example} +0 -0
  79. /package/templates/root-consumer/guides/{SETUP_OAUTH.md.example → dndev/SETUP_OAUTH.md.example} +0 -0
  80. /package/templates/root-consumer/guides/{SETUP_PAGES.md.example → dndev/SETUP_PAGES.md.example} +0 -0
  81. /package/templates/root-consumer/guides/{SETUP_PWA.md.example → dndev/SETUP_PWA.md.example} +0 -0
  82. /package/templates/root-consumer/guides/{SETUP_THEMES.md.example → dndev/SETUP_THEMES.md.example} +0 -0
  83. /package/templates/root-consumer/guides/{USE_ROUTING.md.example → dndev/USE_ROUTING.md.example} +0 -0
  84. /package/templates/root-consumer/guides/{advanced → dndev/advanced}/APP_CHECK.md.example +0 -0
  85. /package/templates/root-consumer/guides/{advanced → dndev/advanced}/COOKIE_REFERENCE.md.example +0 -0
  86. /package/templates/root-consumer/guides/{advanced → dndev/advanced}/EMULATORS.md.example +0 -0
  87. /package/templates/root-consumer/guides/{advanced → dndev/advanced}/VERSION_CONTROL.md.example +0 -0
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAE5B;;;;;GAKG;AAEH,qFAAqF;AACrF,OAAO,EACL,SAAS,EACT,aAAa,EACb,MAAM,EACN,IAAI,EACJ,GAAG,EACH,KAAK,EACL,OAAO,EACP,GAAG,EACH,QAAQ,EACR,WAAW,EACX,MAAM,GACP,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAE5B;;;;;GAKG;AAEH,qFAAqF;AACrF,OAAO,EACL,SAAS,EACT,aAAa,EACb,MAAM,EACN,GAAG,EACH,KAAK,EACL,OAAO,EACP,GAAG,EACH,QAAQ,EACR,WAAW,EACX,MAAM,GACP,MAAM,mBAAmB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@donotdev/cli",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Command-line interface for DoNotDev Framework",
5
5
  "type": "module",
6
6
  "private": false,
@@ -53,4 +53,16 @@ export const appConfig: AppConfig = {
53
53
  // Optional: Enable debug tools in development
54
54
  // debug: true,
55
55
  },
56
+ // Optional: Override query cache defaults
57
+ // Framework defaults (infinite cache - cost-optimized):
58
+ // - staleTime: Infinity (data never becomes stale)
59
+ // - refetchOnWindowFocus: false (no auto-refetch on focus)
60
+ // - refetchOnReconnect: false (no auto-refetch on reconnect)
61
+ // This minimizes API costs and is ideal for single-admin apps with manual refresh buttons.
62
+ // Uncomment below to enable auto-refetch behavior:
63
+ // query: {
64
+ // staleTime: 1000 * 60 * 5, // 5 minutes - data becomes stale after 5 minutes
65
+ // refetchOnWindowFocus: true, // Automatically refetch when window regains focus
66
+ // refetchOnReconnect: true, // Automatically refetch when network reconnects
67
+ // },
56
68
  };
@@ -1,75 +1,102 @@
1
1
  /**
2
- * @fileoverview Application configuration
3
- * @description Defines application metadata and feature flags
4
- * @version 0.0.1
5
- * @since 0.0.1
6
- * @author AMBROISE PARK Consulting
2
+ * @fileoverview Application Configuration
3
+ *
4
+ * THIS FILE IS YOUR MAIN CONFIGURATION. Update the values below.
5
+ *
6
+ * QUICK START:
7
+ * 1. Set APP_NAME and APP_SHORT_NAME
8
+ * 2. Choose your preset (see guide below)
9
+ * 3. Configure footer links
10
+ * 4. Run `bun dev` - everything else is automatic
7
11
  */
8
12
 
9
13
  import type { AppConfig } from '@donotdev/core';
10
14
 
11
- /**
12
- * Application name constant
13
- *
14
- * @version 0.0.1
15
- * @since 0.0.1
16
- * @author AMBROISE PARK Consulting
17
- */
18
- export const APP_NAME = '{{appName}}';
15
+ // ============================================================================
16
+ // APP IDENTITY - Update these values
17
+ // ============================================================================
19
18
 
20
- /**
21
- * Application short name constant
22
- *
23
- * @version 0.0.1
24
- * @since 0.0.1
25
- * @author AMBROISE PARK Consulting
26
- */
19
+ export const APP_NAME = '{{appName}}';
27
20
  export const APP_SHORT_NAME = '{{appShortName}}';
28
-
29
- /**
30
- * Application description constant
31
- *
32
- * @version 0.0.1
33
- * @since 0.0.1
34
- * @author AMBROISE PARK Consulting
35
- */
36
21
  export const APP_DESCRIPTION = 'Built with DoNotDev Framework';
37
22
 
38
- /**
39
- * Application configuration object
40
- *
41
- * @version 0.0.1
42
- * @since 0.0.1
43
- * @author AMBROISE PARK Consulting
44
- */
23
+ // ============================================================================
24
+ // MAIN CONFIGURATION
25
+ // ============================================================================
26
+
45
27
  export const appConfig: AppConfig = {
46
28
  app: {
47
29
  name: APP_NAME,
48
30
  shortName: APP_SHORT_NAME,
49
31
  description: APP_DESCRIPTION,
50
- // Optional: Configure footer legal links
51
- // Remove any links you don't need
32
+ // url: 'https://yourapp.com', // Uncomment for production
33
+
34
+ // Footer legal links - remove any you don't need
52
35
  footer: {
53
36
  legalLinks: [
54
37
  { path: '#cookie-settings', label: 'footer.legal.cookieSettings' },
55
38
  { path: '/legal/privacy', label: 'footer.legal.privacyPolicy' },
56
39
  { path: '/legal/terms', label: 'footer.legal.termsOfService' },
57
- // Add more links as needed:
58
- // { path: '/legal/legal-notice', label: 'footer.legal.legalNotice' },
59
- // { path: '/license', label: 'License' },
40
+ // { path: '/legal/notice', label: 'footer.legal.legalNotice' },
60
41
  ],
61
42
  },
62
43
  },
63
- preset: 'docs', // 'landing' | 'admin' | 'moolti' | 'docs' | 'blog' | 'game' | 'plain'
44
+
45
+ // ==========================================================================
46
+ // PRESET GUIDE - Choose your layout
47
+ // ==========================================================================
48
+ //
49
+ // 'landing' → Marketing site. Full-width sections, centered content, no sidebar.
50
+ // Best for: Homepage, product pages, pricing, landing pages.
51
+ //
52
+ // 'admin' → Dashboard app. Collapsible sidebar, header with user menu.
53
+ // Best for: Admin panels, CRM, internal tools, CRUD apps.
54
+ //
55
+ // 'moolti' → Multi-panel. Left sidebar nav, optional right context sidebar.
56
+ // Best for: Complex apps with nested navigation, settings panels.
57
+ //
58
+ // 'docs' → Documentation. Left sidebar TOC, right sidebar on-page nav.
59
+ // Best for: Documentation sites, knowledge bases, help centers.
60
+ //
61
+ // 'blog' → Blog layout. Wide content area, optional category sidebar.
62
+ // Best for: Blog, news, articles, content-heavy sites.
63
+ //
64
+ // 'game' → Fullscreen. Minimal chrome, focus on content area.
65
+ // Best for: Games, immersive experiences, presentations.
66
+ //
67
+ // 'plain' → No layout. Just your pages, you handle everything.
68
+ // Best for: Custom layouts, embedded widgets, special cases.
69
+ //
70
+ preset: 'docs',
71
+
72
+ // ==========================================================================
73
+ // FEATURES - Uncomment to enable
74
+ // ==========================================================================
64
75
  features: {
65
- // Optional: Enable debug tools in development
66
- // debug: true,
76
+ // debug: true, // Enable debug tools in development
67
77
  },
68
- // Optional: Override auth routes
78
+
79
+ // ==========================================================================
80
+ // AUTH CONFIG - Uncomment to customize
81
+ // ==========================================================================
69
82
  // auth: {
70
- // authRoute: '/signin',
71
- // roleRoute: '/403',
72
- // tierRoute: '/pricing',
83
+ // authRoute: '/signin', // Redirect when auth required
84
+ // roleRoute: '/403', // Redirect when role insufficient
85
+ // tierRoute: '/pricing', // Redirect when subscription required
86
+ // profilePath: '/profile', // Profile page path (undefined to hide)
87
+ // authMenuItems: [ // Custom menu items for logged-in users
88
+ // { path: '/dashboard', label: 'Dashboard' },
89
+ // ],
73
90
  // },
74
- };
75
91
 
92
+ // ==========================================================================
93
+ // QUERY CACHE - Uncomment to enable auto-refetch
94
+ // ==========================================================================
95
+ // Default: Infinite cache (cost-optimized, manual refresh)
96
+ // Uncomment for auto-refetch behavior:
97
+ // query: {
98
+ // staleTime: 1000 * 60 * 5, // 5 minutes
99
+ // refetchOnWindowFocus: true,
100
+ // refetchOnReconnect: true,
101
+ // },
102
+ };
@@ -16,6 +16,9 @@
16
16
  <!-- ✅ PWA: Manifest link (if exists) -->
17
17
  <link rel="manifest" href="/manifest.json" />
18
18
 
19
+ <!-- ✅ PERFORMANCE: Load fonts early to avoid preload warnings -->
20
+ <link rel="stylesheet" href="/fonts/fonts.css" />
21
+
19
22
  <!-- ✅ PERFORMANCE: Preconnect to external domains (OAuth providers) -->
20
23
  <!-- GitHub OAuth -->
21
24
  <link rel="preconnect" href="https://github.com">
@@ -30,16 +33,17 @@
30
33
  <title>Loading...</title>
31
34
  <meta name="description" content="Modern web application powered by DoNotDev" />
32
35
 
33
- <!-- ✅ PERFORMANCE: Critical font preloads (loads before CSS) -->
34
- <!-- Only preload fonts with font-display: swap (not optional) -->
35
- <!-- Example: <link rel="preload" href="/fonts/YourFont.woff2" as="font" type="font/woff2" crossorigin="anonymous"> -->
36
36
 
37
37
  <!-- ✅ PERFORMANCE: Critical CSS inlined here by build -->
38
38
  <style>
39
39
  /* Critical above-the-fold styles */
40
+ html, body {
41
+ margin: 0;
42
+ padding: 0;
43
+ box-sizing: border-box;
44
+ }
40
45
  body {
41
- margin: 0;
42
- font-family: var(--font-family, ui-monospace, 'SF Mono', 'Cascadia Code', 'Roboto Mono', Consolas, Monaco, 'Liberation Mono', monospace);
46
+ font-family: 'Inter', var(--font-family, ui-sans-serif, system-ui, -apple-system, sans-serif);
43
47
  line-height: 1.5;
44
48
  -webkit-font-smoothing: antialiased;
45
49
  -moz-osx-font-smoothing: grayscale;
@@ -55,54 +59,85 @@
55
59
  /* Critical shell loader styles - pure CSS, instant render */
56
60
  #shell-loader {
57
61
  position: fixed;
58
- top: 0;
59
- left: 0;
60
- width: 100%;
61
- height: 100%;
62
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
62
+ inset: 0;
63
+ background: #000000;
63
64
  display: flex;
64
65
  align-items: center;
65
66
  justify-content: center;
66
67
  z-index: 9999;
67
68
  opacity: 1;
68
69
  transition: opacity 0.3s ease-out;
70
+ will-change: opacity;
71
+ /* Isolate from framework CSS */
72
+ margin: 0;
73
+ padding: 0;
74
+ box-sizing: border-box;
69
75
  }
70
76
  #shell-loader.shell-loader--fading {
71
77
  opacity: 0;
78
+ pointer-events: none;
72
79
  }
73
80
  .shell-loader__content {
74
81
  text-align: center;
75
82
  color: white;
76
- font-family: ui-monospace, 'SF Mono', 'Cascadia Code', 'Roboto Mono', Consolas, Monaco, 'Liberation Mono', monospace !important;
77
- font-size: 2.4em;
78
- font-weight: 500;
79
- line-height: 1.8;
83
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
84
+ width: 100%;
85
+ max-width: 500px;
86
+ /* Prevent layout shifts from framework CSS */
87
+ margin: 0;
88
+ padding: 0;
89
+ box-sizing: border-box;
90
+ line-height: 1.2;
80
91
  }
81
92
  .shell-loader__brand {
82
93
  display: block;
94
+ font-size: clamp(3rem, 10vw, 5rem);
95
+ font-weight: 800;
96
+ letter-spacing: -0.05em;
97
+ margin: 0 0 1rem 0;
98
+ padding: 0;
99
+ box-sizing: border-box;
83
100
  }
101
+ /* ECG Waveform Animation - stroke-dasharray (performant, cross-browser, standard SVG technique) */
84
102
  .shell-loader__dots {
85
- display: inline-flex;
86
- align-items: center;
87
- gap: 12px;
88
- }
89
- .shell-loader__dots span {
90
- display: inline-block;
91
- width: 12px;
92
- height: 12px;
93
- border-radius: 50%;
94
- background: white;
95
- animation: blink 1.4s infinite;
103
+ display: block;
104
+ width: 300px;
105
+ height: 60px;
106
+ margin: 0 auto;
107
+ padding: 0;
108
+ box-sizing: border-box;
96
109
  }
97
- .shell-loader__dots span:nth-child(1) { animation-delay: 0s; }
98
- .shell-loader__dots span:nth-child(2) { animation-delay: 0.2s; }
99
- .shell-loader__dots span:nth-child(3) { animation-delay: 0.4s; }
100
- .shell-loader__content > :last-child {
110
+ .shell-loader__dots svg {
111
+ width: 100%;
112
+ height: 100%;
101
113
  display: block;
102
114
  }
103
- @keyframes blink {
104
- 0%, 80%, 100% { opacity: 0.3; }
105
- 40% { opacity: 1; }
115
+ .shell-loader__dots path {
116
+ stroke: #667eea;
117
+ stroke-width: 3;
118
+ fill: none;
119
+ stroke-linecap: round;
120
+ stroke-linejoin: round;
121
+ stroke-dasharray: 400;
122
+ stroke-dashoffset: 400;
123
+ animation: ecg-draw 2s linear infinite;
124
+ }
125
+ @keyframes ecg-draw {
126
+ 0% {
127
+ stroke-dashoffset: 400;
128
+ opacity: 0;
129
+ }
130
+ 10% {
131
+ opacity: 1;
132
+ }
133
+ 70% {
134
+ stroke-dashoffset: 0;
135
+ opacity: 1;
136
+ }
137
+ 90%, 100% {
138
+ stroke-dashoffset: 0;
139
+ opacity: 0;
140
+ }
106
141
  }
107
142
  </style>
108
143
  </head>
@@ -113,11 +148,10 @@
113
148
  <div class="shell-loader__content">
114
149
  <span class="shell-loader__brand">DoNotDev</span>
115
150
  <span class="shell-loader__dots">
116
- <span></span>
117
- <span></span>
118
- <span></span>
151
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 60" preserveAspectRatio="xMidYMid meet">
152
+ <path d="M0,30 L100,30 L110,20 L120,30 L130,30 L140,5 L150,55 L160,30 L175,30 L190,20 L205,30 L300,30" />
153
+ </svg>
119
154
  </span>
120
- <span>is loading</span>
121
155
  </div>
122
156
  </div>
123
157
 
@@ -127,4 +161,4 @@
127
161
  <!-- ✅ PERFORMANCE: Module script with proper attributes -->
128
162
  <script type="module" src="/src/main.tsx"></script>
129
163
  </body>
130
- </html>
164
+ </html>
@@ -1,75 +1,103 @@
1
1
  /**
2
- * @fileoverview Application configuration
3
- * @description Defines application metadata and feature flags
4
- * @version 0.0.1
5
- * @since 0.0.1
6
- * @author AMBROISE PARK Consulting
2
+ * @fileoverview Application Configuration
3
+ *
4
+ * THIS FILE IS YOUR MAIN CONFIGURATION. Update the values below.
5
+ *
6
+ * QUICK START:
7
+ * 1. Set APP_NAME and APP_SHORT_NAME
8
+ * 2. Choose your preset (see guide below)
9
+ * 3. Configure footer links
10
+ * 4. Run `bun dev` - everything else is automatic
7
11
  */
8
12
 
9
13
  import type { AppConfig } from '@donotdev/core';
10
14
 
11
- /**
12
- * Application name constant
13
- *
14
- * @version 0.0.1
15
- * @since 0.0.1
16
- * @author AMBROISE PARK Consulting
17
- */
18
- export const APP_NAME = '{{appName}}';
15
+ // ============================================================================
16
+ // APP IDENTITY - Update these values
17
+ // ============================================================================
19
18
 
20
- /**
21
- * Application short name constant
22
- *
23
- * @version 0.0.1
24
- * @since 0.0.1
25
- * @author AMBROISE PARK Consulting
26
- */
19
+ export const APP_NAME = '{{appName}}';
27
20
  export const APP_SHORT_NAME = '{{appShortName}}';
28
-
29
- /**
30
- * Application description constant
31
- *
32
- * @version 0.0.1
33
- * @since 0.0.1
34
- * @author AMBROISE PARK Consulting
35
- */
36
21
  export const APP_DESCRIPTION = 'Built with DoNotDev Framework';
37
22
 
38
- /**
39
- * Application configuration object
40
- *
41
- * @version 0.0.1
42
- * @since 0.0.1
43
- * @author AMBROISE PARK Consulting
44
- */
23
+ // ============================================================================
24
+ // MAIN CONFIGURATION
25
+ // ============================================================================
26
+
45
27
  export const appConfig: AppConfig = {
46
28
  app: {
47
29
  name: APP_NAME,
48
30
  shortName: APP_SHORT_NAME,
49
31
  description: APP_DESCRIPTION,
50
- // Optional: Configure footer legal links
51
- // Remove any links you don't need
32
+ // url: 'https://yourapp.com', // Uncomment for production
33
+
34
+ // Footer legal links - remove any you don't need
52
35
  footer: {
53
36
  legalLinks: [
54
37
  { path: '#cookie-settings', label: 'footer.legal.cookieSettings' },
55
38
  { path: '/legal/privacy', label: 'footer.legal.privacyPolicy' },
56
39
  { path: '/legal/terms', label: 'footer.legal.termsOfService' },
57
- // Add more links as needed:
58
- // { path: '/legal/legal-notice', label: 'footer.legal.legalNotice' },
59
- // { path: '/license', label: 'License' },
40
+ // { path: '/legal/notice', label: 'footer.legal.legalNotice' },
60
41
  ],
61
42
  },
62
43
  },
63
- preset: 'landing', // 'landing' | 'admin' | 'moolti' | 'docs' | 'blog' | 'game' | 'plain'
44
+
45
+ // ==========================================================================
46
+ // PRESET GUIDE - Choose your layout
47
+ // ==========================================================================
48
+ //
49
+ // 'landing' → Marketing site. Full-width sections, centered content, no sidebar.
50
+ // Best for: Homepage, product pages, pricing, landing pages.
51
+ //
52
+ // 'admin' → Dashboard app. Collapsible sidebar, header with user menu.
53
+ // Best for: Admin panels, CRM, internal tools, CRUD apps.
54
+ //
55
+ // 'moolti' → Multi-panel. Left sidebar nav, optional right context sidebar.
56
+ // Best for: Complex apps with nested navigation, settings panels.
57
+ //
58
+ // 'docs' → Documentation. Left sidebar TOC, right sidebar on-page nav.
59
+ // Best for: Documentation sites, knowledge bases, help centers.
60
+ //
61
+ // 'blog' → Blog layout. Wide content area, optional category sidebar.
62
+ // Best for: Blog, news, articles, content-heavy sites.
63
+ //
64
+ // 'game' → Fullscreen. Minimal chrome, focus on content area.
65
+ // Best for: Games, immersive experiences, presentations.
66
+ //
67
+ // 'plain' → No layout. Just your pages, you handle everything.
68
+ // Best for: Custom layouts, embedded widgets, special cases.
69
+ //
70
+ preset: 'landing',
71
+
72
+ // ==========================================================================
73
+ // FEATURES - Uncomment to enable
74
+ // ==========================================================================
64
75
  features: {
65
- // Optional: Enable debug tools in development
66
- // debug: true,
76
+ // debug: true, // Enable debug tools in development
67
77
  },
68
- // Optional: Override auth routes
78
+
79
+ // ==========================================================================
80
+ // AUTH CONFIG - Uncomment to customize
81
+ // ==========================================================================
69
82
  // auth: {
70
- // authRoute: '/signin',
71
- // roleRoute: '/403',
72
- // tierRoute: '/pricing',
83
+ // authRoute: '/signin', // Redirect when auth required
84
+ // roleRoute: '/403', // Redirect when role insufficient
85
+ // tierRoute: '/pricing', // Redirect when subscription required
86
+ // profilePath: '/profile', // Profile page path (undefined to hide)
87
+ // authMenuItems: [ // Custom menu items for logged-in users
88
+ // { path: '/dashboard', label: 'Dashboard' },
89
+ // ],
90
+ // },
91
+
92
+ // ==========================================================================
93
+ // QUERY CACHE - Uncomment to enable auto-refetch
94
+ // ==========================================================================
95
+ // Default: Infinite cache (cost-optimized, manual refresh)
96
+ // Uncomment for auto-refetch behavior:
97
+ // query: {
98
+ // staleTime: 1000 * 60 * 5, // 5 minutes
99
+ // refetchOnWindowFocus: true,
100
+ // refetchOnReconnect: true,
73
101
  // },
74
102
  };
75
103
 
@@ -0,0 +1,152 @@
1
+ /**
2
+ * @fileoverview Example CRUD Form Page (Create/Edit)
3
+ *
4
+ * COPY THIS FILE and rename (e.g., ProductPage.tsx, CustomerPage.tsx)
5
+ *
6
+ * HOW IT WORKS:
7
+ * 1. Route: /products/:id (edit) or /products/new (create)
8
+ * 2. EntityFormRenderer generates form from entity fields
9
+ * 3. useCrud provides get/add/update operations
10
+ * 4. Optimistic updates - navigation is instant, sync happens in background
11
+ */
12
+
13
+ import { useEffect, useState } from 'react';
14
+
15
+ import { Section, Button, Alert } from '@donotdev/components';
16
+ import { EntityFormRenderer, useCrud } from '@donotdev/crud';
17
+ import { useTranslation } from '@donotdev/core';
18
+ import type { PageMeta } from '@donotdev/core';
19
+ import { PageContainer, Link, useNavigate } from '@donotdev/ui';
20
+
21
+ // Import your entity from root-level entities folder
22
+ // import { productEntity } from 'entities/Product';
23
+
24
+ // Placeholder - replace with your entity import
25
+ const productEntity = null as any;
26
+
27
+ // Helper to get route param - replace with your routing solution
28
+ const useParam = (name: string) => {
29
+ // For react-router: const { id } = useParams();
30
+ // For TanStack Router: const { id } = Route.useParams();
31
+ return 'new'; // Placeholder
32
+ };
33
+
34
+ // ============================================================================
35
+ // PAGE METADATA
36
+ // ============================================================================
37
+
38
+ export const NAMESPACE = 'product';
39
+
40
+ export const meta: PageMeta = {
41
+ namespace: NAMESPACE,
42
+ route: '/products/:id',
43
+ auth: { required: true, role: 'admin' },
44
+ hideFromMenu: true, // Don't show in navigation (accessed via list page)
45
+ };
46
+
47
+ // ============================================================================
48
+ // PAGE COMPONENT
49
+ // ============================================================================
50
+
51
+ export default function ProductPage() {
52
+ const { t } = useTranslation(NAMESPACE);
53
+ const id = useParam('id');
54
+ const navigate = useNavigate();
55
+ const isNew = id === 'new';
56
+
57
+ // useCrud provides CRUD operations with optimistic updates
58
+ // backend: 'functions' uses Cloud Functions, 'firestore' uses direct Firestore
59
+ const { get, add, update, error } = useCrud(productEntity, { backend: 'functions' });
60
+ const [formData, setFormData] = useState<any>(null);
61
+
62
+ // ==========================================================================
63
+ // FETCH EXISTING DATA (edit mode only)
64
+ // ==========================================================================
65
+ useEffect(() => {
66
+ if (!isNew && id) {
67
+ get(id).then((data) => {
68
+ if (data) setFormData(data);
69
+ });
70
+ }
71
+ }, [id, isNew, get]);
72
+
73
+ // ==========================================================================
74
+ // FORM SUBMISSION - Optimistic Update Pattern
75
+ // ==========================================================================
76
+ const handleSubmit = async (data: any) => {
77
+ // OPTIMISTIC UPDATE: Fire and forget!
78
+ // We don't await the backend. We navigate immediately.
79
+ // CrudStore handles background sync and optimistic cache update.
80
+
81
+ if (isNew) {
82
+ add(data); // No await - fires in background
83
+ } else if (id) {
84
+ update(id, data); // No await - fires in background
85
+ }
86
+
87
+ // Instant navigation - feels incredibly fast
88
+ navigate('/products');
89
+ };
90
+
91
+ // ==========================================================================
92
+ // ERROR STATE
93
+ // ==========================================================================
94
+ if (!isNew && error) {
95
+ return (
96
+ <PageContainer>
97
+ <Section title={t('error')}>
98
+ <Alert variant="error" description={t('failedToLoadData')} />
99
+ <Link path="/products">
100
+ <Button variant="outline">{t('backToList')}</Button>
101
+ </Link>
102
+ </Section>
103
+ </PageContainer>
104
+ );
105
+ }
106
+
107
+ // ==========================================================================
108
+ // RENDER FORM
109
+ // ==========================================================================
110
+ return (
111
+ <PageContainer>
112
+ <Section
113
+ gridCols={[1, 1, 2, 2]} // Responsive: 1 col mobile, 2 cols desktop
114
+ title={isNew ? t('addNew') : t('edit')}
115
+ >
116
+ {isNew ? (
117
+ // CREATE MODE
118
+ <EntityFormRenderer
119
+ entity={productEntity}
120
+ operation="create"
121
+ onSubmit={handleSubmit}
122
+ defaultValues={{ status: 'draft' }} // Initial values for new items
123
+ submitText={t('create')}
124
+ />
125
+ ) : (
126
+ // EDIT MODE
127
+ <EntityFormRenderer
128
+ entity={productEntity}
129
+ operation="edit"
130
+ onSubmit={handleSubmit}
131
+ defaultValues={formData} // Loaded data
132
+ submitText={t('update')}
133
+ />
134
+ )}
135
+ </Section>
136
+ </PageContainer>
137
+ );
138
+ }
139
+
140
+ // ============================================================================
141
+ // i18n KEYS NEEDED (add to locales/product_en.json)
142
+ // ============================================================================
143
+ //
144
+ // {
145
+ // "addNew": "Add New Product",
146
+ // "edit": "Edit Product",
147
+ // "create": "Create Product",
148
+ // "update": "Update Product",
149
+ // "error": "Error",
150
+ // "failedToLoadData": "Failed to load product data",
151
+ // "backToList": "Back to Products"
152
+ // }