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