@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 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/site/editor/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export type ContentTab = "pages" | "posts" | "messages" | "subscribers";
2
+ /** Parse ?tab= (unknown values fall back to "pages"). */
3
+ export declare const contentTab: (value: string | null | undefined) => ContentTab;
4
+ export declare function ContentAdminPage(): import("react").JSX.Element;
@@ -0,0 +1,65 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /*
4
+ * Admin "Content" page (/admin/content): the website's pages (with the visual page editor), posts, contact
5
+ * messages and newsletter subscribers. Tabs and the open page/post live in the URL (?tab=pages&page=<id>).
6
+ */
7
+ import { FileText, Inbox, Mail, Newspaper } from "lucide-react";
8
+ import { usePathname, useRouter, useSearchParams } from "next/navigation";
9
+ import { useCallback } from "react";
10
+ import { useForge } from "../../context.js";
11
+ import { ListSkeleton } from "../../skeleton.js";
12
+ import { Badge, Card, EmptyState, PageHeader } from "../../ui.js";
13
+ import { errorMessage, errorStatus, useOverview } from "./api.js";
14
+ import { MessagesTab, SubscribersTab } from "./inbox-tab.js";
15
+ import { PageEditor } from "./page-editor.js";
16
+ import { PagesTab } from "./pages-tab.js";
17
+ import { PostsTab } from "./posts-tab.js";
18
+ import { TabPanel, Tabs } from "./widgets.js";
19
+ const TABS = ["pages", "posts", "messages", "subscribers"];
20
+ /** Parse ?tab= (unknown values fall back to "pages"). */
21
+ export const contentTab = (value) => (TABS.includes(value) ? value : "pages");
22
+ export function ContentAdminPage() {
23
+ const { app, t } = useForge();
24
+ const router = useRouter();
25
+ const pathname = usePathname();
26
+ const params = useSearchParams();
27
+ const tab = contentTab(params.get("tab"));
28
+ const pageId = params.get("page");
29
+ const postId = params.get("post");
30
+ const overview = useOverview();
31
+ const go = useCallback((next) => {
32
+ const q = new URLSearchParams(params.toString());
33
+ for (const [k, v] of Object.entries(next)) {
34
+ if (v === null)
35
+ q.delete(k);
36
+ else
37
+ q.set(k, v);
38
+ }
39
+ const qs = q.toString();
40
+ router.push(`${pathname}${qs ? `?${qs}` : ""}`, { scroll: false });
41
+ }, [params, pathname, router]);
42
+ const header = _jsx(PageHeader, { title: t("siteAdmin.title"), description: t("siteAdmin.description") });
43
+ if (!app.site) {
44
+ return (_jsxs("div", { children: [header, _jsx(Card, { children: _jsx(EmptyState, { illustration: "dashboard", title: t("siteAdmin.disabled.title"), description: t("siteAdmin.disabled.description") }) })] }));
45
+ }
46
+ const status = errorStatus(overview.error);
47
+ if (status === 403 || status === 401) {
48
+ return (_jsxs("div", { children: [header, _jsx(Card, { children: _jsx(EmptyState, { illustration: "search", title: t("siteAdmin.forbidden.title"), description: t("siteAdmin.forbidden.description", { roles: app.site.editors.join(", ") }) }) })] }));
49
+ }
50
+ if (overview.error) {
51
+ return (_jsxs("div", { children: [header, _jsx(Card, { children: _jsx(EmptyState, { title: status === 404 ? t("siteAdmin.disabled.title") : t("siteAdmin.error.load"), description: status === 404 ? t("siteAdmin.disabled.description") : errorMessage(overview.error) }) })] }));
52
+ }
53
+ const data = overview.data;
54
+ // A page open in the editor takes the whole area.
55
+ if (tab === "pages" && pageId)
56
+ return _jsx(PageEditor, { pageId: pageId, overview: data, onBack: () => go({ page: null }) }, pageId);
57
+ const count = (n) => (n ? _jsx(Badge, { tone: 0, children: n }) : null);
58
+ return (_jsxs("div", { children: [header, _jsx("div", { className: "mb-4", children: _jsx(Tabs, { idPrefix: "site-content", label: t("siteAdmin.title"), value: tab, onChange: (k) => go({ tab: k === "pages" ? null : k, page: null, post: null }), tabs: [
59
+ { key: "pages", label: t("siteAdmin.tab.pages"), icon: _jsx(FileText, { className: "size-4", "aria-hidden": true }), badge: data?.conflicts ? _jsx(Badge, { tone: 2, children: data.conflicts }) : null },
60
+ { key: "posts", label: t("siteAdmin.tab.posts"), icon: _jsx(Newspaper, { className: "size-4", "aria-hidden": true }) },
61
+ { key: "messages", label: t("siteAdmin.tab.messages"), icon: _jsx(Mail, { className: "size-4", "aria-hidden": true }), badge: count(data?.messages.new) },
62
+ { key: "subscribers", label: t("siteAdmin.tab.subscribers"), icon: _jsx(Inbox, { className: "size-4", "aria-hidden": true }) },
63
+ ] }) }), _jsx(TabPanel, { idPrefix: "site-content", tab: tab, children: !data ? (_jsx(Card, { children: _jsx(ListSkeleton, { rows: 5 }) })) : tab === "pages" ? (_jsx(PagesTab, { overview: data, onOpen: (id) => go({ page: id }) })) : tab === "posts" ? (_jsx(PostsTab, { overview: data, postId: postId, onOpen: (id) => go({ post: id }) })) : tab === "messages" ? (_jsx(MessagesTab, {})) : (_jsx(SubscribersTab, { count: data.subscribers })) })] }));
64
+ }
65
+ //# sourceMappingURL=content-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-page.js","sourceRoot":"","sources":["../../../src/site/editor/content-page.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function MessagesTab(): import("react").JSX.Element;
2
+ export declare function SubscribersTab({ count }: {
3
+ count: number;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,88 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ /*
4
+ * Messages sent through contact forms (new / read / archived; opening one marks it read) and newsletter
5
+ * subscribers (count, CSV export, delete).
6
+ */
7
+ import { Archive, ArchiveRestore, Download, Inbox, Mail, Reply, Trash2 } from "lucide-react";
8
+ import { useState } from "react";
9
+ import { useForge } from "../../context.js";
10
+ import { ListSkeleton } from "../../skeleton.js";
11
+ import { useToast } from "../../toast.js";
12
+ import { Button, Card, cn, EmptyState, Pagination } from "../../ui.js";
13
+ import { errorMessage, useInvalidateSite, useMessages, useSubscribers } from "./api.js";
14
+ import { Confirm, Pill, TabPanel, Tabs } from "./widgets.js";
15
+ const PAGE_SIZE = 20;
16
+ function when(value, locale) {
17
+ try {
18
+ return new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeStyle: "short" }).format(new Date(value));
19
+ }
20
+ catch {
21
+ return value;
22
+ }
23
+ }
24
+ export function MessagesTab() {
25
+ const { api, t, locale } = useForge();
26
+ const toast = useToast();
27
+ const invalidate = useInvalidateSite();
28
+ const [status, setStatus] = useState("new");
29
+ const [page, setPage] = useState(1);
30
+ const [openId, setOpenId] = useState(null);
31
+ const [deleting, setDeleting] = useState(null);
32
+ const messages = useMessages({ status, page });
33
+ const open = messages.data?.data.find((m) => m.id === openId) ?? null;
34
+ const setMessageStatus = async (m, next, silent = false) => {
35
+ try {
36
+ await api(`/site/admin/messages/${m.id}`, { method: "PATCH", body: JSON.stringify({ status: next }) });
37
+ if (!silent)
38
+ toast.success(next === "archived" ? t("siteAdmin.messages.archived") : t("siteAdmin.messages.restored"));
39
+ void invalidate("messages");
40
+ void invalidate("overview");
41
+ }
42
+ catch (e) {
43
+ toast.error(t("siteAdmin.error.action"), errorMessage(e));
44
+ }
45
+ };
46
+ const select = (m) => {
47
+ setOpenId(m.id === openId ? null : m.id);
48
+ if (m.status === "new")
49
+ void setMessageStatus(m, "read", true);
50
+ };
51
+ return (_jsxs("div", { className: "space-y-4", children: [_jsx(Tabs, { idPrefix: "site-messages", size: "sm", label: t("siteAdmin.messages.filter"), value: status, onChange: (s) => (setStatus(s), setPage(1), setOpenId(null)), tabs: ["new", "read", "archived"].map((s) => ({ key: s, label: t(`siteAdmin.messages.status.${s}`) })) }), _jsx(TabPanel, { idPrefix: "site-messages", tab: status, children: _jsx(Card, { children: messages.isLoading ? (_jsx(ListSkeleton, { rows: 4 })) : messages.error ? (_jsx(EmptyState, { title: t("siteAdmin.error.load"), description: errorMessage(messages.error) })) : !messages.data?.data.length ? (_jsx(EmptyState, { illustration: "notifications", title: t(`siteAdmin.messages.empty.${status}`), description: status === "new" ? t("siteAdmin.messages.emptyHint") : undefined })) : (_jsxs(_Fragment, { children: [_jsx("ul", { className: "divide-y divide-line", children: messages.data.data.map((m) => {
52
+ const expanded = open?.id === m.id;
53
+ return (_jsxs("li", { children: [_jsxs("button", { type: "button", "aria-expanded": expanded, "aria-controls": `message-${m.id}`, onClick: () => select(m), className: cn("forge-focusable flex w-full items-start gap-3 px-4 py-3 text-left hover:bg-hover", expanded && "bg-selected"), children: [_jsx("span", { className: cn("mt-1.5 size-2 shrink-0 rounded-full", m.status === "new" ? "bg-primary" : "bg-transparent"), "aria-hidden": true }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsxs("span", { className: "flex items-center justify-between gap-2", children: [_jsxs("span", { className: cn("truncate text-sm text-ink", m.status === "new" && "font-semibold"), children: [m.name, m.company && _jsxs("span", { className: "font-normal text-ink-muted", children: [" \u00B7 ", m.company] })] }), _jsx("span", { className: "shrink-0 text-xs text-ink-subtle", children: when(m.createdAt, locale) })] }), _jsx("span", { className: "block truncate text-xs text-ink-muted", children: m.message })] }), m.status === "new" && _jsx("span", { className: "sr-only", children: t("siteAdmin.messages.status.new") })] }), expanded && (_jsxs("div", { id: `message-${m.id}`, className: "border-t border-line bg-surface-muted px-4 py-4 sm:pl-9", children: [_jsxs("dl", { className: "mb-3 grid gap-x-6 gap-y-1 text-xs sm:grid-cols-[auto_1fr]", children: [_jsx("dt", { className: "text-ink-muted", children: t("siteAdmin.messages.from") }), _jsxs("dd", { className: "text-ink", children: [m.name, " <", _jsx("a", { className: "text-link hover:underline", href: `mailto:${m.email}`, children: m.email }), ">"] }), m.page && (_jsxs(_Fragment, { children: [_jsx("dt", { className: "text-ink-muted", children: t("siteAdmin.messages.page") }), _jsx("dd", { className: "font-mono text-ink", children: m.page })] }))] }), _jsx("p", { className: "text-sm whitespace-pre-wrap text-ink", children: m.message }), _jsxs("div", { className: "mt-4 flex flex-wrap gap-2", children: [_jsxs("a", { href: `mailto:${m.email}?subject=${encodeURIComponent(t("siteAdmin.messages.replySubject"))}`, className: "forge-btn forge-btn-primary inline-flex h-7 items-center gap-1.5 px-2.5 text-xs font-medium", children: [_jsx(Reply, { className: "size-3.5", "aria-hidden": true }), " ", t("siteAdmin.messages.reply")] }), m.status === "archived" ? (_jsxs(Button, { size: "sm", onClick: () => setMessageStatus(m, "read"), children: [_jsx(ArchiveRestore, { className: "size-3.5", "aria-hidden": true }), " ", t("siteAdmin.messages.unarchive")] })) : (_jsxs(Button, { size: "sm", onClick: () => setMessageStatus(m, "archived"), children: [_jsx(Archive, { className: "size-3.5", "aria-hidden": true }), " ", t("siteAdmin.messages.archive")] })), m.status !== "new" && m.status !== "archived" && (_jsxs(Button, { size: "sm", variant: "ghost", onClick: () => setMessageStatus(m, "new", true), children: [_jsx(Mail, { className: "size-3.5", "aria-hidden": true }), " ", t("siteAdmin.messages.markUnread")] })), _jsxs(Button, { size: "sm", variant: "danger-ghost", onClick: () => setDeleting(m), children: [_jsx(Trash2, { className: "size-3.5", "aria-hidden": true }), " ", t("common.delete")] })] })] }))] }, m.id));
54
+ }) }), messages.data.total > PAGE_SIZE && _jsx(Pagination, { page: page, pages: Math.ceil(messages.data.total / PAGE_SIZE), total: messages.data.total, onPage: setPage })] })) }) }), _jsx(Confirm, { open: !!deleting, danger: true, title: t("siteAdmin.messages.deleteTitle", { name: deleting?.name ?? "" }), message: t("siteAdmin.messages.deleteMessage"), confirmLabel: t("common.delete"), onClose: () => setDeleting(null), onConfirm: async () => {
55
+ try {
56
+ await api(`/site/admin/messages/${deleting.id}`, { method: "DELETE" });
57
+ toast.success(t("siteAdmin.messages.deleted"));
58
+ setDeleting(null);
59
+ setOpenId(null);
60
+ void invalidate("messages");
61
+ void invalidate("overview");
62
+ }
63
+ catch (e) {
64
+ toast.error(t("siteAdmin.error.action"), errorMessage(e));
65
+ }
66
+ } })] }));
67
+ }
68
+ export function SubscribersTab({ count }) {
69
+ const { api, app, t, locale } = useForge();
70
+ const toast = useToast();
71
+ const invalidate = useInvalidateSite();
72
+ const [page, setPage] = useState(1);
73
+ const [deleting, setDeleting] = useState(null);
74
+ const subscribers = useSubscribers(page);
75
+ return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx("p", { className: "text-sm text-ink-muted", children: t("siteAdmin.subscribers.count", { count }) }), _jsxs("a", { href: `${app.api.prefix}/site/admin/subscribers/export`, download: true, className: cn("forge-btn forge-btn-secondary inline-flex h-[var(--forge-control-h)] items-center gap-1.5 px-3.5 text-sm font-medium", !count && "pointer-events-none opacity-55"), "aria-disabled": !count || undefined, children: [_jsx(Download, { className: "size-4", "aria-hidden": true }), " ", t("siteAdmin.subscribers.export")] })] }), _jsx(Card, { children: subscribers.isLoading ? (_jsx(ListSkeleton, { rows: 4 })) : subscribers.error ? (_jsx(EmptyState, { title: t("siteAdmin.error.load"), description: errorMessage(subscribers.error) })) : !subscribers.data?.data.length ? (_jsx(EmptyState, { illustration: "notifications", title: t("siteAdmin.subscribers.empty"), description: t("siteAdmin.subscribers.emptyHint") })) : (_jsxs(_Fragment, { children: [_jsx("ul", { className: "divide-y divide-line", children: subscribers.data.data.map((s) => (_jsxs("li", { className: "flex flex-wrap items-center gap-3 px-4 py-2.5", children: [_jsx(Inbox, { className: "size-4 shrink-0 text-ink-subtle", "aria-hidden": true }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate text-sm text-ink", children: s.email }), _jsxs("span", { className: "block truncate text-xs text-ink-muted", children: [when(s.createdAt, locale), s.source && ` · ${s.source}`] })] }), s.status === "unsubscribed" && _jsx(Pill, { tone: "muted", children: t("siteAdmin.subscribers.unsubscribed") }), _jsx(Button, { size: "sm", variant: "danger-ghost", onClick: () => setDeleting(s), "aria-label": t("siteAdmin.removeNamed", { name: s.email }), children: _jsx(Trash2, { className: "size-3.5", "aria-hidden": true }) })] }, s.id))) }), subscribers.data.total > PAGE_SIZE && _jsx(Pagination, { page: page, pages: Math.ceil(subscribers.data.total / PAGE_SIZE), total: subscribers.data.total, onPage: setPage })] })) }), _jsx(Confirm, { open: !!deleting, danger: true, title: t("siteAdmin.subscribers.deleteTitle", { email: deleting?.email ?? "" }), message: t("siteAdmin.subscribers.deleteMessage"), confirmLabel: t("common.delete"), onClose: () => setDeleting(null), onConfirm: async () => {
76
+ try {
77
+ await api(`/site/admin/subscribers/${deleting.id}`, { method: "DELETE" });
78
+ toast.success(t("siteAdmin.subscribers.deleted"));
79
+ setDeleting(null);
80
+ void invalidate("subscribers");
81
+ void invalidate("overview");
82
+ }
83
+ catch (e) {
84
+ toast.error(t("siteAdmin.error.action"), errorMessage(e));
85
+ }
86
+ } })] }));
87
+ }
88
+ //# sourceMappingURL=inbox-tab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox-tab.js","sourceRoot":"","sources":["../../../src/site/editor/inbox-tab.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { ContentAdminPage, contentTab, type ContentTab } from "./content-page.js";
@@ -0,0 +1,3 @@
1
+ // The admin website editor (/admin/content). Its pure helpers live in ./model.js (not re-exported: generic names).
2
+ export { ContentAdminPage, contentTab } from "./content-page.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/site/editor/index.ts"],"names":[],"mappings":"AAAA,mHAAmH;AACnH,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAmB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,145 @@
1
+ import type { AppIR, EntityIR } from "@tekki-forge/compiler";
2
+ import { type PropSpec } from "@tekki-forge/compiler/site";
3
+ export type Props = Record<string, unknown>;
4
+ export interface FilterRow {
5
+ key: string;
6
+ value: string;
7
+ }
8
+ export type Cell = string | boolean;
9
+ /** The value a form control shows for a prop value (strings for text inputs, rows for filters…). */
10
+ export declare function toInput(spec: Pick<PropSpec, "kind">, value: unknown): unknown;
11
+ /** The prop value for a form input (undefined = remove the prop). Keeps in-progress rows (empty strings) — see cleanProps. */
12
+ export declare function fromInput(spec: Pick<PropSpec, "kind">, input: unknown): unknown;
13
+ /** { status: "open", "price.gte": 10, "tag.in": ["a","b"] } → editable rows. */
14
+ export declare function filterToRows(value: unknown): FilterRow[];
15
+ /** "true"/"false" → boolean, numbers → number, lists for `.in`/`.notIn` keys, otherwise text. */
16
+ export declare function parseFilterValue(key: string, raw: string): string | number | boolean | (string | number)[];
17
+ export declare function rowsToFilter(rows: readonly FilterRow[]): Record<string, unknown> | undefined;
18
+ /** Comparison cells aligned to the number of columns (missing cells start as "yes"). */
19
+ export declare function alignCells(cells: readonly Cell[], columns: number): Cell[];
20
+ /** Set one prop of an object (undefined removes it), and reset props that depend on it. */
21
+ export declare function setProp(fields: readonly PropSpec[], obj: Props, name: string, value: unknown): Props;
22
+ /** Whether a prop's control is shown, given its siblings (live-data props need an entity, and so on). */
23
+ export declare function propVisible(spec: PropSpec, fields: readonly PropSpec[], obj: Props): boolean;
24
+ /**
25
+ * Props ready to save: empty texts, rows and links dropped, list items cleaned recursively, cells aligned to the
26
+ * comparison columns. The editor keeps raw values (an empty new row) while typing; this is what the API receives.
27
+ */
28
+ export declare function cleanProps(fields: readonly PropSpec[], props: Props, context?: {
29
+ columns?: number;
30
+ }): Props;
31
+ /** Clean the props of a section of `type` (unknown types are returned as they are). */
32
+ export declare function cleanSectionProps(type: string, props: Props): Props;
33
+ /** A new, empty item of a list prop (required booleans start false, cells match the columns). */
34
+ export declare function emptyItem(fields: readonly PropSpec[], context?: {
35
+ columns?: number;
36
+ }): Props;
37
+ /** Move the element at `from` to index `to` (clamped). Returns a new array. */
38
+ export declare function moveItem<T>(list: readonly T[], from: number, to: number): T[];
39
+ /** Copy of a list with one element duplicated right after itself. */
40
+ export declare function duplicateItem<T>(list: readonly T[], index: number): T[];
41
+ export declare function removeItem<T>(list: readonly T[], index: number): T[];
42
+ /**
43
+ * Keyboard drag & drop of a list (the WAI pattern): Space/Enter on a handle picks the item up, arrows move it,
44
+ * Space/Enter drops it, Escape puts it back. `state` is null when nothing is picked up.
45
+ */
46
+ export interface KeyboardDrag {
47
+ /** Index the item had when it was picked up. */
48
+ from: number;
49
+ /** Index it would land at now. */
50
+ at: number;
51
+ }
52
+ export type KeyboardDragResult = {
53
+ type: "pick";
54
+ state: KeyboardDrag;
55
+ } | {
56
+ type: "move";
57
+ state: KeyboardDrag;
58
+ } | {
59
+ type: "drop";
60
+ from: number;
61
+ to: number;
62
+ } | {
63
+ type: "cancel";
64
+ from: number;
65
+ } | {
66
+ type: "none";
67
+ };
68
+ export declare function keyboardDrag(state: KeyboardDrag | null, key: string, index: number, count: number): KeyboardDragResult;
69
+ /** Order to show while an item is being dragged (pointer or keyboard). */
70
+ export declare function previewOrder<T>(list: readonly T[], drag: KeyboardDrag | null): T[];
71
+ /**
72
+ * Index the dragged row (at `from`) lands at when the pointer is at `y`: the number of OTHER rows whose vertical
73
+ * midpoint is above the pointer (`midpoints` are those of every row, in order).
74
+ */
75
+ export declare function dropIndex(midpoints: readonly number[], y: number, from: number): number;
76
+ /** "Hello, World! Ça va?" → "hello-world-ca-va" (the API's slug rule: /^[a-z0-9]+(-[a-z0-9]+)*$/, ≤ 100). */
77
+ export declare function slugify(text: string, max?: number): string;
78
+ export declare const SLUG_PATTERN: RegExp;
79
+ /** "/About Us/" → "/about-us" (what a person likely meant; the check below says what's still wrong). */
80
+ export declare function normalizePath(input: string): string;
81
+ /** Paths the app already uses (entity list pages, plugin pages). */
82
+ export declare function takenPaths(app: Pick<AppIR, "entities" | "plugins">): {
83
+ entityPaths: string[];
84
+ pluginPaths: string[];
85
+ };
86
+ export type PathIssue = {
87
+ key: "siteAdmin.path.format" | "siteAdmin.path.reserved" | "siteAdmin.path.entity" | "siteAdmin.path.plugin" | "siteAdmin.path.taken";
88
+ segment?: string;
89
+ };
90
+ /** Why `path` can't be used for a new page (a translation key), or null. `existing` = paths of other pages. */
91
+ export declare function pagePathIssue(path: string, app: Pick<AppIR, "entities" | "plugins">, existing?: readonly string[]): PathIssue | null;
92
+ /** "section.items[2].title" / "props.items[2].title" → "items.2.title"; "section" → "". */
93
+ export declare function issueField(path: string): string;
94
+ /** Issues keyed by form field ("items.2.title"); several messages for one field are joined. */
95
+ export declare function issuesByField(issues: readonly {
96
+ path: string;
97
+ message: string;
98
+ }[] | undefined): Record<string, string>;
99
+ /** The message for a control at `path`: its own, or one about a part of it (a link's label, a filter key). */
100
+ export declare function errorAt(errors: Record<string, string>, path: string): string | undefined;
101
+ /** How many issues are inside `path` (a list item card shows the count). */
102
+ export declare function errorCount(errors: Record<string, string>, path: string): number;
103
+ /** Every entity, with the reason it can't feed the website (undefined when it can). */
104
+ export declare function dataEntities(app: Pick<AppIR, "entities">): {
105
+ entity: EntityIR;
106
+ problem?: string;
107
+ }[];
108
+ /** Fields of `entity` a prop of `kind` can name: public ones (numeric for aggregates, sortable for sorts). */
109
+ export declare function entityFieldOptions(entity: EntityIR | undefined, kind: "fields" | "field" | "sort" | "filter"): {
110
+ name: string;
111
+ label: string;
112
+ }[];
113
+ /** "-createdAt" ↔ { field: "createdAt", desc: true } (one sort key; the editor offers one). */
114
+ export declare function parseSort(value: unknown): {
115
+ field: string;
116
+ desc: boolean;
117
+ };
118
+ export declare const formatSort: (field: string, desc: boolean) => string | undefined;
119
+ /** Short text that identifies a section in the list (its title, else a first item, else ""). */
120
+ export declare function sectionSummary(props: Props): string;
121
+ /** Data sections need the API to resolve their preview (live numbers, records, posts, plans). */
122
+ export declare function needsPreviewData(type: string, props: Props): boolean;
123
+ /** Post kinds the Posts tab offers: "post" plus the kinds the site has a listing for. */
124
+ export declare function postKinds(blogKinds: Record<string, string> | undefined): string[];
125
+ /** Tags typed as "a, b, c" → ["a","b","c"] (unique, ≤ 10 × 40 chars). */
126
+ export declare function parseTags(text: string): string[];
127
+ /** Debounce delay of section autosave (ms). */
128
+ export declare const AUTOSAVE_MS = 800;
129
+ /** The `nav` value of a page from the settings form (null = automatic). */
130
+ export declare function navValue(form: {
131
+ hidden: boolean;
132
+ group: string;
133
+ label: string;
134
+ footerOnly: boolean;
135
+ }): false | {
136
+ group?: string;
137
+ label?: string;
138
+ footerOnly?: boolean;
139
+ } | null;
140
+ export declare function navForm(nav: unknown): {
141
+ hidden: boolean;
142
+ group: string;
143
+ label: string;
144
+ footerOnly: boolean;
145
+ };