@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.
- package/.turbo/turbo-build.log +39 -27
- package/AGENTS.md +50 -27
- package/CHANGELOG.md +36 -0
- package/README.md +65 -144
- package/dist/billing/billing.event.js +1 -1
- package/dist/billing/index.d.ts +6 -6
- package/dist/billing/index.js +1 -1
- package/dist/browser/billing/billing.event.js +1 -1
- package/dist/browser/billing/index.js +1 -1
- package/dist/browser/index.js +1147 -869
- package/dist/browser/project/index.js +209 -209
- package/dist/browser/project/project.event.js +1 -1
- package/dist/browser/saas-boilerplate.feature.js +208 -0
- package/dist/browser/ui/SaasDashboard.js +356 -105
- package/dist/browser/ui/SaasDashboard.visualizations.js +249 -0
- package/dist/browser/ui/SaasProjectList.js +7 -7
- package/dist/browser/ui/SaasSettingsPanel.js +12 -12
- package/dist/browser/ui/hooks/index.js +2 -2
- package/dist/browser/ui/hooks/useProjectList.js +1 -1
- package/dist/browser/ui/hooks/useProjectMutations.js +1 -1
- package/dist/browser/ui/index.js +790 -521
- package/dist/browser/ui/modals/CreateProjectModal.js +10 -10
- package/dist/browser/ui/modals/ProjectActionsModal.js +13 -13
- package/dist/browser/ui/modals/index.js +23 -23
- package/dist/browser/ui/renderers/index.js +341 -115
- package/dist/browser/ui/renderers/project-list.markdown.js +229 -3
- package/dist/browser/ui/renderers/project-list.renderer.js +7 -7
- package/dist/browser/visualizations/catalog.js +155 -0
- package/dist/browser/visualizations/index.js +217 -0
- package/dist/browser/visualizations/selectors.js +210 -0
- package/dist/handlers/index.d.ts +2 -2
- package/dist/index.d.ts +5 -4
- package/dist/index.js +1147 -869
- package/dist/node/billing/billing.event.js +1 -1
- package/dist/node/billing/index.js +1 -1
- package/dist/node/index.js +1147 -869
- package/dist/node/project/index.js +209 -209
- package/dist/node/project/project.event.js +1 -1
- package/dist/node/saas-boilerplate.feature.js +208 -0
- package/dist/node/ui/SaasDashboard.js +356 -105
- package/dist/node/ui/SaasDashboard.visualizations.js +249 -0
- package/dist/node/ui/SaasProjectList.js +7 -7
- package/dist/node/ui/SaasSettingsPanel.js +12 -12
- package/dist/node/ui/hooks/index.js +2 -2
- package/dist/node/ui/hooks/useProjectList.js +1 -1
- package/dist/node/ui/hooks/useProjectMutations.js +1 -1
- package/dist/node/ui/index.js +790 -521
- package/dist/node/ui/modals/CreateProjectModal.js +10 -10
- package/dist/node/ui/modals/ProjectActionsModal.js +13 -13
- package/dist/node/ui/modals/index.js +23 -23
- package/dist/node/ui/renderers/index.js +341 -115
- package/dist/node/ui/renderers/project-list.markdown.js +229 -3
- package/dist/node/ui/renderers/project-list.renderer.js +7 -7
- package/dist/node/visualizations/catalog.js +155 -0
- package/dist/node/visualizations/index.js +217 -0
- package/dist/node/visualizations/selectors.js +210 -0
- package/dist/presentations/index.d.ts +1 -1
- package/dist/project/index.d.ts +7 -7
- package/dist/project/index.js +209 -209
- package/dist/project/project.event.js +1 -1
- package/dist/saas-boilerplate.feature.js +208 -0
- package/dist/settings/index.d.ts +1 -1
- package/dist/ui/SaasDashboard.js +356 -105
- package/dist/ui/SaasDashboard.visualizations.d.ts +5 -0
- package/dist/ui/SaasDashboard.visualizations.js +250 -0
- package/dist/ui/SaasProjectList.js +7 -7
- package/dist/ui/SaasSettingsPanel.js +12 -12
- package/dist/ui/hooks/index.d.ts +2 -2
- package/dist/ui/hooks/index.js +2 -2
- package/dist/ui/hooks/useProjectList.d.ts +5 -0
- package/dist/ui/hooks/useProjectList.js +1 -1
- package/dist/ui/hooks/useProjectMutations.d.ts +8 -0
- package/dist/ui/hooks/useProjectMutations.js +1 -1
- package/dist/ui/index.d.ts +4 -4
- package/dist/ui/index.js +790 -521
- package/dist/ui/modals/CreateProjectModal.js +10 -10
- package/dist/ui/modals/ProjectActionsModal.js +13 -13
- package/dist/ui/modals/index.js +23 -23
- package/dist/ui/renderers/index.d.ts +1 -1
- package/dist/ui/renderers/index.js +341 -115
- package/dist/ui/renderers/project-list.markdown.js +229 -3
- package/dist/ui/renderers/project-list.renderer.d.ts +1 -1
- package/dist/ui/renderers/project-list.renderer.js +7 -7
- package/dist/visualizations/catalog.d.ts +11 -0
- package/dist/visualizations/catalog.js +156 -0
- package/dist/visualizations/index.d.ts +2 -0
- package/dist/visualizations/index.js +218 -0
- package/dist/visualizations/selectors.d.ts +8 -0
- package/dist/visualizations/selectors.js +211 -0
- package/dist/visualizations/selectors.test.d.ts +1 -0
- package/package.json +70 -14
- package/src/billing/billing.entity.ts +132 -132
- package/src/billing/billing.enum.ts +9 -9
- package/src/billing/billing.event.ts +71 -71
- package/src/billing/billing.handler.ts +87 -87
- package/src/billing/billing.operations.ts +158 -158
- package/src/billing/billing.presentation.ts +45 -45
- package/src/billing/billing.schema.ts +76 -76
- package/src/billing/index.ts +43 -48
- package/src/dashboard/dashboard.presentation.ts +45 -45
- package/src/dashboard/index.ts +2 -2
- package/src/docs/saas-boilerplate.docblock.ts +43 -43
- package/src/example.ts +32 -32
- package/src/handlers/index.ts +9 -9
- package/src/handlers/saas.handlers.ts +250 -249
- package/src/index.ts +41 -41
- package/src/presentations/index.ts +18 -20
- package/src/project/index.ts +45 -50
- package/src/project/project.entity.ts +68 -68
- package/src/project/project.enum.ts +8 -8
- package/src/project/project.event.ts +79 -79
- package/src/project/project.handler.ts +103 -103
- package/src/project/project.operations.ts +236 -236
- package/src/project/project.presentation.ts +46 -46
- package/src/project/project.schema.ts +90 -90
- package/src/saas-boilerplate.feature.ts +103 -100
- package/src/seeders/index.ts +20 -20
- package/src/settings/index.ts +2 -3
- package/src/settings/settings.entity.ts +65 -65
- package/src/settings/settings.enum.ts +4 -4
- package/src/shared/mock-data.ts +92 -92
- package/src/shared/overlay-types.ts +23 -23
- package/src/tests/operations.test-spec.ts +96 -96
- package/src/ui/SaasDashboard.tsx +278 -270
- package/src/ui/SaasDashboard.visualizations.tsx +41 -0
- package/src/ui/SaasProjectList.tsx +90 -90
- package/src/ui/SaasSettingsPanel.tsx +84 -84
- package/src/ui/hooks/index.ts +3 -3
- package/src/ui/hooks/useProjectList.ts +69 -68
- package/src/ui/hooks/useProjectMutations.ts +144 -143
- package/src/ui/index.ts +8 -12
- package/src/ui/modals/CreateProjectModal.tsx +154 -154
- package/src/ui/modals/ProjectActionsModal.tsx +321 -321
- package/src/ui/overlays/demo-overlays.ts +49 -49
- package/src/ui/renderers/index.ts +5 -4
- package/src/ui/renderers/project-list.markdown.ts +229 -205
- package/src/ui/renderers/project-list.renderer.tsx +14 -13
- package/src/visualizations/catalog.ts +153 -0
- package/src/visualizations/index.ts +2 -0
- package/src/visualizations/selectors.test.ts +25 -0
- package/src/visualizations/selectors.ts +85 -0
- package/tsconfig.json +7 -8
- package/tsdown.config.js +7 -3
package/dist/ui/SaasDashboard.js
CHANGED
|
@@ -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
|
|
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: "
|
|
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
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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
|
|
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
|
|
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: "
|
|
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: "
|
|
622
|
+
className: "mb-4 border-border border-b pb-4",
|
|
416
623
|
children: [
|
|
417
624
|
/* @__PURE__ */ jsxDEV2("h2", {
|
|
418
|
-
className: "text-xl
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
643
|
-
StatCardGroup,
|
|
644
|
-
StatusChip,
|
|
645
|
-
EntityCard,
|
|
888
|
+
Button as Button3,
|
|
646
889
|
EmptyState,
|
|
647
|
-
|
|
890
|
+
EntityCard,
|
|
648
891
|
ErrorState,
|
|
649
|
-
|
|
892
|
+
LoaderBlock,
|
|
893
|
+
StatCard,
|
|
894
|
+
StatCardGroup,
|
|
895
|
+
StatusChip
|
|
650
896
|
} from "@contractspec/lib.design-system";
|
|
651
|
-
import {
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
945
|
+
return /* @__PURE__ */ jsxDEV4("div", {
|
|
699
946
|
className: "space-y-6",
|
|
700
947
|
children: [
|
|
701
|
-
/* @__PURE__ */
|
|
948
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
702
949
|
className: "flex items-center justify-between",
|
|
703
950
|
children: [
|
|
704
|
-
/* @__PURE__ */
|
|
705
|
-
className: "text-2xl
|
|
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__ */
|
|
955
|
+
activeTab === "projects" && /* @__PURE__ */ jsxDEV4(Button3, {
|
|
709
956
|
onPress: () => setIsCreateModalOpen(true),
|
|
710
957
|
children: [
|
|
711
|
-
/* @__PURE__ */
|
|
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__ */
|
|
967
|
+
stats && subscription && /* @__PURE__ */ jsxDEV4(StatCardGroup, {
|
|
721
968
|
children: [
|
|
722
|
-
/* @__PURE__ */
|
|
969
|
+
/* @__PURE__ */ jsxDEV4(StatCard, {
|
|
723
970
|
label: "Projects",
|
|
724
971
|
value: stats.total.toString()
|
|
725
972
|
}, undefined, false, undefined, this),
|
|
726
|
-
/* @__PURE__ */
|
|
973
|
+
/* @__PURE__ */ jsxDEV4(StatCard, {
|
|
727
974
|
label: "Active",
|
|
728
975
|
value: stats.activeCount.toString()
|
|
729
976
|
}, undefined, false, undefined, this),
|
|
730
|
-
/* @__PURE__ */
|
|
977
|
+
/* @__PURE__ */ jsxDEV4(StatCard, {
|
|
731
978
|
label: "Draft",
|
|
732
979
|
value: stats.draftCount.toString()
|
|
733
980
|
}, undefined, false, undefined, this),
|
|
734
|
-
/* @__PURE__ */
|
|
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__ */
|
|
742
|
-
|
|
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__ */
|
|
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
|
|
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__ */
|
|
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__ */
|
|
1009
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
759
1010
|
className: "min-h-[400px]",
|
|
760
1011
|
role: "tabpanel",
|
|
761
1012
|
children: [
|
|
762
|
-
activeTab === "projects" && /* @__PURE__ */
|
|
1013
|
+
activeTab === "projects" && /* @__PURE__ */ jsxDEV4(ProjectsTab, {
|
|
763
1014
|
data,
|
|
764
1015
|
onProjectClick: handleProjectClick
|
|
765
1016
|
}, undefined, false, undefined, this),
|
|
766
|
-
activeTab === "billing" && /* @__PURE__ */
|
|
1017
|
+
activeTab === "billing" && /* @__PURE__ */ jsxDEV4(BillingTab, {
|
|
767
1018
|
subscription
|
|
768
1019
|
}, undefined, false, undefined, this),
|
|
769
|
-
activeTab === "settings" && /* @__PURE__ */
|
|
1020
|
+
activeTab === "settings" && /* @__PURE__ */ jsxDEV4(SettingsTab, {}, undefined, false, undefined, this)
|
|
770
1021
|
]
|
|
771
1022
|
}, undefined, true, undefined, this),
|
|
772
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1062
|
+
return /* @__PURE__ */ jsxDEV4("div", {
|
|
812
1063
|
className: "space-y-4",
|
|
813
|
-
children: /* @__PURE__ */
|
|
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__ */
|
|
1066
|
+
children: data.items.map((project) => /* @__PURE__ */ jsxDEV4(EntityCard, {
|
|
816
1067
|
cardTitle: project.name,
|
|
817
1068
|
cardSubtitle: project.tier,
|
|
818
|
-
meta: /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
1077
|
+
footer: /* @__PURE__ */ jsxDEV4("div", {
|
|
827
1078
|
className: "flex w-full items-center justify-between",
|
|
828
1079
|
children: [
|
|
829
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
1099
|
+
return /* @__PURE__ */ jsxDEV4("div", {
|
|
849
1100
|
className: "space-y-6",
|
|
850
1101
|
children: [
|
|
851
|
-
/* @__PURE__ */
|
|
852
|
-
className: "border-border bg-card
|
|
1102
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
1103
|
+
className: "rounded-xl border border-border bg-card p-6",
|
|
853
1104
|
children: [
|
|
854
|
-
/* @__PURE__ */
|
|
1105
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
855
1106
|
className: "flex items-start justify-between",
|
|
856
1107
|
children: [
|
|
857
|
-
/* @__PURE__ */
|
|
1108
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
858
1109
|
children: [
|
|
859
|
-
/* @__PURE__ */
|
|
860
|
-
className: "text-lg
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1143
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
893
1144
|
className: "mt-4 flex gap-3",
|
|
894
1145
|
children: [
|
|
895
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
910
|
-
className: "border-border bg-destructive/10 text-destructive
|
|
911
|
-
children: /* @__PURE__ */
|
|
912
|
-
className: "text-sm
|
|
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__ */
|
|
1171
|
+
return /* @__PURE__ */ jsxDEV4("div", {
|
|
921
1172
|
className: "space-y-6",
|
|
922
|
-
children: /* @__PURE__ */
|
|
923
|
-
className: "border-border bg-card
|
|
1173
|
+
children: /* @__PURE__ */ jsxDEV4("div", {
|
|
1174
|
+
className: "rounded-xl border border-border bg-card p-6",
|
|
924
1175
|
children: [
|
|
925
|
-
/* @__PURE__ */
|
|
926
|
-
className: "mb-4 text-lg
|
|
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__ */
|
|
1180
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
930
1181
|
className: "space-y-4",
|
|
931
1182
|
children: [
|
|
932
|
-
/* @__PURE__ */
|
|
1183
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
933
1184
|
children: [
|
|
934
|
-
/* @__PURE__ */
|
|
1185
|
+
/* @__PURE__ */ jsxDEV4("label", {
|
|
935
1186
|
htmlFor: "org-name",
|
|
936
|
-
className: "text-sm
|
|
1187
|
+
className: "font-medium text-sm",
|
|
937
1188
|
children: "Organization Name"
|
|
938
1189
|
}, undefined, false, undefined, this),
|
|
939
|
-
/* @__PURE__ */
|
|
1190
|
+
/* @__PURE__ */ jsxDEV4("input", {
|
|
940
1191
|
id: "org-name",
|
|
941
1192
|
type: "text",
|
|
942
1193
|
defaultValue: "Demo Organization",
|
|
943
|
-
className: "
|
|
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__ */
|
|
1198
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
948
1199
|
children: [
|
|
949
|
-
/* @__PURE__ */
|
|
1200
|
+
/* @__PURE__ */ jsxDEV4("label", {
|
|
950
1201
|
htmlFor: "timezone",
|
|
951
|
-
className: "text-sm
|
|
1202
|
+
className: "font-medium text-sm",
|
|
952
1203
|
children: "Default Timezone"
|
|
953
1204
|
}, undefined, false, undefined, this),
|
|
954
|
-
/* @__PURE__ */
|
|
1205
|
+
/* @__PURE__ */ jsxDEV4("select", {
|
|
955
1206
|
id: "timezone",
|
|
956
|
-
className: "
|
|
1207
|
+
className: "mt-1 block w-full rounded-md border border-input bg-background px-3 py-2",
|
|
957
1208
|
children: [
|
|
958
|
-
/* @__PURE__ */
|
|
1209
|
+
/* @__PURE__ */ jsxDEV4("option", {
|
|
959
1210
|
children: "UTC"
|
|
960
1211
|
}, undefined, false, undefined, this),
|
|
961
|
-
/* @__PURE__ */
|
|
1212
|
+
/* @__PURE__ */ jsxDEV4("option", {
|
|
962
1213
|
children: "America/New_York"
|
|
963
1214
|
}, undefined, false, undefined, this),
|
|
964
|
-
/* @__PURE__ */
|
|
1215
|
+
/* @__PURE__ */ jsxDEV4("option", {
|
|
965
1216
|
children: "Europe/London"
|
|
966
1217
|
}, undefined, false, undefined, this),
|
|
967
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1225
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
975
1226
|
className: "pt-2",
|
|
976
|
-
children: /* @__PURE__ */
|
|
1227
|
+
children: /* @__PURE__ */ jsxDEV4(Button3, {
|
|
977
1228
|
onPress: () => alert("Settings saved!"),
|
|
978
1229
|
children: "Save Settings"
|
|
979
1230
|
}, undefined, false, undefined, this)
|