@openrails/contentkit-ui 0.71.0 → 0.72.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 (120) hide show
  1. package/README.md +98 -10
  2. package/dist/client/content/bans.d.ts +2 -0
  3. package/dist/client/content/bans.js +24 -12
  4. package/dist/client/content/bans.js.map +1 -1
  5. package/dist/client/content/comments.d.ts +2 -0
  6. package/dist/client/content/comments.js.map +1 -1
  7. package/dist/client/content/polls.d.ts +9 -2
  8. package/dist/client/content/polls.js.map +1 -1
  9. package/dist/client/generated/routes.d.ts +28 -2
  10. package/dist/client/generated/routes.js +40 -0
  11. package/dist/client/generated/routes.js.map +1 -1
  12. package/dist/client/generated/wire.d.ts +4 -0
  13. package/dist/client/generated/wire.js.map +1 -1
  14. package/dist/client/index.d.ts +2 -2
  15. package/dist/client/taxonomy.d.ts +5 -1
  16. package/dist/client/taxonomy.js +7 -0
  17. package/dist/client/taxonomy.js.map +1 -1
  18. package/dist/components/admin/poll-manager.d.ts +28 -0
  19. package/dist/components/admin/poll-manager.js +297 -0
  20. package/dist/components/admin/poll-manager.js.map +1 -0
  21. package/dist/components/admin/post-manager.d.ts +45 -0
  22. package/dist/components/admin/post-manager.js +602 -0
  23. package/dist/components/admin/post-manager.js.map +1 -0
  24. package/dist/components/admin/shell.d.ts +73 -0
  25. package/dist/components/admin/shell.js +148 -0
  26. package/dist/components/admin/shell.js.map +1 -0
  27. package/dist/components/admin/taxonomy-manager.d.ts +54 -0
  28. package/dist/components/admin/taxonomy-manager.js +976 -0
  29. package/dist/components/admin/taxonomy-manager.js.map +1 -0
  30. package/dist/components/admin/user-comment-standing.d.ts +25 -0
  31. package/dist/components/admin/user-comment-standing.js +229 -0
  32. package/dist/components/admin/user-comment-standing.js.map +1 -0
  33. package/dist/components/social/bans.d.ts +5 -2
  34. package/dist/components/social/bans.js +132 -134
  35. package/dist/components/social/bans.js.map +1 -1
  36. package/dist/components/social/index.d.ts +1 -1
  37. package/dist/components/social/moderation.d.ts +11 -13
  38. package/dist/components/social/moderation.js +299 -218
  39. package/dist/components/social/moderation.js.map +1 -1
  40. package/dist/components/social/parts.d.ts +3 -2
  41. package/dist/components/social/parts.js +74 -48
  42. package/dist/components/social/parts.js.map +1 -1
  43. package/dist/components/social/poll-editor.js +1 -0
  44. package/dist/components/social/poll-editor.js.map +1 -1
  45. package/dist/editor/index.d.ts +1 -0
  46. package/dist/editor/rich-text-editor.d.ts +13 -0
  47. package/dist/editor/rich-text-editor.js +228 -0
  48. package/dist/editor/rich-text-editor.js.map +1 -0
  49. package/dist/editor.js +2 -0
  50. package/dist/index.d.ts +6 -0
  51. package/dist/index.js +13 -8
  52. package/dist/locales/admin/de.d.ts +2 -0
  53. package/dist/locales/admin/de.js +176 -0
  54. package/dist/locales/admin/de.js.map +1 -0
  55. package/dist/locales/admin/en.d.ts +171 -0
  56. package/dist/locales/admin/en.js +176 -0
  57. package/dist/locales/admin/en.js.map +1 -0
  58. package/dist/locales/admin/es.d.ts +2 -0
  59. package/dist/locales/admin/es.js +176 -0
  60. package/dist/locales/admin/es.js.map +1 -0
  61. package/dist/locales/admin/ja.d.ts +2 -0
  62. package/dist/locales/admin/ja.js +176 -0
  63. package/dist/locales/admin/ja.js.map +1 -0
  64. package/dist/locales/admin/ko.d.ts +2 -0
  65. package/dist/locales/admin/ko.js +176 -0
  66. package/dist/locales/admin/ko.js.map +1 -0
  67. package/dist/locales/admin/zh.d.ts +2 -0
  68. package/dist/locales/admin/zh.js +176 -0
  69. package/dist/locales/admin/zh.js.map +1 -0
  70. package/dist/locales/de.js +5 -3
  71. package/dist/locales/de.js.map +1 -1
  72. package/dist/locales/en.d.ts +176 -0
  73. package/dist/locales/en.js +5 -3
  74. package/dist/locales/en.js.map +1 -1
  75. package/dist/locales/es.js +5 -3
  76. package/dist/locales/es.js.map +1 -1
  77. package/dist/locales/ja.js +5 -3
  78. package/dist/locales/ja.js.map +1 -1
  79. package/dist/locales/ko.js +5 -3
  80. package/dist/locales/ko.js.map +1 -1
  81. package/dist/locales/social/de.js +8 -1
  82. package/dist/locales/social/de.js.map +1 -1
  83. package/dist/locales/social/en.d.ts +7 -0
  84. package/dist/locales/social/en.js +8 -1
  85. package/dist/locales/social/en.js.map +1 -1
  86. package/dist/locales/social/es.js +8 -1
  87. package/dist/locales/social/es.js.map +1 -1
  88. package/dist/locales/social/ja.js +8 -1
  89. package/dist/locales/social/ja.js.map +1 -1
  90. package/dist/locales/social/ko.js +8 -1
  91. package/dist/locales/social/ko.js.map +1 -1
  92. package/dist/locales/social/zh.js +8 -1
  93. package/dist/locales/social/zh.js.map +1 -1
  94. package/dist/locales/zh.js +5 -3
  95. package/dist/locales/zh.js.map +1 -1
  96. package/dist/provider.d.ts +2 -0
  97. package/dist/provider.js +23 -19
  98. package/dist/provider.js.map +1 -1
  99. package/dist/react/admin.d.ts +55 -0
  100. package/dist/react/admin.js +97 -0
  101. package/dist/react/admin.js.map +1 -0
  102. package/dist/react/comments.d.ts +18 -2
  103. package/dist/react/comments.js +24 -8
  104. package/dist/react/comments.js.map +1 -1
  105. package/dist/react/context.d.ts +7 -1
  106. package/dist/react/context.js +6 -1
  107. package/dist/react/context.js.map +1 -1
  108. package/dist/react/index.d.ts +4 -3
  109. package/dist/react/polls.js +88 -87
  110. package/dist/react/polls.js.map +1 -1
  111. package/dist/react/posts.js +123 -122
  112. package/dist/react/posts.js.map +1 -1
  113. package/dist/react/resources.js +3 -0
  114. package/dist/react/resources.js.map +1 -1
  115. package/dist/react/use-resource.d.ts +16 -0
  116. package/dist/react/use-resource.js +20 -1
  117. package/dist/react/use-resource.js.map +1 -1
  118. package/dist/react.js +21 -20
  119. package/dist/styles.css +1 -1
  120. package/package.json +37 -2
@@ -0,0 +1,602 @@
1
+ import { toContentKitError as e } from "../../client/errors.js";
2
+ import { useMessages as t } from "../../i18n/context.js";
3
+ import { useErrorReporter as n } from "../../react/context.js";
4
+ import { Alert as r, AlertDescription as i } from "../../ui/alert.js";
5
+ import { Button as a, buttonVariants as o } from "../../ui/button.js";
6
+ import { keyOf as s, useContentScope as c, usePaged as l } from "../../react/use-resource.js";
7
+ import { Badge as ee } from "../../ui/badge.js";
8
+ import { Input as u } from "../../ui/input.js";
9
+ import { Label as d } from "../../ui/label.js";
10
+ import { Select as f, SelectContent as p, SelectItem as m, SelectTrigger as h, SelectValue as g } from "../../ui/select.js";
11
+ import { Skeleton as _ } from "../../ui/skeleton.js";
12
+ import { Textarea as v } from "../../ui/textarea.js";
13
+ import { ErrorLine as y, RelativeTime as b, contentError as x, formatDate as te, useAction as ne } from "../social/parts.js";
14
+ import { AdminRoot as S, LoadFailed as re, NoAccess as C, Pager as w, Rows as T, pageOf as E, useConfirm as ie } from "./shell.js";
15
+ import { localInput as D } from "../social/bans.js";
16
+ import { imageRefs as O } from "../../client/content/posts.js";
17
+ import { useAdminLocation as k, useFlowClient as A, useStaffAccess as j } from "../../react/admin.js";
18
+ import { usePost as M } from "../../react/posts.js";
19
+ import { useEffect as N, useId as P, useMemo as F, useRef as I, useState as L } from "react";
20
+ import { Fragment as R, jsx as z, jsxs as B } from "react/jsx-runtime";
21
+ //#region src/components/admin/post-manager.tsx
22
+ function V(e = {}) {
23
+ return j(["posts"], e);
24
+ }
25
+ function H(e, t = Date.now()) {
26
+ return e.moderation === "rejected" ? "rejected" : e.moderation === "held" ? "held" : e.is_draft ? "draft" : e.live_at && Date.parse(e.live_at) > t ? "scheduled" : "published";
27
+ }
28
+ var ae = (e) => (e ?? []).map((e) => typeof e == "string" ? {
29
+ value: e,
30
+ label: e
31
+ } : e), oe = {
32
+ published: "default",
33
+ scheduled: "secondary",
34
+ draft: "outline",
35
+ held: "secondary",
36
+ rejected: "destructive"
37
+ };
38
+ function U({ client: e, baseUrl: t, auth: n, guard: r, appearance: i, className: a, language: o, messages: s, ...c }) {
39
+ let l = A({
40
+ client: e,
41
+ baseUrl: t,
42
+ auth: n
43
+ });
44
+ return /* @__PURE__ */ z(S, {
45
+ flow: "post-manager",
46
+ appearance: i,
47
+ className: a,
48
+ language: o,
49
+ messages: s,
50
+ guard: r,
51
+ children: /* @__PURE__ */ z(W, {
52
+ ...c,
53
+ client: l
54
+ })
55
+ });
56
+ }
57
+ function W({ basePath: e, navigation: n, ...r }) {
58
+ let { t: i } = t(), o = k(e, n), s = V({ client: r.client });
59
+ return s.loading ? /* @__PURE__ */ z(T, {}) : s.allowed.posts ? o.view ? /* @__PURE__ */ B(R, { children: [/* @__PURE__ */ z(a, {
60
+ variant: "ghost",
61
+ size: "sm",
62
+ className: "justify-self-start",
63
+ onClick: () => o.go(""),
64
+ children: i("postManager.back")
65
+ }), /* @__PURE__ */ z(q, {
66
+ ...r,
67
+ loc: o,
68
+ id: o.view === "new" ? null : o.view
69
+ }, o.view)] }) : /* @__PURE__ */ z(G, {
70
+ ...r,
71
+ loc: o
72
+ }) : /* @__PURE__ */ z(C, { children: i("postManager.noAccess") });
73
+ }
74
+ function G({ loc: e, client: n, languages: r, postHref: i, pageSize: _ = 20, onError: v }) {
75
+ let x = t(), { t: S } = x, C = P(), D = ae(r), O = e.query.get("q") ?? "", k = e.query.get("language") ?? "", A = e.query.get("status") === "draft" ? "draft" : e.query.get("status") === "live" ? "live" : "", j = e.query.get("deleted") === "1", M = E(e.query), F = {
76
+ q: O,
77
+ language: k,
78
+ status: A,
79
+ deleted: j ? "1" : void 0
80
+ }, I = (t) => e.go("", {
81
+ ...F,
82
+ ...t
83
+ }), [V, U] = L(O);
84
+ N(() => U(O), [O]);
85
+ let { store: W, scope: G } = c(n), K = l(W, s("posts-page", G, O, k, A, j, _), {
86
+ type: "posts",
87
+ scope: j ? "deleted" : void 0
88
+ }, M, _, (e, t) => n.posts.adminList({
89
+ ...e,
90
+ q: O || void 0,
91
+ language: k || void 0,
92
+ draft: j || !A ? void 0 : A === "draft",
93
+ deleted: j || void 0
94
+ }, t)), q = ne("post.save", v), { confirm: se, dialog: J } = ie(), Y = async (e) => {
95
+ await se({
96
+ title: S("postManager.deleteTitle", { title: e.title }),
97
+ description: S("postManager.deleteBody"),
98
+ confirm: S("postManager.delete")
99
+ }) && await q.run(() => n.posts.delete(e.id));
100
+ };
101
+ return /* @__PURE__ */ B("div", {
102
+ className: "grid gap-4",
103
+ children: [
104
+ /* @__PURE__ */ B("div", {
105
+ className: "flex flex-wrap items-center justify-between gap-2",
106
+ children: [/* @__PURE__ */ z("h2", {
107
+ className: "text-base font-semibold",
108
+ children: S("postManager.title")
109
+ }), /* @__PURE__ */ z(a, {
110
+ size: "sm",
111
+ onClick: () => e.go("new"),
112
+ children: S("postManager.new")
113
+ })]
114
+ }),
115
+ /* @__PURE__ */ B("div", {
116
+ className: "flex gap-2",
117
+ role: "group",
118
+ "aria-label": S("postManager.title"),
119
+ children: [/* @__PURE__ */ z(a, {
120
+ size: "sm",
121
+ variant: j ? "outline" : "default",
122
+ "aria-pressed": !j,
123
+ onClick: () => e.go("", {
124
+ q: O,
125
+ language: k
126
+ }),
127
+ children: S("postManager.posts")
128
+ }), /* @__PURE__ */ z(a, {
129
+ size: "sm",
130
+ variant: j ? "default" : "outline",
131
+ "aria-pressed": j,
132
+ onClick: () => e.go("", {
133
+ q: O,
134
+ language: k,
135
+ deleted: "1"
136
+ }),
137
+ children: S("postManager.deleted")
138
+ })]
139
+ }),
140
+ /* @__PURE__ */ B("div", {
141
+ className: "grid gap-2 sm:grid-cols-[minmax(0,1fr)_auto]",
142
+ children: [/* @__PURE__ */ B("form", {
143
+ className: "flex gap-2",
144
+ role: "search",
145
+ onSubmit: (e) => {
146
+ e.preventDefault(), I({ q: V.trim() });
147
+ },
148
+ children: [
149
+ /* @__PURE__ */ z(d, {
150
+ htmlFor: `${C}-q`,
151
+ className: "sr-only",
152
+ children: S("postManager.search")
153
+ }),
154
+ /* @__PURE__ */ z(u, {
155
+ id: `${C}-q`,
156
+ className: "h-8",
157
+ type: "search",
158
+ value: V,
159
+ placeholder: S("postManager.search"),
160
+ onChange: (e) => U(e.target.value)
161
+ }),
162
+ /* @__PURE__ */ z(a, {
163
+ type: "submit",
164
+ size: "sm",
165
+ variant: "outline",
166
+ children: S("moderation.filter")
167
+ })
168
+ ]
169
+ }), /* @__PURE__ */ B("div", {
170
+ className: "flex flex-wrap gap-2",
171
+ children: [D.length > 0 && /* @__PURE__ */ B(f, {
172
+ value: k,
173
+ onValueChange: (e) => I({ language: String(e ?? "") }),
174
+ children: [/* @__PURE__ */ z(h, {
175
+ size: "sm",
176
+ "aria-label": S("postManager.language"),
177
+ children: /* @__PURE__ */ z(g, { children: (e) => e ? D.find((t) => t.value === e)?.label ?? e : S("pollManager.allLanguages") })
178
+ }), /* @__PURE__ */ B(p, { children: [/* @__PURE__ */ z(m, {
179
+ value: "",
180
+ children: S("pollManager.allLanguages")
181
+ }), D.map((e) => /* @__PURE__ */ z(m, {
182
+ value: e.value,
183
+ children: e.label
184
+ }, e.value))] })]
185
+ }), !j && /* @__PURE__ */ B(f, {
186
+ value: A,
187
+ onValueChange: (e) => I({ status: String(e ?? "") }),
188
+ children: [/* @__PURE__ */ z(h, {
189
+ size: "sm",
190
+ "aria-label": S("postManager.status"),
191
+ children: /* @__PURE__ */ z(g, { children: (e) => S(e === "draft" ? "postManager.drafts" : e === "live" ? "postManager.notDrafts" : "postManager.allStatuses") })
192
+ }), /* @__PURE__ */ B(p, { children: [
193
+ /* @__PURE__ */ z(m, {
194
+ value: "",
195
+ children: S("postManager.allStatuses")
196
+ }),
197
+ /* @__PURE__ */ z(m, {
198
+ value: "draft",
199
+ children: S("postManager.drafts")
200
+ }),
201
+ /* @__PURE__ */ z(m, {
202
+ value: "live",
203
+ children: S("postManager.notDrafts")
204
+ })
205
+ ] })]
206
+ })]
207
+ })]
208
+ }),
209
+ /* @__PURE__ */ z(y, { error: q.error }),
210
+ K.loading && !K.items.length ? /* @__PURE__ */ z(T, {}) : K.error && !K.items.length ? /* @__PURE__ */ z(re, {
211
+ error: K.error,
212
+ message: S("postManager.loadFailed"),
213
+ retry: K.reload
214
+ }) : K.items.length ? /* @__PURE__ */ z("ul", {
215
+ className: "grid divide-y divide-border rounded-lg border border-border",
216
+ "aria-busy": K.loading,
217
+ children: K.items.map((t) => {
218
+ let r = H(t), s = r === "published" ? i?.(t) : void 0;
219
+ return /* @__PURE__ */ B("li", {
220
+ className: "flex flex-wrap items-start gap-3 p-3",
221
+ "data-ckui": "post-row",
222
+ "data-status": j ? "deleted" : r,
223
+ children: [/* @__PURE__ */ B("div", {
224
+ className: "grid min-w-0 flex-1 gap-1",
225
+ children: [j ? /* @__PURE__ */ z("span", {
226
+ className: "font-medium break-words",
227
+ children: t.title
228
+ }) : /* @__PURE__ */ z("button", {
229
+ type: "button",
230
+ className: "text-left font-medium break-words hover:underline",
231
+ onClick: () => e.go(t.id),
232
+ children: t.title
233
+ }), /* @__PURE__ */ B("div", {
234
+ className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground",
235
+ children: [
236
+ !j && /* @__PURE__ */ z(ee, {
237
+ variant: oe[r],
238
+ children: S(`postManager.${r}`)
239
+ }),
240
+ /* @__PURE__ */ z("span", { children: t.language }),
241
+ /* @__PURE__ */ z(b, { at: j && t.deleted_at ? t.deleted_at : t.updated_at }),
242
+ r === "scheduled" && t.live_at && /* @__PURE__ */ z("span", { children: S("pollManager.goesLive", { date: te(x, t.live_at) }) })
243
+ ]
244
+ })]
245
+ }), /* @__PURE__ */ z("div", {
246
+ className: "flex flex-wrap gap-2",
247
+ children: j ? /* @__PURE__ */ z(a, {
248
+ size: "sm",
249
+ variant: "outline",
250
+ disabled: q.pending,
251
+ onClick: () => void q.run(() => n.posts.restore(t.id)),
252
+ children: S("moderation.restore")
253
+ }) : /* @__PURE__ */ B(R, { children: [
254
+ s && /* @__PURE__ */ z("a", {
255
+ className: o({
256
+ size: "sm",
257
+ variant: "ghost"
258
+ }),
259
+ href: s,
260
+ children: S("postManager.view")
261
+ }),
262
+ /* @__PURE__ */ z(a, {
263
+ size: "sm",
264
+ variant: "outline",
265
+ onClick: () => e.go(t.id),
266
+ children: S("comments.edit")
267
+ }),
268
+ /* @__PURE__ */ z(a, {
269
+ size: "sm",
270
+ variant: "destructive",
271
+ disabled: q.pending,
272
+ onClick: () => void Y(t),
273
+ children: S("comments.delete")
274
+ })
275
+ ] })
276
+ })]
277
+ }, t.id);
278
+ })
279
+ }) : /* @__PURE__ */ z("p", {
280
+ className: "text-muted-foreground",
281
+ children: S(j ? "postManager.noDeleted" : "postManager.empty")
282
+ }),
283
+ /* @__PURE__ */ z(w, {
284
+ page: M,
285
+ hasNext: K.hasNext,
286
+ disabled: K.loading,
287
+ onPage: (t) => e.go("", {
288
+ ...F,
289
+ page: t > 1 ? t : void 0
290
+ })
291
+ }),
292
+ J
293
+ ]
294
+ });
295
+ }
296
+ var K = (e) => ({
297
+ title: e.title,
298
+ slug: e.slug ?? "",
299
+ language: e.language,
300
+ excerpt: e.excerpt ?? "",
301
+ liveAt: e.live_at ? D(new Date(e.live_at)) : "",
302
+ body: e.body
303
+ });
304
+ function q({ id: o, loc: s, client: c, languages: l, renderEditor: b, postHref: te, onError: ne }) {
305
+ let S = t(), { t: C } = S, w = P(), T = ae(l), E = M(o, { client: c }), D = n(ne), [k, A] = L(o ? null : {
306
+ title: "",
307
+ slug: "",
308
+ language: T[0]?.value ?? "en",
309
+ excerpt: "",
310
+ liveAt: "",
311
+ body: ""
312
+ }), [j, I] = L(null), [R, V] = L(null), { confirm: U, dialog: W } = ie();
313
+ N(() => {
314
+ E.post && A((e) => e ?? K(E.post));
315
+ }, [E.post]);
316
+ let { imageSrc: G } = E, q = F(() => (k?.body ?? "").replace(O(), (e, t) => {
317
+ let n = G(t);
318
+ return n && n !== t ? n.replaceAll("&", "&") : e;
319
+ }), [k?.body, G]);
320
+ if (o && !k) return E.error ? /* @__PURE__ */ z(re, {
321
+ error: E.error,
322
+ message: C("postManager.loadFailed"),
323
+ retry: () => s.go(o, void 0, { replace: !0 })
324
+ }) : /* @__PURE__ */ B("div", {
325
+ className: "grid gap-3",
326
+ "aria-busy": !0,
327
+ children: [/* @__PURE__ */ z(_, { className: "h-9 w-full" }), /* @__PURE__ */ z(_, { className: "h-48 w-full" })]
328
+ });
329
+ let J = k, Y = (e) => A((t) => ({
330
+ ...t,
331
+ ...e
332
+ })), X = (t) => {
333
+ let n = e(t);
334
+ I(n), D(n, "post.save");
335
+ }, ce = (e) => ({
336
+ title: J.title.trim(),
337
+ slug: J.slug.trim() || void 0,
338
+ language: J.language,
339
+ excerpt: J.excerpt.trim(),
340
+ body: J.body,
341
+ live_at: J.liveAt ? new Date(J.liveAt).toISOString() : void 0,
342
+ ...e === void 0 ? {} : { is_draft: e }
343
+ }), le = async (e) => {
344
+ if (I(null), V(null), !J.title.trim()) return I(C("postManager.titleRequired"));
345
+ try {
346
+ if (!E.post) {
347
+ let e = await E.create({
348
+ ...ce(),
349
+ is_draft: !0
350
+ });
351
+ s.go(e.id, void 0, { replace: !0 });
352
+ return;
353
+ }
354
+ let t = await E.update(ce(e));
355
+ V(C(e === !1 ? "postManager.publishedNotice" : e === !0 ? "postManager.unpublishedNotice" : "pollEditor.saved")), A((e) => ({
356
+ ...e,
357
+ slug: t.slug ?? ""
358
+ }));
359
+ } catch (e) {
360
+ X(e);
361
+ }
362
+ }, ue = async () => {
363
+ if (E.post && await U({
364
+ title: C("postManager.deleteTitle", { title: E.post.title }),
365
+ description: C("postManager.deleteBody"),
366
+ confirm: C("postManager.delete")
367
+ })) try {
368
+ await E.remove(), s.go("", void 0, { replace: !0 });
369
+ } catch (e) {
370
+ X(e);
371
+ }
372
+ }, Z = E.post, Q = Z ? H(Z) : "draft", de = Z && Q === "published" ? te?.(Z) : void 0, $ = {
373
+ value: q,
374
+ onChange: (e) => Y({ body: E.storedBody(e) }),
375
+ uploadImage: Z ? (e) => E.uploadImage(e) : void 0,
376
+ disabled: E.saving,
377
+ placeholder: C("postManager.bodyPlaceholder"),
378
+ "aria-label": C("postManager.body")
379
+ };
380
+ return /* @__PURE__ */ B("form", {
381
+ className: "grid gap-4",
382
+ "data-ckui": "post-form",
383
+ onSubmit: (e) => {
384
+ e.preventDefault(), le();
385
+ },
386
+ children: [
387
+ /* @__PURE__ */ B("div", {
388
+ className: "flex flex-wrap items-center gap-2",
389
+ children: [
390
+ /* @__PURE__ */ z("h2", {
391
+ className: "text-base font-semibold",
392
+ children: C(Z ? "postManager.editTitle" : "postManager.newTitle")
393
+ }),
394
+ Z && /* @__PURE__ */ z(ee, {
395
+ variant: oe[Q],
396
+ children: C(`postManager.${Q}`)
397
+ }),
398
+ de && /* @__PURE__ */ z("a", {
399
+ className: "text-xs text-muted-foreground hover:underline",
400
+ href: de,
401
+ children: C("postManager.view")
402
+ })
403
+ ]
404
+ }),
405
+ Z?.moderation && /* @__PURE__ */ z(r, {
406
+ variant: Z.moderation === "rejected" ? "destructive" : "default",
407
+ children: /* @__PURE__ */ z(i, { children: Z.moderation_reason ? C(`postManager.${Z.moderation === "rejected" ? "rejectedBecause" : "heldBecause"}`, { reason: Z.moderation_reason }) : C(`postManager.${Z.moderation === "rejected" ? "rejectedNote" : "heldNote"}`) })
408
+ }),
409
+ /* @__PURE__ */ B("div", {
410
+ className: "grid gap-1.5",
411
+ children: [/* @__PURE__ */ z(d, {
412
+ htmlFor: `${w}-title`,
413
+ children: C("postManager.postTitle")
414
+ }), /* @__PURE__ */ z(u, {
415
+ id: `${w}-title`,
416
+ value: J.title,
417
+ required: !0,
418
+ maxLength: 300,
419
+ onChange: (e) => Y({ title: e.target.value })
420
+ })]
421
+ }),
422
+ /* @__PURE__ */ B("div", {
423
+ className: "grid gap-4 sm:grid-cols-2",
424
+ children: [
425
+ /* @__PURE__ */ B("div", {
426
+ className: "grid gap-1.5",
427
+ children: [/* @__PURE__ */ z(d, {
428
+ htmlFor: `${w}-slug`,
429
+ children: C("postManager.slug")
430
+ }), /* @__PURE__ */ z(u, {
431
+ id: `${w}-slug`,
432
+ value: J.slug,
433
+ placeholder: C("postManager.slugAuto"),
434
+ onChange: (e) => Y({ slug: e.target.value })
435
+ })]
436
+ }),
437
+ /* @__PURE__ */ B("div", {
438
+ className: "grid gap-1.5",
439
+ children: [/* @__PURE__ */ z(d, {
440
+ htmlFor: `${w}-lang`,
441
+ children: C("postManager.language")
442
+ }), T.length ? /* @__PURE__ */ B(f, {
443
+ value: J.language,
444
+ onValueChange: (e) => Y({ language: String(e ?? "") }),
445
+ children: [/* @__PURE__ */ z(h, {
446
+ id: `${w}-lang`,
447
+ className: "w-full",
448
+ children: /* @__PURE__ */ z(g, { children: (e) => T.find((t) => t.value === e)?.label ?? e })
449
+ }), /* @__PURE__ */ z(p, { children: T.map((e) => /* @__PURE__ */ z(m, {
450
+ value: e.value,
451
+ children: e.label
452
+ }, e.value)) })]
453
+ }) : /* @__PURE__ */ z(u, {
454
+ id: `${w}-lang`,
455
+ value: J.language,
456
+ onChange: (e) => Y({ language: e.target.value })
457
+ })]
458
+ }),
459
+ /* @__PURE__ */ B("div", {
460
+ className: "grid gap-1.5",
461
+ children: [/* @__PURE__ */ z(d, {
462
+ htmlFor: `${w}-live`,
463
+ children: C("postManager.liveAt")
464
+ }), /* @__PURE__ */ z(u, {
465
+ id: `${w}-live`,
466
+ type: "datetime-local",
467
+ value: J.liveAt,
468
+ onChange: (e) => Y({ liveAt: e.target.value })
469
+ })]
470
+ })
471
+ ]
472
+ }),
473
+ /* @__PURE__ */ B("div", {
474
+ className: "grid gap-1.5",
475
+ children: [/* @__PURE__ */ z(d, {
476
+ htmlFor: `${w}-excerpt`,
477
+ children: C("postManager.excerpt")
478
+ }), /* @__PURE__ */ z(v, {
479
+ id: `${w}-excerpt`,
480
+ rows: 2,
481
+ value: J.excerpt,
482
+ onChange: (e) => Y({ excerpt: e.target.value })
483
+ })]
484
+ }),
485
+ /* @__PURE__ */ z(se, {
486
+ post: Z,
487
+ src: E.coverSrc,
488
+ saving: E.saving,
489
+ onFile: (e) => void E.setCover(e).catch(X)
490
+ }),
491
+ /* @__PURE__ */ B("div", {
492
+ className: "grid gap-1.5",
493
+ children: [
494
+ /* @__PURE__ */ z("span", {
495
+ className: "text-sm font-medium",
496
+ children: C("postManager.body")
497
+ }),
498
+ b ? b($) : /* @__PURE__ */ z(v, {
499
+ "aria-label": $["aria-label"],
500
+ rows: 12,
501
+ value: J.body,
502
+ placeholder: $.placeholder,
503
+ onChange: (e) => Y({ body: e.target.value })
504
+ }),
505
+ !Z && /* @__PURE__ */ z("p", {
506
+ className: "text-xs text-muted-foreground",
507
+ children: C("postManager.imagesAfterCreate")
508
+ })
509
+ ]
510
+ }),
511
+ j && /* @__PURE__ */ z(y, { children: typeof j == "string" ? j : x(S, j) }),
512
+ R && !j && /* @__PURE__ */ z("p", {
513
+ role: "status",
514
+ className: "text-sm text-muted-foreground",
515
+ children: R
516
+ }),
517
+ /* @__PURE__ */ B("div", {
518
+ className: "flex flex-wrap gap-2 border-t border-border pt-4",
519
+ children: [
520
+ /* @__PURE__ */ z(a, {
521
+ type: "submit",
522
+ disabled: E.saving,
523
+ children: E.saving ? C("common.saving") : C(Z ? "common.save" : "postManager.createDraft")
524
+ }),
525
+ Z && /* @__PURE__ */ z(a, {
526
+ type: "button",
527
+ variant: "outline",
528
+ disabled: E.saving,
529
+ onClick: () => void le(!Z.is_draft),
530
+ children: C(Z.is_draft ? "postManager.publish" : "postManager.unpublish")
531
+ }),
532
+ Z && /* @__PURE__ */ z(a, {
533
+ type: "button",
534
+ variant: "destructive",
535
+ className: "ms-auto",
536
+ disabled: E.saving,
537
+ onClick: () => void ue(),
538
+ children: C("postManager.delete")
539
+ })
540
+ ]
541
+ }),
542
+ W
543
+ ]
544
+ });
545
+ }
546
+ function se({ post: e, src: n, saving: r, onFile: i }) {
547
+ let { t: o } = t(), s = I(null);
548
+ return /* @__PURE__ */ B("div", {
549
+ className: "grid gap-1.5",
550
+ "data-ckui": "post-cover",
551
+ children: [/* @__PURE__ */ z("span", {
552
+ className: "text-sm font-medium",
553
+ children: o("postManager.cover")
554
+ }), e ? /* @__PURE__ */ B("div", {
555
+ className: "flex flex-wrap items-center gap-3",
556
+ children: [
557
+ n ? /* @__PURE__ */ z("img", {
558
+ src: n,
559
+ alt: "",
560
+ className: "h-20 w-36 rounded-md border border-border object-cover"
561
+ }) : /* @__PURE__ */ z("span", {
562
+ className: "text-muted-foreground",
563
+ children: o("postManager.noCover")
564
+ }),
565
+ /* @__PURE__ */ z(a, {
566
+ type: "button",
567
+ size: "sm",
568
+ variant: "outline",
569
+ disabled: r,
570
+ onClick: () => s.current?.click(),
571
+ children: o(n ? "pollEditor.replaceImage" : "postManager.addCover")
572
+ }),
573
+ n && /* @__PURE__ */ z(a, {
574
+ type: "button",
575
+ size: "sm",
576
+ variant: "ghost",
577
+ disabled: r,
578
+ onClick: () => i(null),
579
+ children: o("pollEditor.removeImage")
580
+ }),
581
+ /* @__PURE__ */ z("input", {
582
+ ref: s,
583
+ type: "file",
584
+ accept: "image/*",
585
+ hidden: !0,
586
+ "aria-label": o("postManager.cover"),
587
+ onChange: (e) => {
588
+ let t = e.target.files?.[0];
589
+ e.target.value = "", t && i(t);
590
+ }
591
+ })
592
+ ]
593
+ }) : /* @__PURE__ */ z("p", {
594
+ className: "text-xs text-muted-foreground",
595
+ children: o("postManager.imagesAfterCreate")
596
+ })]
597
+ });
598
+ }
599
+ //#endregion
600
+ export { U as PostManager, H as postStatus, V as usePostManagerAccess };
601
+
602
+ //# sourceMappingURL=post-manager.js.map