@contractspec/example.saas-boilerplate 3.7.5 → 3.7.7

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 (115) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/AGENTS.md +50 -27
  3. package/CHANGELOG.md +16 -0
  4. package/README.md +64 -144
  5. package/dist/billing/billing.event.js +1 -1
  6. package/dist/billing/index.d.ts +6 -6
  7. package/dist/billing/index.js +1 -1
  8. package/dist/browser/billing/billing.event.js +1 -1
  9. package/dist/browser/billing/index.js +1 -1
  10. package/dist/browser/index.js +931 -932
  11. package/dist/browser/project/index.js +209 -209
  12. package/dist/browser/project/project.event.js +1 -1
  13. package/dist/browser/ui/SaasDashboard.js +45 -45
  14. package/dist/browser/ui/SaasProjectList.js +7 -7
  15. package/dist/browser/ui/SaasSettingsPanel.js +12 -12
  16. package/dist/browser/ui/hooks/index.js +2 -2
  17. package/dist/browser/ui/hooks/useProjectList.js +1 -1
  18. package/dist/browser/ui/hooks/useProjectMutations.js +1 -1
  19. package/dist/browser/ui/index.js +483 -484
  20. package/dist/browser/ui/modals/CreateProjectModal.js +10 -10
  21. package/dist/browser/ui/modals/ProjectActionsModal.js +13 -13
  22. package/dist/browser/ui/modals/index.js +23 -23
  23. package/dist/browser/ui/renderers/index.js +112 -112
  24. package/dist/browser/ui/renderers/project-list.renderer.js +7 -7
  25. package/dist/handlers/index.d.ts +2 -2
  26. package/dist/index.d.ts +4 -4
  27. package/dist/index.js +931 -932
  28. package/dist/node/billing/billing.event.js +1 -1
  29. package/dist/node/billing/index.js +1 -1
  30. package/dist/node/index.js +931 -932
  31. package/dist/node/project/index.js +209 -209
  32. package/dist/node/project/project.event.js +1 -1
  33. package/dist/node/ui/SaasDashboard.js +45 -45
  34. package/dist/node/ui/SaasProjectList.js +7 -7
  35. package/dist/node/ui/SaasSettingsPanel.js +12 -12
  36. package/dist/node/ui/hooks/index.js +2 -2
  37. package/dist/node/ui/hooks/useProjectList.js +1 -1
  38. package/dist/node/ui/hooks/useProjectMutations.js +1 -1
  39. package/dist/node/ui/index.js +483 -484
  40. package/dist/node/ui/modals/CreateProjectModal.js +10 -10
  41. package/dist/node/ui/modals/ProjectActionsModal.js +13 -13
  42. package/dist/node/ui/modals/index.js +23 -23
  43. package/dist/node/ui/renderers/index.js +112 -112
  44. package/dist/node/ui/renderers/project-list.renderer.js +7 -7
  45. package/dist/presentations/index.d.ts +1 -1
  46. package/dist/project/index.d.ts +7 -7
  47. package/dist/project/index.js +209 -209
  48. package/dist/project/project.event.js +1 -1
  49. package/dist/settings/index.d.ts +1 -1
  50. package/dist/ui/SaasDashboard.js +45 -45
  51. package/dist/ui/SaasProjectList.js +7 -7
  52. package/dist/ui/SaasSettingsPanel.js +12 -12
  53. package/dist/ui/hooks/index.d.ts +2 -2
  54. package/dist/ui/hooks/index.js +2 -2
  55. package/dist/ui/hooks/useProjectList.d.ts +5 -0
  56. package/dist/ui/hooks/useProjectList.js +1 -1
  57. package/dist/ui/hooks/useProjectMutations.d.ts +8 -0
  58. package/dist/ui/hooks/useProjectMutations.js +1 -1
  59. package/dist/ui/index.d.ts +4 -4
  60. package/dist/ui/index.js +483 -484
  61. package/dist/ui/modals/CreateProjectModal.js +10 -10
  62. package/dist/ui/modals/ProjectActionsModal.js +13 -13
  63. package/dist/ui/modals/index.js +23 -23
  64. package/dist/ui/renderers/index.d.ts +1 -1
  65. package/dist/ui/renderers/index.js +112 -112
  66. package/dist/ui/renderers/project-list.renderer.d.ts +1 -1
  67. package/dist/ui/renderers/project-list.renderer.js +7 -7
  68. package/package.json +14 -14
  69. package/src/billing/billing.entity.ts +132 -132
  70. package/src/billing/billing.enum.ts +9 -9
  71. package/src/billing/billing.event.ts +71 -71
  72. package/src/billing/billing.handler.ts +87 -87
  73. package/src/billing/billing.operations.ts +158 -158
  74. package/src/billing/billing.presentation.ts +45 -45
  75. package/src/billing/billing.schema.ts +76 -76
  76. package/src/billing/index.ts +43 -48
  77. package/src/dashboard/dashboard.presentation.ts +45 -45
  78. package/src/dashboard/index.ts +2 -2
  79. package/src/docs/saas-boilerplate.docblock.ts +43 -43
  80. package/src/example.ts +32 -32
  81. package/src/handlers/index.ts +9 -9
  82. package/src/handlers/saas.handlers.ts +250 -249
  83. package/src/index.ts +40 -41
  84. package/src/presentations/index.ts +18 -20
  85. package/src/project/index.ts +45 -50
  86. package/src/project/project.entity.ts +68 -68
  87. package/src/project/project.enum.ts +8 -8
  88. package/src/project/project.event.ts +79 -79
  89. package/src/project/project.handler.ts +103 -103
  90. package/src/project/project.operations.ts +236 -236
  91. package/src/project/project.presentation.ts +46 -46
  92. package/src/project/project.schema.ts +90 -90
  93. package/src/saas-boilerplate.feature.ts +100 -100
  94. package/src/seeders/index.ts +20 -20
  95. package/src/settings/index.ts +2 -3
  96. package/src/settings/settings.entity.ts +65 -65
  97. package/src/settings/settings.enum.ts +4 -4
  98. package/src/shared/mock-data.ts +92 -92
  99. package/src/shared/overlay-types.ts +23 -23
  100. package/src/tests/operations.test-spec.ts +96 -96
  101. package/src/ui/SaasDashboard.tsx +270 -270
  102. package/src/ui/SaasProjectList.tsx +90 -90
  103. package/src/ui/SaasSettingsPanel.tsx +84 -84
  104. package/src/ui/hooks/index.ts +3 -3
  105. package/src/ui/hooks/useProjectList.ts +69 -68
  106. package/src/ui/hooks/useProjectMutations.ts +144 -143
  107. package/src/ui/index.ts +8 -12
  108. package/src/ui/modals/CreateProjectModal.tsx +154 -154
  109. package/src/ui/modals/ProjectActionsModal.tsx +321 -321
  110. package/src/ui/overlays/demo-overlays.ts +49 -49
  111. package/src/ui/renderers/index.ts +5 -4
  112. package/src/ui/renderers/project-list.markdown.ts +204 -204
  113. package/src/ui/renderers/project-list.renderer.tsx +14 -13
  114. package/tsconfig.json +7 -8
  115. package/tsdown.config.js +7 -3
@@ -1,6 +1,6 @@
1
1
  // src/ui/modals/CreateProjectModal.tsx
2
- import { useState } from "react";
3
2
  import { Button, Input } from "@contractspec/lib.design-system";
3
+ import { useState } from "react";
4
4
  import { jsxDEV } from "react/jsx-dev-runtime";
5
5
  "use client";
6
6
  var TIERS = [
@@ -45,7 +45,7 @@ function CreateProjectModal({
45
45
  className: "fixed inset-0 z-50 flex items-center justify-center",
46
46
  children: [
47
47
  /* @__PURE__ */ jsxDEV("div", {
48
- className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
48
+ className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
49
49
  onClick: onClose,
50
50
  role: "button",
51
51
  tabIndex: 0,
@@ -56,10 +56,10 @@ function CreateProjectModal({
56
56
  "aria-label": "Close modal"
57
57
  }, undefined, false, undefined, this),
58
58
  /* @__PURE__ */ jsxDEV("div", {
59
- className: "bg-card border-border relative z-10 w-full max-w-md rounded-xl border p-6 shadow-xl",
59
+ className: "relative z-10 w-full max-w-md rounded-xl border border-border bg-card p-6 shadow-xl",
60
60
  children: [
61
61
  /* @__PURE__ */ jsxDEV("h2", {
62
- className: "mb-4 text-xl font-semibold",
62
+ className: "mb-4 font-semibold text-xl",
63
63
  children: "Create New Project"
64
64
  }, undefined, false, undefined, this),
65
65
  /* @__PURE__ */ jsxDEV("form", {
@@ -70,7 +70,7 @@ function CreateProjectModal({
70
70
  children: [
71
71
  /* @__PURE__ */ jsxDEV("label", {
72
72
  htmlFor: "project-name",
73
- className: "text-muted-foreground mb-1 block text-sm font-medium",
73
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
74
74
  children: "Project Name *"
75
75
  }, undefined, false, undefined, this),
76
76
  /* @__PURE__ */ jsxDEV(Input, {
@@ -86,7 +86,7 @@ function CreateProjectModal({
86
86
  children: [
87
87
  /* @__PURE__ */ jsxDEV("label", {
88
88
  htmlFor: "project-description",
89
- className: "text-muted-foreground mb-1 block text-sm font-medium",
89
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
90
90
  children: "Description"
91
91
  }, undefined, false, undefined, this),
92
92
  /* @__PURE__ */ jsxDEV("textarea", {
@@ -96,7 +96,7 @@ function CreateProjectModal({
96
96
  placeholder: "Describe what this project is about...",
97
97
  rows: 3,
98
98
  disabled: isLoading,
99
- className: "border-input bg-background focus:ring-ring w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50"
99
+ className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50"
100
100
  }, undefined, false, undefined, this)
101
101
  ]
102
102
  }, undefined, true, undefined, this),
@@ -104,7 +104,7 @@ function CreateProjectModal({
104
104
  children: [
105
105
  /* @__PURE__ */ jsxDEV("label", {
106
106
  htmlFor: "project-tier",
107
- className: "text-muted-foreground mb-1 block text-sm font-medium",
107
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
108
108
  children: "Tier"
109
109
  }, undefined, false, undefined, this),
110
110
  /* @__PURE__ */ jsxDEV("select", {
@@ -112,7 +112,7 @@ function CreateProjectModal({
112
112
  value: tier,
113
113
  onChange: (e) => setTier(e.target.value),
114
114
  disabled: isLoading,
115
- className: "border-input bg-background focus:ring-ring h-10 w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50",
115
+ className: "h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50",
116
116
  children: TIERS.map((t) => /* @__PURE__ */ jsxDEV("option", {
117
117
  value: t.value,
118
118
  children: t.label
@@ -121,7 +121,7 @@ function CreateProjectModal({
121
121
  ]
122
122
  }, undefined, true, undefined, this),
123
123
  error && /* @__PURE__ */ jsxDEV("div", {
124
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
124
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
125
125
  children: error
126
126
  }, undefined, false, undefined, this),
127
127
  /* @__PURE__ */ jsxDEV("div", {
@@ -1,6 +1,6 @@
1
1
  // src/ui/modals/ProjectActionsModal.tsx
2
- import { useEffect, useState } from "react";
3
2
  import { Button, Input } from "@contractspec/lib.design-system";
3
+ import { useEffect, useState } from "react";
4
4
  import { jsxDEV } from "react/jsx-dev-runtime";
5
5
  "use client";
6
6
  function ProjectActionsModal({
@@ -93,7 +93,7 @@ function ProjectActionsModal({
93
93
  className: "fixed inset-0 z-50 flex items-center justify-center",
94
94
  children: [
95
95
  /* @__PURE__ */ jsxDEV("div", {
96
- className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
96
+ className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
97
97
  onClick: handleClose,
98
98
  role: "button",
99
99
  tabIndex: 0,
@@ -104,13 +104,13 @@ function ProjectActionsModal({
104
104
  "aria-label": "Close modal"
105
105
  }, undefined, false, undefined, this),
106
106
  /* @__PURE__ */ jsxDEV("div", {
107
- className: "bg-card border-border relative z-10 w-full max-w-md rounded-xl border p-6 shadow-xl",
107
+ className: "relative z-10 w-full max-w-md rounded-xl border border-border bg-card p-6 shadow-xl",
108
108
  children: [
109
109
  /* @__PURE__ */ jsxDEV("div", {
110
- className: "border-border mb-4 border-b pb-4",
110
+ className: "mb-4 border-border border-b pb-4",
111
111
  children: [
112
112
  /* @__PURE__ */ jsxDEV("h2", {
113
- className: "text-xl font-semibold",
113
+ className: "font-semibold text-xl",
114
114
  children: project.name
115
115
  }, undefined, false, undefined, this),
116
116
  /* @__PURE__ */ jsxDEV("p", {
@@ -192,7 +192,7 @@ function ProjectActionsModal({
192
192
  children: [
193
193
  /* @__PURE__ */ jsxDEV("label", {
194
194
  htmlFor: "edit-name",
195
- className: "text-muted-foreground mb-1 block text-sm font-medium",
195
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
196
196
  children: "Project Name *"
197
197
  }, undefined, false, undefined, this),
198
198
  /* @__PURE__ */ jsxDEV(Input, {
@@ -207,7 +207,7 @@ function ProjectActionsModal({
207
207
  children: [
208
208
  /* @__PURE__ */ jsxDEV("label", {
209
209
  htmlFor: "edit-description",
210
- className: "text-muted-foreground mb-1 block text-sm font-medium",
210
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
211
211
  children: "Description"
212
212
  }, undefined, false, undefined, this),
213
213
  /* @__PURE__ */ jsxDEV("textarea", {
@@ -216,12 +216,12 @@ function ProjectActionsModal({
216
216
  onChange: (e) => setDescription(e.target.value),
217
217
  rows: 3,
218
218
  disabled: isLoading,
219
- className: "border-input bg-background focus:ring-ring w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50"
219
+ className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50"
220
220
  }, undefined, false, undefined, this)
221
221
  ]
222
222
  }, undefined, true, undefined, this),
223
223
  error && /* @__PURE__ */ jsxDEV("div", {
224
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
224
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
225
225
  children: error
226
226
  }, undefined, false, undefined, this),
227
227
  /* @__PURE__ */ jsxDEV("div", {
@@ -251,7 +251,7 @@ function ProjectActionsModal({
251
251
  "Are you sure you want to archive",
252
252
  " ",
253
253
  /* @__PURE__ */ jsxDEV("span", {
254
- className: "text-foreground font-medium",
254
+ className: "font-medium text-foreground",
255
255
  children: project.name
256
256
  }, undefined, false, undefined, this),
257
257
  "?"
@@ -262,7 +262,7 @@ function ProjectActionsModal({
262
262
  children: "Archived projects can be restored later."
263
263
  }, undefined, false, undefined, this),
264
264
  error && /* @__PURE__ */ jsxDEV("div", {
265
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
265
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
266
266
  children: error
267
267
  }, undefined, false, undefined, this),
268
268
  /* @__PURE__ */ jsxDEV("div", {
@@ -292,7 +292,7 @@ function ProjectActionsModal({
292
292
  "Are you sure you want to delete",
293
293
  " ",
294
294
  /* @__PURE__ */ jsxDEV("span", {
295
- className: "text-foreground font-medium",
295
+ className: "font-medium text-foreground",
296
296
  children: project.name
297
297
  }, undefined, false, undefined, this),
298
298
  "?"
@@ -303,7 +303,7 @@ function ProjectActionsModal({
303
303
  children: "This action cannot be undone."
304
304
  }, undefined, false, undefined, this),
305
305
  error && /* @__PURE__ */ jsxDEV("div", {
306
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
306
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
307
307
  children: error
308
308
  }, undefined, false, undefined, this),
309
309
  /* @__PURE__ */ jsxDEV("div", {
@@ -1,6 +1,6 @@
1
1
  // src/ui/modals/CreateProjectModal.tsx
2
- import { useState } from "react";
3
2
  import { Button, Input } from "@contractspec/lib.design-system";
3
+ import { useState } from "react";
4
4
  import { jsxDEV } from "react/jsx-dev-runtime";
5
5
  "use client";
6
6
  var TIERS = [
@@ -45,7 +45,7 @@ function CreateProjectModal({
45
45
  className: "fixed inset-0 z-50 flex items-center justify-center",
46
46
  children: [
47
47
  /* @__PURE__ */ jsxDEV("div", {
48
- className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
48
+ className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
49
49
  onClick: onClose,
50
50
  role: "button",
51
51
  tabIndex: 0,
@@ -56,10 +56,10 @@ function CreateProjectModal({
56
56
  "aria-label": "Close modal"
57
57
  }, undefined, false, undefined, this),
58
58
  /* @__PURE__ */ jsxDEV("div", {
59
- className: "bg-card border-border relative z-10 w-full max-w-md rounded-xl border p-6 shadow-xl",
59
+ className: "relative z-10 w-full max-w-md rounded-xl border border-border bg-card p-6 shadow-xl",
60
60
  children: [
61
61
  /* @__PURE__ */ jsxDEV("h2", {
62
- className: "mb-4 text-xl font-semibold",
62
+ className: "mb-4 font-semibold text-xl",
63
63
  children: "Create New Project"
64
64
  }, undefined, false, undefined, this),
65
65
  /* @__PURE__ */ jsxDEV("form", {
@@ -70,7 +70,7 @@ function CreateProjectModal({
70
70
  children: [
71
71
  /* @__PURE__ */ jsxDEV("label", {
72
72
  htmlFor: "project-name",
73
- className: "text-muted-foreground mb-1 block text-sm font-medium",
73
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
74
74
  children: "Project Name *"
75
75
  }, undefined, false, undefined, this),
76
76
  /* @__PURE__ */ jsxDEV(Input, {
@@ -86,7 +86,7 @@ function CreateProjectModal({
86
86
  children: [
87
87
  /* @__PURE__ */ jsxDEV("label", {
88
88
  htmlFor: "project-description",
89
- className: "text-muted-foreground mb-1 block text-sm font-medium",
89
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
90
90
  children: "Description"
91
91
  }, undefined, false, undefined, this),
92
92
  /* @__PURE__ */ jsxDEV("textarea", {
@@ -96,7 +96,7 @@ function CreateProjectModal({
96
96
  placeholder: "Describe what this project is about...",
97
97
  rows: 3,
98
98
  disabled: isLoading,
99
- className: "border-input bg-background focus:ring-ring w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50"
99
+ className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50"
100
100
  }, undefined, false, undefined, this)
101
101
  ]
102
102
  }, undefined, true, undefined, this),
@@ -104,7 +104,7 @@ function CreateProjectModal({
104
104
  children: [
105
105
  /* @__PURE__ */ jsxDEV("label", {
106
106
  htmlFor: "project-tier",
107
- className: "text-muted-foreground mb-1 block text-sm font-medium",
107
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
108
108
  children: "Tier"
109
109
  }, undefined, false, undefined, this),
110
110
  /* @__PURE__ */ jsxDEV("select", {
@@ -112,7 +112,7 @@ function CreateProjectModal({
112
112
  value: tier,
113
113
  onChange: (e) => setTier(e.target.value),
114
114
  disabled: isLoading,
115
- className: "border-input bg-background focus:ring-ring h-10 w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50",
115
+ className: "h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50",
116
116
  children: TIERS.map((t) => /* @__PURE__ */ jsxDEV("option", {
117
117
  value: t.value,
118
118
  children: t.label
@@ -121,7 +121,7 @@ function CreateProjectModal({
121
121
  ]
122
122
  }, undefined, true, undefined, this),
123
123
  error && /* @__PURE__ */ jsxDEV("div", {
124
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
124
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
125
125
  children: error
126
126
  }, undefined, false, undefined, this),
127
127
  /* @__PURE__ */ jsxDEV("div", {
@@ -150,8 +150,8 @@ function CreateProjectModal({
150
150
  }
151
151
 
152
152
  // src/ui/modals/ProjectActionsModal.tsx
153
- import { useEffect, useState as useState2 } from "react";
154
153
  import { Button as Button2, Input as Input2 } from "@contractspec/lib.design-system";
154
+ import { useEffect, useState as useState2 } from "react";
155
155
  import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
156
156
  "use client";
157
157
  function ProjectActionsModal({
@@ -244,7 +244,7 @@ function ProjectActionsModal({
244
244
  className: "fixed inset-0 z-50 flex items-center justify-center",
245
245
  children: [
246
246
  /* @__PURE__ */ jsxDEV2("div", {
247
- className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
247
+ className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
248
248
  onClick: handleClose,
249
249
  role: "button",
250
250
  tabIndex: 0,
@@ -255,13 +255,13 @@ function ProjectActionsModal({
255
255
  "aria-label": "Close modal"
256
256
  }, undefined, false, undefined, this),
257
257
  /* @__PURE__ */ jsxDEV2("div", {
258
- className: "bg-card border-border relative z-10 w-full max-w-md rounded-xl border p-6 shadow-xl",
258
+ className: "relative z-10 w-full max-w-md rounded-xl border border-border bg-card p-6 shadow-xl",
259
259
  children: [
260
260
  /* @__PURE__ */ jsxDEV2("div", {
261
- className: "border-border mb-4 border-b pb-4",
261
+ className: "mb-4 border-border border-b pb-4",
262
262
  children: [
263
263
  /* @__PURE__ */ jsxDEV2("h2", {
264
- className: "text-xl font-semibold",
264
+ className: "font-semibold text-xl",
265
265
  children: project.name
266
266
  }, undefined, false, undefined, this),
267
267
  /* @__PURE__ */ jsxDEV2("p", {
@@ -343,7 +343,7 @@ function ProjectActionsModal({
343
343
  children: [
344
344
  /* @__PURE__ */ jsxDEV2("label", {
345
345
  htmlFor: "edit-name",
346
- className: "text-muted-foreground mb-1 block text-sm font-medium",
346
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
347
347
  children: "Project Name *"
348
348
  }, undefined, false, undefined, this),
349
349
  /* @__PURE__ */ jsxDEV2(Input2, {
@@ -358,7 +358,7 @@ function ProjectActionsModal({
358
358
  children: [
359
359
  /* @__PURE__ */ jsxDEV2("label", {
360
360
  htmlFor: "edit-description",
361
- className: "text-muted-foreground mb-1 block text-sm font-medium",
361
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
362
362
  children: "Description"
363
363
  }, undefined, false, undefined, this),
364
364
  /* @__PURE__ */ jsxDEV2("textarea", {
@@ -367,12 +367,12 @@ function ProjectActionsModal({
367
367
  onChange: (e) => setDescription(e.target.value),
368
368
  rows: 3,
369
369
  disabled: isLoading,
370
- className: "border-input bg-background focus:ring-ring w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50"
370
+ className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50"
371
371
  }, undefined, false, undefined, this)
372
372
  ]
373
373
  }, undefined, true, undefined, this),
374
374
  error && /* @__PURE__ */ jsxDEV2("div", {
375
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
375
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
376
376
  children: error
377
377
  }, undefined, false, undefined, this),
378
378
  /* @__PURE__ */ jsxDEV2("div", {
@@ -402,7 +402,7 @@ function ProjectActionsModal({
402
402
  "Are you sure you want to archive",
403
403
  " ",
404
404
  /* @__PURE__ */ jsxDEV2("span", {
405
- className: "text-foreground font-medium",
405
+ className: "font-medium text-foreground",
406
406
  children: project.name
407
407
  }, undefined, false, undefined, this),
408
408
  "?"
@@ -413,7 +413,7 @@ function ProjectActionsModal({
413
413
  children: "Archived projects can be restored later."
414
414
  }, undefined, false, undefined, this),
415
415
  error && /* @__PURE__ */ jsxDEV2("div", {
416
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
416
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
417
417
  children: error
418
418
  }, undefined, false, undefined, this),
419
419
  /* @__PURE__ */ jsxDEV2("div", {
@@ -443,7 +443,7 @@ function ProjectActionsModal({
443
443
  "Are you sure you want to delete",
444
444
  " ",
445
445
  /* @__PURE__ */ jsxDEV2("span", {
446
- className: "text-foreground font-medium",
446
+ className: "font-medium text-foreground",
447
447
  children: project.name
448
448
  }, undefined, false, undefined, this),
449
449
  "?"
@@ -454,7 +454,7 @@ function ProjectActionsModal({
454
454
  children: "This action cannot be undone."
455
455
  }, undefined, false, undefined, this),
456
456
  error && /* @__PURE__ */ jsxDEV2("div", {
457
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
457
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
458
458
  children: error
459
459
  }, undefined, false, undefined, this),
460
460
  /* @__PURE__ */ jsxDEV2("div", {
@@ -345,8 +345,8 @@ function createSaasHandlers(db) {
345
345
  };
346
346
  }
347
347
  // src/ui/hooks/useProjectList.ts
348
- import { useCallback, useEffect, useMemo, useState } from "react";
349
348
  import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
349
+ import { useCallback, useEffect, useMemo, useState } from "react";
350
350
  function useProjectList(options = {}) {
351
351
  const { handlers, projectId } = useTemplateRuntime();
352
352
  const { saas: saas2 } = handlers;
@@ -408,117 +408,6 @@ function useProjectList(options = {}) {
408
408
  };
409
409
  }
410
410
 
411
- // src/ui/SaasProjectList.tsx
412
- import {
413
- StatCard,
414
- StatCardGroup,
415
- StatusChip,
416
- EntityCard,
417
- EmptyState,
418
- LoaderBlock,
419
- ErrorState,
420
- Button
421
- } from "@contractspec/lib.design-system";
422
- import { jsxDEV } from "react/jsx-dev-runtime";
423
- "use client";
424
- function getStatusTone(status) {
425
- switch (status) {
426
- case "ACTIVE":
427
- return "success";
428
- case "DRAFT":
429
- return "neutral";
430
- case "ARCHIVED":
431
- return "danger";
432
- default:
433
- return "neutral";
434
- }
435
- }
436
- function SaasProjectList({
437
- onProjectClick,
438
- onCreateProject
439
- }) {
440
- const { data, loading, error, stats, refetch } = useProjectList();
441
- if (loading && !data) {
442
- return /* @__PURE__ */ jsxDEV(LoaderBlock, {
443
- label: "Loading projects..."
444
- }, undefined, false, undefined, this);
445
- }
446
- if (error) {
447
- return /* @__PURE__ */ jsxDEV(ErrorState, {
448
- title: "Failed to load projects",
449
- description: error.message,
450
- onRetry: refetch,
451
- retryLabel: "Retry"
452
- }, undefined, false, undefined, this);
453
- }
454
- if (!data?.items.length) {
455
- return /* @__PURE__ */ jsxDEV(EmptyState, {
456
- title: "No projects found",
457
- description: "Create your first project to get started.",
458
- primaryAction: onCreateProject ? /* @__PURE__ */ jsxDEV(Button, {
459
- onPress: onCreateProject,
460
- children: "Create Project"
461
- }, undefined, false, undefined, this) : undefined
462
- }, undefined, false, undefined, this);
463
- }
464
- return /* @__PURE__ */ jsxDEV("div", {
465
- className: "space-y-6",
466
- children: [
467
- stats && /* @__PURE__ */ jsxDEV(StatCardGroup, {
468
- children: [
469
- /* @__PURE__ */ jsxDEV(StatCard, {
470
- label: "Total Projects",
471
- value: stats.total.toString()
472
- }, undefined, false, undefined, this),
473
- /* @__PURE__ */ jsxDEV(StatCard, {
474
- label: "Active",
475
- value: stats.activeCount.toString()
476
- }, undefined, false, undefined, this),
477
- /* @__PURE__ */ jsxDEV(StatCard, {
478
- label: "Draft",
479
- value: stats.draftCount.toString()
480
- }, undefined, false, undefined, this)
481
- ]
482
- }, undefined, true, undefined, this),
483
- /* @__PURE__ */ jsxDEV("div", {
484
- className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
485
- children: data.items.map((project) => /* @__PURE__ */ jsxDEV(EntityCard, {
486
- cardTitle: project.name,
487
- cardSubtitle: project.tier,
488
- meta: /* @__PURE__ */ jsxDEV("p", {
489
- className: "text-muted-foreground text-sm",
490
- children: project.description
491
- }, undefined, false, undefined, this),
492
- chips: /* @__PURE__ */ jsxDEV(StatusChip, {
493
- tone: getStatusTone(project.status),
494
- label: project.status
495
- }, undefined, false, undefined, this),
496
- footer: /* @__PURE__ */ jsxDEV("span", {
497
- className: "text-muted-foreground text-xs",
498
- children: project.updatedAt.toLocaleDateString()
499
- }, undefined, false, undefined, this),
500
- onClick: onProjectClick ? () => onProjectClick(project.id) : undefined
501
- }, project.id, false, undefined, this))
502
- }, undefined, false, undefined, this)
503
- ]
504
- }, undefined, true, undefined, this);
505
- }
506
-
507
- // src/ui/renderers/project-list.renderer.tsx
508
- import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
509
- var projectListReactRenderer = {
510
- target: "react",
511
- render: async (desc, _ctx) => {
512
- if (desc.source.type !== "component") {
513
- throw new Error("Invalid source type");
514
- }
515
- if (desc.source.componentKey !== "SaasProjectListView") {
516
- throw new Error(`Unknown component: ${desc.source.componentKey}`);
517
- }
518
- return /* @__PURE__ */ jsxDEV2(SaasProjectList, {}, undefined, false, undefined, this);
519
- }
520
- };
521
-
522
411
  // src/ui/renderers/project-list.markdown.ts
523
412
  var projectListMarkdownRenderer = {
524
413
  target: "markdown",
@@ -667,6 +556,117 @@ var saasBillingMarkdownRenderer = {
667
556
  };
668
557
  }
669
558
  };
559
+
560
+ // src/ui/SaasProjectList.tsx
561
+ import {
562
+ Button,
563
+ EmptyState,
564
+ EntityCard,
565
+ ErrorState,
566
+ LoaderBlock,
567
+ StatCard,
568
+ StatCardGroup,
569
+ StatusChip
570
+ } from "@contractspec/lib.design-system";
571
+ import { jsxDEV } from "react/jsx-dev-runtime";
572
+ "use client";
573
+ function getStatusTone(status) {
574
+ switch (status) {
575
+ case "ACTIVE":
576
+ return "success";
577
+ case "DRAFT":
578
+ return "neutral";
579
+ case "ARCHIVED":
580
+ return "danger";
581
+ default:
582
+ return "neutral";
583
+ }
584
+ }
585
+ function SaasProjectList({
586
+ onProjectClick,
587
+ onCreateProject
588
+ }) {
589
+ const { data, loading, error, stats, refetch } = useProjectList();
590
+ if (loading && !data) {
591
+ return /* @__PURE__ */ jsxDEV(LoaderBlock, {
592
+ label: "Loading projects..."
593
+ }, undefined, false, undefined, this);
594
+ }
595
+ if (error) {
596
+ return /* @__PURE__ */ jsxDEV(ErrorState, {
597
+ title: "Failed to load projects",
598
+ description: error.message,
599
+ onRetry: refetch,
600
+ retryLabel: "Retry"
601
+ }, undefined, false, undefined, this);
602
+ }
603
+ if (!data?.items.length) {
604
+ return /* @__PURE__ */ jsxDEV(EmptyState, {
605
+ title: "No projects found",
606
+ description: "Create your first project to get started.",
607
+ primaryAction: onCreateProject ? /* @__PURE__ */ jsxDEV(Button, {
608
+ onPress: onCreateProject,
609
+ children: "Create Project"
610
+ }, undefined, false, undefined, this) : undefined
611
+ }, undefined, false, undefined, this);
612
+ }
613
+ return /* @__PURE__ */ jsxDEV("div", {
614
+ className: "space-y-6",
615
+ children: [
616
+ stats && /* @__PURE__ */ jsxDEV(StatCardGroup, {
617
+ children: [
618
+ /* @__PURE__ */ jsxDEV(StatCard, {
619
+ label: "Total Projects",
620
+ value: stats.total.toString()
621
+ }, undefined, false, undefined, this),
622
+ /* @__PURE__ */ jsxDEV(StatCard, {
623
+ label: "Active",
624
+ value: stats.activeCount.toString()
625
+ }, undefined, false, undefined, this),
626
+ /* @__PURE__ */ jsxDEV(StatCard, {
627
+ label: "Draft",
628
+ value: stats.draftCount.toString()
629
+ }, undefined, false, undefined, this)
630
+ ]
631
+ }, undefined, true, undefined, this),
632
+ /* @__PURE__ */ jsxDEV("div", {
633
+ className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
634
+ children: data.items.map((project) => /* @__PURE__ */ jsxDEV(EntityCard, {
635
+ cardTitle: project.name,
636
+ cardSubtitle: project.tier,
637
+ meta: /* @__PURE__ */ jsxDEV("p", {
638
+ className: "text-muted-foreground text-sm",
639
+ children: project.description
640
+ }, undefined, false, undefined, this),
641
+ chips: /* @__PURE__ */ jsxDEV(StatusChip, {
642
+ tone: getStatusTone(project.status),
643
+ label: project.status
644
+ }, undefined, false, undefined, this),
645
+ footer: /* @__PURE__ */ jsxDEV("span", {
646
+ className: "text-muted-foreground text-xs",
647
+ children: project.updatedAt.toLocaleDateString()
648
+ }, undefined, false, undefined, this),
649
+ onClick: onProjectClick ? () => onProjectClick(project.id) : undefined
650
+ }, project.id, false, undefined, this))
651
+ }, undefined, false, undefined, this)
652
+ ]
653
+ }, undefined, true, undefined, this);
654
+ }
655
+
656
+ // src/ui/renderers/project-list.renderer.tsx
657
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
658
+ var projectListReactRenderer = {
659
+ target: "react",
660
+ render: async (desc, _ctx) => {
661
+ if (desc.source.type !== "component") {
662
+ throw new Error("Invalid source type");
663
+ }
664
+ if (desc.source.componentKey !== "SaasProjectListView") {
665
+ throw new Error(`Unknown component: ${desc.source.componentKey}`);
666
+ }
667
+ return /* @__PURE__ */ jsxDEV2(SaasProjectList, {}, undefined, false, undefined, this);
668
+ }
669
+ };
670
670
  export {
671
671
  saasDashboardMarkdownRenderer,
672
672
  saasBillingMarkdownRenderer,
@@ -1,6 +1,6 @@
1
1
  // src/ui/hooks/useProjectList.ts
2
- import { useCallback, useEffect, useMemo, useState } from "react";
3
2
  import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
3
+ import { useCallback, useEffect, useMemo, useState } from "react";
4
4
  function useProjectList(options = {}) {
5
5
  const { handlers, projectId } = useTemplateRuntime();
6
6
  const { saas } = handlers;
@@ -64,14 +64,14 @@ function useProjectList(options = {}) {
64
64
 
65
65
  // src/ui/SaasProjectList.tsx
66
66
  import {
67
- StatCard,
68
- StatCardGroup,
69
- StatusChip,
70
- EntityCard,
67
+ Button,
71
68
  EmptyState,
72
- LoaderBlock,
69
+ EntityCard,
73
70
  ErrorState,
74
- Button
71
+ LoaderBlock,
72
+ StatCard,
73
+ StatCardGroup,
74
+ StatusChip
75
75
  } from "@contractspec/lib.design-system";
76
76
  import { jsxDEV } from "react/jsx-dev-runtime";
77
77
  "use client";
@@ -2,8 +2,8 @@
2
2
  * SaaS Boilerplate Presentations - re-exports from domain modules for backward compatibility.
3
3
  */
4
4
  export { SubscriptionPresentation, UsageDashboardPresentation, } from '../billing/billing.presentation';
5
- export { ProjectListPresentation, ProjectDetailPresentation, } from '../project/project.presentation';
6
5
  export { SaasDashboardPresentation, SettingsPanelPresentation, } from '../dashboard/dashboard.presentation';
6
+ export { ProjectDetailPresentation, ProjectListPresentation, } from '../project/project.presentation';
7
7
  export declare const SaasBoilerplatePresentations: {
8
8
  SubscriptionPresentation: undefined;
9
9
  UsageDashboardPresentation: undefined;