@tekki-forge/runtime-admin 0.2.0 → 0.3.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 (136) hide show
  1. package/dist/admin-dashboard.d.ts +16 -0
  2. package/dist/admin-dashboard.js +60 -0
  3. package/dist/admin-dashboard.js.map +1 -0
  4. package/dist/admin-orgs.d.ts +14 -0
  5. package/dist/admin-orgs.js +75 -0
  6. package/dist/admin-orgs.js.map +1 -0
  7. package/dist/admin-shell.d.ts +55 -0
  8. package/dist/admin-shell.js +141 -0
  9. package/dist/admin-shell.js.map +1 -0
  10. package/dist/admin.js +35 -4
  11. package/dist/admin.js.map +1 -1
  12. package/dist/app-pages.d.ts +19 -0
  13. package/dist/app-pages.js +109 -0
  14. package/dist/app-pages.js.map +1 -0
  15. package/dist/auth-pages.js +7 -2
  16. package/dist/auth-pages.js.map +1 -1
  17. package/dist/charts.d.ts +98 -2
  18. package/dist/charts.js +264 -24
  19. package/dist/charts.js.map +1 -1
  20. package/dist/context.js +32 -1
  21. package/dist/context.js.map +1 -1
  22. package/dist/dashboard.d.ts +63 -8
  23. package/dist/dashboard.js +180 -36
  24. package/dist/dashboard.js.map +1 -1
  25. package/dist/i18n/messages/de.js +751 -0
  26. package/dist/i18n/messages/de.js.map +1 -1
  27. package/dist/i18n/messages/en.js +751 -0
  28. package/dist/i18n/messages/en.js.map +1 -1
  29. package/dist/i18n/messages/es.js +751 -0
  30. package/dist/i18n/messages/es.js.map +1 -1
  31. package/dist/i18n/messages/fr.js +751 -0
  32. package/dist/i18n/messages/fr.js.map +1 -1
  33. package/dist/i18n/messages/pt.js +751 -0
  34. package/dist/i18n/messages/pt.js.map +1 -1
  35. package/dist/index.d.ts +9 -0
  36. package/dist/index.js +9 -0
  37. package/dist/index.js.map +1 -1
  38. package/dist/shell.js +37 -34
  39. package/dist/shell.js.map +1 -1
  40. package/dist/site/editor/api.d.ts +74 -0
  41. package/dist/site/editor/api.js +93 -0
  42. package/dist/site/editor/api.js.map +1 -0
  43. package/dist/site/editor/content-page.d.ts +4 -0
  44. package/dist/site/editor/content-page.js +65 -0
  45. package/dist/site/editor/content-page.js.map +1 -0
  46. package/dist/site/editor/inbox-tab.d.ts +4 -0
  47. package/dist/site/editor/inbox-tab.js +88 -0
  48. package/dist/site/editor/inbox-tab.js.map +1 -0
  49. package/dist/site/editor/index.d.ts +1 -0
  50. package/dist/site/editor/index.js +3 -0
  51. package/dist/site/editor/index.js.map +1 -0
  52. package/dist/site/editor/model.d.ts +145 -0
  53. package/dist/site/editor/model.js +408 -0
  54. package/dist/site/editor/model.js.map +1 -0
  55. package/dist/site/editor/page-editor.d.ts +10 -0
  56. package/dist/site/editor/page-editor.js +257 -0
  57. package/dist/site/editor/page-editor.js.map +1 -0
  58. package/dist/site/editor/page-settings.d.ts +9 -0
  59. package/dist/site/editor/page-settings.js +105 -0
  60. package/dist/site/editor/page-settings.js.map +1 -0
  61. package/dist/site/editor/pages-tab.d.ts +5 -0
  62. package/dist/site/editor/pages-tab.js +108 -0
  63. package/dist/site/editor/pages-tab.js.map +1 -0
  64. package/dist/site/editor/posts-tab.d.ts +6 -0
  65. package/dist/site/editor/posts-tab.js +139 -0
  66. package/dist/site/editor/posts-tab.js.map +1 -0
  67. package/dist/site/editor/preview.d.ts +32 -0
  68. package/dist/site/editor/preview.js +104 -0
  69. package/dist/site/editor/preview.js.map +1 -0
  70. package/dist/site/editor/prop-fields.d.ts +53 -0
  71. package/dist/site/editor/prop-fields.js +233 -0
  72. package/dist/site/editor/prop-fields.js.map +1 -0
  73. package/dist/site/editor/section-list.d.ts +14 -0
  74. package/dist/site/editor/section-list.js +110 -0
  75. package/dist/site/editor/section-list.js.map +1 -0
  76. package/dist/site/editor/section-picker.d.ts +12 -0
  77. package/dist/site/editor/section-picker.js +44 -0
  78. package/dist/site/editor/section-picker.js.map +1 -0
  79. package/dist/site/editor/widgets.d.ts +84 -0
  80. package/dist/site/editor/widgets.js +130 -0
  81. package/dist/site/editor/widgets.js.map +1 -0
  82. package/dist/site/format.d.ts +31 -0
  83. package/dist/site/format.js +106 -0
  84. package/dist/site/format.js.map +1 -0
  85. package/dist/site/forms.d.ts +43 -0
  86. package/dist/site/forms.js +155 -0
  87. package/dist/site/forms.js.map +1 -0
  88. package/dist/site/header.d.ts +32 -0
  89. package/dist/site/header.js +76 -0
  90. package/dist/site/header.js.map +1 -0
  91. package/dist/site/icons.d.ts +10 -0
  92. package/dist/site/icons.js +28 -0
  93. package/dist/site/icons.js.map +1 -0
  94. package/dist/site/index.d.ts +11 -0
  95. package/dist/site/index.js +13 -0
  96. package/dist/site/index.js.map +1 -0
  97. package/dist/site/markdown.d.ts +14 -0
  98. package/dist/site/markdown.js +457 -0
  99. package/dist/site/markdown.js.map +1 -0
  100. package/dist/site/page.d.ts +16 -0
  101. package/dist/site/page.js +65 -0
  102. package/dist/site/page.js.map +1 -0
  103. package/dist/site/proxy.d.ts +13 -0
  104. package/dist/site/proxy.js +43 -0
  105. package/dist/site/proxy.js.map +1 -0
  106. package/dist/site/sections.d.ts +43 -0
  107. package/dist/site/sections.js +560 -0
  108. package/dist/site/sections.js.map +1 -0
  109. package/dist/site/server.d.ts +73 -0
  110. package/dist/site/server.js +235 -0
  111. package/dist/site/server.js.map +1 -0
  112. package/dist/site/types.d.ts +137 -0
  113. package/dist/site/types.js +2 -0
  114. package/dist/site/types.js.map +1 -0
  115. package/dist/support.d.ts +29 -0
  116. package/dist/support.js +165 -0
  117. package/dist/support.js.map +1 -0
  118. package/dist/system-config.d.ts +24 -0
  119. package/dist/system-config.js +37 -0
  120. package/dist/system-config.js.map +1 -0
  121. package/dist/system-settings.d.ts +9 -0
  122. package/dist/system-settings.js +60 -0
  123. package/dist/system-settings.js.map +1 -0
  124. package/dist/theme-catalog.d.ts +72 -2
  125. package/dist/theme-catalog.js +47 -0
  126. package/dist/theme-catalog.js.map +1 -1
  127. package/dist/theme-switcher.d.ts +8 -0
  128. package/dist/theme-switcher.js +39 -4
  129. package/dist/theme-switcher.js.map +1 -1
  130. package/dist/theme.js +8 -0
  131. package/dist/theme.js.map +1 -1
  132. package/dist/transactions.d.ts +4 -0
  133. package/dist/transactions.js +60 -0
  134. package/dist/transactions.js.map +1 -0
  135. package/package.json +9 -5
  136. package/styles.css +1089 -0
@@ -0,0 +1,29 @@
1
+ interface Ticket {
2
+ id: string;
3
+ number: number;
4
+ subject: string;
5
+ status: "open" | "pending" | "closed";
6
+ priority: "low" | "normal" | "high" | "urgent";
7
+ requester: {
8
+ id: string;
9
+ name: string;
10
+ email: string;
11
+ } | null;
12
+ assignee: {
13
+ id: string;
14
+ name: string;
15
+ } | null;
16
+ organizationId: string | null;
17
+ messages?: number;
18
+ lastMessageAt: string;
19
+ closedAt: string | null;
20
+ createdAt: string;
21
+ }
22
+ export declare function TicketStatus({ status }: {
23
+ status: Ticket["status"];
24
+ }): import("react").JSX.Element;
25
+ /** Help & support (in the app): contact the support team and follow your requests. `?ticket=<id>` opens one. */
26
+ export declare function SupportPage(): import("react").JSX.Element;
27
+ /** Administration → Support (global admins): every request, its thread, status, priority, assignee and quick actions. */
28
+ export declare function SupportInboxPage(): import("react").JSX.Element;
29
+ export {};
@@ -0,0 +1,165 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useQuery } from "@tanstack/react-query";
4
+ import { ArrowLeft, Building2, Mail, Plus, Search, Send, UserRound } from "lucide-react";
5
+ import Link from "next/link";
6
+ import { useState } from "react";
7
+ import { useQueryParam, useDebouncedValue } from "./admin-orgs.js";
8
+ import { useForge, useMe } from "./context.js";
9
+ import { useSystemConfig } from "./system-config.js";
10
+ import { ListSkeleton } from "./skeleton.js";
11
+ import { Alert, Badge, Button, Card, EmptyState, FieldShell, Input, PageHeader, Pagination, Select, Spinner, Textarea, cn } from "./ui.js";
12
+ const PRIORITIES = ["low", "normal", "high", "urgent"];
13
+ const STATUS_TONE = { open: 3, pending: 2, closed: 6 };
14
+ const PRIORITY_TONE = { low: 6, normal: 0, high: 2, urgent: 4 };
15
+ const errorText = (e) => {
16
+ const body = e?.body;
17
+ if (body?.issues?.length)
18
+ return body.issues.map((i) => `${i.path}: ${i.message}`).join(" · ");
19
+ return typeof body?.message === "string" ? body.message : (e?.message ?? String(e));
20
+ };
21
+ export function TicketStatus({ status }) {
22
+ const { t } = useForge();
23
+ return _jsx(Badge, { tone: STATUS_TONE[status], children: t(`support.status.${status}`) });
24
+ }
25
+ function TicketPriority({ priority }) {
26
+ const { t } = useForge();
27
+ return _jsx(Badge, { tone: PRIORITY_TONE[priority], children: t(`support.priority.${priority}`) });
28
+ }
29
+ function Thread({ ticket, staffView }) {
30
+ const { locale, t } = useForge();
31
+ return (_jsx("ol", { className: "space-y-3", "aria-label": t("support.thread"), children: ticket.thread.map((m) => {
32
+ // In the inbox the support team's messages sit on the right; in the app, the person's own do.
33
+ const mine = staffView ? m.staff : !m.staff;
34
+ return (_jsx("li", { className: cn("flex", mine ? "justify-end" : "justify-start"), children: _jsxs("div", { className: cn("forge-support-message max-w-[85%] px-3.5 py-2.5 text-sm", mine && "forge-support-message-own"), "data-staff": m.staff || undefined, children: [_jsxs("p", { className: "mb-1 text-xs font-medium text-ink-muted", children: [m.staff ? t("support.team", { name: m.author?.name ?? "" }) : (m.author?.name ?? t("support.deletedUser")), " \u00B7 ", _jsx("time", { dateTime: m.createdAt, children: new Date(m.createdAt).toLocaleString(locale) })] }), _jsx("p", { className: "whitespace-pre-wrap text-ink", children: m.body })] }) }, m.id));
35
+ }) }));
36
+ }
37
+ function ReplyBox({ ticket, staff, onSent }) {
38
+ const { api, t } = useForge();
39
+ const [body, setBody] = useState("");
40
+ const [busy, setBusy] = useState(null);
41
+ const [error, setError] = useState(null);
42
+ const send = async (close) => {
43
+ if (!body.trim())
44
+ return;
45
+ setBusy(close ? "close" : "reply");
46
+ setError(null);
47
+ try {
48
+ await api(`/support/tickets/${ticket.id}/messages`, { method: "POST", body: JSON.stringify({ body, close }) });
49
+ setBody("");
50
+ onSent();
51
+ }
52
+ catch (e) {
53
+ setError(errorText(e));
54
+ }
55
+ finally {
56
+ setBusy(null);
57
+ }
58
+ };
59
+ return (_jsxs("form", { className: "space-y-2", onSubmit: (e) => {
60
+ e.preventDefault();
61
+ void send(false);
62
+ }, children: [error && _jsx(Alert, { children: error }), _jsx("label", { htmlFor: `reply-${ticket.id}`, className: "sr-only", children: t("support.reply") }), _jsx(Textarea, { id: `reply-${ticket.id}`, rows: 3, value: body, maxLength: 10000, onChange: (e) => setBody(e.target.value), placeholder: ticket.status === "closed" && !staff ? t("support.reopenPlaceholder") : t("support.replyPlaceholder") }), _jsxs("div", { className: "flex flex-wrap justify-end gap-2", children: [staff && (_jsx(Button, { onClick: () => send(true), loading: busy === "close", disabled: !body.trim(), children: t("support.replyAndClose") })), _jsxs(Button, { type: "submit", variant: "primary", loading: busy === "reply", disabled: !body.trim(), children: [_jsx(Send, { className: "size-4", "aria-hidden": true }), " ", t("support.send")] })] })] }));
63
+ }
64
+ /** Help & support (in the app): contact the support team and follow your requests. `?ticket=<id>` opens one. */
65
+ export function SupportPage() {
66
+ const { api, locale, t } = useForge();
67
+ const config = useSystemConfig();
68
+ const [ticketId, setTicketId] = useQueryParam("ticket");
69
+ const [creating, setCreating] = useState(false);
70
+ const tickets = useQuery({ queryKey: ["forge", "support", "mine"], queryFn: () => api("/support/tickets") });
71
+ const email = config.data?.settings?.supportEmail;
72
+ if (ticketId)
73
+ return _jsx(MyTicket, { id: ticketId, onBack: () => setTicketId(null) });
74
+ const list = tickets.data?.data ?? [];
75
+ return (_jsxs("div", { className: "mx-auto max-w-3xl space-y-6", children: [_jsx(PageHeader, { title: t("support.title"), description: t("support.description"), actions: !creating && (_jsxs(Button, { variant: "primary", onClick: () => setCreating(true), children: [_jsx(Plus, { className: "size-4", "aria-hidden": true }), " ", t("support.new")] })) }), email && (_jsxs("p", { className: "flex items-center gap-2 text-sm text-ink-muted", children: [_jsx(Mail, { className: "size-4", "aria-hidden": true }), " ", t("support.emailUs"), " ", _jsx("a", { href: `mailto:${email}`, className: "text-link hover:underline", children: email })] })), (creating || (!tickets.isLoading && !list.length)) && (_jsx(NewTicket, { onCancel: list.length ? () => setCreating(false) : undefined, onCreated: (id) => {
76
+ setCreating(false);
77
+ void tickets.refetch();
78
+ setTicketId(id);
79
+ } })), _jsxs(Card, { children: [_jsx("h2", { className: "border-b border-line px-4 py-3 text-sm font-semibold text-ink", children: t("support.myRequests") }), tickets.isLoading ? (_jsx(ListSkeleton, { rows: 3 })) : tickets.error ? (_jsx("div", { className: "p-3", children: _jsx(Alert, { children: errorText(tickets.error) }) })) : !list.length ? (_jsx(EmptyState, { title: t("support.noRequests") })) : (_jsx("ul", { className: "divide-y divide-line", children: list.map((x) => (_jsx("li", { children: _jsxs("button", { type: "button", onClick: () => setTicketId(x.id), className: "forge-focusable flex w-full flex-wrap items-center gap-x-3 gap-y-1 px-4 py-3 text-left text-sm hover:bg-hover", children: [_jsxs("span", { className: "font-mono text-xs text-ink-subtle", children: ["#", x.number] }), _jsx("span", { className: "min-w-0 flex-1 truncate font-medium text-ink", children: x.subject }), _jsx(TicketStatus, { status: x.status }), _jsx("span", { className: "text-xs text-ink-subtle tabular-nums", children: new Date(x.lastMessageAt).toLocaleDateString(locale) })] }) }, x.id))) }))] })] }));
80
+ }
81
+ function NewTicket({ onCreated, onCancel }) {
82
+ const { api, t } = useForge();
83
+ const [form, setForm] = useState({ subject: "", body: "", priority: "normal" });
84
+ const [error, setError] = useState(null);
85
+ const [loading, setLoading] = useState(false);
86
+ return (_jsx(Card, { className: "p-5", children: _jsxs("form", { className: "space-y-4", onSubmit: async (e) => {
87
+ e.preventDefault();
88
+ setLoading(true);
89
+ setError(null);
90
+ try {
91
+ const created = await api("/support/tickets", { method: "POST", body: JSON.stringify(form) });
92
+ setForm({ subject: "", body: "", priority: "normal" });
93
+ onCreated(created.id);
94
+ }
95
+ catch (err) {
96
+ setError(errorText(err));
97
+ }
98
+ finally {
99
+ setLoading(false);
100
+ }
101
+ }, children: [_jsx("h2", { className: "text-sm font-semibold text-ink", children: t("support.new") }), error && _jsx(Alert, { children: error }), _jsxs("div", { className: "grid gap-4 sm:grid-cols-[1fr_10rem]", children: [_jsx(FieldShell, { label: t("support.subject"), htmlFor: "support-subject", required: true, children: _jsx(Input, { id: "support-subject", required: true, maxLength: 200, value: form.subject, onChange: (e) => setForm({ ...form, subject: e.target.value }) }) }), _jsx(FieldShell, { label: t("support.priorityLabel"), htmlFor: "support-priority", children: _jsx(Select, { id: "support-priority", value: form.priority, onChange: (e) => setForm({ ...form, priority: e.target.value }), children: PRIORITIES.map((p) => (_jsx("option", { value: p, children: t(`support.priority.${p}`) }, p))) }) })] }), _jsx(FieldShell, { label: t("support.message"), htmlFor: "support-body", required: true, hint: t("support.messageHint"), children: _jsx(Textarea, { id: "support-body", required: true, rows: 5, maxLength: 10000, value: form.body, onChange: (e) => setForm({ ...form, body: e.target.value }) }) }), _jsxs("div", { className: "flex justify-end gap-2", children: [onCancel && _jsx(Button, { onClick: onCancel, children: t("common.cancel") }), _jsxs(Button, { type: "submit", variant: "primary", loading: loading, children: [_jsx(Send, { className: "size-4", "aria-hidden": true }), " ", t("support.send")] })] })] }) }));
102
+ }
103
+ function MyTicket({ id, onBack }) {
104
+ const { api, t } = useForge();
105
+ const ticket = useQuery({ queryKey: ["forge", "support", id], queryFn: () => api(`/support/tickets/${id}`) });
106
+ return (_jsxs("div", { className: "mx-auto max-w-3xl space-y-4", children: [_jsxs("button", { type: "button", onClick: onBack, className: "inline-flex items-center gap-1.5 text-sm text-ink-muted hover:text-ink", children: [_jsx(ArrowLeft, { className: "size-4", "aria-hidden": true }), " ", t("support.myRequests")] }), ticket.isLoading ? (_jsx(Spinner, {})) : ticket.error ? (_jsx(Alert, { children: errorText(ticket.error) })) : (_jsxs(_Fragment, { children: [_jsx(PageHeader, { title: `#${ticket.data.number} · ${ticket.data.subject}`, actions: _jsx(TicketStatus, { status: ticket.data.status }) }), _jsxs(Card, { className: "space-y-5 p-5", children: [_jsx(Thread, { ticket: ticket.data, staffView: false }), _jsx(ReplyBox, { ticket: ticket.data, staff: false, onSent: () => void ticket.refetch() })] })] }))] }));
107
+ }
108
+ const FILTERS = ["open", "pending", "closed", "all"];
109
+ /** Administration → Support (global admins): every request, its thread, status, priority, assignee and quick actions. */
110
+ export function SupportInboxPage() {
111
+ const { api, locale, t } = useForge();
112
+ const [ticketId, setTicketId] = useQueryParam("ticket");
113
+ const [status, setStatus] = useState("open");
114
+ const [priority, setPriority] = useState("");
115
+ const [assignee, setAssignee] = useState("");
116
+ const [search, setSearch] = useState("");
117
+ const [page, setPage] = useState(1);
118
+ const q = useDebouncedValue(search);
119
+ const inbox = useQuery({
120
+ queryKey: ["forge", "admin", "support", status, priority, assignee, q, page],
121
+ queryFn: () => api("/admin/support/tickets", {
122
+ query: { status, priority, assignee, search: q, page },
123
+ }),
124
+ refetchInterval: 30_000,
125
+ });
126
+ const list = inbox.data?.data ?? [];
127
+ return (_jsxs("div", { children: [_jsx(PageHeader, { title: t("adminArea.nav.support"), description: t("adminArea.support.description") }), _jsxs("div", { className: "grid gap-4 lg:grid-cols-[minmax(0,24rem)_minmax(0,1fr)]", children: [_jsxs(Card, { className: cn("min-w-0", ticketId && "hidden lg:block"), children: [_jsxs("div", { className: "space-y-2 border-b border-line p-3", children: [_jsx("div", { className: "forge-admin-segmented flex flex-wrap gap-0.5 p-0.5", role: "group", "aria-label": t("support.statusLabel"), children: FILTERS.map((f) => (_jsxs("button", { type: "button", "aria-pressed": status === f, onClick: () => {
128
+ setStatus(f);
129
+ setPage(1);
130
+ }, className: cn("forge-btn h-7 flex-1 px-2 text-xs font-medium", status === f ? "forge-btn-secondary" : "forge-btn-ghost"), children: [f === "all" ? t("adminArea.support.all") : t(`support.status.${f}`), f !== "all" && inbox.data && _jsx("span", { className: "ml-1 text-ink-subtle tabular-nums", children: inbox.data.counts[f] ?? 0 })] }, f))) }), _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-ink-subtle", "aria-hidden": true }), _jsx(Input, { "aria-label": t("adminArea.support.search"), placeholder: t("adminArea.support.search"), value: search, onChange: (e) => { setSearch(e.target.value); setPage(1); }, className: "h-8 pl-8" })] }), _jsxs("div", { className: "grid grid-cols-2 gap-2", children: [_jsxs(Select, { "aria-label": t("support.priorityLabel"), value: priority, onChange: (e) => { setPriority(e.target.value); setPage(1); }, className: "h-8 py-0 text-xs", children: [_jsx("option", { value: "", children: t("adminArea.support.anyPriority") }), PRIORITIES.map((p) => (_jsx("option", { value: p, children: t(`support.priority.${p}`) }, p)))] }), _jsxs(Select, { "aria-label": t("support.assignee"), value: assignee, onChange: (e) => { setAssignee(e.target.value); setPage(1); }, className: "h-8 py-0 text-xs", children: [_jsx("option", { value: "", children: t("adminArea.support.anyone") }), _jsx("option", { value: "me", children: t("adminArea.support.mine") }), _jsx("option", { value: "none", children: t("adminArea.support.unassigned") })] })] })] }), inbox.isLoading ? (_jsx(ListSkeleton, { rows: 5 })) : inbox.error ? (_jsx("div", { className: "p-3", children: _jsx(Alert, { children: errorText(inbox.error) }) })) : !list.length ? (_jsx(EmptyState, { title: t("adminArea.support.empty") })) : (_jsx("ul", { className: "divide-y divide-line", children: list.map((x) => (_jsx("li", { children: _jsxs("button", { type: "button", "aria-current": ticketId === x.id ? "true" : undefined, onClick: () => setTicketId(x.id), className: "forge-support-row forge-focusable block w-full px-4 py-3 text-left text-sm hover:bg-hover", children: [_jsxs("span", { className: "flex items-center gap-2", children: [_jsxs("span", { className: "font-mono text-xs text-ink-subtle", children: ["#", x.number] }), _jsx("span", { className: "min-w-0 flex-1 truncate font-medium text-ink", children: x.subject })] }), _jsxs("span", { className: "mt-1 flex flex-wrap items-center gap-1.5 text-xs text-ink-muted", children: [_jsx(TicketStatus, { status: x.status }), _jsx(TicketPriority, { priority: x.priority }), _jsx("span", { className: "truncate", children: x.requester?.name ?? "—" }), _jsx("span", { className: "ml-auto tabular-nums", children: new Date(x.lastMessageAt).toLocaleDateString(locale) })] })] }) }, x.id))) })), inbox.data && inbox.data.meta.total > 0 && _jsx(Pagination, { page: inbox.data.meta.page, pages: inbox.data.meta.pages, total: inbox.data.meta.total, onPage: setPage })] }), _jsx("div", { className: cn("min-w-0", !ticketId && "hidden lg:block"), children: ticketId ? (_jsx(InboxTicket, { id: ticketId, assignees: inbox.data?.assignees ?? [], onBack: () => setTicketId(null), onChanged: () => void inbox.refetch() })) : (_jsx(Card, { children: _jsx(EmptyState, { title: t("adminArea.support.pick") }) })) })] })] }));
131
+ }
132
+ function InboxTicket({ id, assignees, onBack, onChanged }) {
133
+ const { api, app, auth, locale, t } = useForge();
134
+ const me = useMe();
135
+ const [error, setError] = useState(null);
136
+ const ticket = useQuery({ queryKey: ["forge", "admin", "support", "ticket", id], queryFn: () => api(`/support/tickets/${id}`) });
137
+ const update = async (data) => {
138
+ setError(null);
139
+ try {
140
+ await api(`/admin/support/tickets/${id}`, { method: "PATCH", body: JSON.stringify(data) });
141
+ await ticket.refetch();
142
+ onChanged();
143
+ }
144
+ catch (e) {
145
+ setError(errorText(e));
146
+ }
147
+ };
148
+ if (ticket.isLoading)
149
+ return _jsx(Card, { children: _jsx(Spinner, {}) });
150
+ if (ticket.error)
151
+ return _jsx(Alert, { children: errorText(ticket.error) });
152
+ const x = ticket.data;
153
+ const requester = x.requester;
154
+ return (_jsxs(Card, { className: "space-y-5 p-5", children: [_jsxs("button", { type: "button", onClick: onBack, className: "inline-flex items-center gap-1.5 text-sm text-ink-muted hover:text-ink lg:hidden", children: [_jsx(ArrowLeft, { className: "size-4", "aria-hidden": true }), " ", t("adminArea.nav.support")] }), _jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("h2", { className: "forge-heading text-lg font-semibold text-ink", children: [_jsxs("span", { className: "font-mono text-ink-subtle", children: ["#", x.number] }), " ", x.subject] }), _jsxs("p", { className: "mt-1 text-sm text-ink-muted", children: [requester ? `${requester.name} · ${requester.email}` : t("support.deletedUser"), " \u00B7 ", new Date(x.createdAt).toLocaleString(locale)] })] }), _jsxs("div", { className: "flex flex-wrap gap-2", children: [requester && requester.id !== me.data?.user?.id && (_jsxs(Button, { size: "sm", onClick: async () => {
155
+ const r = await auth.admin.impersonateUser({ userId: requester.id });
156
+ if (r.error)
157
+ setError(r.error.message);
158
+ else
159
+ window.location.href = "/";
160
+ }, children: [_jsx(UserRound, { className: "size-3.5", "aria-hidden": true }), " ", t("admin.users.impersonate")] })), app.tenancy.enabled && x.organizationId && (_jsxs(Link, { href: `/admin/organizations?id=${x.organizationId}`, className: "forge-btn forge-btn-secondary inline-flex h-7 items-center gap-1.5 px-2.5 text-xs font-medium", children: [_jsx(Building2, { className: "size-3.5", "aria-hidden": true }), " ", t("adminArea.support.viewOrganization")] }))] })] }), error && _jsx(Alert, { children: error }), _jsxs("div", { className: "grid gap-3 sm:grid-cols-3", children: [_jsx(FieldShell, { label: t("support.statusLabel"), htmlFor: "ticket-status", children: _jsx(Select, { id: "ticket-status", value: x.status, onChange: (e) => update({ status: e.target.value }), children: ["open", "pending", "closed"].map((s) => (_jsx("option", { value: s, children: t(`support.status.${s}`) }, s))) }) }), _jsx(FieldShell, { label: t("support.priorityLabel"), htmlFor: "ticket-priority", children: _jsx(Select, { id: "ticket-priority", value: x.priority, onChange: (e) => update({ priority: e.target.value }), children: PRIORITIES.map((p) => (_jsx("option", { value: p, children: t(`support.priority.${p}`) }, p))) }) }), _jsx(FieldShell, { label: t("support.assignee"), htmlFor: "ticket-assignee", children: _jsxs(Select, { id: "ticket-assignee", value: x.assignee?.id ?? "", onChange: (e) => update({ assigneeId: e.target.value || null }), children: [_jsx("option", { value: "", children: t("adminArea.support.unassigned") }), assignees.map((a) => (_jsx("option", { value: a.id, children: a.name }, a.id)))] }) })] }), _jsx(Thread, { ticket: x, staffView: true }), _jsx(ReplyBox, { ticket: x, staff: true, onSent: () => {
161
+ void ticket.refetch();
162
+ onChanged();
163
+ } })] }));
164
+ }
165
+ //# sourceMappingURL=support.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support.js","sourceRoot":"","sources":["../src/support.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /** Runtime settings anyone may read (GET /config): set by global admins in Administration → System settings. */
2
+ export interface PublicSystemSettings {
3
+ appName: string | null;
4
+ supportEmail: string | null;
5
+ maintenance: {
6
+ enabled: boolean;
7
+ message: string | null;
8
+ };
9
+ registration: boolean;
10
+ featureFlags: Record<string, boolean>;
11
+ }
12
+ export declare function useSystemConfig(): import("@tanstack/react-query").UseQueryResult<{
13
+ socialProviders: string[];
14
+ settings?: PublicSystemSettings;
15
+ }, Error>;
16
+ /** The app's name: the override from System settings, else `name` from forge.config.ts. */
17
+ export declare function useAppName(): string;
18
+ /**
19
+ * A feature flag declared in `featureFlags` of forge.config.ts, with its runtime value from System settings
20
+ * (the config's default until the settings are loaded).
21
+ */
22
+ export declare function useFeatureFlag(name: string): boolean;
23
+ /** Shown on every page while maintenance mode is on. */
24
+ export declare function MaintenanceBanner(): import("react").JSX.Element | null;
@@ -0,0 +1,37 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useQuery } from "@tanstack/react-query";
4
+ import { Wrench } from "lucide-react";
5
+ import { useForge } from "./context.js";
6
+ export function useSystemConfig() {
7
+ const { api } = useForge();
8
+ return useQuery({
9
+ queryKey: ["forge", "config"],
10
+ queryFn: () => api("/config"),
11
+ staleTime: 60_000,
12
+ });
13
+ }
14
+ /** The app's name: the override from System settings, else `name` from forge.config.ts. */
15
+ export function useAppName() {
16
+ const { app } = useForge();
17
+ return useSystemConfig().data?.settings?.appName ?? app.name;
18
+ }
19
+ /**
20
+ * A feature flag declared in `featureFlags` of forge.config.ts, with its runtime value from System settings
21
+ * (the config's default until the settings are loaded).
22
+ */
23
+ export function useFeatureFlag(name) {
24
+ const { app } = useForge();
25
+ const runtime = useSystemConfig().data?.settings?.featureFlags?.[name];
26
+ return typeof runtime === "boolean" ? runtime : app.featureFlags?.[name] === true;
27
+ }
28
+ /** Shown on every page while maintenance mode is on. */
29
+ export function MaintenanceBanner() {
30
+ const { t } = useForge();
31
+ const config = useSystemConfig();
32
+ const m = config.data?.settings?.maintenance;
33
+ if (!m?.enabled)
34
+ return null;
35
+ return (_jsxs("div", { role: "status", className: "forge-banner forge-admin-maintenance flex items-center justify-center gap-2 px-4 py-1.5 text-center text-sm", children: [_jsx(Wrench, { className: "size-4 shrink-0", "aria-hidden": true }), _jsx("span", { children: m.message ? t("maintenance.bannerWithMessage", { message: m.message }) : t("maintenance.banner") })] }));
36
+ }
37
+ //# sourceMappingURL=system-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-config.js","sourceRoot":"","sources":["../src/system-config.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAWxC,MAAM,UAAU,eAAe;IAC7B,MAAM,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC3B,OAAO,QAAQ,CAAC;QACd,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC7B,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAiE,SAAS,CAAC;QAC7F,SAAS,EAAE,MAAM;KAClB,CAAC,CAAC;AACL,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,UAAU;IACxB,MAAM,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC3B,OAAO,eAAe,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;IACvE,OAAO,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;AACpF,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,iBAAiB;IAC/B,MAAM,EAAE,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC;IAC7C,IAAI,CAAC,CAAC,EAAE,OAAO;QAAE,OAAO,IAAI,CAAC;IAC7B,OAAO,CACL,eAAK,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,6GAA6G,aACxI,KAAC,MAAM,IAAC,SAAS,EAAC,iBAAiB,wBAAe,EAClD,yBAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,+BAA+B,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,GAAQ,IAC3G,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare function Switch({ id, checked, onChange, disabled, label }: {
2
+ id?: string;
3
+ checked: boolean;
4
+ onChange: (v: boolean) => void;
5
+ disabled?: boolean;
6
+ label?: string;
7
+ }): import("react").JSX.Element;
8
+ /** Administration → System settings (global admins): stored in the database, every change audited. */
9
+ export declare function SystemSettingsPage(): import("react").JSX.Element;
@@ -0,0 +1,60 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useQuery, useQueryClient } from "@tanstack/react-query";
4
+ import { CircleAlert, CircleCheck } from "lucide-react";
5
+ import { useEffect, useState } from "react";
6
+ import { useForge } from "./context.js";
7
+ import { FormSkeleton } from "./skeleton.js";
8
+ import { Alert, Badge, Button, Card, FieldShell, Input, PageHeader, Select, Textarea, cn } from "./ui.js";
9
+ export function Switch({ id, checked, onChange, disabled, label }) {
10
+ return (_jsx("button", { id: id, type: "button", role: "switch", "aria-checked": checked, "aria-label": label, disabled: disabled, onClick: () => onChange(!checked), className: "forge-switch relative inline-flex h-6 w-11 shrink-0 items-center disabled:opacity-50", children: _jsx("span", { className: cn("forge-switch-thumb inline-block size-5 transition-transform", checked ? "translate-x-5" : "translate-x-0.5") }) }));
11
+ }
12
+ function Section({ title, description, children }) {
13
+ return (_jsxs(Card, { className: "p-[var(--forge-pad-card-lg)]", children: [_jsx("h2", { className: "text-sm font-semibold text-ink", children: title }), description && _jsx("p", { className: "mt-1 text-sm text-ink-muted", children: description }), _jsx("div", { className: "mt-5 space-y-4", children: children })] }));
14
+ }
15
+ function Toggle({ id, label, hint, checked, onChange, disabled }) {
16
+ return (_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsx("label", { htmlFor: id, className: "text-sm font-medium text-ink", children: label }), hint && _jsx("p", { className: "mt-0.5 text-xs text-ink-muted", children: hint })] }), _jsx(Switch, { id: id, checked: checked, onChange: onChange, disabled: disabled })] }));
17
+ }
18
+ /** Administration → System settings (global admins): stored in the database, every change audited. */
19
+ export function SystemSettingsPage() {
20
+ const { api, t } = useForge();
21
+ const queryClient = useQueryClient();
22
+ const q = useQuery({ queryKey: ["forge", "admin", "settings"], queryFn: () => api("/admin/settings") });
23
+ const [form, setForm] = useState(null);
24
+ const [notice, setNotice] = useState(null);
25
+ const [saving, setSaving] = useState(false);
26
+ useEffect(() => {
27
+ if (q.data && !form)
28
+ setForm(q.data.settings);
29
+ }, [q.data, form]);
30
+ if (q.error)
31
+ return _jsxs("div", { children: [_jsx(PageHeader, { title: t("adminArea.nav.settings") }), _jsx(Alert, { children: q.error.message })] });
32
+ if (!q.data || !form)
33
+ return _jsxs("div", { children: [_jsx(PageHeader, { title: t("adminArea.nav.settings") }), _jsx(FormSkeleton, { fields: 6 })] });
34
+ const d = q.data;
35
+ const set = (key, value) => setForm({ ...form, [key]: value });
36
+ const norm = (v) => JSON.stringify(typeof v === "string" && !v.trim() ? null : (v ?? null));
37
+ const changed = Object.keys(form).filter((k) => norm(form[k]) !== norm(d.settings[k]));
38
+ const save = async () => {
39
+ setSaving(true);
40
+ setNotice(null);
41
+ try {
42
+ const body = Object.fromEntries(changed.map((k) => [k, typeof form[k] === "string" && !form[k].trim() ? null : form[k]]));
43
+ const next = await api("/admin/settings", { method: "PATCH", body: JSON.stringify(body) });
44
+ queryClient.setQueryData(["forge", "admin", "settings"], next);
45
+ setForm(next.settings);
46
+ await queryClient.invalidateQueries({ queryKey: ["forge", "config"] });
47
+ setNotice({ tone: "success", text: t("adminArea.settings.saved") });
48
+ }
49
+ catch (e) {
50
+ const body = e.body;
51
+ setNotice({ tone: "error", text: body?.issues?.map((i) => `${i.path}: ${i.message}`).join(" · ") ?? body?.message ?? e.message });
52
+ }
53
+ finally {
54
+ setSaving(false);
55
+ }
56
+ };
57
+ const flags = Object.keys(d.defaults.featureFlags);
58
+ return (_jsxs("div", { className: "mx-auto max-w-3xl space-y-6 pb-20", children: [_jsx(PageHeader, { title: t("adminArea.nav.settings"), description: t("adminArea.settings.description") }), notice && _jsx(Alert, { tone: notice.tone, children: notice.text }), _jsxs(Section, { title: t("adminArea.settings.general"), children: [_jsx(FieldShell, { label: t("adminArea.settings.appName"), htmlFor: "set-app-name", hint: t("adminArea.settings.appNameHint", { name: d.defaults.appName }), children: _jsx(Input, { id: "set-app-name", maxLength: 80, placeholder: d.defaults.appName, value: form.appName ?? "", onChange: (e) => set("appName", e.target.value) }) }), _jsx(FieldShell, { label: t("adminArea.settings.supportEmail"), htmlFor: "set-support-email", hint: t("adminArea.settings.supportEmailHint"), children: _jsx(Input, { id: "set-support-email", type: "email", maxLength: 254, placeholder: "support@example.com", value: form.supportEmail ?? "", onChange: (e) => set("supportEmail", e.target.value) }) })] }), _jsxs(Section, { title: t("adminArea.settings.access"), children: [_jsx(Toggle, { id: "set-registration", label: t("adminArea.settings.registration"), hint: d.defaults.registration ? t("adminArea.settings.registrationHint") : t("adminArea.settings.registrationDisabled"), checked: d.defaults.registration && form.registrationOpen !== false, disabled: !d.defaults.registration, onChange: (v) => set("registrationOpen", v ? null : false) }), d.roles.length > 0 && (_jsx(FieldShell, { label: t("adminArea.settings.defaultRole"), htmlFor: "set-default-role", hint: t("adminArea.settings.defaultRoleHint"), children: _jsxs(Select, { id: "set-default-role", value: form.defaultRole ?? "", onChange: (e) => set("defaultRole", e.target.value || null), children: [_jsx("option", { value: "", children: t("adminArea.settings.defaultRoleNone") }), d.roles.map((r) => (_jsx("option", { value: r, children: r }, r)))] }) }))] }), _jsx(Section, { title: t("adminArea.settings.email"), children: _jsx(FieldShell, { label: t("adminArea.settings.emailFrom"), htmlFor: "set-email-from", hint: t("adminArea.settings.emailFromHint"), children: _jsx(Input, { id: "set-email-from", maxLength: 200, placeholder: "Acme <hello@acme.com>", value: form.emailFrom ?? "", onChange: (e) => set("emailFrom", e.target.value) }) }) }), _jsxs(Section, { title: t("adminArea.settings.maintenance"), description: t("adminArea.settings.maintenanceHint"), children: [_jsx(Toggle, { id: "set-maintenance", label: t("adminArea.settings.maintenanceMode"), checked: form.maintenance, onChange: (v) => set("maintenance", v) }), _jsx(FieldShell, { label: t("adminArea.settings.maintenanceMessage"), htmlFor: "set-maintenance-message", children: _jsx(Textarea, { id: "set-maintenance-message", rows: 2, maxLength: 500, value: form.maintenanceMessage ?? "", onChange: (e) => set("maintenanceMessage", e.target.value) }) })] }), _jsx(Section, { title: t("adminArea.settings.flags"), description: t("adminArea.settings.flagsHint"), children: flags.length === 0 ? (_jsx("p", { className: "text-sm text-ink-muted", children: t("adminArea.settings.noFlags") })) : (flags.map((name) => (_jsx(Toggle, { id: `flag-${name}`, label: name, hint: t("adminArea.settings.flagDefault", { value: t(d.defaults.featureFlags[name] ? "common.yes" : "common.no") }), checked: !!form.featureFlags[name], onChange: (v) => set("featureFlags", { ...form.featureFlags, [name]: v }) }, name)))) }), _jsx(Section, { title: t("adminArea.settings.environment"), description: t("adminArea.settings.environmentHint"), children: _jsx("ul", { className: "divide-y divide-line", children: d.environment.map((e) => (_jsxs("li", { className: "flex items-center justify-between gap-3 py-2 text-sm", children: [_jsxs("span", { className: "flex items-center gap-2 text-ink", children: [e.ok ? _jsx(CircleCheck, { className: "size-4 text-[var(--forge-success)]", "aria-hidden": true }) : _jsx(CircleAlert, { className: "size-4 text-danger", "aria-hidden": true }), t(`adminArea.env.${e.key}`)] }), _jsxs("span", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-mono text-xs text-ink-muted", children: e.detail }), _jsx(Badge, { tone: e.ok ? 1 : 2, children: t(e.ok ? "adminArea.env.ok" : "adminArea.env.missing") })] })] }, e.key))) }) }), _jsxs("div", { className: "forge-admin-savebar sticky bottom-4 flex items-center justify-end gap-3 p-3", children: [_jsx("span", { className: "text-sm text-ink-muted", "aria-live": "polite", children: changed.length ? t("adminArea.settings.unsaved", { count: changed.length }) : t("adminArea.settings.upToDate") }), _jsx(Button, { disabled: !changed.length || saving, onClick: () => setForm(d.settings), children: t("common.cancel") }), _jsx(Button, { variant: "primary", loading: saving, disabled: !changed.length, onClick: save, children: t("common.save") })] })] }));
59
+ }
60
+ //# sourceMappingURL=system-settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-settings.js","sourceRoot":"","sources":["../src/system-settings.tsx"],"names":[],"mappings":"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"}
@@ -42,6 +42,46 @@ export declare const STYLE_OPTIONS: readonly [{
42
42
  readonly id: "clay";
43
43
  readonly label: "Clay";
44
44
  readonly hint: "Puffy, soft and rounded";
45
+ }, {
46
+ readonly id: "corporate";
47
+ readonly label: "Corporate";
48
+ readonly hint: "Sober, dense, crisp tables";
49
+ }, {
50
+ readonly id: "soft";
51
+ readonly label: "Soft";
52
+ readonly hint: "Pastel, rounded, airy";
53
+ }, {
54
+ readonly id: "luxury";
55
+ readonly label: "Luxury";
56
+ readonly hint: "Deep tones, gold, serif";
57
+ }, {
58
+ readonly id: "retro";
59
+ readonly label: "Retro";
60
+ readonly hint: "90s windows, bevels";
61
+ }, {
62
+ readonly id: "neon";
63
+ readonly label: "Neon";
64
+ readonly hint: "Dark with glowing accents";
65
+ }, {
66
+ readonly id: "swiss";
67
+ readonly label: "Swiss";
68
+ readonly hint: "Grid, big type, red";
69
+ }, {
70
+ readonly id: "nature";
71
+ readonly label: "Nature";
72
+ readonly hint: "Earthy, organic, paper";
73
+ }, {
74
+ readonly id: "cyber";
75
+ readonly label: "Cyber";
76
+ readonly hint: "Angled corners, HUD";
77
+ }, {
78
+ readonly id: "minimal";
79
+ readonly label: "Minimal";
80
+ readonly hint: "Whitespace and hairlines";
81
+ }, {
82
+ readonly id: "playful";
83
+ readonly label: "Playful";
84
+ readonly hint: "Bold, hand-drawn, bouncy";
45
85
  }];
46
86
  export declare const FONT_OPTIONS: Record<string, {
47
87
  label: string;
@@ -50,7 +90,17 @@ export declare const FONT_OPTIONS: Record<string, {
50
90
  families: readonly string[];
51
91
  }>;
52
92
  export declare function fontHref(font: string): string | null;
53
- export interface PresetOption {
93
+ /** Look-and-feel values; null for cards/buttons/sidebar means "the style's own" (mirrors ThemeLook in the compiler). */
94
+ export interface LookOption {
95
+ background?: string;
96
+ cards?: string | null;
97
+ buttons?: string | null;
98
+ motion?: string;
99
+ sidebar?: string | null;
100
+ iconStyle?: string;
101
+ chartPalette?: string;
102
+ }
103
+ export interface PresetOption extends LookOption {
54
104
  label: string;
55
105
  style: string;
56
106
  primary: string;
@@ -66,6 +116,26 @@ export declare const PRESET_OPTIONS: Record<string, PresetOption>;
66
116
  export declare const STYLE_COMPANIONS: Record<string, {
67
117
  font?: string;
68
118
  mode?: string;
69
- }>;
119
+ radius?: string;
120
+ } & LookOption>;
70
121
  export declare const LAYOUT_OPTIONS: readonly ["sidebar", "topbar", "compact"];
71
122
  export declare const DENSITY_OPTIONS: readonly ["comfortable", "compact"];
123
+ /** Look-and-feel choices (mirrors LOOK_OPTIONS in the compiler); "" in the switcher means the style's own. */
124
+ export declare const LOOK_OPTIONS: {
125
+ readonly background: readonly ["plain", "gradient", "mesh", "dots", "grid", "noise"];
126
+ readonly cards: readonly ["flat", "bordered", "elevated", "glass"];
127
+ readonly buttons: readonly ["solid", "soft", "outline", "pill"];
128
+ readonly motion: readonly ["none", "subtle", "lively"];
129
+ readonly sidebar: readonly ["light", "dark", "brand"];
130
+ readonly iconStyle: readonly ["outline", "duotone"];
131
+ readonly chartPalette: readonly ["theme", "vivid", "pastel", "mono"];
132
+ };
133
+ export declare const DEFAULT_LOOK: {
134
+ readonly background: "plain";
135
+ readonly cards: null;
136
+ readonly buttons: null;
137
+ readonly motion: "subtle";
138
+ readonly sidebar: null;
139
+ readonly iconStyle: "outline";
140
+ readonly chartPalette: "theme";
141
+ };
@@ -14,6 +14,16 @@ export const STYLE_OPTIONS = [
14
14
  { id: "aurora", label: "Aurora", hint: "Living gradient, glassy cards" },
15
15
  { id: "terminal", label: "Terminal", hint: "Monospace, phosphor accents" },
16
16
  { id: "clay", label: "Clay", hint: "Puffy, soft and rounded" },
17
+ { id: "corporate", label: "Corporate", hint: "Sober, dense, crisp tables" },
18
+ { id: "soft", label: "Soft", hint: "Pastel, rounded, airy" },
19
+ { id: "luxury", label: "Luxury", hint: "Deep tones, gold, serif" },
20
+ { id: "retro", label: "Retro", hint: "90s windows, bevels" },
21
+ { id: "neon", label: "Neon", hint: "Dark with glowing accents" },
22
+ { id: "swiss", label: "Swiss", hint: "Grid, big type, red" },
23
+ { id: "nature", label: "Nature", hint: "Earthy, organic, paper" },
24
+ { id: "cyber", label: "Cyber", hint: "Angled corners, HUD" },
25
+ { id: "minimal", label: "Minimal", hint: "Whitespace and hairlines" },
26
+ { id: "playful", label: "Playful", hint: "Bold, hand-drawn, bouncy" },
17
27
  ];
18
28
  const SANS = `ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif`;
19
29
  const SERIF = `ui-serif, Georgia, Cambria, "Times New Roman", serif`;
@@ -27,6 +37,10 @@ export const FONT_OPTIONS = {
27
37
  rounded: { label: "Nunito", display: `"Nunito", ${SANS}`, body: `"Nunito", ${SANS}`, families: ["Nunito:wght@400;500;600;700;800"] },
28
38
  mono: { label: "JetBrains Mono", display: `"JetBrains Mono", ${MONO}`, body: `"JetBrains Mono", ${MONO}`, families: ["JetBrains+Mono:wght@400;500;600;700"] },
29
39
  system: { label: "System", display: SANS, body: SANS, families: [] },
40
+ elegant: { label: "Cormorant + Inter", display: `"Cormorant Garamond", ${SERIF}`, body: `"Inter", ${SANS}`, families: ["Cormorant+Garamond:wght@500;600;700", "Inter:wght@400;500;600;700"] },
41
+ pixel: { label: "Silkscreen + IBM Plex", display: `"Silkscreen", ${MONO}`, body: `"IBM Plex Sans", ${SANS}`, families: ["Silkscreen:wght@400;700", "IBM+Plex+Sans:wght@400;500;600;700"] },
42
+ tech: { label: "Chakra Petch + Inter", display: `"Chakra Petch", ${SANS}`, body: `"Inter", ${SANS}`, families: ["Chakra+Petch:wght@500;600;700", "Inter:wght@400;500;600;700"] },
43
+ playful: { label: "Fredoka + Nunito", display: `"Fredoka", ${SANS}`, body: `"Nunito", ${SANS}`, families: ["Fredoka:wght@500;600;700", "Nunito:wght@400;500;600;700;800"] },
30
44
  };
31
45
  export function fontHref(font) {
32
46
  const families = FONT_OPTIONS[font]?.families ?? [];
@@ -42,6 +56,18 @@ export const PRESET_OPTIONS = {
42
56
  candy: { label: "Candy", style: "brutalist", primary: "#db2777", accent: "#facc15", mode: "light", radius: "none", font: "grotesk", layout: "topbar", density: "comfortable" },
43
57
  paper: { label: "Paper", style: "editorial", primary: "#1c1917", accent: "#b91c1c", mode: "light", radius: "none", font: "serif", layout: "topbar", density: "comfortable" },
44
58
  phosphor: { label: "Phosphor", style: "terminal", primary: "#16a34a", accent: "#f59e0b", mode: "dark", radius: "small", font: "mono", layout: "compact", density: "compact" },
59
+ boardroom: { label: "Boardroom", style: "corporate", primary: "#1d4ed8", accent: "#0e7490", mode: "light", radius: "small", font: "plex", layout: "sidebar", density: "compact", sidebar: "dark" },
60
+ sakura: { label: "Sakura", style: "soft", primary: "#be185d", accent: "#f9a8d4", mode: "light", radius: "large", font: "rounded", layout: "sidebar", density: "comfortable", background: "gradient" },
61
+ noir: { label: "Noir", style: "luxury", primary: "#c9a227", accent: "#9f1239", mode: "dark", radius: "small", font: "elegant", layout: "topbar", density: "comfortable" },
62
+ arcade: { label: "Arcade", style: "retro", primary: "#1e3a8a", accent: "#008080", mode: "light", radius: "none", font: "pixel", layout: "sidebar", density: "comfortable" },
63
+ ember: { label: "Ember", style: "neon", primary: "#f97316", accent: "#ec4899", mode: "dark", radius: "medium", font: "grotesk", layout: "sidebar", density: "comfortable", background: "mesh" },
64
+ atelier: { label: "Atelier", style: "swiss", primary: "#dc2626", accent: "#171717", mode: "light", radius: "none", font: "inter", layout: "topbar", density: "comfortable" },
65
+ matcha: { label: "Matcha", style: "nature", primary: "#4d7c0f", accent: "#b45309", mode: "light", radius: "large", font: "serif", layout: "sidebar", density: "comfortable", background: "noise" },
66
+ circuit: { label: "Circuit", style: "cyber", primary: "#facc15", accent: "#22d3ee", mode: "dark", radius: "none", font: "tech", layout: "compact", density: "compact", background: "grid" },
67
+ lagoon: { label: "Lagoon", style: "minimal", primary: "#0f766e", accent: "#38bdf8", mode: "system", radius: "small", font: "geist", layout: "topbar", density: "comfortable" },
68
+ orchid: { label: "Orchid", style: "playful", primary: "#7c3aed", accent: "#facc15", mode: "light", radius: "large", font: "playful", layout: "sidebar", density: "comfortable", background: "dots", motion: "lively" },
69
+ harbor: { label: "Harbor", style: "shadow", primary: "#1e3a8a", accent: "#f97316", mode: "light", radius: "medium", font: "inter", layout: "sidebar", density: "comfortable", sidebar: "brand", buttons: "pill", cards: "elevated", chartPalette: "vivid" },
70
+ blueprint: { label: "Blueprint", style: "simple", primary: "#3b82f6", accent: "#f59e0b", mode: "dark", radius: "small", font: "plex", layout: "sidebar", density: "comfortable", background: "grid", cards: "bordered", iconStyle: "duotone", chartPalette: "mono" },
45
71
  };
46
72
  /** Companions a style brings when the theme doesn't set them (mirrors STYLE_DEFAULTS in the compiler). */
47
73
  export const STYLE_COMPANIONS = {
@@ -49,7 +75,28 @@ export const STYLE_COMPANIONS = {
49
75
  editorial: { font: "serif" },
50
76
  terminal: { font: "mono", mode: "dark" },
51
77
  clay: { font: "rounded" },
78
+ corporate: { font: "plex", radius: "small" },
79
+ soft: { font: "rounded", radius: "large" },
80
+ luxury: { font: "elegant", mode: "dark", radius: "small" },
81
+ retro: { font: "pixel", radius: "none" },
82
+ neon: { font: "grotesk", mode: "dark", radius: "medium" },
83
+ swiss: { font: "inter", radius: "none" },
84
+ nature: { font: "serif", radius: "large", background: "noise" },
85
+ cyber: { font: "tech", mode: "dark", radius: "none", background: "grid" },
86
+ minimal: { font: "geist", radius: "small" },
87
+ playful: { font: "playful", radius: "large", background: "dots", motion: "lively" },
52
88
  };
53
89
  export const LAYOUT_OPTIONS = ["sidebar", "topbar", "compact"];
54
90
  export const DENSITY_OPTIONS = ["comfortable", "compact"];
91
+ /** Look-and-feel choices (mirrors LOOK_OPTIONS in the compiler); "" in the switcher means the style's own. */
92
+ export const LOOK_OPTIONS = {
93
+ background: ["plain", "gradient", "mesh", "dots", "grid", "noise"],
94
+ cards: ["flat", "bordered", "elevated", "glass"],
95
+ buttons: ["solid", "soft", "outline", "pill"],
96
+ motion: ["none", "subtle", "lively"],
97
+ sidebar: ["light", "dark", "brand"],
98
+ iconStyle: ["outline", "duotone"],
99
+ chartPalette: ["theme", "vivid", "pastel", "mono"],
100
+ };
101
+ export const DEFAULT_LOOK = { background: "plain", cards: null, buttons: null, motion: "subtle", sidebar: null, iconStyle: "outline", chartPalette: "theme" };
55
102
  //# sourceMappingURL=theme-catalog.js.map