@gtcx/templates 0.1.0

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 (51) hide show
  1. package/dist/components/audit-trail.d.ts +19 -0
  2. package/dist/components/audit-trail.d.ts.map +1 -0
  3. package/dist/components/bulk-actions.d.ts +16 -0
  4. package/dist/components/bulk-actions.d.ts.map +1 -0
  5. package/dist/components/kpi-card.d.ts +15 -0
  6. package/dist/components/kpi-card.d.ts.map +1 -0
  7. package/dist/components/page-header.d.ts +9 -0
  8. package/dist/components/page-header.d.ts.map +1 -0
  9. package/dist/components/section-card.d.ts +10 -0
  10. package/dist/components/section-card.d.ts.map +1 -0
  11. package/dist/index.cjs +757 -0
  12. package/dist/index.d.cts +282 -0
  13. package/dist/index.d.ts +43 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +1433 -0
  16. package/dist/index.mjs +1386 -0
  17. package/dist/template-frame.d.ts +19 -0
  18. package/dist/template-frame.d.ts.map +1 -0
  19. package/dist/templates/activity.d.ts +24 -0
  20. package/dist/templates/activity.d.ts.map +1 -0
  21. package/dist/templates/auth-shell.d.ts +11 -0
  22. package/dist/templates/auth-shell.d.ts.map +1 -0
  23. package/dist/templates/billing.d.ts +35 -0
  24. package/dist/templates/billing.d.ts.map +1 -0
  25. package/dist/templates/dashboard.d.ts +37 -0
  26. package/dist/templates/dashboard.d.ts.map +1 -0
  27. package/dist/templates/detail.d.ts +33 -0
  28. package/dist/templates/detail.d.ts.map +1 -0
  29. package/dist/templates/error.d.ts +12 -0
  30. package/dist/templates/error.d.ts.map +1 -0
  31. package/dist/templates/invite.d.ts +22 -0
  32. package/dist/templates/invite.d.ts.map +1 -0
  33. package/dist/templates/list.d.ts +48 -0
  34. package/dist/templates/list.d.ts.map +1 -0
  35. package/dist/templates/members.d.ts +28 -0
  36. package/dist/templates/members.d.ts.map +1 -0
  37. package/dist/templates/notifications.d.ts +24 -0
  38. package/dist/templates/notifications.d.ts.map +1 -0
  39. package/dist/templates/profile.d.ts +31 -0
  40. package/dist/templates/profile.d.ts.map +1 -0
  41. package/dist/templates/projects.d.ts +27 -0
  42. package/dist/templates/projects.d.ts.map +1 -0
  43. package/dist/templates/security.d.ts +34 -0
  44. package/dist/templates/security.d.ts.map +1 -0
  45. package/dist/templates/settings.d.ts +19 -0
  46. package/dist/templates/settings.d.ts.map +1 -0
  47. package/dist/templates/wizard.d.ts +22 -0
  48. package/dist/templates/wizard.d.ts.map +1 -0
  49. package/dist/types.d.ts +52 -0
  50. package/dist/types.d.ts.map +1 -0
  51. package/package.json +44 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,1386 @@
1
+ // src/types.ts
2
+ function templateActionsToPageHeaderActions(actions) {
3
+ return actions.map((action) => ({
4
+ key: action.key,
5
+ label: action.label,
6
+ onClick: action.onAction,
7
+ kind: action.kind,
8
+ disabled: action.disabled,
9
+ ariaLabel: action.ariaLabel,
10
+ icon: action.icon
11
+ }));
12
+ }
13
+
14
+ // src/template-frame.tsx
15
+ import { Card, Typography as Typography2, Space as Space2, theme as theme2 } from "antd";
16
+
17
+ // src/components/page-header.tsx
18
+ import { Typography, Space, Button, Breadcrumb, theme } from "antd";
19
+ import { jsx, jsxs } from "react/jsx-runtime";
20
+ var { Title, Text } = Typography;
21
+ function PageHeader({ title, subtitle, breadcrumbs, actions }) {
22
+ const { token } = theme.useToken();
23
+ return /* @__PURE__ */ jsxs("header", { style: { marginBottom: token.marginLG }, children: [
24
+ breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(
25
+ Breadcrumb,
26
+ {
27
+ style: { marginBottom: token.marginSM },
28
+ items: breadcrumbs.map((item) => ({
29
+ title: item.href ? /* @__PURE__ */ jsx("a", { href: item.href, style: { color: token.colorText }, children: item.label }) : item.label
30
+ }))
31
+ }
32
+ ),
33
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "flex-start" }, children: [
34
+ /* @__PURE__ */ jsxs("div", { children: [
35
+ /* @__PURE__ */ jsx(Title, { level: 3, style: { margin: 0 }, children: title }),
36
+ subtitle && /* @__PURE__ */ jsx(Text, { style: { marginTop: token.marginXXS, color: token.colorTextSecondary }, children: subtitle })
37
+ ] }),
38
+ actions && actions.length > 0 && /* @__PURE__ */ jsx(Space, { children: actions.map((action) => /* @__PURE__ */ jsx(
39
+ Button,
40
+ {
41
+ type: action.kind === "primary" ? "primary" : action.kind === "link" ? "link" : "default",
42
+ danger: action.kind === "danger",
43
+ disabled: action.disabled,
44
+ icon: action.icon,
45
+ onClick: action.onClick,
46
+ "aria-label": action.ariaLabel,
47
+ children: action.label
48
+ },
49
+ action.key
50
+ )) })
51
+ ] })
52
+ ] });
53
+ }
54
+
55
+ // src/template-frame.tsx
56
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
57
+ var { Text: Text2 } = Typography2;
58
+ function TemplateFrame({
59
+ title,
60
+ subtitle,
61
+ breadcrumbs,
62
+ data: _data,
63
+ actions,
64
+ filters,
65
+ audit,
66
+ layout,
67
+ children
68
+ }) {
69
+ const { token } = theme2.useToken();
70
+ const showBreadcrumbs = layout?.showBreadcrumbs ?? true;
71
+ const contentPadding = layout?.contentPadding ?? void 0;
72
+ const pageHeaderActions = actions ? templateActionsToPageHeaderActions(actions) : void 0;
73
+ return /* @__PURE__ */ jsxs2("div", { style: { padding: contentPadding }, children: [
74
+ /* @__PURE__ */ jsx2(
75
+ PageHeader,
76
+ {
77
+ title,
78
+ subtitle,
79
+ breadcrumbs: showBreadcrumbs ? breadcrumbs : void 0,
80
+ actions: pageHeaderActions
81
+ }
82
+ ),
83
+ filters?.content && /* @__PURE__ */ jsx2("div", { style: { marginBottom: token.marginLG }, children: filters.content }),
84
+ /* @__PURE__ */ jsx2("main", { children }),
85
+ audit && /* @__PURE__ */ jsx2(
86
+ Card,
87
+ {
88
+ size: "small",
89
+ style: { marginTop: token.marginXL },
90
+ styles: { body: { padding: token.paddingSM } },
91
+ children: /* @__PURE__ */ jsxs2(Space2, { direction: "vertical", size: 4, children: [
92
+ audit.summary && /* @__PURE__ */ jsx2(Text2, { style: { color: token.colorTextSecondary }, children: audit.summary }),
93
+ /* @__PURE__ */ jsxs2(Space2, { size: "large", wrap: true, children: [
94
+ audit.lastUpdatedAt && /* @__PURE__ */ jsxs2(Text2, { style: { fontSize: token.fontSizeSM, color: token.colorTextSecondary }, children: [
95
+ "Updated: ",
96
+ /* @__PURE__ */ jsx2("time", { dateTime: audit.lastUpdatedAt, children: audit.lastUpdatedAt })
97
+ ] }),
98
+ audit.lastUpdatedBy && /* @__PURE__ */ jsxs2(Text2, { style: { fontSize: token.fontSizeSM, color: token.colorTextSecondary }, children: [
99
+ "By: ",
100
+ audit.lastUpdatedBy
101
+ ] }),
102
+ audit.sourceSystem && /* @__PURE__ */ jsxs2(Text2, { style: { fontSize: token.fontSizeSM, color: token.colorTextSecondary }, children: [
103
+ "Source: ",
104
+ audit.sourceSystem
105
+ ] }),
106
+ audit.evidenceUrl && /* @__PURE__ */ jsx2(
107
+ "a",
108
+ {
109
+ href: audit.evidenceUrl,
110
+ target: "_blank",
111
+ rel: "noopener noreferrer",
112
+ style: { fontSize: token.fontSizeSM, color: token.colorPrimary },
113
+ children: "View Evidence"
114
+ }
115
+ )
116
+ ] })
117
+ ] })
118
+ }
119
+ )
120
+ ] });
121
+ }
122
+
123
+ // src/components/kpi-card.tsx
124
+ import { ArrowUpOutlined, ArrowDownOutlined, MinusOutlined } from "@ant-design/icons";
125
+ import { Card as Card2, Typography as Typography3, Space as Space3, theme as theme3 } from "antd";
126
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
127
+ var { Text: Text3, Title: Title2 } = Typography3;
128
+ function KpiCard({
129
+ label,
130
+ value,
131
+ delta,
132
+ trend,
133
+ helpText,
134
+ icon,
135
+ onClick,
136
+ "aria-label": ariaLabel
137
+ }) {
138
+ const { token } = theme3.useToken();
139
+ const trendColor = trend === "up" ? token.colorSuccess : trend === "down" ? token.colorError : token.colorTextSecondary;
140
+ const TrendIcon = trend === "up" ? ArrowUpOutlined : trend === "down" ? ArrowDownOutlined : MinusOutlined;
141
+ const isInteractive = !!onClick;
142
+ const handleKeyDown = (e) => {
143
+ if (isInteractive && (e.key === "Enter" || e.key === " ")) {
144
+ e.preventDefault();
145
+ onClick?.();
146
+ }
147
+ };
148
+ return /* @__PURE__ */ jsx3(
149
+ Card2,
150
+ {
151
+ size: "small",
152
+ hoverable: isInteractive,
153
+ onClick,
154
+ tabIndex: isInteractive ? 0 : void 0,
155
+ role: isInteractive ? "button" : void 0,
156
+ onKeyDown: isInteractive ? handleKeyDown : void 0,
157
+ "aria-label": ariaLabel ?? label,
158
+ styles: { body: { padding: token.paddingMD } },
159
+ children: /* @__PURE__ */ jsxs3(Space3, { direction: "vertical", size: 4, style: { width: "100%" }, children: [
160
+ /* @__PURE__ */ jsxs3(Space3, { size: "small", children: [
161
+ icon && /* @__PURE__ */ jsx3("span", { style: { color: token.colorTextSecondary }, children: icon }),
162
+ /* @__PURE__ */ jsx3(Text3, { type: "secondary", style: { fontSize: token.fontSizeSM }, children: label })
163
+ ] }),
164
+ /* @__PURE__ */ jsx3(Title2, { level: 3, style: { margin: 0 }, children: value }),
165
+ (delta || helpText) && /* @__PURE__ */ jsxs3(Space3, { size: "small", children: [
166
+ delta && trend && /* @__PURE__ */ jsxs3(Text3, { style: { color: trendColor, fontSize: token.fontSizeSM }, children: [
167
+ /* @__PURE__ */ jsx3(TrendIcon, { style: { marginRight: 4 } }),
168
+ delta
169
+ ] }),
170
+ helpText && /* @__PURE__ */ jsx3(Text3, { type: "secondary", style: { fontSize: token.fontSizeSM }, children: helpText })
171
+ ] })
172
+ ] })
173
+ }
174
+ );
175
+ }
176
+
177
+ // src/components/section-card.tsx
178
+ import { Card as Card3, Typography as Typography4, theme as theme4 } from "antd";
179
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
180
+ var { Title: Title3 } = Typography4;
181
+ function SectionCard({ title, subtitle, extra, children, noPadding }) {
182
+ const { token } = theme4.useToken();
183
+ return /* @__PURE__ */ jsxs4(
184
+ Card3,
185
+ {
186
+ role: "region",
187
+ "aria-label": title,
188
+ styles: { body: noPadding ? { padding: 0 } : void 0 },
189
+ children: [
190
+ (title || extra) && /* @__PURE__ */ jsxs4(
191
+ "div",
192
+ {
193
+ style: {
194
+ display: "flex",
195
+ justifyContent: "space-between",
196
+ alignItems: "flex-start",
197
+ marginBottom: token.marginMD
198
+ },
199
+ children: [
200
+ /* @__PURE__ */ jsxs4("div", { children: [
201
+ title && /* @__PURE__ */ jsx4(Title3, { level: 4, style: { margin: 0 }, children: title }),
202
+ subtitle && /* @__PURE__ */ jsx4("span", { style: { color: token.colorTextSecondary, fontSize: token.fontSizeSM }, children: subtitle })
203
+ ] }),
204
+ extra && /* @__PURE__ */ jsx4("div", { children: extra })
205
+ ]
206
+ }
207
+ ),
208
+ children
209
+ ]
210
+ }
211
+ );
212
+ }
213
+
214
+ // src/components/bulk-actions.tsx
215
+ import { Button as Button2, Space as Space4, Typography as Typography5, theme as theme5 } from "antd";
216
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
217
+ var { Text: Text4 } = Typography5;
218
+ function BulkActionsBar({
219
+ selectedCount,
220
+ selectedRowKeys,
221
+ actions,
222
+ onClear
223
+ }) {
224
+ const { token } = theme5.useToken();
225
+ if (selectedCount === 0) return null;
226
+ return /* @__PURE__ */ jsxs5(
227
+ "div",
228
+ {
229
+ role: "toolbar",
230
+ "aria-label": "Bulk actions",
231
+ style: {
232
+ display: "flex",
233
+ alignItems: "center",
234
+ justifyContent: "space-between",
235
+ padding: `${token.paddingSM}px ${token.paddingMD}px`,
236
+ background: token.colorBgContainer,
237
+ border: `1px solid ${token.colorPrimaryBorder ?? token.colorPrimary}`,
238
+ borderRadius: token.borderRadius,
239
+ marginBottom: token.marginMD
240
+ },
241
+ children: [
242
+ /* @__PURE__ */ jsxs5(Space4, { children: [
243
+ /* @__PURE__ */ jsxs5(Text4, { strong: true, "aria-live": "polite", children: [
244
+ selectedCount,
245
+ " selected"
246
+ ] }),
247
+ onClear && /* @__PURE__ */ jsx5(Button2, { type: "text", size: "small", onClick: onClear, children: "Clear" })
248
+ ] }),
249
+ /* @__PURE__ */ jsx5(Space4, { children: actions.map((action) => {
250
+ const isDanger = action.kind === "danger";
251
+ return /* @__PURE__ */ jsx5(
252
+ Button2,
253
+ {
254
+ type: isDanger ? "default" : action.kind === "primary" ? "primary" : action.kind === "link" ? "link" : "default",
255
+ danger: isDanger,
256
+ size: "small",
257
+ disabled: action.disabled,
258
+ onClick: () => action.onAction(selectedRowKeys),
259
+ children: action.label
260
+ },
261
+ action.key
262
+ );
263
+ }) })
264
+ ]
265
+ }
266
+ );
267
+ }
268
+
269
+ // src/components/audit-trail.tsx
270
+ import { ClockCircleOutlined } from "@ant-design/icons";
271
+ import { Timeline, Card as Card4, Typography as Typography6, Space as Space5, Button as Button3, Spin, theme as theme6 } from "antd";
272
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
273
+ var { Text: Text5, Title: Title4 } = Typography6;
274
+ function AuditTrail({
275
+ title = "Audit Trail",
276
+ events,
277
+ loading,
278
+ onLoadMore
279
+ }) {
280
+ const { token } = theme6.useToken();
281
+ const timelineItems = events.map((event) => ({
282
+ key: event.key,
283
+ dot: /* @__PURE__ */ jsx6(ClockCircleOutlined, { style: { fontSize: 14 } }),
284
+ children: /* @__PURE__ */ jsxs6(Space5, { direction: "vertical", size: 2, children: [
285
+ /* @__PURE__ */ jsxs6(Space5, { size: "small", wrap: true, children: [
286
+ /* @__PURE__ */ jsx6(Text5, { strong: true, children: event.action }),
287
+ event.by && /* @__PURE__ */ jsxs6(Text5, { type: "secondary", children: [
288
+ "by ",
289
+ event.by
290
+ ] })
291
+ ] }),
292
+ /* @__PURE__ */ jsxs6(Text5, { type: "secondary", style: { fontSize: token.fontSizeSM }, children: [
293
+ /* @__PURE__ */ jsx6("time", { dateTime: event.at, children: event.at }),
294
+ event.sourceSystem && ` \xB7 ${event.sourceSystem}`
295
+ ] }),
296
+ event.description && /* @__PURE__ */ jsx6("div", { children: event.description }),
297
+ event.evidenceUrl && /* @__PURE__ */ jsx6(
298
+ "a",
299
+ {
300
+ href: event.evidenceUrl,
301
+ target: "_blank",
302
+ rel: "noopener noreferrer",
303
+ style: { fontSize: token.fontSizeSM },
304
+ children: "View Evidence"
305
+ }
306
+ )
307
+ ] })
308
+ }));
309
+ return /* @__PURE__ */ jsxs6(Card4, { children: [
310
+ /* @__PURE__ */ jsx6(Title4, { level: 5, style: { marginBottom: token.marginMD }, children: title }),
311
+ loading && events.length === 0 ? /* @__PURE__ */ jsx6("div", { style: { textAlign: "center", padding: token.paddingLG }, children: /* @__PURE__ */ jsx6(Spin, {}) }) : /* @__PURE__ */ jsxs6("div", { role: "log", "aria-label": title, children: [
312
+ /* @__PURE__ */ jsx6(Timeline, { items: timelineItems }),
313
+ onLoadMore && /* @__PURE__ */ jsx6("div", { style: { textAlign: "center" }, children: /* @__PURE__ */ jsx6(Button3, { type: "link", onClick: onLoadMore, loading, children: "Load more" }) })
314
+ ] })
315
+ ] });
316
+ }
317
+
318
+ // src/templates/dashboard.tsx
319
+ import { Row, Col, Space as Space6, theme as theme7 } from "antd";
320
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
321
+ function DashboardTemplate({
322
+ title,
323
+ subtitle,
324
+ breadcrumbs,
325
+ data,
326
+ actions,
327
+ filters,
328
+ audit,
329
+ layout
330
+ }) {
331
+ const { token } = theme7.useToken();
332
+ const kpis = data?.kpis ?? [];
333
+ const panels = data?.panels ?? [];
334
+ return /* @__PURE__ */ jsx7(
335
+ TemplateFrame,
336
+ {
337
+ title,
338
+ subtitle,
339
+ breadcrumbs,
340
+ data,
341
+ actions,
342
+ filters,
343
+ audit,
344
+ layout,
345
+ children: /* @__PURE__ */ jsxs7(Space6, { direction: "vertical", size: "large", style: { width: "100%" }, children: [
346
+ kpis.length > 0 && /* @__PURE__ */ jsx7(Row, { gutter: [token.marginMD, token.marginMD], children: kpis.map((kpi) => /* @__PURE__ */ jsx7(Col, { xs: 24, sm: 12, lg: 6, children: /* @__PURE__ */ jsx7(
347
+ KpiCard,
348
+ {
349
+ label: kpi.label,
350
+ value: kpi.value,
351
+ delta: kpi.delta,
352
+ trend: kpi.trend,
353
+ helpText: kpi.helpText,
354
+ icon: kpi.icon,
355
+ onClick: kpi.onClick
356
+ }
357
+ ) }, kpi.key)) }),
358
+ panels.length > 0 && /* @__PURE__ */ jsx7(Row, { gutter: [token.marginMD, token.marginMD], children: panels.map((panel) => /* @__PURE__ */ jsx7(Col, { xs: 24, lg: panel.span ?? 12, children: /* @__PURE__ */ jsx7(SectionCard, { title: panel.title, subtitle: panel.subtitle, extra: panel.extra, children: panel.content }) }, panel.key)) })
359
+ ] })
360
+ }
361
+ );
362
+ }
363
+
364
+ // src/templates/list.tsx
365
+ import { DownloadOutlined } from "@ant-design/icons";
366
+ import { Table, Button as Button4, Space as Space7, Card as Card5, theme as theme8 } from "antd";
367
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
368
+ function ListTemplate({
369
+ title,
370
+ subtitle,
371
+ breadcrumbs,
372
+ data,
373
+ actions,
374
+ filters,
375
+ audit,
376
+ layout,
377
+ table,
378
+ selection,
379
+ exports: exportSpecs,
380
+ tools
381
+ }) {
382
+ const { token } = theme8.useToken();
383
+ const items = data?.items ?? [];
384
+ const loading = data?.loading ?? false;
385
+ const selectedRowKeys = selection?.selectedRowKeys;
386
+ const selectedCount = selectedRowKeys?.length ?? 0;
387
+ const bulkActions = selection?.bulkActions?.map((action) => ({
388
+ key: action.key,
389
+ label: action.label,
390
+ kind: action.kind,
391
+ disabled: action.disabled,
392
+ onAction: (keys) => action.onAction(keys)
393
+ })) ?? [];
394
+ const rowSelection = selection?.enabled ? {
395
+ ...selectedRowKeys !== void 0 ? { selectedRowKeys } : {},
396
+ onChange: (keys) => selection.onSelectionChange?.(keys),
397
+ getCheckboxProps: (record, index) => {
398
+ if (selection.getAriaLabel) {
399
+ const label = selection.getAriaLabel(record, index);
400
+ return { name: label, "aria-label": `Select ${label}` };
401
+ }
402
+ const fallback = record?.name ?? record?.title ?? record?.key ?? "row";
403
+ return {
404
+ name: String(fallback),
405
+ "aria-label": `Select ${fallback}`
406
+ };
407
+ }
408
+ } : void 0;
409
+ const hasToolbar = exportSpecs && exportSpecs.length > 0 || tools;
410
+ return /* @__PURE__ */ jsx8(
411
+ TemplateFrame,
412
+ {
413
+ title,
414
+ subtitle,
415
+ breadcrumbs,
416
+ data,
417
+ actions,
418
+ filters,
419
+ audit,
420
+ layout,
421
+ children: /* @__PURE__ */ jsxs8(Space7, { direction: "vertical", size: "middle", style: { width: "100%" }, children: [
422
+ hasToolbar && /* @__PURE__ */ jsxs8(
423
+ "div",
424
+ {
425
+ style: {
426
+ display: "flex",
427
+ justifyContent: "flex-end",
428
+ gap: token.marginSM,
429
+ flexWrap: "wrap"
430
+ },
431
+ children: [
432
+ exportSpecs?.map((exp) => /* @__PURE__ */ jsx8(
433
+ Button4,
434
+ {
435
+ icon: exp.icon ?? /* @__PURE__ */ jsx8(DownloadOutlined, {}),
436
+ onClick: exp.onExport,
437
+ disabled: exp.disabled,
438
+ children: exp.label
439
+ },
440
+ exp.key
441
+ )),
442
+ tools
443
+ ]
444
+ }
445
+ ),
446
+ selection?.enabled && selectedCount > 0 && /* @__PURE__ */ jsx8(
447
+ BulkActionsBar,
448
+ {
449
+ selectedCount,
450
+ selectedRowKeys: selectedRowKeys ?? [],
451
+ actions: bulkActions,
452
+ onClear: () => selection.onSelectionChange?.([])
453
+ }
454
+ ),
455
+ /* @__PURE__ */ jsx8(Card5, { styles: { body: { padding: 0 } }, children: /* @__PURE__ */ jsx8(Table, { ...table, dataSource: items, loading, rowSelection }) })
456
+ ] })
457
+ }
458
+ );
459
+ }
460
+
461
+ // src/templates/detail.tsx
462
+ import { Descriptions, Space as Space8 } from "antd";
463
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
464
+ function DetailTemplate({
465
+ title,
466
+ subtitle,
467
+ breadcrumbs,
468
+ data,
469
+ actions,
470
+ audit,
471
+ layout
472
+ }) {
473
+ const summary = data?.summary;
474
+ const sections = data?.sections ?? [];
475
+ const auditTrail = data?.auditTrail;
476
+ return /* @__PURE__ */ jsx9(
477
+ TemplateFrame,
478
+ {
479
+ title,
480
+ subtitle,
481
+ breadcrumbs,
482
+ data,
483
+ actions,
484
+ audit,
485
+ layout,
486
+ children: /* @__PURE__ */ jsxs9(Space8, { direction: "vertical", size: "large", style: { width: "100%" }, children: [
487
+ summary && /* @__PURE__ */ jsx9(SectionCard, { children: /* @__PURE__ */ jsx9(
488
+ Descriptions,
489
+ {
490
+ items: summary.items,
491
+ column: summary.columns ?? { xs: 1, sm: 2, lg: 3 },
492
+ size: "small",
493
+ bordered: true
494
+ }
495
+ ) }),
496
+ sections.map((section) => /* @__PURE__ */ jsx9(SectionCard, { title: section.title, extra: section.extra, children: section.content }, section.key)),
497
+ auditTrail && (auditTrail.events.length > 0 || auditTrail.loading) && /* @__PURE__ */ jsx9(
498
+ AuditTrail,
499
+ {
500
+ title: auditTrail.title,
501
+ events: auditTrail.events,
502
+ loading: auditTrail.loading,
503
+ onLoadMore: auditTrail.onLoadMore
504
+ }
505
+ )
506
+ ] })
507
+ }
508
+ );
509
+ }
510
+
511
+ // src/templates/error.tsx
512
+ import { Result, Button as Button5, Space as Space9, theme as theme9 } from "antd";
513
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
514
+ var defaultTitles = {
515
+ 401: "Unauthorized",
516
+ 403: "Access Denied",
517
+ 404: "Page Not Found",
518
+ 500: "Server Error"
519
+ };
520
+ var defaultMessages = {
521
+ 401: "You need to sign in to access this page.",
522
+ 403: "You don't have permission to access this resource.",
523
+ 404: "The page you're looking for doesn't exist or has been moved.",
524
+ 500: "Something went wrong on our end. Please try again later."
525
+ };
526
+ var statusToResultStatus = {
527
+ 401: "warning",
528
+ 403: "error",
529
+ 404: "404",
530
+ 500: "500"
531
+ };
532
+ function ErrorPageTemplate({
533
+ status,
534
+ title,
535
+ message,
536
+ actions,
537
+ extra
538
+ }) {
539
+ const { token } = theme9.useToken();
540
+ const resolvedTitle = title ?? defaultTitles[status];
541
+ const resolvedMessage = message ?? defaultMessages[status];
542
+ return /* @__PURE__ */ jsx10(
543
+ "div",
544
+ {
545
+ style: {
546
+ minHeight: "100vh",
547
+ display: "flex",
548
+ alignItems: "center",
549
+ justifyContent: "center",
550
+ padding: token.paddingLG,
551
+ background: token.colorBgLayout
552
+ },
553
+ children: /* @__PURE__ */ jsx10(
554
+ Result,
555
+ {
556
+ status: statusToResultStatus[status],
557
+ title: resolvedTitle,
558
+ subTitle: resolvedMessage,
559
+ extra: /* @__PURE__ */ jsxs10(Space9, { direction: "vertical", size: "middle", align: "center", children: [
560
+ actions && actions.length > 0 && /* @__PURE__ */ jsx10(Space9, { children: actions.map((action) => /* @__PURE__ */ jsx10(
561
+ Button5,
562
+ {
563
+ type: action.kind === "primary" ? "primary" : action.kind === "link" ? "link" : "default",
564
+ danger: action.kind === "danger",
565
+ disabled: action.disabled,
566
+ icon: action.icon,
567
+ onClick: action.onAction,
568
+ "aria-label": action.ariaLabel,
569
+ children: action.label
570
+ },
571
+ action.key
572
+ )) }),
573
+ extra
574
+ ] })
575
+ }
576
+ )
577
+ }
578
+ );
579
+ }
580
+
581
+ // src/templates/wizard.tsx
582
+ import { Steps, Space as Space10, Empty } from "antd";
583
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
584
+ function WizardTemplate({
585
+ title,
586
+ subtitle,
587
+ breadcrumbs,
588
+ actions,
589
+ data,
590
+ filters,
591
+ audit,
592
+ layout,
593
+ onStepChange
594
+ }) {
595
+ const steps = data?.steps ?? [];
596
+ const currentStep = data?.currentStep ?? 0;
597
+ const activeStep = steps[currentStep];
598
+ return /* @__PURE__ */ jsx11(
599
+ TemplateFrame,
600
+ {
601
+ title,
602
+ subtitle,
603
+ breadcrumbs,
604
+ actions,
605
+ data,
606
+ filters,
607
+ audit,
608
+ layout,
609
+ children: steps.length === 0 ? /* @__PURE__ */ jsx11(Empty, { description: "No steps configured" }) : /* @__PURE__ */ jsxs11(Space10, { direction: "vertical", size: "large", style: { width: "100%" }, children: [
610
+ /* @__PURE__ */ jsx11(
611
+ Steps,
612
+ {
613
+ current: currentStep,
614
+ onChange: onStepChange,
615
+ items: steps.map((step) => ({
616
+ key: step.key,
617
+ title: step.title,
618
+ description: step.description
619
+ }))
620
+ }
621
+ ),
622
+ activeStep && /* @__PURE__ */ jsx11(SectionCard, { title: activeStep.title, subtitle: activeStep.description, children: activeStep.content })
623
+ ] })
624
+ }
625
+ );
626
+ }
627
+
628
+ // src/templates/settings.tsx
629
+ import { Space as Space11 } from "antd";
630
+ import { jsx as jsx12 } from "react/jsx-runtime";
631
+ function SettingsTemplate({
632
+ title,
633
+ subtitle,
634
+ breadcrumbs,
635
+ actions,
636
+ data,
637
+ filters,
638
+ audit,
639
+ layout
640
+ }) {
641
+ const sections = data?.sections ?? [];
642
+ return /* @__PURE__ */ jsx12(
643
+ TemplateFrame,
644
+ {
645
+ title,
646
+ subtitle,
647
+ breadcrumbs,
648
+ actions,
649
+ data,
650
+ filters,
651
+ audit,
652
+ layout,
653
+ children: /* @__PURE__ */ jsx12(Space11, { direction: "vertical", size: "large", style: { width: "100%" }, children: sections.map((section) => /* @__PURE__ */ jsx12(SectionCard, { title: section.title, subtitle: section.subtitle, children: section.content }, section.key)) })
654
+ }
655
+ );
656
+ }
657
+
658
+ // src/templates/auth-shell.tsx
659
+ import { Card as Card6, Typography as Typography7, theme as theme10 } from "antd";
660
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
661
+ var { Title: Title5, Text: Text6 } = Typography7;
662
+ function AuthShell({
663
+ brand,
664
+ title,
665
+ subtitle,
666
+ footer,
667
+ children,
668
+ maxWidth = 420
669
+ }) {
670
+ const { token } = theme10.useToken();
671
+ return /* @__PURE__ */ jsx13(
672
+ "div",
673
+ {
674
+ style: {
675
+ minHeight: "100vh",
676
+ display: "flex",
677
+ flexDirection: "column",
678
+ alignItems: "center",
679
+ justifyContent: "center",
680
+ padding: token.paddingLG,
681
+ background: token.colorBgLayout
682
+ },
683
+ children: /* @__PURE__ */ jsxs12("div", { style: { width: "100%", maxWidth }, children: [
684
+ brand && /* @__PURE__ */ jsx13("div", { style: { textAlign: "center", marginBottom: token.marginLG }, children: brand }),
685
+ /* @__PURE__ */ jsxs12(Card6, { styles: { body: { padding: token.paddingXL } }, children: [
686
+ (title || subtitle) && /* @__PURE__ */ jsxs12("div", { style: { textAlign: "center", marginBottom: token.marginLG }, children: [
687
+ title && /* @__PURE__ */ jsx13(Title5, { level: 3, style: { margin: 0 }, children: title }),
688
+ subtitle && /* @__PURE__ */ jsx13(
689
+ Text6,
690
+ {
691
+ style: {
692
+ marginTop: token.marginXS,
693
+ display: "block",
694
+ color: token.colorTextSecondary
695
+ },
696
+ children: subtitle
697
+ }
698
+ )
699
+ ] }),
700
+ children
701
+ ] }),
702
+ footer && /* @__PURE__ */ jsx13(
703
+ "div",
704
+ {
705
+ style: {
706
+ textAlign: "center",
707
+ marginTop: token.marginLG,
708
+ color: token.colorTextSecondary,
709
+ fontSize: token.fontSizeSM
710
+ },
711
+ children: footer
712
+ }
713
+ )
714
+ ] })
715
+ }
716
+ );
717
+ }
718
+
719
+ // src/templates/profile.tsx
720
+ import { Avatar, Descriptions as Descriptions2, Space as Space12, Tabs, Tag, Typography as Typography8, theme as theme11 } from "antd";
721
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
722
+ function ProfileTemplate({
723
+ title,
724
+ breadcrumbs,
725
+ actions,
726
+ data,
727
+ filters: _filters,
728
+ audit,
729
+ layout
730
+ }) {
731
+ const { token } = theme11.useToken();
732
+ const profile = data ?? {};
733
+ return /* @__PURE__ */ jsxs13(
734
+ TemplateFrame,
735
+ {
736
+ title: title ?? profile.name ?? "Profile",
737
+ breadcrumbs,
738
+ actions,
739
+ audit,
740
+ layout,
741
+ children: [
742
+ /* @__PURE__ */ jsxs13("div", { style: { display: "flex", gap: 24, flexWrap: "wrap", marginBottom: 24 }, children: [
743
+ /* @__PURE__ */ jsx14(
744
+ Avatar,
745
+ {
746
+ size: 96,
747
+ src: profile.avatar ? /* @__PURE__ */ jsx14("img", { src: profile.avatar, alt: profile.name ?? "Profile avatar" }) : void 0,
748
+ children: profile.name?.[0]
749
+ }
750
+ ),
751
+ /* @__PURE__ */ jsxs13("div", { style: { flex: 1 }, children: [
752
+ /* @__PURE__ */ jsx14(Typography8.Title, { level: 3, style: { margin: 0 }, children: profile.name }),
753
+ profile.role && /* @__PURE__ */ jsx14(Typography8.Text, { style: { color: token.colorTextSecondary }, children: profile.role }),
754
+ profile.bio && /* @__PURE__ */ jsx14(Typography8.Paragraph, { style: { marginTop: 8 }, children: profile.bio }),
755
+ profile.tags && /* @__PURE__ */ jsx14(Space12, { wrap: true, children: profile.tags.map((tag) => /* @__PURE__ */ jsx14(Tag, { children: tag }, tag)) })
756
+ ] })
757
+ ] }),
758
+ profile.stats && profile.stats.length > 0 && /* @__PURE__ */ jsx14(
759
+ "div",
760
+ {
761
+ style: {
762
+ display: "flex",
763
+ gap: 32,
764
+ padding: "16px 0",
765
+ borderTop: `1px solid ${token.colorBorderSecondary}`,
766
+ borderBottom: `1px solid ${token.colorBorderSecondary}`,
767
+ marginBottom: 24
768
+ },
769
+ children: profile.stats.map((stat) => /* @__PURE__ */ jsxs13("div", { style: { textAlign: "center" }, children: [
770
+ /* @__PURE__ */ jsx14("div", { style: { fontSize: 24, fontWeight: 600 }, children: stat.value }),
771
+ /* @__PURE__ */ jsx14("div", { style: { fontSize: 13, color: token.colorTextSecondary }, children: stat.label })
772
+ ] }, stat.label))
773
+ }
774
+ ),
775
+ profile.details && /* @__PURE__ */ jsx14(Descriptions2, { column: 2, style: { marginBottom: 24 }, children: profile.details.map((d) => /* @__PURE__ */ jsx14(Descriptions2.Item, { label: d.label, children: d.value }, d.label)) }),
776
+ profile.tabs && profile.tabs.length > 0 && /* @__PURE__ */ jsx14(
777
+ Tabs,
778
+ {
779
+ items: profile.tabs.map((tab) => ({
780
+ key: tab.key,
781
+ label: tab.label,
782
+ children: tab.content
783
+ }))
784
+ }
785
+ )
786
+ ]
787
+ }
788
+ );
789
+ }
790
+
791
+ // src/templates/billing.tsx
792
+ import { Descriptions as Descriptions3, Space as Space13, Table as Table2, Tag as Tag2, Typography as Typography9, theme as theme12 } from "antd";
793
+ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
794
+ function BillingTemplate({
795
+ title = "Billing",
796
+ breadcrumbs,
797
+ actions,
798
+ data,
799
+ audit,
800
+ layout,
801
+ onChangePlan: _onChangePlan,
802
+ onAddPaymentMethod: _onAddPaymentMethod
803
+ }) {
804
+ const { token } = theme12.useToken();
805
+ const billing = data ?? {};
806
+ const invoiceColumns = [
807
+ { title: "Invoice", dataIndex: "id", key: "id" },
808
+ { title: "Date", dataIndex: "date", key: "date" },
809
+ { title: "Amount", dataIndex: "amount", key: "amount" },
810
+ {
811
+ title: "Status",
812
+ dataIndex: "status",
813
+ key: "status",
814
+ render: (status) => /* @__PURE__ */ jsx15(
815
+ Tag2,
816
+ {
817
+ color: status === "paid" ? "#166534" : status === "pending" ? "#92400e" : "#991b1b",
818
+ style: { color: "#ffffff", borderColor: "transparent" },
819
+ children: status
820
+ }
821
+ )
822
+ }
823
+ ];
824
+ return /* @__PURE__ */ jsx15(
825
+ TemplateFrame,
826
+ {
827
+ title,
828
+ breadcrumbs,
829
+ actions,
830
+ audit,
831
+ layout,
832
+ children: /* @__PURE__ */ jsxs14(Space13, { direction: "vertical", size: "large", style: { width: "100%" }, children: [
833
+ billing.currentPlan && /* @__PURE__ */ jsx15(SectionCard, { title: "Current Plan", children: /* @__PURE__ */ jsxs14(Descriptions3, { column: 2, children: [
834
+ /* @__PURE__ */ jsx15(Descriptions3.Item, { label: "Plan", children: billing.currentPlan.name }),
835
+ /* @__PURE__ */ jsxs14(Descriptions3.Item, { label: "Price", children: [
836
+ billing.currentPlan.price,
837
+ billing.currentPlan.interval && ` / ${billing.currentPlan.interval}`
838
+ ] })
839
+ ] }) }),
840
+ billing.paymentMethods && billing.paymentMethods.length > 0 && /* @__PURE__ */ jsx15(SectionCard, { title: "Payment Methods", children: billing.paymentMethods.map((pm, i) => /* @__PURE__ */ jsxs14(
841
+ "div",
842
+ {
843
+ style: {
844
+ display: "flex",
845
+ justifyContent: "space-between",
846
+ padding: "8px 0",
847
+ borderBottom: `1px solid ${token.colorBorderSecondary}`
848
+ },
849
+ children: [
850
+ /* @__PURE__ */ jsxs14("span", { children: [
851
+ pm.type,
852
+ " ending in ",
853
+ pm.last4
854
+ ] }),
855
+ /* @__PURE__ */ jsxs14("span", { children: [
856
+ pm.expiry && /* @__PURE__ */ jsxs14(Typography9.Text, { style: { color: token.colorTextSecondary }, children: [
857
+ "Expires ",
858
+ pm.expiry
859
+ ] }),
860
+ pm.isDefault && /* @__PURE__ */ jsx15(
861
+ Tag2,
862
+ {
863
+ color: "#1d4ed8",
864
+ style: { marginLeft: 8, color: "#ffffff", borderColor: "transparent" },
865
+ children: "Default"
866
+ }
867
+ )
868
+ ] })
869
+ ]
870
+ },
871
+ i
872
+ )) }),
873
+ billing.invoices && billing.invoices.length > 0 && /* @__PURE__ */ jsx15(SectionCard, { title: "Invoice History", children: /* @__PURE__ */ jsx15(
874
+ Table2,
875
+ {
876
+ dataSource: billing.invoices,
877
+ columns: invoiceColumns,
878
+ rowKey: "id",
879
+ pagination: false,
880
+ size: "small"
881
+ }
882
+ ) })
883
+ ] })
884
+ }
885
+ );
886
+ }
887
+
888
+ // src/templates/security.tsx
889
+ import { Descriptions as Descriptions4, Space as Space14, Table as Table3, Tag as Tag3 } from "antd";
890
+ import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
891
+ function SecurityTemplate({
892
+ title = "Security",
893
+ breadcrumbs,
894
+ actions,
895
+ data,
896
+ audit,
897
+ layout
898
+ }) {
899
+ const security = data ?? {};
900
+ const sessionColumns = [
901
+ { title: "Device", dataIndex: "device", key: "device" },
902
+ { title: "Location", dataIndex: "location", key: "location" },
903
+ { title: "Last Active", dataIndex: "lastActive", key: "lastActive" },
904
+ {
905
+ title: "Current Session",
906
+ key: "current",
907
+ render: (_, record) => record.isCurrent ? /* @__PURE__ */ jsx16(Tag3, { color: "#166534", style: { color: "#ffffff", borderColor: "transparent" }, children: "Current" }) : null
908
+ }
909
+ ];
910
+ const logColumns = [
911
+ { title: "Time", dataIndex: "timestamp", key: "timestamp" },
912
+ { title: "Action", dataIndex: "action", key: "action" },
913
+ { title: "IP", dataIndex: "ip", key: "ip" },
914
+ {
915
+ title: "Status",
916
+ dataIndex: "status",
917
+ key: "status",
918
+ render: (status) => /* @__PURE__ */ jsx16(
919
+ Tag3,
920
+ {
921
+ color: status === "success" ? "#166534" : status === "warning" ? "#92400e" : "#991b1b",
922
+ style: { color: "#ffffff", borderColor: "transparent" },
923
+ children: status
924
+ }
925
+ )
926
+ }
927
+ ];
928
+ return /* @__PURE__ */ jsx16(
929
+ TemplateFrame,
930
+ {
931
+ title,
932
+ breadcrumbs,
933
+ actions,
934
+ audit,
935
+ layout,
936
+ children: /* @__PURE__ */ jsxs15(Space14, { direction: "vertical", size: "large", style: { width: "100%" }, children: [
937
+ /* @__PURE__ */ jsx16(SectionCard, { title: "Overview", children: /* @__PURE__ */ jsxs15(Descriptions4, { column: 2, children: [
938
+ /* @__PURE__ */ jsx16(Descriptions4.Item, { label: "Two-Factor Authentication", children: /* @__PURE__ */ jsx16(
939
+ Tag3,
940
+ {
941
+ color: security.twoFactorEnabled ? "#166534" : "#525252",
942
+ style: { color: "#ffffff", borderColor: "transparent" },
943
+ children: security.twoFactorEnabled ? "Enabled" : "Disabled"
944
+ }
945
+ ) }),
946
+ security.passwordLastChanged && /* @__PURE__ */ jsx16(Descriptions4.Item, { label: "Password Last Changed", children: security.passwordLastChanged })
947
+ ] }) }),
948
+ security.sessions && security.sessions.length > 0 && /* @__PURE__ */ jsx16(SectionCard, { title: "Active Sessions", children: /* @__PURE__ */ jsx16(
949
+ Table3,
950
+ {
951
+ dataSource: security.sessions,
952
+ columns: sessionColumns,
953
+ rowKey: "id",
954
+ pagination: false,
955
+ size: "small"
956
+ }
957
+ ) }),
958
+ security.securityLog && security.securityLog.length > 0 && /* @__PURE__ */ jsx16(SectionCard, { title: "Security Log", children: /* @__PURE__ */ jsx16(
959
+ Table3,
960
+ {
961
+ dataSource: security.securityLog,
962
+ columns: logColumns,
963
+ rowKey: "timestamp",
964
+ pagination: { pageSize: 10 },
965
+ size: "small"
966
+ }
967
+ ) })
968
+ ] })
969
+ }
970
+ );
971
+ }
972
+
973
+ // src/templates/members.tsx
974
+ import { Avatar as Avatar2, Space as Space15, Table as Table4, Tag as Tag4, Typography as Typography10, theme as theme13 } from "antd";
975
+ import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
976
+ function MembersTemplate({
977
+ title = "Team Members",
978
+ breadcrumbs,
979
+ actions,
980
+ data,
981
+ audit,
982
+ layout
983
+ }) {
984
+ const { token } = theme13.useToken();
985
+ const members = data ?? {};
986
+ const memberColumns = [
987
+ {
988
+ title: "Member",
989
+ key: "member",
990
+ render: (_, record) => /* @__PURE__ */ jsxs16(Space15, { children: [
991
+ /* @__PURE__ */ jsx17(Avatar2, { size: "small", src: record.avatar, children: record.name[0] }),
992
+ /* @__PURE__ */ jsxs16("div", { children: [
993
+ /* @__PURE__ */ jsx17("div", { style: { fontWeight: 500 }, children: record.name }),
994
+ /* @__PURE__ */ jsx17(Typography10.Text, { style: { fontSize: 12, color: token.colorTextSecondary }, children: record.email })
995
+ ] })
996
+ ] })
997
+ },
998
+ { title: "Role", dataIndex: "role", key: "role", render: (role) => /* @__PURE__ */ jsx17(Tag4, { children: role }) },
999
+ {
1000
+ title: "Status",
1001
+ dataIndex: "status",
1002
+ key: "status",
1003
+ render: (status) => /* @__PURE__ */ jsx17(
1004
+ Tag4,
1005
+ {
1006
+ color: status === "active" ? "#166534" : status === "invited" ? "#92400e" : "#525252",
1007
+ style: { color: "#ffffff", borderColor: "transparent" },
1008
+ children: status
1009
+ }
1010
+ )
1011
+ },
1012
+ { title: "Joined", dataIndex: "joinedAt", key: "joinedAt" }
1013
+ ];
1014
+ return /* @__PURE__ */ jsx17(
1015
+ TemplateFrame,
1016
+ {
1017
+ title,
1018
+ breadcrumbs,
1019
+ actions,
1020
+ audit,
1021
+ layout,
1022
+ children: /* @__PURE__ */ jsxs16(Space15, { direction: "vertical", size: "large", style: { width: "100%" }, children: [
1023
+ members.roles && members.roles.length > 0 && /* @__PURE__ */ jsx17(SectionCard, { title: "Roles", children: /* @__PURE__ */ jsx17("div", { style: { display: "flex", gap: 16, flexWrap: "wrap" }, children: members.roles.map((role) => /* @__PURE__ */ jsxs16(
1024
+ "div",
1025
+ {
1026
+ style: {
1027
+ padding: "12px 16px",
1028
+ border: `1px solid ${token.colorBorderSecondary}`,
1029
+ borderRadius: 8,
1030
+ minWidth: 150
1031
+ },
1032
+ children: [
1033
+ /* @__PURE__ */ jsx17("div", { style: { fontWeight: 600 }, children: role.name }),
1034
+ role.description && /* @__PURE__ */ jsx17("div", { style: { fontSize: 12, color: token.colorTextSecondary }, children: role.description }),
1035
+ /* @__PURE__ */ jsxs16("div", { style: { fontSize: 13, marginTop: 4 }, children: [
1036
+ role.memberCount,
1037
+ " members"
1038
+ ] })
1039
+ ]
1040
+ },
1041
+ role.name
1042
+ )) }) }),
1043
+ members.members && members.members.length > 0 && /* @__PURE__ */ jsx17(SectionCard, { title: `Members${members.totalMembers ? ` (${members.totalMembers})` : ""}`, children: /* @__PURE__ */ jsx17(
1044
+ Table4,
1045
+ {
1046
+ dataSource: members.members,
1047
+ columns: memberColumns,
1048
+ rowKey: "id",
1049
+ pagination: { pageSize: 10 },
1050
+ size: "small"
1051
+ }
1052
+ ) })
1053
+ ] })
1054
+ }
1055
+ );
1056
+ }
1057
+
1058
+ // src/templates/notifications.tsx
1059
+ import { Space as Space16, Switch, Typography as Typography11, theme as theme14 } from "antd";
1060
+ import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
1061
+ function NotificationsTemplate({
1062
+ title = "Notifications",
1063
+ breadcrumbs,
1064
+ actions,
1065
+ data,
1066
+ audit,
1067
+ layout,
1068
+ onToggle
1069
+ }) {
1070
+ const { token } = theme14.useToken();
1071
+ const notifications = data ?? {};
1072
+ return /* @__PURE__ */ jsx18(
1073
+ TemplateFrame,
1074
+ {
1075
+ title,
1076
+ breadcrumbs,
1077
+ actions,
1078
+ audit,
1079
+ layout,
1080
+ children: /* @__PURE__ */ jsx18(Space16, { direction: "vertical", size: "large", style: { width: "100%" }, children: notifications.groups?.map((group) => /* @__PURE__ */ jsx18(SectionCard, { title: group.title, children: group.channels.map((channel) => /* @__PURE__ */ jsxs17(
1081
+ "div",
1082
+ {
1083
+ style: {
1084
+ display: "flex",
1085
+ justifyContent: "space-between",
1086
+ alignItems: "center",
1087
+ padding: "12px 0",
1088
+ borderBottom: `1px solid ${token.colorBorderSecondary}`
1089
+ },
1090
+ children: [
1091
+ /* @__PURE__ */ jsxs17("div", { children: [
1092
+ /* @__PURE__ */ jsx18("div", { style: { fontWeight: 500, color: token.colorText }, children: channel.label }),
1093
+ channel.description && /* @__PURE__ */ jsx18(Typography11.Text, { style: { fontSize: 12, color: token.colorTextSecondary }, children: channel.description })
1094
+ ] }),
1095
+ /* @__PURE__ */ jsxs17(Space16, { size: "large", children: [
1096
+ /* @__PURE__ */ jsxs17(Space16, { direction: "vertical", align: "center", size: 0, children: [
1097
+ /* @__PURE__ */ jsx18(Typography11.Text, { style: { fontSize: 12, color: token.colorTextSecondary }, children: "Email" }),
1098
+ /* @__PURE__ */ jsx18(
1099
+ Switch,
1100
+ {
1101
+ size: "small",
1102
+ checked: channel.email,
1103
+ "aria-label": `${channel.label}: email notifications`,
1104
+ onChange: (v) => onToggle?.(channel.key, "email", v)
1105
+ }
1106
+ )
1107
+ ] }),
1108
+ /* @__PURE__ */ jsxs17(Space16, { direction: "vertical", align: "center", size: 0, children: [
1109
+ /* @__PURE__ */ jsx18(Typography11.Text, { style: { fontSize: 12, color: token.colorTextSecondary }, children: "Push" }),
1110
+ /* @__PURE__ */ jsx18(
1111
+ Switch,
1112
+ {
1113
+ size: "small",
1114
+ checked: channel.push,
1115
+ "aria-label": `${channel.label}: push notifications`,
1116
+ onChange: (v) => onToggle?.(channel.key, "push", v)
1117
+ }
1118
+ )
1119
+ ] }),
1120
+ /* @__PURE__ */ jsxs17(Space16, { direction: "vertical", align: "center", size: 0, children: [
1121
+ /* @__PURE__ */ jsx18(Typography11.Text, { style: { fontSize: 12, color: token.colorTextSecondary }, children: "SMS" }),
1122
+ /* @__PURE__ */ jsx18(
1123
+ Switch,
1124
+ {
1125
+ size: "small",
1126
+ checked: channel.sms,
1127
+ "aria-label": `${channel.label}: sms notifications`,
1128
+ onChange: (v) => onToggle?.(channel.key, "sms", v)
1129
+ }
1130
+ )
1131
+ ] })
1132
+ ] })
1133
+ ]
1134
+ },
1135
+ channel.key
1136
+ )) }, group.title)) })
1137
+ }
1138
+ );
1139
+ }
1140
+
1141
+ // src/templates/activity.tsx
1142
+ import { Avatar as Avatar3, Space as Space17, Timeline as Timeline2, Typography as Typography12, theme as theme15 } from "antd";
1143
+ import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
1144
+ var colorMap = {
1145
+ info: "#1d4ed8",
1146
+ success: "#166534",
1147
+ warning: "#92400e",
1148
+ error: "#991b1b"
1149
+ };
1150
+ function ActivityTemplate({
1151
+ title = "Activity",
1152
+ breadcrumbs,
1153
+ actions,
1154
+ data,
1155
+ audit,
1156
+ layout
1157
+ }) {
1158
+ const { token } = theme15.useToken();
1159
+ const activity = data ?? {};
1160
+ return /* @__PURE__ */ jsx19(
1161
+ TemplateFrame,
1162
+ {
1163
+ title,
1164
+ breadcrumbs,
1165
+ actions,
1166
+ audit,
1167
+ layout,
1168
+ children: /* @__PURE__ */ jsx19(
1169
+ Timeline2,
1170
+ {
1171
+ items: activity.events?.map((event) => ({
1172
+ color: colorMap[event.type ?? "info"],
1173
+ children: /* @__PURE__ */ jsx19("div", { children: /* @__PURE__ */ jsxs18(Space17, { align: "start", children: [
1174
+ /* @__PURE__ */ jsx19(Avatar3, { size: "small", src: event.actor.avatar, children: event.actor.name[0] }),
1175
+ /* @__PURE__ */ jsxs18("div", { children: [
1176
+ /* @__PURE__ */ jsxs18("div", { children: [
1177
+ /* @__PURE__ */ jsx19(Typography12.Text, { strong: true, children: event.actor.name }),
1178
+ " ",
1179
+ /* @__PURE__ */ jsx19(Typography12.Text, { children: event.action }),
1180
+ event.target && /* @__PURE__ */ jsxs18(Typography12.Text, { strong: true, children: [
1181
+ " ",
1182
+ event.target
1183
+ ] })
1184
+ ] }),
1185
+ /* @__PURE__ */ jsx19(Typography12.Text, { style: { fontSize: 12, color: token.colorTextSecondary }, children: event.timestamp }),
1186
+ event.detail && /* @__PURE__ */ jsx19("div", { style: { marginTop: 4 }, children: event.detail })
1187
+ ] })
1188
+ ] }) }, event.id)
1189
+ }))
1190
+ }
1191
+ )
1192
+ }
1193
+ );
1194
+ }
1195
+
1196
+ // src/templates/invite.tsx
1197
+ import { Card as Card7, Input, Space as Space18, Typography as Typography13, theme as theme16 } from "antd";
1198
+ import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
1199
+ function InviteTemplate({
1200
+ title = "Invite a Friend",
1201
+ breadcrumbs,
1202
+ actions,
1203
+ data,
1204
+ audit,
1205
+ layout,
1206
+ onCopyLink
1207
+ }) {
1208
+ const { token } = theme16.useToken();
1209
+ const invite = data ?? {};
1210
+ return /* @__PURE__ */ jsx20(
1211
+ TemplateFrame,
1212
+ {
1213
+ title,
1214
+ breadcrumbs,
1215
+ actions,
1216
+ audit,
1217
+ layout,
1218
+ children: /* @__PURE__ */ jsxs19(Space18, { direction: "vertical", size: "large", style: { width: "100%" }, children: [
1219
+ /* @__PURE__ */ jsx20(SectionCard, { title: "Your Referral Link", children: /* @__PURE__ */ jsxs19(Space18, { direction: "vertical", style: { width: "100%" }, children: [
1220
+ invite.referralLink && /* @__PURE__ */ jsx20(
1221
+ Input.Search,
1222
+ {
1223
+ value: invite.referralLink,
1224
+ readOnly: true,
1225
+ enterButton: "Copy",
1226
+ "aria-label": "Referral link",
1227
+ onSearch: onCopyLink
1228
+ }
1229
+ ),
1230
+ invite.referralCode && /* @__PURE__ */ jsxs19(Typography13.Text, { style: { color: token.colorTextSecondary }, children: [
1231
+ "Referral code: ",
1232
+ /* @__PURE__ */ jsx20(Typography13.Text, { code: true, children: invite.referralCode })
1233
+ ] })
1234
+ ] }) }),
1235
+ /* @__PURE__ */ jsxs19("div", { style: { display: "flex", gap: 16, flexWrap: "wrap" }, children: [
1236
+ /* @__PURE__ */ jsxs19(Card7, { size: "small", style: { flex: 1, minWidth: 150, textAlign: "center" }, children: [
1237
+ /* @__PURE__ */ jsx20("div", { style: { fontSize: 28, fontWeight: 700 }, children: invite.totalInvites ?? 0 }),
1238
+ /* @__PURE__ */ jsx20("div", { style: { color: token.colorTextSecondary, fontSize: 13 }, children: "Invites Sent" })
1239
+ ] }),
1240
+ /* @__PURE__ */ jsxs19(Card7, { size: "small", style: { flex: 1, minWidth: 150, textAlign: "center" }, children: [
1241
+ /* @__PURE__ */ jsx20("div", { style: { fontSize: 28, fontWeight: 700 }, children: invite.acceptedInvites ?? 0 }),
1242
+ /* @__PURE__ */ jsx20("div", { style: { color: token.colorTextSecondary, fontSize: 13 }, children: "Accepted" })
1243
+ ] })
1244
+ ] }),
1245
+ invite.rewards && invite.rewards.length > 0 && /* @__PURE__ */ jsx20(SectionCard, { title: "Rewards", children: invite.rewards.map((reward) => /* @__PURE__ */ jsxs19(
1246
+ "div",
1247
+ {
1248
+ style: {
1249
+ display: "flex",
1250
+ alignItems: "center",
1251
+ gap: 12,
1252
+ padding: "12px 0",
1253
+ borderBottom: `1px solid ${token.colorBorderSecondary}`
1254
+ },
1255
+ children: [
1256
+ reward.icon && /* @__PURE__ */ jsx20("div", { children: reward.icon }),
1257
+ /* @__PURE__ */ jsxs19("div", { children: [
1258
+ /* @__PURE__ */ jsx20("div", { style: { fontWeight: 500 }, children: reward.label }),
1259
+ reward.description && /* @__PURE__ */ jsx20(Typography13.Text, { style: { fontSize: 12, color: token.colorTextSecondary }, children: reward.description })
1260
+ ] })
1261
+ ]
1262
+ },
1263
+ reward.label
1264
+ )) })
1265
+ ] })
1266
+ }
1267
+ );
1268
+ }
1269
+
1270
+ // src/templates/projects.tsx
1271
+ import { Avatar as Avatar4, Card as Card8, Progress, Space as Space19, Tag as Tag5, Typography as Typography14, theme as theme17 } from "antd";
1272
+ import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
1273
+ var statusColor = {
1274
+ active: "#1d4ed8",
1275
+ completed: "#166534",
1276
+ "on-hold": "#92400e",
1277
+ archived: "#525252"
1278
+ };
1279
+ function ProjectsTemplate({
1280
+ title = "Projects",
1281
+ breadcrumbs,
1282
+ actions,
1283
+ data,
1284
+ audit,
1285
+ layout,
1286
+ onProjectClick
1287
+ }) {
1288
+ const { token } = theme17.useToken();
1289
+ const projects = data ?? {};
1290
+ const cols = projects.columns ?? 3;
1291
+ return /* @__PURE__ */ jsx21(
1292
+ TemplateFrame,
1293
+ {
1294
+ title,
1295
+ breadcrumbs,
1296
+ actions,
1297
+ audit,
1298
+ layout,
1299
+ children: /* @__PURE__ */ jsx21(
1300
+ "div",
1301
+ {
1302
+ style: {
1303
+ display: "grid",
1304
+ gridTemplateColumns: `repeat(${cols}, 1fr)`,
1305
+ gap: 16
1306
+ },
1307
+ children: projects.projects?.map((project) => /* @__PURE__ */ jsx21(
1308
+ Card8,
1309
+ {
1310
+ hoverable: true,
1311
+ size: "small",
1312
+ onClick: () => onProjectClick?.(project),
1313
+ style: { cursor: "pointer" },
1314
+ children: /* @__PURE__ */ jsxs20(Space19, { direction: "vertical", style: { width: "100%" }, children: [
1315
+ /* @__PURE__ */ jsxs20(
1316
+ "div",
1317
+ {
1318
+ style: { display: "flex", justifyContent: "space-between", alignItems: "start" },
1319
+ children: [
1320
+ /* @__PURE__ */ jsx21(Typography14.Text, { strong: true, children: project.title }),
1321
+ project.status && /* @__PURE__ */ jsx21(
1322
+ Tag5,
1323
+ {
1324
+ color: statusColor[project.status],
1325
+ style: { color: "#ffffff", borderColor: "transparent" },
1326
+ children: project.status
1327
+ }
1328
+ )
1329
+ ]
1330
+ }
1331
+ ),
1332
+ project.description && /* @__PURE__ */ jsx21(Typography14.Text, { style: { fontSize: 13, color: token.colorTextSecondary }, children: project.description }),
1333
+ project.progress !== void 0 && /* @__PURE__ */ jsx21(
1334
+ Progress,
1335
+ {
1336
+ percent: project.progress,
1337
+ size: "small",
1338
+ "aria-label": `${project.title} completion ${project.progress}%`
1339
+ }
1340
+ ),
1341
+ project.tags && /* @__PURE__ */ jsx21(Space19, { wrap: true, size: 4, children: project.tags.map((tag) => /* @__PURE__ */ jsx21(Tag5, { style: { fontSize: 11 }, children: tag }, tag)) }),
1342
+ /* @__PURE__ */ jsxs20(
1343
+ "div",
1344
+ {
1345
+ style: { display: "flex", justifyContent: "space-between", alignItems: "center" },
1346
+ children: [
1347
+ project.members && /* @__PURE__ */ jsx21(Avatar4.Group, { size: "small", max: { count: 3 }, children: project.members.map((m, i) => /* @__PURE__ */ jsx21(Avatar4, { size: "small", src: m.avatar, alt: m.name, children: m.name[0] }, i)) }),
1348
+ project.dueDate && /* @__PURE__ */ jsxs20(Typography14.Text, { style: { fontSize: 12, color: token.colorTextSecondary }, children: [
1349
+ "Due ",
1350
+ project.dueDate
1351
+ ] })
1352
+ ]
1353
+ }
1354
+ )
1355
+ ] })
1356
+ },
1357
+ project.id
1358
+ ))
1359
+ }
1360
+ )
1361
+ }
1362
+ );
1363
+ }
1364
+ export {
1365
+ ActivityTemplate,
1366
+ AuditTrail,
1367
+ AuthShell,
1368
+ BillingTemplate,
1369
+ BulkActionsBar,
1370
+ DashboardTemplate,
1371
+ DetailTemplate,
1372
+ ErrorPageTemplate,
1373
+ InviteTemplate,
1374
+ KpiCard,
1375
+ ListTemplate,
1376
+ MembersTemplate,
1377
+ NotificationsTemplate,
1378
+ ProfileTemplate,
1379
+ ProjectsTemplate,
1380
+ SectionCard,
1381
+ SecurityTemplate,
1382
+ SettingsTemplate,
1383
+ TemplateFrame,
1384
+ WizardTemplate,
1385
+ templateActionsToPageHeaderActions
1386
+ };