@contractspec/example.saas-boilerplate 3.7.6 → 3.8.2

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 (143) hide show
  1. package/.turbo/turbo-build.log +39 -27
  2. package/AGENTS.md +50 -27
  3. package/CHANGELOG.md +36 -0
  4. package/README.md +65 -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 +1147 -869
  11. package/dist/browser/project/index.js +209 -209
  12. package/dist/browser/project/project.event.js +1 -1
  13. package/dist/browser/saas-boilerplate.feature.js +208 -0
  14. package/dist/browser/ui/SaasDashboard.js +356 -105
  15. package/dist/browser/ui/SaasDashboard.visualizations.js +249 -0
  16. package/dist/browser/ui/SaasProjectList.js +7 -7
  17. package/dist/browser/ui/SaasSettingsPanel.js +12 -12
  18. package/dist/browser/ui/hooks/index.js +2 -2
  19. package/dist/browser/ui/hooks/useProjectList.js +1 -1
  20. package/dist/browser/ui/hooks/useProjectMutations.js +1 -1
  21. package/dist/browser/ui/index.js +790 -521
  22. package/dist/browser/ui/modals/CreateProjectModal.js +10 -10
  23. package/dist/browser/ui/modals/ProjectActionsModal.js +13 -13
  24. package/dist/browser/ui/modals/index.js +23 -23
  25. package/dist/browser/ui/renderers/index.js +341 -115
  26. package/dist/browser/ui/renderers/project-list.markdown.js +229 -3
  27. package/dist/browser/ui/renderers/project-list.renderer.js +7 -7
  28. package/dist/browser/visualizations/catalog.js +155 -0
  29. package/dist/browser/visualizations/index.js +217 -0
  30. package/dist/browser/visualizations/selectors.js +210 -0
  31. package/dist/handlers/index.d.ts +2 -2
  32. package/dist/index.d.ts +5 -4
  33. package/dist/index.js +1147 -869
  34. package/dist/node/billing/billing.event.js +1 -1
  35. package/dist/node/billing/index.js +1 -1
  36. package/dist/node/index.js +1147 -869
  37. package/dist/node/project/index.js +209 -209
  38. package/dist/node/project/project.event.js +1 -1
  39. package/dist/node/saas-boilerplate.feature.js +208 -0
  40. package/dist/node/ui/SaasDashboard.js +356 -105
  41. package/dist/node/ui/SaasDashboard.visualizations.js +249 -0
  42. package/dist/node/ui/SaasProjectList.js +7 -7
  43. package/dist/node/ui/SaasSettingsPanel.js +12 -12
  44. package/dist/node/ui/hooks/index.js +2 -2
  45. package/dist/node/ui/hooks/useProjectList.js +1 -1
  46. package/dist/node/ui/hooks/useProjectMutations.js +1 -1
  47. package/dist/node/ui/index.js +790 -521
  48. package/dist/node/ui/modals/CreateProjectModal.js +10 -10
  49. package/dist/node/ui/modals/ProjectActionsModal.js +13 -13
  50. package/dist/node/ui/modals/index.js +23 -23
  51. package/dist/node/ui/renderers/index.js +341 -115
  52. package/dist/node/ui/renderers/project-list.markdown.js +229 -3
  53. package/dist/node/ui/renderers/project-list.renderer.js +7 -7
  54. package/dist/node/visualizations/catalog.js +155 -0
  55. package/dist/node/visualizations/index.js +217 -0
  56. package/dist/node/visualizations/selectors.js +210 -0
  57. package/dist/presentations/index.d.ts +1 -1
  58. package/dist/project/index.d.ts +7 -7
  59. package/dist/project/index.js +209 -209
  60. package/dist/project/project.event.js +1 -1
  61. package/dist/saas-boilerplate.feature.js +208 -0
  62. package/dist/settings/index.d.ts +1 -1
  63. package/dist/ui/SaasDashboard.js +356 -105
  64. package/dist/ui/SaasDashboard.visualizations.d.ts +5 -0
  65. package/dist/ui/SaasDashboard.visualizations.js +250 -0
  66. package/dist/ui/SaasProjectList.js +7 -7
  67. package/dist/ui/SaasSettingsPanel.js +12 -12
  68. package/dist/ui/hooks/index.d.ts +2 -2
  69. package/dist/ui/hooks/index.js +2 -2
  70. package/dist/ui/hooks/useProjectList.d.ts +5 -0
  71. package/dist/ui/hooks/useProjectList.js +1 -1
  72. package/dist/ui/hooks/useProjectMutations.d.ts +8 -0
  73. package/dist/ui/hooks/useProjectMutations.js +1 -1
  74. package/dist/ui/index.d.ts +4 -4
  75. package/dist/ui/index.js +790 -521
  76. package/dist/ui/modals/CreateProjectModal.js +10 -10
  77. package/dist/ui/modals/ProjectActionsModal.js +13 -13
  78. package/dist/ui/modals/index.js +23 -23
  79. package/dist/ui/renderers/index.d.ts +1 -1
  80. package/dist/ui/renderers/index.js +341 -115
  81. package/dist/ui/renderers/project-list.markdown.js +229 -3
  82. package/dist/ui/renderers/project-list.renderer.d.ts +1 -1
  83. package/dist/ui/renderers/project-list.renderer.js +7 -7
  84. package/dist/visualizations/catalog.d.ts +11 -0
  85. package/dist/visualizations/catalog.js +156 -0
  86. package/dist/visualizations/index.d.ts +2 -0
  87. package/dist/visualizations/index.js +218 -0
  88. package/dist/visualizations/selectors.d.ts +8 -0
  89. package/dist/visualizations/selectors.js +211 -0
  90. package/dist/visualizations/selectors.test.d.ts +1 -0
  91. package/package.json +70 -14
  92. package/src/billing/billing.entity.ts +132 -132
  93. package/src/billing/billing.enum.ts +9 -9
  94. package/src/billing/billing.event.ts +71 -71
  95. package/src/billing/billing.handler.ts +87 -87
  96. package/src/billing/billing.operations.ts +158 -158
  97. package/src/billing/billing.presentation.ts +45 -45
  98. package/src/billing/billing.schema.ts +76 -76
  99. package/src/billing/index.ts +43 -48
  100. package/src/dashboard/dashboard.presentation.ts +45 -45
  101. package/src/dashboard/index.ts +2 -2
  102. package/src/docs/saas-boilerplate.docblock.ts +43 -43
  103. package/src/example.ts +32 -32
  104. package/src/handlers/index.ts +9 -9
  105. package/src/handlers/saas.handlers.ts +250 -249
  106. package/src/index.ts +41 -41
  107. package/src/presentations/index.ts +18 -20
  108. package/src/project/index.ts +45 -50
  109. package/src/project/project.entity.ts +68 -68
  110. package/src/project/project.enum.ts +8 -8
  111. package/src/project/project.event.ts +79 -79
  112. package/src/project/project.handler.ts +103 -103
  113. package/src/project/project.operations.ts +236 -236
  114. package/src/project/project.presentation.ts +46 -46
  115. package/src/project/project.schema.ts +90 -90
  116. package/src/saas-boilerplate.feature.ts +103 -100
  117. package/src/seeders/index.ts +20 -20
  118. package/src/settings/index.ts +2 -3
  119. package/src/settings/settings.entity.ts +65 -65
  120. package/src/settings/settings.enum.ts +4 -4
  121. package/src/shared/mock-data.ts +92 -92
  122. package/src/shared/overlay-types.ts +23 -23
  123. package/src/tests/operations.test-spec.ts +96 -96
  124. package/src/ui/SaasDashboard.tsx +278 -270
  125. package/src/ui/SaasDashboard.visualizations.tsx +41 -0
  126. package/src/ui/SaasProjectList.tsx +90 -90
  127. package/src/ui/SaasSettingsPanel.tsx +84 -84
  128. package/src/ui/hooks/index.ts +3 -3
  129. package/src/ui/hooks/useProjectList.ts +69 -68
  130. package/src/ui/hooks/useProjectMutations.ts +144 -143
  131. package/src/ui/index.ts +8 -12
  132. package/src/ui/modals/CreateProjectModal.tsx +154 -154
  133. package/src/ui/modals/ProjectActionsModal.tsx +321 -321
  134. package/src/ui/overlays/demo-overlays.ts +49 -49
  135. package/src/ui/renderers/index.ts +5 -4
  136. package/src/ui/renderers/project-list.markdown.ts +229 -205
  137. package/src/ui/renderers/project-list.renderer.tsx +14 -13
  138. package/src/visualizations/catalog.ts +153 -0
  139. package/src/visualizations/index.ts +2 -0
  140. package/src/visualizations/selectors.test.ts +25 -0
  141. package/src/visualizations/selectors.ts +85 -0
  142. package/tsconfig.json +7 -8
  143. package/tsdown.config.js +7 -3
@@ -1,7 +1,214 @@
1
1
  // @bun
2
+ // src/visualizations/catalog.ts
3
+ import {
4
+ defineVisualization,
5
+ VisualizationRegistry
6
+ } from "@contractspec/lib.contracts-spec/visualizations";
7
+ var PROJECT_LIST_REF = {
8
+ key: "saas.project.list",
9
+ version: "1.0.0"
10
+ };
11
+ var META = {
12
+ version: "1.0.0",
13
+ domain: "saas",
14
+ stability: "experimental",
15
+ owners: ["@example.saas-boilerplate"],
16
+ tags: ["saas", "visualization", "projects"]
17
+ };
18
+ var SaasProjectUsageVisualization = defineVisualization({
19
+ meta: {
20
+ ...META,
21
+ key: "saas-boilerplate.visualization.project-usage",
22
+ title: "Project Capacity",
23
+ description: "Current project count against the current plan limit.",
24
+ goal: "Show usage against the active plan allowance.",
25
+ context: "SaaS account overview."
26
+ },
27
+ source: { primary: PROJECT_LIST_REF, resultPath: "data" },
28
+ visualization: {
29
+ kind: "metric",
30
+ measure: "totalProjects",
31
+ comparisonMeasure: "projectLimit",
32
+ measures: [
33
+ {
34
+ key: "totalProjects",
35
+ label: "Projects",
36
+ dataPath: "totalProjects",
37
+ format: "number"
38
+ },
39
+ {
40
+ key: "projectLimit",
41
+ label: "Plan Limit",
42
+ dataPath: "projectLimit",
43
+ format: "number"
44
+ }
45
+ ],
46
+ table: { caption: "Current project count and plan limit." }
47
+ }
48
+ });
49
+ var SaasProjectStatusVisualization = defineVisualization({
50
+ meta: {
51
+ ...META,
52
+ key: "saas-boilerplate.visualization.project-status",
53
+ title: "Project Status",
54
+ description: "Distribution of project states.",
55
+ goal: "Show the mix of active, draft, and archived projects.",
56
+ context: "Project portfolio overview."
57
+ },
58
+ source: { primary: PROJECT_LIST_REF, resultPath: "data" },
59
+ visualization: {
60
+ kind: "pie",
61
+ nameDimension: "status",
62
+ valueMeasure: "projects",
63
+ dimensions: [
64
+ { key: "status", label: "Status", dataPath: "status", type: "category" }
65
+ ],
66
+ measures: [
67
+ {
68
+ key: "projects",
69
+ label: "Projects",
70
+ dataPath: "projects",
71
+ format: "number"
72
+ }
73
+ ],
74
+ table: { caption: "Project counts by status." }
75
+ }
76
+ });
77
+ var SaasProjectTierVisualization = defineVisualization({
78
+ meta: {
79
+ ...META,
80
+ key: "saas-boilerplate.visualization.project-tiers",
81
+ title: "Tier Comparison",
82
+ description: "Distribution of projects across tiers.",
83
+ goal: "Compare how the current portfolio is distributed by tier.",
84
+ context: "Plan and packaging overview."
85
+ },
86
+ source: { primary: PROJECT_LIST_REF, resultPath: "data" },
87
+ visualization: {
88
+ kind: "cartesian",
89
+ variant: "bar",
90
+ xDimension: "tier",
91
+ yMeasures: ["projects"],
92
+ dimensions: [
93
+ { key: "tier", label: "Tier", dataPath: "tier", type: "category" }
94
+ ],
95
+ measures: [
96
+ {
97
+ key: "projects",
98
+ label: "Projects",
99
+ dataPath: "projects",
100
+ format: "number",
101
+ color: "#1d4ed8"
102
+ }
103
+ ],
104
+ table: { caption: "Project counts by tier." }
105
+ }
106
+ });
107
+ var SaasProjectActivityVisualization = defineVisualization({
108
+ meta: {
109
+ ...META,
110
+ key: "saas-boilerplate.visualization.project-activity",
111
+ title: "Recent Project Activity",
112
+ description: "Daily project creation activity.",
113
+ goal: "Show recent project activity over time.",
114
+ context: "Project portfolio trend view."
115
+ },
116
+ source: { primary: PROJECT_LIST_REF, resultPath: "data" },
117
+ visualization: {
118
+ kind: "cartesian",
119
+ variant: "line",
120
+ xDimension: "day",
121
+ yMeasures: ["projects"],
122
+ dimensions: [{ key: "day", label: "Day", dataPath: "day", type: "time" }],
123
+ measures: [
124
+ {
125
+ key: "projects",
126
+ label: "Projects",
127
+ dataPath: "projects",
128
+ format: "number",
129
+ color: "#0f766e"
130
+ }
131
+ ],
132
+ table: { caption: "Daily project creation counts." }
133
+ }
134
+ });
135
+ var SaasVisualizationSpecs = [
136
+ SaasProjectUsageVisualization,
137
+ SaasProjectStatusVisualization,
138
+ SaasProjectTierVisualization,
139
+ SaasProjectActivityVisualization
140
+ ];
141
+ var SaasVisualizationRegistry = new VisualizationRegistry([
142
+ ...SaasVisualizationSpecs
143
+ ]);
144
+ var SaasVisualizationRefs = SaasVisualizationSpecs.map((spec) => ({
145
+ key: spec.meta.key,
146
+ version: spec.meta.version
147
+ }));
148
+
149
+ // src/visualizations/selectors.ts
150
+ function toDayKey(value) {
151
+ const date = value instanceof Date ? value : new Date(value);
152
+ return date.toISOString().slice(0, 10);
153
+ }
154
+ function createSaasVisualizationItems(projects, projectLimit = 10) {
155
+ const statusCounts = new Map;
156
+ const tierCounts = new Map;
157
+ const activityCounts = new Map;
158
+ for (const project of projects) {
159
+ statusCounts.set(project.status, (statusCounts.get(project.status) ?? 0) + 1);
160
+ tierCounts.set(project.tier, (tierCounts.get(project.tier) ?? 0) + 1);
161
+ const day = toDayKey(project.createdAt);
162
+ activityCounts.set(day, (activityCounts.get(day) ?? 0) + 1);
163
+ }
164
+ return [
165
+ {
166
+ key: "saas-capacity",
167
+ spec: SaasProjectUsageVisualization,
168
+ data: { data: [{ totalProjects: projects.length, projectLimit }] },
169
+ title: "Project Capacity",
170
+ description: "Current project count compared to the active limit.",
171
+ height: 220
172
+ },
173
+ {
174
+ key: "saas-status",
175
+ spec: SaasProjectStatusVisualization,
176
+ data: {
177
+ data: Array.from(statusCounts.entries()).map(([status, count]) => ({
178
+ status,
179
+ projects: count
180
+ }))
181
+ },
182
+ title: "Project Status",
183
+ description: "Status mix across the current project portfolio.",
184
+ height: 260
185
+ },
186
+ {
187
+ key: "saas-tier",
188
+ spec: SaasProjectTierVisualization,
189
+ data: {
190
+ data: Array.from(tierCounts.entries()).map(([tier, count]) => ({
191
+ tier,
192
+ projects: count
193
+ }))
194
+ },
195
+ title: "Tier Comparison",
196
+ description: "How projects are distributed across tiers."
197
+ },
198
+ {
199
+ key: "saas-activity",
200
+ spec: SaasProjectActivityVisualization,
201
+ data: {
202
+ data: Array.from(activityCounts.entries()).sort(([left], [right]) => left.localeCompare(right)).map(([day, count]) => ({ day, projects: count }))
203
+ },
204
+ title: "Recent Project Activity",
205
+ description: "Daily project creation activity."
206
+ }
207
+ ];
208
+ }
2
209
  // src/ui/hooks/useProjectList.ts
3
- import { useCallback, useEffect, useMemo, useState } from "react";
4
210
  import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
211
+ import { useCallback, useEffect, useMemo, useState } from "react";
5
212
  function useProjectList(options = {}) {
6
213
  const { handlers, projectId } = useTemplateRuntime();
7
214
  const { saas } = handlers;
@@ -64,8 +271,8 @@ function useProjectList(options = {}) {
64
271
  }
65
272
 
66
273
  // src/ui/hooks/useProjectMutations.ts
67
- import { useCallback as useCallback2, useState as useState2 } from "react";
68
274
  import { useTemplateRuntime as useTemplateRuntime2 } from "@contractspec/lib.example-shared-ui";
275
+ import { useCallback as useCallback2, useState as useState2 } from "react";
69
276
  function useProjectMutations(options = {}) {
70
277
  const { handlers, projectId } = useTemplateRuntime2();
71
278
  const { saas } = handlers;
@@ -153,8 +360,8 @@ function useProjectMutations(options = {}) {
153
360
  }
154
361
 
155
362
  // src/ui/modals/CreateProjectModal.tsx
156
- import { useState as useState3 } from "react";
157
363
  import { Button, Input } from "@contractspec/lib.design-system";
364
+ import { useState as useState3 } from "react";
158
365
  import { jsxDEV } from "react/jsx-dev-runtime";
159
366
  "use client";
160
367
  var TIERS = [
@@ -199,7 +406,7 @@ function CreateProjectModal({
199
406
  className: "fixed inset-0 z-50 flex items-center justify-center",
200
407
  children: [
201
408
  /* @__PURE__ */ jsxDEV("div", {
202
- className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
409
+ className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
203
410
  onClick: onClose,
204
411
  role: "button",
205
412
  tabIndex: 0,
@@ -210,10 +417,10 @@ function CreateProjectModal({
210
417
  "aria-label": "Close modal"
211
418
  }, undefined, false, undefined, this),
212
419
  /* @__PURE__ */ jsxDEV("div", {
213
- className: "bg-card border-border relative z-10 w-full max-w-md rounded-xl border p-6 shadow-xl",
420
+ className: "relative z-10 w-full max-w-md rounded-xl border border-border bg-card p-6 shadow-xl",
214
421
  children: [
215
422
  /* @__PURE__ */ jsxDEV("h2", {
216
- className: "mb-4 text-xl font-semibold",
423
+ className: "mb-4 font-semibold text-xl",
217
424
  children: "Create New Project"
218
425
  }, undefined, false, undefined, this),
219
426
  /* @__PURE__ */ jsxDEV("form", {
@@ -224,7 +431,7 @@ function CreateProjectModal({
224
431
  children: [
225
432
  /* @__PURE__ */ jsxDEV("label", {
226
433
  htmlFor: "project-name",
227
- className: "text-muted-foreground mb-1 block text-sm font-medium",
434
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
228
435
  children: "Project Name *"
229
436
  }, undefined, false, undefined, this),
230
437
  /* @__PURE__ */ jsxDEV(Input, {
@@ -240,7 +447,7 @@ function CreateProjectModal({
240
447
  children: [
241
448
  /* @__PURE__ */ jsxDEV("label", {
242
449
  htmlFor: "project-description",
243
- className: "text-muted-foreground mb-1 block text-sm font-medium",
450
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
244
451
  children: "Description"
245
452
  }, undefined, false, undefined, this),
246
453
  /* @__PURE__ */ jsxDEV("textarea", {
@@ -250,7 +457,7 @@ function CreateProjectModal({
250
457
  placeholder: "Describe what this project is about...",
251
458
  rows: 3,
252
459
  disabled: isLoading,
253
- 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"
460
+ 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"
254
461
  }, undefined, false, undefined, this)
255
462
  ]
256
463
  }, undefined, true, undefined, this),
@@ -258,7 +465,7 @@ function CreateProjectModal({
258
465
  children: [
259
466
  /* @__PURE__ */ jsxDEV("label", {
260
467
  htmlFor: "project-tier",
261
- className: "text-muted-foreground mb-1 block text-sm font-medium",
468
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
262
469
  children: "Tier"
263
470
  }, undefined, false, undefined, this),
264
471
  /* @__PURE__ */ jsxDEV("select", {
@@ -266,7 +473,7 @@ function CreateProjectModal({
266
473
  value: tier,
267
474
  onChange: (e) => setTier(e.target.value),
268
475
  disabled: isLoading,
269
- 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",
476
+ 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",
270
477
  children: TIERS.map((t) => /* @__PURE__ */ jsxDEV("option", {
271
478
  value: t.value,
272
479
  children: t.label
@@ -275,7 +482,7 @@ function CreateProjectModal({
275
482
  ]
276
483
  }, undefined, true, undefined, this),
277
484
  error && /* @__PURE__ */ jsxDEV("div", {
278
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
485
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
279
486
  children: error
280
487
  }, undefined, false, undefined, this),
281
488
  /* @__PURE__ */ jsxDEV("div", {
@@ -304,8 +511,8 @@ function CreateProjectModal({
304
511
  }
305
512
 
306
513
  // src/ui/modals/ProjectActionsModal.tsx
307
- import { useEffect as useEffect2, useState as useState4 } from "react";
308
514
  import { Button as Button2, Input as Input2 } from "@contractspec/lib.design-system";
515
+ import { useEffect as useEffect2, useState as useState4 } from "react";
309
516
  import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
310
517
  "use client";
311
518
  function ProjectActionsModal({
@@ -398,7 +605,7 @@ function ProjectActionsModal({
398
605
  className: "fixed inset-0 z-50 flex items-center justify-center",
399
606
  children: [
400
607
  /* @__PURE__ */ jsxDEV2("div", {
401
- className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
608
+ className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
402
609
  onClick: handleClose,
403
610
  role: "button",
404
611
  tabIndex: 0,
@@ -409,13 +616,13 @@ function ProjectActionsModal({
409
616
  "aria-label": "Close modal"
410
617
  }, undefined, false, undefined, this),
411
618
  /* @__PURE__ */ jsxDEV2("div", {
412
- className: "bg-card border-border relative z-10 w-full max-w-md rounded-xl border p-6 shadow-xl",
619
+ className: "relative z-10 w-full max-w-md rounded-xl border border-border bg-card p-6 shadow-xl",
413
620
  children: [
414
621
  /* @__PURE__ */ jsxDEV2("div", {
415
- className: "border-border mb-4 border-b pb-4",
622
+ className: "mb-4 border-border border-b pb-4",
416
623
  children: [
417
624
  /* @__PURE__ */ jsxDEV2("h2", {
418
- className: "text-xl font-semibold",
625
+ className: "font-semibold text-xl",
419
626
  children: project.name
420
627
  }, undefined, false, undefined, this),
421
628
  /* @__PURE__ */ jsxDEV2("p", {
@@ -497,7 +704,7 @@ function ProjectActionsModal({
497
704
  children: [
498
705
  /* @__PURE__ */ jsxDEV2("label", {
499
706
  htmlFor: "edit-name",
500
- className: "text-muted-foreground mb-1 block text-sm font-medium",
707
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
501
708
  children: "Project Name *"
502
709
  }, undefined, false, undefined, this),
503
710
  /* @__PURE__ */ jsxDEV2(Input2, {
@@ -512,7 +719,7 @@ function ProjectActionsModal({
512
719
  children: [
513
720
  /* @__PURE__ */ jsxDEV2("label", {
514
721
  htmlFor: "edit-description",
515
- className: "text-muted-foreground mb-1 block text-sm font-medium",
722
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
516
723
  children: "Description"
517
724
  }, undefined, false, undefined, this),
518
725
  /* @__PURE__ */ jsxDEV2("textarea", {
@@ -521,12 +728,12 @@ function ProjectActionsModal({
521
728
  onChange: (e) => setDescription(e.target.value),
522
729
  rows: 3,
523
730
  disabled: isLoading,
524
- 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"
731
+ 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"
525
732
  }, undefined, false, undefined, this)
526
733
  ]
527
734
  }, undefined, true, undefined, this),
528
735
  error && /* @__PURE__ */ jsxDEV2("div", {
529
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
736
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
530
737
  children: error
531
738
  }, undefined, false, undefined, this),
532
739
  /* @__PURE__ */ jsxDEV2("div", {
@@ -556,7 +763,7 @@ function ProjectActionsModal({
556
763
  "Are you sure you want to archive",
557
764
  " ",
558
765
  /* @__PURE__ */ jsxDEV2("span", {
559
- className: "text-foreground font-medium",
766
+ className: "font-medium text-foreground",
560
767
  children: project.name
561
768
  }, undefined, false, undefined, this),
562
769
  "?"
@@ -567,7 +774,7 @@ function ProjectActionsModal({
567
774
  children: "Archived projects can be restored later."
568
775
  }, undefined, false, undefined, this),
569
776
  error && /* @__PURE__ */ jsxDEV2("div", {
570
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
777
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
571
778
  children: error
572
779
  }, undefined, false, undefined, this),
573
780
  /* @__PURE__ */ jsxDEV2("div", {
@@ -597,7 +804,7 @@ function ProjectActionsModal({
597
804
  "Are you sure you want to delete",
598
805
  " ",
599
806
  /* @__PURE__ */ jsxDEV2("span", {
600
- className: "text-foreground font-medium",
807
+ className: "font-medium text-foreground",
601
808
  children: project.name
602
809
  }, undefined, false, undefined, this),
603
810
  "?"
@@ -608,7 +815,7 @@ function ProjectActionsModal({
608
815
  children: "This action cannot be undone."
609
816
  }, undefined, false, undefined, this),
610
817
  error && /* @__PURE__ */ jsxDEV2("div", {
611
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
818
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
612
819
  children: error
613
820
  }, undefined, false, undefined, this),
614
821
  /* @__PURE__ */ jsxDEV2("div", {
@@ -636,19 +843,59 @@ function ProjectActionsModal({
636
843
  }, undefined, true, undefined, this);
637
844
  }
638
845
 
846
+ // src/ui/SaasDashboard.visualizations.tsx
847
+ import {
848
+ VisualizationCard,
849
+ VisualizationGrid
850
+ } from "@contractspec/lib.design-system";
851
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
852
+ "use client";
853
+ function SaasVisualizationOverview({
854
+ projects,
855
+ projectLimit
856
+ }) {
857
+ const items = createSaasVisualizationItems(projects, projectLimit);
858
+ return /* @__PURE__ */ jsxDEV3("section", {
859
+ className: "space-y-3",
860
+ children: [
861
+ /* @__PURE__ */ jsxDEV3("div", {
862
+ children: [
863
+ /* @__PURE__ */ jsxDEV3("h3", {
864
+ className: "font-semibold text-lg",
865
+ children: "Portfolio Visualizations"
866
+ }, undefined, false, undefined, this),
867
+ /* @__PURE__ */ jsxDEV3("p", {
868
+ className: "text-muted-foreground text-sm",
869
+ children: "Contract-backed charts for project mix, capacity, and activity."
870
+ }, undefined, false, undefined, this)
871
+ ]
872
+ }, undefined, true, undefined, this),
873
+ /* @__PURE__ */ jsxDEV3(VisualizationGrid, {
874
+ children: items.map((item) => /* @__PURE__ */ jsxDEV3(VisualizationCard, {
875
+ data: item.data,
876
+ description: item.description,
877
+ height: item.height,
878
+ spec: item.spec,
879
+ title: item.title
880
+ }, item.key, false, undefined, this))
881
+ }, undefined, false, undefined, this)
882
+ ]
883
+ }, undefined, true, undefined, this);
884
+ }
885
+
639
886
  // src/ui/SaasDashboard.tsx
640
- import { useState as useState5, useCallback as useCallback3 } from "react";
641
887
  import {
642
- StatCard,
643
- StatCardGroup,
644
- StatusChip,
645
- EntityCard,
888
+ Button as Button3,
646
889
  EmptyState,
647
- LoaderBlock,
890
+ EntityCard,
648
891
  ErrorState,
649
- Button as Button3
892
+ LoaderBlock,
893
+ StatCard,
894
+ StatCardGroup,
895
+ StatusChip
650
896
  } from "@contractspec/lib.design-system";
651
- import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
897
+ import { useCallback as useCallback3, useState as useState5 } from "react";
898
+ import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
652
899
  "use client";
653
900
  function getStatusTone(status) {
654
901
  switch (status) {
@@ -683,32 +930,32 @@ function SaasDashboard() {
683
930
  { id: "settings", label: "Settings", icon: "\u2699\uFE0F" }
684
931
  ];
685
932
  if (loading && !data) {
686
- return /* @__PURE__ */ jsxDEV3(LoaderBlock, {
933
+ return /* @__PURE__ */ jsxDEV4(LoaderBlock, {
687
934
  label: "Loading dashboard..."
688
935
  }, undefined, false, undefined, this);
689
936
  }
690
937
  if (error) {
691
- return /* @__PURE__ */ jsxDEV3(ErrorState, {
938
+ return /* @__PURE__ */ jsxDEV4(ErrorState, {
692
939
  title: "Failed to load dashboard",
693
940
  description: error.message,
694
941
  onRetry: refetch,
695
942
  retryLabel: "Retry"
696
943
  }, undefined, false, undefined, this);
697
944
  }
698
- return /* @__PURE__ */ jsxDEV3("div", {
945
+ return /* @__PURE__ */ jsxDEV4("div", {
699
946
  className: "space-y-6",
700
947
  children: [
701
- /* @__PURE__ */ jsxDEV3("div", {
948
+ /* @__PURE__ */ jsxDEV4("div", {
702
949
  className: "flex items-center justify-between",
703
950
  children: [
704
- /* @__PURE__ */ jsxDEV3("h2", {
705
- className: "text-2xl font-bold",
951
+ /* @__PURE__ */ jsxDEV4("h2", {
952
+ className: "font-bold text-2xl",
706
953
  children: "SaaS Dashboard"
707
954
  }, undefined, false, undefined, this),
708
- activeTab === "projects" && /* @__PURE__ */ jsxDEV3(Button3, {
955
+ activeTab === "projects" && /* @__PURE__ */ jsxDEV4(Button3, {
709
956
  onPress: () => setIsCreateModalOpen(true),
710
957
  children: [
711
- /* @__PURE__ */ jsxDEV3("span", {
958
+ /* @__PURE__ */ jsxDEV4("span", {
712
959
  className: "mr-2",
713
960
  children: "+"
714
961
  }, undefined, false, undefined, this),
@@ -717,59 +964,63 @@ function SaasDashboard() {
717
964
  }, undefined, true, undefined, this)
718
965
  ]
719
966
  }, undefined, true, undefined, this),
720
- stats && subscription && /* @__PURE__ */ jsxDEV3(StatCardGroup, {
967
+ stats && subscription && /* @__PURE__ */ jsxDEV4(StatCardGroup, {
721
968
  children: [
722
- /* @__PURE__ */ jsxDEV3(StatCard, {
969
+ /* @__PURE__ */ jsxDEV4(StatCard, {
723
970
  label: "Projects",
724
971
  value: stats.total.toString()
725
972
  }, undefined, false, undefined, this),
726
- /* @__PURE__ */ jsxDEV3(StatCard, {
973
+ /* @__PURE__ */ jsxDEV4(StatCard, {
727
974
  label: "Active",
728
975
  value: stats.activeCount.toString()
729
976
  }, undefined, false, undefined, this),
730
- /* @__PURE__ */ jsxDEV3(StatCard, {
977
+ /* @__PURE__ */ jsxDEV4(StatCard, {
731
978
  label: "Draft",
732
979
  value: stats.draftCount.toString()
733
980
  }, undefined, false, undefined, this),
734
- /* @__PURE__ */ jsxDEV3(StatCard, {
981
+ /* @__PURE__ */ jsxDEV4(StatCard, {
735
982
  label: "Plan",
736
983
  value: subscription.plan,
737
984
  hint: subscription.status
738
985
  }, undefined, false, undefined, this)
739
986
  ]
740
987
  }, undefined, true, undefined, this),
741
- /* @__PURE__ */ jsxDEV3("nav", {
742
- className: "bg-muted flex gap-1 rounded-lg p-1",
988
+ data && stats && /* @__PURE__ */ jsxDEV4(SaasVisualizationOverview, {
989
+ projectLimit: stats.projectLimit,
990
+ projects: data.items
991
+ }, undefined, false, undefined, this),
992
+ /* @__PURE__ */ jsxDEV4("nav", {
993
+ className: "flex gap-1 rounded-lg bg-muted p-1",
743
994
  role: "tablist",
744
- children: tabs.map((tab) => /* @__PURE__ */ jsxDEV3("button", {
995
+ children: tabs.map((tab) => /* @__PURE__ */ jsxDEV4("button", {
745
996
  type: "button",
746
997
  role: "tab",
747
998
  "aria-selected": activeTab === tab.id,
748
999
  onClick: () => setActiveTab(tab.id),
749
- className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors ${activeTab === tab.id ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
1000
+ className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 font-medium text-sm transition-colors ${activeTab === tab.id ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
750
1001
  children: [
751
- /* @__PURE__ */ jsxDEV3("span", {
1002
+ /* @__PURE__ */ jsxDEV4("span", {
752
1003
  children: tab.icon
753
1004
  }, undefined, false, undefined, this),
754
1005
  tab.label
755
1006
  ]
756
1007
  }, tab.id, true, undefined, this))
757
1008
  }, undefined, false, undefined, this),
758
- /* @__PURE__ */ jsxDEV3("div", {
1009
+ /* @__PURE__ */ jsxDEV4("div", {
759
1010
  className: "min-h-[400px]",
760
1011
  role: "tabpanel",
761
1012
  children: [
762
- activeTab === "projects" && /* @__PURE__ */ jsxDEV3(ProjectsTab, {
1013
+ activeTab === "projects" && /* @__PURE__ */ jsxDEV4(ProjectsTab, {
763
1014
  data,
764
1015
  onProjectClick: handleProjectClick
765
1016
  }, undefined, false, undefined, this),
766
- activeTab === "billing" && /* @__PURE__ */ jsxDEV3(BillingTab, {
1017
+ activeTab === "billing" && /* @__PURE__ */ jsxDEV4(BillingTab, {
767
1018
  subscription
768
1019
  }, undefined, false, undefined, this),
769
- activeTab === "settings" && /* @__PURE__ */ jsxDEV3(SettingsTab, {}, undefined, false, undefined, this)
1020
+ activeTab === "settings" && /* @__PURE__ */ jsxDEV4(SettingsTab, {}, undefined, false, undefined, this)
770
1021
  ]
771
1022
  }, undefined, true, undefined, this),
772
- /* @__PURE__ */ jsxDEV3(CreateProjectModal, {
1023
+ /* @__PURE__ */ jsxDEV4(CreateProjectModal, {
773
1024
  isOpen: isCreateModalOpen,
774
1025
  onClose: () => setIsCreateModalOpen(false),
775
1026
  onSubmit: async (input) => {
@@ -777,7 +1028,7 @@ function SaasDashboard() {
777
1028
  },
778
1029
  isLoading: mutations.createState.loading
779
1030
  }, undefined, false, undefined, this),
780
- /* @__PURE__ */ jsxDEV3(ProjectActionsModal, {
1031
+ /* @__PURE__ */ jsxDEV4(ProjectActionsModal, {
781
1032
  isOpen: isProjectActionsOpen,
782
1033
  project: selectedProject,
783
1034
  onClose: () => {
@@ -803,34 +1054,34 @@ function SaasDashboard() {
803
1054
  }
804
1055
  function ProjectsTab({ data, onProjectClick }) {
805
1056
  if (!data?.items.length) {
806
- return /* @__PURE__ */ jsxDEV3(EmptyState, {
1057
+ return /* @__PURE__ */ jsxDEV4(EmptyState, {
807
1058
  title: "No projects yet",
808
1059
  description: "Create your first project to get started."
809
1060
  }, undefined, false, undefined, this);
810
1061
  }
811
- return /* @__PURE__ */ jsxDEV3("div", {
1062
+ return /* @__PURE__ */ jsxDEV4("div", {
812
1063
  className: "space-y-4",
813
- children: /* @__PURE__ */ jsxDEV3("div", {
1064
+ children: /* @__PURE__ */ jsxDEV4("div", {
814
1065
  className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
815
- children: data.items.map((project) => /* @__PURE__ */ jsxDEV3(EntityCard, {
1066
+ children: data.items.map((project) => /* @__PURE__ */ jsxDEV4(EntityCard, {
816
1067
  cardTitle: project.name,
817
1068
  cardSubtitle: project.tier,
818
- meta: /* @__PURE__ */ jsxDEV3("p", {
1069
+ meta: /* @__PURE__ */ jsxDEV4("p", {
819
1070
  className: "text-muted-foreground text-sm",
820
1071
  children: project.description
821
1072
  }, undefined, false, undefined, this),
822
- chips: /* @__PURE__ */ jsxDEV3(StatusChip, {
1073
+ chips: /* @__PURE__ */ jsxDEV4(StatusChip, {
823
1074
  tone: getStatusTone(project.status),
824
1075
  label: project.status
825
1076
  }, undefined, false, undefined, this),
826
- footer: /* @__PURE__ */ jsxDEV3("div", {
1077
+ footer: /* @__PURE__ */ jsxDEV4("div", {
827
1078
  className: "flex w-full items-center justify-between",
828
1079
  children: [
829
- /* @__PURE__ */ jsxDEV3("span", {
1080
+ /* @__PURE__ */ jsxDEV4("span", {
830
1081
  className: "text-muted-foreground text-xs",
831
1082
  children: project.updatedAt.toLocaleDateString()
832
1083
  }, undefined, false, undefined, this),
833
- /* @__PURE__ */ jsxDEV3(Button3, {
1084
+ /* @__PURE__ */ jsxDEV4(Button3, {
834
1085
  variant: "ghost",
835
1086
  size: "sm",
836
1087
  onPress: () => onProjectClick?.(project),
@@ -845,25 +1096,25 @@ function ProjectsTab({ data, onProjectClick }) {
845
1096
  function BillingTab({ subscription }) {
846
1097
  if (!subscription)
847
1098
  return null;
848
- return /* @__PURE__ */ jsxDEV3("div", {
1099
+ return /* @__PURE__ */ jsxDEV4("div", {
849
1100
  className: "space-y-6",
850
1101
  children: [
851
- /* @__PURE__ */ jsxDEV3("div", {
852
- className: "border-border bg-card rounded-xl border p-6",
1102
+ /* @__PURE__ */ jsxDEV4("div", {
1103
+ className: "rounded-xl border border-border bg-card p-6",
853
1104
  children: [
854
- /* @__PURE__ */ jsxDEV3("div", {
1105
+ /* @__PURE__ */ jsxDEV4("div", {
855
1106
  className: "flex items-start justify-between",
856
1107
  children: [
857
- /* @__PURE__ */ jsxDEV3("div", {
1108
+ /* @__PURE__ */ jsxDEV4("div", {
858
1109
  children: [
859
- /* @__PURE__ */ jsxDEV3("h3", {
860
- className: "text-lg font-semibold",
1110
+ /* @__PURE__ */ jsxDEV4("h3", {
1111
+ className: "font-semibold text-lg",
861
1112
  children: [
862
1113
  subscription.plan,
863
1114
  " Plan"
864
1115
  ]
865
1116
  }, undefined, true, undefined, this),
866
- /* @__PURE__ */ jsxDEV3("p", {
1117
+ /* @__PURE__ */ jsxDEV4("p", {
867
1118
  className: "text-muted-foreground text-sm",
868
1119
  children: [
869
1120
  "Current period:",
@@ -874,7 +1125,7 @@ function BillingTab({ subscription }) {
874
1125
  subscription.currentPeriodEnd.toLocaleDateString()
875
1126
  ]
876
1127
  }, undefined, true, undefined, this),
877
- /* @__PURE__ */ jsxDEV3("p", {
1128
+ /* @__PURE__ */ jsxDEV4("p", {
878
1129
  className: "text-muted-foreground text-sm",
879
1130
  children: [
880
1131
  "Billing cycle: ",
@@ -883,21 +1134,21 @@ function BillingTab({ subscription }) {
883
1134
  }, undefined, true, undefined, this)
884
1135
  ]
885
1136
  }, undefined, true, undefined, this),
886
- /* @__PURE__ */ jsxDEV3(StatusChip, {
1137
+ /* @__PURE__ */ jsxDEV4(StatusChip, {
887
1138
  tone: "success",
888
1139
  label: subscription.status
889
1140
  }, undefined, false, undefined, this)
890
1141
  ]
891
1142
  }, undefined, true, undefined, this),
892
- /* @__PURE__ */ jsxDEV3("div", {
1143
+ /* @__PURE__ */ jsxDEV4("div", {
893
1144
  className: "mt-4 flex gap-3",
894
1145
  children: [
895
- /* @__PURE__ */ jsxDEV3(Button3, {
1146
+ /* @__PURE__ */ jsxDEV4(Button3, {
896
1147
  variant: "outline",
897
1148
  onPress: () => alert("Upgrade clicked!"),
898
1149
  children: "Upgrade Plan"
899
1150
  }, undefined, false, undefined, this),
900
- /* @__PURE__ */ jsxDEV3(Button3, {
1151
+ /* @__PURE__ */ jsxDEV4(Button3, {
901
1152
  variant: "ghost",
902
1153
  onPress: () => alert("Manage Billing clicked!"),
903
1154
  children: "Manage Billing"
@@ -906,10 +1157,10 @@ function BillingTab({ subscription }) {
906
1157
  }, undefined, true, undefined, this)
907
1158
  ]
908
1159
  }, undefined, true, undefined, this),
909
- subscription.cancelAtPeriodEnd && /* @__PURE__ */ jsxDEV3("div", {
910
- className: "border-border bg-destructive/10 text-destructive rounded-xl border p-4",
911
- children: /* @__PURE__ */ jsxDEV3("p", {
912
- className: "text-sm font-medium",
1160
+ subscription.cancelAtPeriodEnd && /* @__PURE__ */ jsxDEV4("div", {
1161
+ className: "rounded-xl border border-border bg-destructive/10 p-4 text-destructive",
1162
+ children: /* @__PURE__ */ jsxDEV4("p", {
1163
+ className: "font-medium text-sm",
913
1164
  children: "\u26A0\uFE0F Your subscription will be cancelled at the end of the current period."
914
1165
  }, undefined, false, undefined, this)
915
1166
  }, undefined, false, undefined, this)
@@ -917,63 +1168,63 @@ function BillingTab({ subscription }) {
917
1168
  }, undefined, true, undefined, this);
918
1169
  }
919
1170
  function SettingsTab() {
920
- return /* @__PURE__ */ jsxDEV3("div", {
1171
+ return /* @__PURE__ */ jsxDEV4("div", {
921
1172
  className: "space-y-6",
922
- children: /* @__PURE__ */ jsxDEV3("div", {
923
- className: "border-border bg-card rounded-xl border p-6",
1173
+ children: /* @__PURE__ */ jsxDEV4("div", {
1174
+ className: "rounded-xl border border-border bg-card p-6",
924
1175
  children: [
925
- /* @__PURE__ */ jsxDEV3("h3", {
926
- className: "mb-4 text-lg font-semibold",
1176
+ /* @__PURE__ */ jsxDEV4("h3", {
1177
+ className: "mb-4 font-semibold text-lg",
927
1178
  children: "Organization Settings"
928
1179
  }, undefined, false, undefined, this),
929
- /* @__PURE__ */ jsxDEV3("div", {
1180
+ /* @__PURE__ */ jsxDEV4("div", {
930
1181
  className: "space-y-4",
931
1182
  children: [
932
- /* @__PURE__ */ jsxDEV3("div", {
1183
+ /* @__PURE__ */ jsxDEV4("div", {
933
1184
  children: [
934
- /* @__PURE__ */ jsxDEV3("label", {
1185
+ /* @__PURE__ */ jsxDEV4("label", {
935
1186
  htmlFor: "org-name",
936
- className: "text-sm font-medium",
1187
+ className: "font-medium text-sm",
937
1188
  children: "Organization Name"
938
1189
  }, undefined, false, undefined, this),
939
- /* @__PURE__ */ jsxDEV3("input", {
1190
+ /* @__PURE__ */ jsxDEV4("input", {
940
1191
  id: "org-name",
941
1192
  type: "text",
942
1193
  defaultValue: "Demo Organization",
943
- className: "border-input bg-background mt-1 block w-full rounded-md border px-3 py-2"
1194
+ className: "mt-1 block w-full rounded-md border border-input bg-background px-3 py-2"
944
1195
  }, undefined, false, undefined, this)
945
1196
  ]
946
1197
  }, undefined, true, undefined, this),
947
- /* @__PURE__ */ jsxDEV3("div", {
1198
+ /* @__PURE__ */ jsxDEV4("div", {
948
1199
  children: [
949
- /* @__PURE__ */ jsxDEV3("label", {
1200
+ /* @__PURE__ */ jsxDEV4("label", {
950
1201
  htmlFor: "timezone",
951
- className: "text-sm font-medium",
1202
+ className: "font-medium text-sm",
952
1203
  children: "Default Timezone"
953
1204
  }, undefined, false, undefined, this),
954
- /* @__PURE__ */ jsxDEV3("select", {
1205
+ /* @__PURE__ */ jsxDEV4("select", {
955
1206
  id: "timezone",
956
- className: "border-input bg-background mt-1 block w-full rounded-md border px-3 py-2",
1207
+ className: "mt-1 block w-full rounded-md border border-input bg-background px-3 py-2",
957
1208
  children: [
958
- /* @__PURE__ */ jsxDEV3("option", {
1209
+ /* @__PURE__ */ jsxDEV4("option", {
959
1210
  children: "UTC"
960
1211
  }, undefined, false, undefined, this),
961
- /* @__PURE__ */ jsxDEV3("option", {
1212
+ /* @__PURE__ */ jsxDEV4("option", {
962
1213
  children: "America/New_York"
963
1214
  }, undefined, false, undefined, this),
964
- /* @__PURE__ */ jsxDEV3("option", {
1215
+ /* @__PURE__ */ jsxDEV4("option", {
965
1216
  children: "Europe/London"
966
1217
  }, undefined, false, undefined, this),
967
- /* @__PURE__ */ jsxDEV3("option", {
1218
+ /* @__PURE__ */ jsxDEV4("option", {
968
1219
  children: "Asia/Tokyo"
969
1220
  }, undefined, false, undefined, this)
970
1221
  ]
971
1222
  }, undefined, true, undefined, this)
972
1223
  ]
973
1224
  }, undefined, true, undefined, this),
974
- /* @__PURE__ */ jsxDEV3("div", {
1225
+ /* @__PURE__ */ jsxDEV4("div", {
975
1226
  className: "pt-2",
976
- children: /* @__PURE__ */ jsxDEV3(Button3, {
1227
+ children: /* @__PURE__ */ jsxDEV4(Button3, {
977
1228
  onPress: () => alert("Settings saved!"),
978
1229
  children: "Save Settings"
979
1230
  }, undefined, false, undefined, this)