@openrails/contentkit-ui 0.83.0 → 0.86.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 (219) hide show
  1. package/README.md +18 -7
  2. package/dist/client/beacons.d.ts +18 -6
  3. package/dist/client/beacons.js +26 -11
  4. package/dist/client/beacons.js.map +1 -1
  5. package/dist/client/client.d.ts +3 -0
  6. package/dist/client/client.js +29 -27
  7. package/dist/client/client.js.map +1 -1
  8. package/dist/client/codes.d.ts +6 -1
  9. package/dist/client/codes.js +4 -1
  10. package/dist/client/codes.js.map +1 -1
  11. package/dist/client/content/moderation.d.ts +14 -2
  12. package/dist/client/content/moderation.js +34 -0
  13. package/dist/client/content/moderation.js.map +1 -1
  14. package/dist/client/content/types.d.ts +13 -0
  15. package/dist/client/content/types.js.map +1 -1
  16. package/dist/client/discovery.d.ts +6 -0
  17. package/dist/client/discovery.js.map +1 -1
  18. package/dist/client/generated/error-codes.d.ts +1 -1
  19. package/dist/client/generated/error-codes.js +9 -1
  20. package/dist/client/generated/error-codes.js.map +1 -1
  21. package/dist/client/generated/routes.d.ts +91 -13
  22. package/dist/client/generated/routes.js +123 -2
  23. package/dist/client/generated/routes.js.map +1 -1
  24. package/dist/client/generated/wire.d.ts +81 -0
  25. package/dist/client/generated/wire.js.map +1 -1
  26. package/dist/client/index.d.ts +4 -2
  27. package/dist/client/media/queue.d.ts +4 -2
  28. package/dist/client/media/queue.js +18 -12
  29. package/dist/client/media/queue.js.map +1 -1
  30. package/dist/client/media/rules.d.ts +7 -1
  31. package/dist/client/media/rules.js +27 -21
  32. package/dist/client/media/rules.js.map +1 -1
  33. package/dist/client/reader-meta.d.ts +27 -0
  34. package/dist/client/reader-meta.js +99 -0
  35. package/dist/client/reader-meta.js.map +1 -0
  36. package/dist/client/stats.d.ts +32 -0
  37. package/dist/client/stats.js +35 -0
  38. package/dist/client/stats.js.map +1 -0
  39. package/dist/client/versions.d.ts +1 -1
  40. package/dist/client/versions.js +7 -2
  41. package/dist/client/versions.js.map +1 -1
  42. package/dist/client.js +30 -28
  43. package/dist/components/admin/content-manager.js +206 -206
  44. package/dist/components/admin/content-manager.js.map +1 -1
  45. package/dist/components/admin/group-manager.js +71 -70
  46. package/dist/components/admin/group-manager.js.map +1 -1
  47. package/dist/components/admin/media-item-panel.d.ts +24 -7
  48. package/dist/components/admin/media-item-panel.js +209 -197
  49. package/dist/components/admin/media-item-panel.js.map +1 -1
  50. package/dist/components/admin/poll-manager.js +25 -25
  51. package/dist/components/admin/reader-manifest.d.ts +18 -0
  52. package/dist/components/admin/reader-manifest.js +490 -0
  53. package/dist/components/admin/reader-manifest.js.map +1 -0
  54. package/dist/components/admin/stats-dashboard.d.ts +22 -0
  55. package/dist/components/admin/stats-dashboard.js +257 -0
  56. package/dist/components/admin/stats-dashboard.js.map +1 -0
  57. package/dist/components/content/card.js +43 -43
  58. package/dist/components/content/card.js.map +1 -1
  59. package/dist/components/content/editors.d.ts +2 -1
  60. package/dist/components/content/editors.js +479 -416
  61. package/dist/components/content/editors.js.map +1 -1
  62. package/dist/components/content/grid.js +47 -47
  63. package/dist/components/content/index.d.ts +2 -1
  64. package/dist/components/content/listing.js +34 -34
  65. package/dist/components/content/listing.js.map +1 -1
  66. package/dist/components/content/paywall.d.ts +17 -5
  67. package/dist/components/content/paywall.js +115 -100
  68. package/dist/components/content/paywall.js.map +1 -1
  69. package/dist/components/content/reader-stats.d.ts +12 -0
  70. package/dist/components/content/reader-stats.js +47 -0
  71. package/dist/components/content/reader-stats.js.map +1 -0
  72. package/dist/components/groups/banner.d.ts +1 -1
  73. package/dist/components/groups/banner.js +34 -34
  74. package/dist/components/groups/banner.js.map +1 -1
  75. package/dist/components/groups/directory.js +11 -11
  76. package/dist/components/groups/editor.js +294 -294
  77. package/dist/components/groups/editor.js.map +1 -1
  78. package/dist/components/groups/header.js +27 -27
  79. package/dist/components/groups/header.js.map +1 -1
  80. package/dist/components/groups/memberships.js +180 -180
  81. package/dist/components/groups/parts.d.ts +2 -4
  82. package/dist/components/groups/parts.js +69 -88
  83. package/dist/components/groups/parts.js.map +1 -1
  84. package/dist/components/media-folder-editor.js +239 -189
  85. package/dist/components/media-folder-editor.js.map +1 -1
  86. package/dist/components/notifications.js +17 -17
  87. package/dist/components/slot-upload.d.ts +2 -2
  88. package/dist/components/slot-upload.js +84 -79
  89. package/dist/components/slot-upload.js.map +1 -1
  90. package/dist/components/social/bans.js +34 -34
  91. package/dist/components/social/comments.js +59 -45
  92. package/dist/components/social/comments.js.map +1 -1
  93. package/dist/components/social/index.d.ts +1 -0
  94. package/dist/components/social/moderation.d.ts +5 -4
  95. package/dist/components/social/moderation.js +177 -160
  96. package/dist/components/social/moderation.js.map +1 -1
  97. package/dist/components/social/parts.js +22 -14
  98. package/dist/components/social/parts.js.map +1 -1
  99. package/dist/components/social/rules.d.ts +23 -0
  100. package/dist/components/social/rules.js +261 -0
  101. package/dist/components/social/rules.js.map +1 -0
  102. package/dist/components/video-player.d.ts +2 -0
  103. package/dist/components/video-player.js +318 -314
  104. package/dist/components/video-player.js.map +1 -1
  105. package/dist/i18n/context.d.ts +2 -0
  106. package/dist/i18n/context.js +23 -5
  107. package/dist/i18n/context.js.map +1 -1
  108. package/dist/index.d.ts +3 -1
  109. package/dist/index.js +28 -24
  110. package/dist/locales/admin/de.js +105 -0
  111. package/dist/locales/admin/de.js.map +1 -1
  112. package/dist/locales/admin/en.d.ts +105 -0
  113. package/dist/locales/admin/en.js +105 -0
  114. package/dist/locales/admin/en.js.map +1 -1
  115. package/dist/locales/admin/es.js +105 -0
  116. package/dist/locales/admin/es.js.map +1 -1
  117. package/dist/locales/admin/ja.js +105 -0
  118. package/dist/locales/admin/ja.js.map +1 -1
  119. package/dist/locales/admin/ko.js +105 -0
  120. package/dist/locales/admin/ko.js.map +1 -1
  121. package/dist/locales/admin/zh.js +105 -0
  122. package/dist/locales/admin/zh.js.map +1 -1
  123. package/dist/locales/content/de.js +6 -0
  124. package/dist/locales/content/de.js.map +1 -1
  125. package/dist/locales/content/en.d.ts +6 -0
  126. package/dist/locales/content/en.js +6 -0
  127. package/dist/locales/content/en.js.map +1 -1
  128. package/dist/locales/content/es.js +6 -0
  129. package/dist/locales/content/es.js.map +1 -1
  130. package/dist/locales/content/ja.js +6 -0
  131. package/dist/locales/content/ja.js.map +1 -1
  132. package/dist/locales/content/ko.js +6 -0
  133. package/dist/locales/content/ko.js.map +1 -1
  134. package/dist/locales/content/zh.js +6 -0
  135. package/dist/locales/content/zh.js.map +1 -1
  136. package/dist/locales/de.js +4 -1
  137. package/dist/locales/de.js.map +1 -1
  138. package/dist/locales/discovery/de.js +1 -0
  139. package/dist/locales/discovery/de.js.map +1 -1
  140. package/dist/locales/discovery/en.d.ts +1 -0
  141. package/dist/locales/discovery/en.js +1 -0
  142. package/dist/locales/discovery/en.js.map +1 -1
  143. package/dist/locales/discovery/es.js +1 -0
  144. package/dist/locales/discovery/es.js.map +1 -1
  145. package/dist/locales/discovery/ja.js +1 -0
  146. package/dist/locales/discovery/ja.js.map +1 -1
  147. package/dist/locales/discovery/ko.js +1 -0
  148. package/dist/locales/discovery/ko.js.map +1 -1
  149. package/dist/locales/discovery/zh.js +1 -0
  150. package/dist/locales/discovery/zh.js.map +1 -1
  151. package/dist/locales/en.d.ts +118 -0
  152. package/dist/locales/en.js +4 -1
  153. package/dist/locales/en.js.map +1 -1
  154. package/dist/locales/es.js +4 -1
  155. package/dist/locales/es.js.map +1 -1
  156. package/dist/locales/ja.js +4 -1
  157. package/dist/locales/ja.js.map +1 -1
  158. package/dist/locales/ko.js +4 -1
  159. package/dist/locales/ko.js.map +1 -1
  160. package/dist/locales/social/de.js +3 -0
  161. package/dist/locales/social/de.js.map +1 -1
  162. package/dist/locales/social/en.d.ts +3 -0
  163. package/dist/locales/social/en.js +3 -0
  164. package/dist/locales/social/en.js.map +1 -1
  165. package/dist/locales/social/es.js +3 -0
  166. package/dist/locales/social/es.js.map +1 -1
  167. package/dist/locales/social/ja.js +3 -0
  168. package/dist/locales/social/ja.js.map +1 -1
  169. package/dist/locales/social/ko.js +3 -0
  170. package/dist/locales/social/ko.js.map +1 -1
  171. package/dist/locales/social/zh.js +3 -0
  172. package/dist/locales/social/zh.js.map +1 -1
  173. package/dist/locales/zh.js +4 -1
  174. package/dist/locales/zh.js.map +1 -1
  175. package/dist/react/admin.d.ts +1 -1
  176. package/dist/react/admin.js +24 -23
  177. package/dist/react/admin.js.map +1 -1
  178. package/dist/react/canonical.d.ts +4 -3
  179. package/dist/react/canonical.js +34 -33
  180. package/dist/react/canonical.js.map +1 -1
  181. package/dist/react/comments.d.ts +29 -1
  182. package/dist/react/comments.js +30 -2
  183. package/dist/react/comments.js.map +1 -1
  184. package/dist/react/contents.js +144 -144
  185. package/dist/react/contents.js.map +1 -1
  186. package/dist/react/context.d.ts +1 -1
  187. package/dist/react/context.js.map +1 -1
  188. package/dist/react/detail.d.ts +12 -6
  189. package/dist/react/detail.js +31 -24
  190. package/dist/react/detail.js.map +1 -1
  191. package/dist/react/discovery.js +1 -1
  192. package/dist/react/discovery.js.map +1 -1
  193. package/dist/react/folder.d.ts +7 -2
  194. package/dist/react/folder.js +165 -147
  195. package/dist/react/folder.js.map +1 -1
  196. package/dist/react/groups.d.ts +0 -1
  197. package/dist/react/groups.js +13 -12
  198. package/dist/react/groups.js.map +1 -1
  199. package/dist/react/index.d.ts +5 -3
  200. package/dist/react/location.d.ts +11 -0
  201. package/dist/react/location.js +18 -0
  202. package/dist/react/location.js.map +1 -0
  203. package/dist/react/public.d.ts +8 -0
  204. package/dist/react/public.js +32 -27
  205. package/dist/react/public.js.map +1 -1
  206. package/dist/react/resources.js +6 -0
  207. package/dist/react/resources.js.map +1 -1
  208. package/dist/react/stats.d.ts +24 -0
  209. package/dist/react/stats.js +28 -0
  210. package/dist/react/stats.js.map +1 -0
  211. package/dist/react/use-resource.js +8 -7
  212. package/dist/react/use-resource.js.map +1 -1
  213. package/dist/react/versions.js +20 -20
  214. package/dist/react.js +26 -24
  215. package/dist/styles.css +1 -1
  216. package/dist/urls/index.d.ts +35 -10
  217. package/dist/urls.js +100 -70
  218. package/dist/urls.js.map +1 -1
  219. package/package.json +1 -1
@@ -2,41 +2,46 @@ import { ratio as e } from "../client/aspect.js";
2
2
  import { presetFor as t } from "../client/media/rules.js";
3
3
  import { useMessages as n } from "../i18n/context.js";
4
4
  import { ContentKitUiRoot as r } from "../scope.js";
5
- import { usePresets as i } from "../react/public.js";
6
- import { Button as a } from "../ui/button.js";
7
- import { SlotImage as o } from "./slot-image.js";
8
- import { SlotEditError as s, SlotEditor as c, useSlotEditor as l } from "./slot-editor.js";
9
- import { useState as u } from "react";
10
- import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
11
- import { cn as m } from "cn";
12
- import { Camera01Icon as h, CropIcon as g, Delete02Icon as _, ImageUpload01Icon as v, Loading03Icon as y } from "@hugeicons/core-free-icons";
13
- import { HugeiconsIcon as b } from "@hugeicons/react";
5
+ import { useContentScope as i } from "../react/use-resource.js";
6
+ import { useKinds as a } from "../react/groups.js";
7
+ import { usePresets as o } from "../react/public.js";
8
+ import { Button as s } from "../ui/button.js";
9
+ import { SlotImage as c } from "./slot-image.js";
10
+ import { SlotEditError as l, SlotEditor as u, useSlotEditor as d } from "./slot-editor.js";
11
+ import { useState as f } from "react";
12
+ import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
13
+ import { cn as g } from "cn";
14
+ import { Camera01Icon as _, CropIcon as v, Delete02Icon as y, ImageUpload01Icon as b, Loading03Icon as x } from "@hugeicons/core-free-icons";
15
+ import { HugeiconsIcon as S } from "@hugeicons/react";
14
16
  //#region src/components/slot-upload.tsx
15
- function x(e) {
16
- return /* @__PURE__ */ f(C, {
17
+ function C(e) {
18
+ return /* @__PURE__ */ m(T, {
17
19
  ...e,
18
20
  variant: "avatar"
19
21
  });
20
22
  }
21
- function S(e) {
22
- return /* @__PURE__ */ f(C, {
23
+ function w(e) {
24
+ return /* @__PURE__ */ m(T, {
23
25
  ...e,
24
26
  variant: "cover"
25
27
  });
26
28
  }
27
- function C({ variant: e, ...n }) {
28
- let a = n.path ?? e, { presets: o } = i({ client: n.client }), s = t(o, n.item.kind, a, n.image?.preset);
29
- return /* @__PURE__ */ f(r, {
30
- className: m("text-sm", n.className),
29
+ function T({ variant: e, ...n }) {
30
+ let s = n.path ?? e, { presets: c } = o({ client: n.client }), { kinds: l } = a({ client: n.client }), { viewer: d } = i(n.client), f = e === "avatar" ? l?.avatars : void 0, p = n.item ?? (f && d ? {
31
+ kind: f.kind,
32
+ id: d
33
+ } : void 0), h = p && (t(c, p.kind, s, n.image?.preset) ?? (f?.kind === p.kind ? f : void 0));
34
+ return p ? /* @__PURE__ */ m(r, {
35
+ className: g("text-sm", n.className),
31
36
  "data-ckui": e === "avatar" ? "avatar-upload" : "cover-upload",
32
- children: /* @__PURE__ */ f(c, {
33
- item: n.item,
34
- path: a,
37
+ children: /* @__PURE__ */ m(u, {
38
+ item: p,
39
+ path: s,
35
40
  image: n.image,
36
41
  client: n.client,
37
42
  read: n.read,
38
43
  onChange: n.onChange,
39
- aspect: n.aspect || n.image?.aspect || s?.aspect || (e === "avatar" ? "1:1" : "3:1"),
44
+ aspect: n.aspect || n.image?.aspect || h?.aspect || (e === "avatar" ? "1:1" : "3:1"),
40
45
  minWidth: n.minWidth,
41
46
  animation: n.animation,
42
47
  targetWidth: n.targetWidth ?? (e === "avatar" ? 512 : 3e3),
@@ -45,171 +50,171 @@ function C({ variant: e, ...n }) {
45
50
  disabled: n.disabled,
46
51
  removable: n.removable ?? e === "avatar",
47
52
  decode: n.decode,
48
- children: /* @__PURE__ */ f(w, {
53
+ children: /* @__PURE__ */ m(E, {
49
54
  ...n,
50
55
  variant: e
51
56
  })
52
57
  })
53
- });
58
+ }) : null;
54
59
  }
55
- function w({ variant: t, ...r }) {
56
- let { t: i } = n(), c = l(), { crop: x, has: S, busy: C, disabled: w } = c, E = {
60
+ function E({ variant: t, ...r }) {
61
+ let { t: i } = n(), a = d(), { crop: o, has: u, busy: C, disabled: w } = a, T = {
57
62
  preset: r.image?.preset ?? t,
58
- aspect: c.image.aspect,
59
- renditions: c.image.renditions
60
- }, [D, O] = u(!1), k = x.aspect, A = r.targetWidth ?? (t === "avatar" ? 512 : 3e3), j = (e) => {
63
+ aspect: a.image.aspect,
64
+ renditions: a.image.renditions
65
+ }, [E, O] = f(!1), k = o.aspect, A = r.targetWidth ?? (t === "avatar" ? 512 : 3e3), j = (e) => {
61
66
  e.preventDefault(), O(!1);
62
67
  let t = [...e.dataTransfer.files].find((e) => e.type.startsWith("image/")) ?? e.dataTransfer.files[0];
63
- t && c.pick(t);
68
+ t && a.pick(t);
64
69
  }, M = r.hint ?? (t === "avatar" ? i("avatar.hint", { size: A }) : i("cover.hint", {
65
70
  width: A,
66
71
  height: Math.round(A / (e(k) ?? 3))
67
- })), N = r.label ?? i(t === "avatar" ? "avatar.label" : "cover.label"), P = (e) => /* @__PURE__ */ p(d, { children: [
68
- /* @__PURE__ */ p(a, {
69
- variant: e && S ? "secondary" : "outline",
72
+ })), N = r.label ?? i(t === "avatar" ? "avatar.label" : "cover.label"), P = (e) => /* @__PURE__ */ h(p, { children: [
73
+ /* @__PURE__ */ h(s, {
74
+ variant: e && u ? "secondary" : "outline",
70
75
  size: "sm",
71
76
  disabled: w,
72
- onClick: c.choose,
77
+ onClick: a.choose,
73
78
  "data-ckui": "change",
74
- children: [/* @__PURE__ */ f(b, {
75
- icon: C ? y : h,
79
+ children: [/* @__PURE__ */ m(S, {
80
+ icon: C ? x : _,
76
81
  strokeWidth: 2,
77
82
  "data-icon": "inline-start",
78
83
  className: C ? "animate-spin" : void 0
79
- }), i(S ? "common.change" : "common.upload")]
84
+ }), i(u ? "common.change" : "common.upload")]
80
85
  }),
81
- S && x.canRecrop && /* @__PURE__ */ p(a, {
86
+ u && o.canRecrop && /* @__PURE__ */ h(s, {
82
87
  variant: e ? "secondary" : "ghost",
83
88
  size: "sm",
84
89
  disabled: w,
85
- onClick: c.recrop,
90
+ onClick: a.recrop,
86
91
  "data-ckui": "edit-crop",
87
- children: [/* @__PURE__ */ f(b, {
88
- icon: g,
92
+ children: [/* @__PURE__ */ m(S, {
93
+ icon: v,
89
94
  strokeWidth: 2,
90
95
  "data-icon": "inline-start"
91
96
  }), i("common.editCrop")]
92
97
  }),
93
- S && c.removable && /* @__PURE__ */ p(a, {
98
+ u && a.removable && /* @__PURE__ */ h(s, {
94
99
  variant: e ? "secondary" : "ghost",
95
100
  size: "sm",
96
101
  disabled: w,
97
- onClick: c.remove,
102
+ onClick: a.remove,
98
103
  "data-ckui": "remove",
99
- children: [/* @__PURE__ */ f(b, {
100
- icon: _,
104
+ children: [/* @__PURE__ */ m(S, {
105
+ icon: y,
101
106
  strokeWidth: 2,
102
107
  "data-icon": "inline-start"
103
108
  }), i("common.remove")]
104
109
  })
105
110
  ] });
106
- return t === "avatar" ? /* @__PURE__ */ p("div", {
111
+ return t === "avatar" ? /* @__PURE__ */ h("div", {
107
112
  className: "flex items-center gap-4",
108
- children: [/* @__PURE__ */ p("div", {
113
+ children: [/* @__PURE__ */ h("div", {
109
114
  className: "relative size-20 shrink-0",
110
- children: [/* @__PURE__ */ f(o, {
111
- image: S ? E : null,
115
+ children: [/* @__PURE__ */ m(c, {
116
+ image: u ? T : null,
112
117
  round: !0,
113
118
  emptyLabel: i("avatar.empty"),
114
119
  className: "size-full ring-1 ring-foreground/10"
115
- }), C && /* @__PURE__ */ f(T, {
120
+ }), C && /* @__PURE__ */ m(D, {
116
121
  round: !0,
117
- label: i(x.status === "decoding" ? "progress.decoding" : "common.saving")
122
+ label: i(o.status === "decoding" ? "progress.decoding" : "common.saving")
118
123
  })]
119
- }), /* @__PURE__ */ p("div", {
124
+ }), /* @__PURE__ */ h("div", {
120
125
  className: "grid min-w-0 gap-1",
121
126
  children: [
122
- /* @__PURE__ */ f("div", {
127
+ /* @__PURE__ */ m("div", {
123
128
  className: "font-medium",
124
129
  children: N
125
130
  }),
126
- /* @__PURE__ */ f("div", {
131
+ /* @__PURE__ */ m("div", {
127
132
  className: "text-xs text-muted-foreground",
128
133
  children: M
129
134
  }),
130
- /* @__PURE__ */ f("div", {
135
+ /* @__PURE__ */ m("div", {
131
136
  className: "mt-1.5 flex flex-wrap gap-2",
132
137
  children: P(!1)
133
138
  }),
134
- /* @__PURE__ */ f(s, {})
139
+ /* @__PURE__ */ m(l, {})
135
140
  ]
136
141
  })]
137
- }) : /* @__PURE__ */ p("div", {
142
+ }) : /* @__PURE__ */ h("div", {
138
143
  className: "grid gap-2",
139
144
  children: [
140
- /* @__PURE__ */ p("div", {
141
- className: m("group/cover relative overflow-hidden rounded-xl ring-1 ring-foreground/10 transition-shadow", D && "ring-2 ring-ring"),
145
+ /* @__PURE__ */ h("div", {
146
+ className: g("group/cover relative overflow-hidden rounded-xl ring-1 ring-foreground/10 transition-shadow", E && "ring-2 ring-ring"),
142
147
  onDragOver: (e) => {
143
148
  e.preventDefault(), w || O(!0);
144
149
  },
145
150
  onDragLeave: () => O(!1),
146
151
  onDrop: j,
147
152
  children: [
148
- /* @__PURE__ */ f(o, {
149
- image: S ? E : null,
153
+ /* @__PURE__ */ m(c, {
154
+ image: u ? T : null,
150
155
  aspect: k,
151
156
  className: "w-full rounded-none",
152
- fallback: /* @__PURE__ */ p("div", {
157
+ fallback: /* @__PURE__ */ h("div", {
153
158
  "aria-label": i("cover.empty"),
154
159
  role: "group",
155
160
  className: "absolute inset-0 flex flex-col items-center justify-center gap-1.5 bg-[repeating-linear-gradient(135deg,transparent_0_10px,color-mix(in_oklch,var(--ckui-foreground)_3%,transparent)_10px_20px)] p-4 text-center",
156
161
  children: [
157
- /* @__PURE__ */ f(b, {
158
- icon: v,
162
+ /* @__PURE__ */ m(S, {
163
+ icon: b,
159
164
  strokeWidth: 1.5,
160
165
  className: "size-7 text-muted-foreground"
161
166
  }),
162
- /* @__PURE__ */ f("span", {
167
+ /* @__PURE__ */ m("span", {
163
168
  className: "hidden text-xs text-muted-foreground sm:block",
164
169
  children: i("cover.drop")
165
170
  }),
166
- /* @__PURE__ */ f("div", {
171
+ /* @__PURE__ */ m("div", {
167
172
  className: "mt-1 flex gap-2",
168
173
  children: P(!1)
169
174
  })
170
175
  ]
171
176
  })
172
177
  }),
173
- C && /* @__PURE__ */ f(T, { label: i(x.status === "decoding" ? "progress.decoding" : "common.saving") }),
174
- S && /* @__PURE__ */ f("div", {
178
+ C && /* @__PURE__ */ m(D, { label: i(o.status === "decoding" ? "progress.decoding" : "common.saving") }),
179
+ u && /* @__PURE__ */ m("div", {
175
180
  className: "absolute right-2 bottom-2 flex gap-2 max-sm:hidden [&_button]:bg-background/80 [&_button]:backdrop-blur-sm",
176
181
  children: P(!0)
177
182
  })
178
183
  ]
179
184
  }),
180
- /* @__PURE__ */ p("div", {
185
+ /* @__PURE__ */ h("div", {
181
186
  className: "flex flex-wrap items-center justify-between gap-x-3 gap-y-1.5",
182
- children: [/* @__PURE__ */ p("div", {
187
+ children: [/* @__PURE__ */ h("div", {
183
188
  className: "grid min-w-0 gap-0.5 sm:flex sm:flex-1 sm:items-baseline sm:justify-between sm:gap-3",
184
- children: [/* @__PURE__ */ f("div", {
189
+ children: [/* @__PURE__ */ m("div", {
185
190
  className: "font-medium",
186
191
  children: N
187
- }), /* @__PURE__ */ f("div", {
192
+ }), /* @__PURE__ */ m("div", {
188
193
  className: "text-xs text-muted-foreground sm:truncate",
189
194
  children: M
190
195
  })]
191
- }), S && /* @__PURE__ */ f("div", {
196
+ }), u && /* @__PURE__ */ m("div", {
192
197
  className: "flex gap-2 sm:hidden",
193
198
  children: P(!1)
194
199
  })]
195
200
  }),
196
- /* @__PURE__ */ f(s, {})
201
+ /* @__PURE__ */ m(l, {})
197
202
  ]
198
203
  });
199
204
  }
200
- function T({ round: e, label: t }) {
201
- return /* @__PURE__ */ f("div", {
205
+ function D({ round: e, label: t }) {
206
+ return /* @__PURE__ */ m("div", {
202
207
  role: "status",
203
208
  "aria-label": t,
204
- className: m("absolute inset-0 flex items-center justify-center bg-background/60 backdrop-blur-[1px]", e && "rounded-full"),
205
- children: /* @__PURE__ */ f(b, {
206
- icon: y,
209
+ className: g("absolute inset-0 flex items-center justify-center bg-background/60 backdrop-blur-[1px]", e && "rounded-full"),
210
+ children: /* @__PURE__ */ m(S, {
211
+ icon: x,
207
212
  strokeWidth: 2,
208
213
  className: "size-5 animate-spin text-foreground"
209
214
  })
210
215
  });
211
216
  }
212
217
  //#endregion
213
- export { x as AvatarUpload, S as CoverUpload };
218
+ export { C as AvatarUpload, w as CoverUpload };
214
219
 
215
220
  //# sourceMappingURL=slot-upload.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"slot-upload.js","names":[],"sources":["../../src/components/slot-upload.tsx"],"sourcesContent":["import { ratio, type AspectRatio } from \"../client/aspect.js\";\nimport { Camera01Icon, CropIcon, Delete02Icon, ImageUpload01Icon, Loading03Icon } from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { cn } from \"cn\";\nimport { useState, type DragEvent, type ReactNode } from \"react\";\nimport type { ContentKitClient } from \"../client/client.js\";\nimport { useMessages } from \"../i18n/context.js\";\nimport type { CropSource } from \"../client/image.js\";\nimport { ContentKitUiRoot } from \"../scope.js\";\nimport type { PublicPreset } from \"../client/public.js\";\nimport type { FileInfo, ReadResult, RefBody } from \"../client/generated/wire.js\";\nimport { presetFor } from \"../client/media/rules.js\";\nimport { usePresets } from \"../react/public.js\";\nimport { Button } from \"#ckui/ui/button\";\nimport { SlotEditError, SlotEditor, useSlotEditor } from \"./slot-editor.js\";\nimport { SlotImage } from \"./slot-image.js\";\n\nexport interface SlotUploadProps {\n /** The item that owns the upload. */\n item: RefBody;\n /** The upload path; default \"avatar\" or \"cover\". */\n path?: string;\n /** The public preset showing it. */\n image?: PublicPreset | null;\n client?: ContentKitClient;\n /** An editor read of the item from the host; otherwise fetched. */\n read?: ReadResult | null;\n /** Called with the processed upload after every save, null after a removal. */\n onChange?: (file: FileInfo | null) => void;\n /** The output's \"W:H\"; default the preset's aspect, else \"1:1\" (avatar) or \"3:1\" (cover). */\n aspect?: AspectRatio;\n /** The narrowest edit the server accepts (the preset's Image.MinWidth). */\n minWidth?: number;\n /** \"reject\" refuses animated images before uploading. */\n animation?: \"reject\";\n /** Crops narrower than this many source pixels get a sharpness warning; default 512 (avatar) or 3000 (cover). */\n targetWidth?: number;\n /** `accept` of the file input. Default \"image/*\". */\n accept?: string;\n disabled?: boolean;\n /** Offers Remove once set; default true for avatars, false for covers. */\n removable?: boolean;\n label?: ReactNode;\n hint?: ReactNode;\n className?: string;\n /** Replaces decodeImage (tests). */\n decode?: (file: File) => Promise<CropSource>;\n}\n\ntype Variant = \"avatar\" | \"cover\";\n\n/** Round 1:1 avatar field: image, label, hint, Change / Edit crop, crop dialog, progress, errors. For custom layouts use SlotEditor. */\nexport function AvatarUpload(p: SlotUploadProps) {\n return <SlotUpload {...p} variant=\"avatar\" />;\n}\n\n/** Wide cover field at the preset's aspect (e.g. 3:1), with drop-to-upload. For custom layouts use SlotEditor. */\nexport function CoverUpload(p: SlotUploadProps) {\n return <SlotUpload {...p} variant=\"cover\" />;\n}\n\nfunction SlotUpload({ variant, ...p }: SlotUploadProps & { variant: Variant }) {\n const path = p.path ?? variant;\n const { presets } = usePresets({ client: p.client });\n const rule = presetFor(presets, p.item.kind, path, p.image?.preset);\n return (\n <ContentKitUiRoot className={cn(\"text-sm\", p.className)} data-ckui={variant === \"avatar\" ? \"avatar-upload\" : \"cover-upload\"}>\n <SlotEditor\n item={p.item}\n path={path}\n image={p.image}\n client={p.client}\n read={p.read}\n onChange={p.onChange}\n aspect={p.aspect || p.image?.aspect || rule?.aspect || (variant === \"avatar\" ? \"1:1\" : \"3:1\")}\n minWidth={p.minWidth}\n animation={p.animation}\n targetWidth={p.targetWidth ?? (variant === \"avatar\" ? 512 : 3000)}\n round={variant === \"avatar\"}\n accept={p.accept}\n disabled={p.disabled}\n removable={p.removable ?? variant === \"avatar\"}\n decode={p.decode}\n >\n <SlotUploadLayout {...p} variant={variant} />\n </SlotEditor>\n </ContentKitUiRoot>\n );\n}\n\nfunction SlotUploadLayout({ variant, ...p }: SlotUploadProps & { variant: Variant }) {\n const { t } = useMessages();\n const s = useSlotEditor();\n const { crop, has, busy, disabled } = s;\n const image = { preset: p.image?.preset ?? variant, aspect: s.image.aspect, renditions: s.image.renditions };\n const [dragging, setDragging] = useState(false);\n const aspect = crop.aspect;\n const target = p.targetWidth ?? (variant === \"avatar\" ? 512 : 3000);\n const onDrop = (e: DragEvent) => {\n e.preventDefault();\n setDragging(false);\n const f = [...e.dataTransfer.files].find((f) => f.type.startsWith(\"image/\")) ?? e.dataTransfer.files[0];\n if (f) s.pick(f);\n };\n\n const hint =\n p.hint ?? (variant === \"avatar\" ? t(\"avatar.hint\", { size: target }) : t(\"cover.hint\", { width: target, height: Math.round(target / (ratio(aspect) ?? 3)) }));\n const label = p.label ?? t(variant === \"avatar\" ? \"avatar.label\" : \"cover.label\");\n\n // overlay: buttons on top of the cover image; otherwise a plain row.\n const actions = (overlay: boolean) => (\n <>\n <Button variant={overlay && has ? \"secondary\" : \"outline\"} size=\"sm\" disabled={disabled} onClick={s.choose} data-ckui=\"change\">\n <HugeiconsIcon icon={busy ? Loading03Icon : Camera01Icon} strokeWidth={2} data-icon=\"inline-start\" className={busy ? \"animate-spin\" : undefined} />\n {has ? t(\"common.change\") : t(\"common.upload\")}\n </Button>\n {has && crop.canRecrop && (\n <Button variant={overlay ? \"secondary\" : \"ghost\"} size=\"sm\" disabled={disabled} onClick={s.recrop} data-ckui=\"edit-crop\">\n <HugeiconsIcon icon={CropIcon} strokeWidth={2} data-icon=\"inline-start\" />\n {t(\"common.editCrop\")}\n </Button>\n )}\n {has && s.removable && (\n <Button variant={overlay ? \"secondary\" : \"ghost\"} size=\"sm\" disabled={disabled} onClick={s.remove} data-ckui=\"remove\">\n <HugeiconsIcon icon={Delete02Icon} strokeWidth={2} data-icon=\"inline-start\" />\n {t(\"common.remove\")}\n </Button>\n )}\n </>\n );\n\n return variant === \"avatar\" ? (\n <div className=\"flex items-center gap-4\">\n <div className=\"relative size-20 shrink-0\">\n <SlotImage image={has ? image : null} round emptyLabel={t(\"avatar.empty\")} className=\"size-full ring-1 ring-foreground/10\" />\n {busy && <BusyOverlay round label={t(crop.status === \"decoding\" ? \"progress.decoding\" : \"common.saving\")} />}\n </div>\n <div className=\"grid min-w-0 gap-1\">\n <div className=\"font-medium\">{label}</div>\n <div className=\"text-xs text-muted-foreground\">{hint}</div>\n <div className=\"mt-1.5 flex flex-wrap gap-2\">{actions(false)}</div>\n <SlotEditError />\n </div>\n </div>\n ) : (\n <div className=\"grid gap-2\">\n <div\n className={cn(\n \"group/cover relative overflow-hidden rounded-xl ring-1 ring-foreground/10 transition-shadow\",\n dragging && \"ring-2 ring-ring\",\n )}\n onDragOver={(e) => {\n e.preventDefault();\n if (!disabled) setDragging(true);\n }}\n onDragLeave={() => setDragging(false)}\n onDrop={onDrop}\n >\n <SlotImage\n image={has ? image : null}\n aspect={aspect}\n className=\"w-full rounded-none\"\n fallback={\n <div aria-label={t(\"cover.empty\")} role=\"group\" className=\"absolute inset-0 flex flex-col items-center justify-center gap-1.5 bg-[repeating-linear-gradient(135deg,transparent_0_10px,color-mix(in_oklch,var(--ckui-foreground)_3%,transparent)_10px_20px)] p-4 text-center\">\n <HugeiconsIcon icon={ImageUpload01Icon} strokeWidth={1.5} className=\"size-7 text-muted-foreground\" />\n <span className=\"hidden text-xs text-muted-foreground sm:block\">{t(\"cover.drop\")}</span>\n <div className=\"mt-1 flex gap-2\">{actions(false)}</div>\n </div>\n }\n />\n {busy && <BusyOverlay label={t(crop.status === \"decoding\" ? \"progress.decoding\" : \"common.saving\")} />}\n {has && (\n <div className=\"absolute right-2 bottom-2 flex gap-2 max-sm:hidden [&_button]:bg-background/80 [&_button]:backdrop-blur-sm\">\n {actions(true)}\n </div>\n )}\n </div>\n <div className=\"flex flex-wrap items-center justify-between gap-x-3 gap-y-1.5\">\n <div className=\"grid min-w-0 gap-0.5 sm:flex sm:flex-1 sm:items-baseline sm:justify-between sm:gap-3\">\n <div className=\"font-medium\">{label}</div>\n <div className=\"text-xs text-muted-foreground sm:truncate\">{hint}</div>\n </div>\n {has && <div className=\"flex gap-2 sm:hidden\">{actions(false)}</div>}\n </div>\n <SlotEditError />\n </div>\n );\n}\n\nfunction BusyOverlay({ round, label }: { round?: boolean; label: string }) {\n return (\n <div role=\"status\" aria-label={label} className={cn(\"absolute inset-0 flex items-center justify-center bg-background/60 backdrop-blur-[1px]\", round && \"rounded-full\")}>\n <HugeiconsIcon icon={Loading03Icon} strokeWidth={2} className=\"size-5 animate-spin text-foreground\" />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"slot-upload.js","names":[],"sources":["../../src/components/slot-upload.tsx"],"sourcesContent":["import { ratio, type AspectRatio } from \"../client/aspect.js\";\nimport { Camera01Icon, CropIcon, Delete02Icon, ImageUpload01Icon, Loading03Icon } from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { cn } from \"cn\";\nimport { useState, type DragEvent, type ReactNode } from \"react\";\nimport type { ContentKitClient } from \"../client/client.js\";\nimport { useMessages } from \"../i18n/context.js\";\nimport type { CropSource } from \"../client/image.js\";\nimport { ContentKitUiRoot } from \"../scope.js\";\nimport type { PublicPreset } from \"../client/public.js\";\nimport type { FileInfo, ReadResult, RefBody } from \"../client/generated/wire.js\";\nimport { presetFor } from \"../client/media/rules.js\";\nimport { useKinds } from \"../react/groups.js\";\nimport { usePresets } from \"../react/public.js\";\nimport { useContentScope } from \"../react/use-resource.js\";\nimport { Button } from \"#ckui/ui/button\";\nimport { SlotEditError, SlotEditor, useSlotEditor } from \"./slot-editor.js\";\nimport { SlotImage } from \"./slot-image.js\";\n\nexport interface SlotUploadProps {\n /** The item that owns the upload; an AvatarUpload's default is the viewer's avatar (the content model's `avatars`), on whichever site holds it. */\n item?: RefBody;\n /** The upload path; default \"avatar\" or \"cover\". */\n path?: string;\n /** The public preset showing it. */\n image?: PublicPreset | null;\n client?: ContentKitClient;\n /** An editor read of the item from the host; otherwise fetched. */\n read?: ReadResult | null;\n /** Called with the processed upload after every save, null after a removal. */\n onChange?: (file: FileInfo | null) => void;\n /** The output's \"W:H\"; default the preset's aspect, else \"1:1\" (avatar) or \"3:1\" (cover). */\n aspect?: AspectRatio;\n /** The narrowest edit the server accepts (the preset's Image.MinWidth). */\n minWidth?: number;\n /** \"reject\" refuses animated images before uploading. */\n animation?: \"reject\";\n /** Crops narrower than this many source pixels get a sharpness warning; default 512 (avatar) or 3000 (cover). */\n targetWidth?: number;\n /** `accept` of the file input. Default \"image/*\". */\n accept?: string;\n disabled?: boolean;\n /** Offers Remove once set; default true for avatars, false for covers. */\n removable?: boolean;\n label?: ReactNode;\n hint?: ReactNode;\n className?: string;\n /** Replaces decodeImage (tests). */\n decode?: (file: File) => Promise<CropSource>;\n}\n\ntype Variant = \"avatar\" | \"cover\";\n\n/** Round 1:1 avatar field: image, label, hint, Change / Edit crop, crop dialog, progress, errors. For custom layouts use SlotEditor. */\nexport function AvatarUpload(p: SlotUploadProps) {\n return <SlotUpload {...p} variant=\"avatar\" />;\n}\n\n/** Wide cover field at the preset's aspect (e.g. 3:1), with drop-to-upload. For custom layouts use SlotEditor. */\nexport function CoverUpload(p: SlotUploadProps) {\n return <SlotUpload {...p} variant=\"cover\" />;\n}\n\nfunction SlotUpload({ variant, ...p }: SlotUploadProps & { variant: Variant }) {\n const path = p.path ?? variant;\n const { presets } = usePresets({ client: p.client });\n const { kinds } = useKinds({ client: p.client });\n const { viewer } = useContentScope(p.client);\n // Another site's avatars: the site forwards their writes, and its presets lack the kind.\n const avatars = variant === \"avatar\" ? kinds?.avatars : undefined;\n const item = p.item ?? (avatars && viewer ? { kind: avatars.kind, id: viewer } : undefined);\n const rule = item && (presetFor(presets, item.kind, path, p.image?.preset) ?? (avatars?.kind === item.kind ? avatars : undefined));\n if (!item) return null;\n return (\n <ContentKitUiRoot className={cn(\"text-sm\", p.className)} data-ckui={variant === \"avatar\" ? \"avatar-upload\" : \"cover-upload\"}>\n <SlotEditor\n item={item}\n path={path}\n image={p.image}\n client={p.client}\n read={p.read}\n onChange={p.onChange}\n aspect={p.aspect || p.image?.aspect || rule?.aspect || (variant === \"avatar\" ? \"1:1\" : \"3:1\")}\n minWidth={p.minWidth}\n animation={p.animation}\n targetWidth={p.targetWidth ?? (variant === \"avatar\" ? 512 : 3000)}\n round={variant === \"avatar\"}\n accept={p.accept}\n disabled={p.disabled}\n removable={p.removable ?? variant === \"avatar\"}\n decode={p.decode}\n >\n <SlotUploadLayout {...p} variant={variant} />\n </SlotEditor>\n </ContentKitUiRoot>\n );\n}\n\nfunction SlotUploadLayout({ variant, ...p }: SlotUploadProps & { variant: Variant }) {\n const { t } = useMessages();\n const s = useSlotEditor();\n const { crop, has, busy, disabled } = s;\n const image = { preset: p.image?.preset ?? variant, aspect: s.image.aspect, renditions: s.image.renditions };\n const [dragging, setDragging] = useState(false);\n const aspect = crop.aspect;\n const target = p.targetWidth ?? (variant === \"avatar\" ? 512 : 3000);\n const onDrop = (e: DragEvent) => {\n e.preventDefault();\n setDragging(false);\n const f = [...e.dataTransfer.files].find((f) => f.type.startsWith(\"image/\")) ?? e.dataTransfer.files[0];\n if (f) s.pick(f);\n };\n\n const hint =\n p.hint ?? (variant === \"avatar\" ? t(\"avatar.hint\", { size: target }) : t(\"cover.hint\", { width: target, height: Math.round(target / (ratio(aspect) ?? 3)) }));\n const label = p.label ?? t(variant === \"avatar\" ? \"avatar.label\" : \"cover.label\");\n\n // overlay: buttons on top of the cover image; otherwise a plain row.\n const actions = (overlay: boolean) => (\n <>\n <Button variant={overlay && has ? \"secondary\" : \"outline\"} size=\"sm\" disabled={disabled} onClick={s.choose} data-ckui=\"change\">\n <HugeiconsIcon icon={busy ? Loading03Icon : Camera01Icon} strokeWidth={2} data-icon=\"inline-start\" className={busy ? \"animate-spin\" : undefined} />\n {has ? t(\"common.change\") : t(\"common.upload\")}\n </Button>\n {has && crop.canRecrop && (\n <Button variant={overlay ? \"secondary\" : \"ghost\"} size=\"sm\" disabled={disabled} onClick={s.recrop} data-ckui=\"edit-crop\">\n <HugeiconsIcon icon={CropIcon} strokeWidth={2} data-icon=\"inline-start\" />\n {t(\"common.editCrop\")}\n </Button>\n )}\n {has && s.removable && (\n <Button variant={overlay ? \"secondary\" : \"ghost\"} size=\"sm\" disabled={disabled} onClick={s.remove} data-ckui=\"remove\">\n <HugeiconsIcon icon={Delete02Icon} strokeWidth={2} data-icon=\"inline-start\" />\n {t(\"common.remove\")}\n </Button>\n )}\n </>\n );\n\n return variant === \"avatar\" ? (\n <div className=\"flex items-center gap-4\">\n <div className=\"relative size-20 shrink-0\">\n <SlotImage image={has ? image : null} round emptyLabel={t(\"avatar.empty\")} className=\"size-full ring-1 ring-foreground/10\" />\n {busy && <BusyOverlay round label={t(crop.status === \"decoding\" ? \"progress.decoding\" : \"common.saving\")} />}\n </div>\n <div className=\"grid min-w-0 gap-1\">\n <div className=\"font-medium\">{label}</div>\n <div className=\"text-xs text-muted-foreground\">{hint}</div>\n <div className=\"mt-1.5 flex flex-wrap gap-2\">{actions(false)}</div>\n <SlotEditError />\n </div>\n </div>\n ) : (\n <div className=\"grid gap-2\">\n <div\n className={cn(\n \"group/cover relative overflow-hidden rounded-xl ring-1 ring-foreground/10 transition-shadow\",\n dragging && \"ring-2 ring-ring\",\n )}\n onDragOver={(e) => {\n e.preventDefault();\n if (!disabled) setDragging(true);\n }}\n onDragLeave={() => setDragging(false)}\n onDrop={onDrop}\n >\n <SlotImage\n image={has ? image : null}\n aspect={aspect}\n className=\"w-full rounded-none\"\n fallback={\n <div aria-label={t(\"cover.empty\")} role=\"group\" className=\"absolute inset-0 flex flex-col items-center justify-center gap-1.5 bg-[repeating-linear-gradient(135deg,transparent_0_10px,color-mix(in_oklch,var(--ckui-foreground)_3%,transparent)_10px_20px)] p-4 text-center\">\n <HugeiconsIcon icon={ImageUpload01Icon} strokeWidth={1.5} className=\"size-7 text-muted-foreground\" />\n <span className=\"hidden text-xs text-muted-foreground sm:block\">{t(\"cover.drop\")}</span>\n <div className=\"mt-1 flex gap-2\">{actions(false)}</div>\n </div>\n }\n />\n {busy && <BusyOverlay label={t(crop.status === \"decoding\" ? \"progress.decoding\" : \"common.saving\")} />}\n {has && (\n <div className=\"absolute right-2 bottom-2 flex gap-2 max-sm:hidden [&_button]:bg-background/80 [&_button]:backdrop-blur-sm\">\n {actions(true)}\n </div>\n )}\n </div>\n <div className=\"flex flex-wrap items-center justify-between gap-x-3 gap-y-1.5\">\n <div className=\"grid min-w-0 gap-0.5 sm:flex sm:flex-1 sm:items-baseline sm:justify-between sm:gap-3\">\n <div className=\"font-medium\">{label}</div>\n <div className=\"text-xs text-muted-foreground sm:truncate\">{hint}</div>\n </div>\n {has && <div className=\"flex gap-2 sm:hidden\">{actions(false)}</div>}\n </div>\n <SlotEditError />\n </div>\n );\n}\n\nfunction BusyOverlay({ round, label }: { round?: boolean; label: string }) {\n return (\n <div role=\"status\" aria-label={label} className={cn(\"absolute inset-0 flex items-center justify-center bg-background/60 backdrop-blur-[1px]\", round && \"rounded-full\")}>\n <HugeiconsIcon icon={Loading03Icon} strokeWidth={2} className=\"size-5 animate-spin text-foreground\" />\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import { useMessages as e } from "../../i18n/context.js";
2
2
  import { ContentKitUiRoot as t } from "../../scope.js";
3
3
  import { useContentKitClient as n } from "../../react/context.js";
4
- import { Alert as r, AlertDescription as i } from "../../ui/alert.js";
5
- import { Button as a } from "../../ui/button.js";
6
- import { Dialog as o, DialogContent as s, DialogDescription as c, DialogFooter as l, DialogHeader as u, DialogTitle as d } from "../../ui/dialog.js";
7
- import { keyOf as f, useContentScope as p, usePaged as m } from "../../react/use-resource.js";
4
+ import { keyOf as r, useContentScope as i, usePaged as a } from "../../react/use-resource.js";
5
+ import { Alert as o, AlertDescription as s } from "../../ui/alert.js";
6
+ import { Button as c } from "../../ui/button.js";
7
+ import { Dialog as l, DialogContent as u, DialogDescription as d, DialogFooter as f, DialogHeader as p, DialogTitle as m } from "../../ui/dialog.js";
8
8
  import { Badge as h } from "../../ui/badge.js";
9
9
  import { Input as g } from "../../ui/input.js";
10
10
  import { Label as _ } from "../../ui/label.js";
@@ -16,20 +16,20 @@ import { jsx as A, jsxs as j } from "react/jsx-runtime";
16
16
  import { cn as M } from "cn";
17
17
  //#region src/components/social/bans.tsx
18
18
  function N({ ban: t, className: n }) {
19
- let a = e(), { t: o } = a;
20
- return /* @__PURE__ */ A(r, {
19
+ let r = e(), { t: i } = r;
20
+ return /* @__PURE__ */ A(o, {
21
21
  variant: "destructive",
22
22
  className: n,
23
23
  "data-ckui": "ban-notice",
24
- children: /* @__PURE__ */ j(i, {
24
+ children: /* @__PURE__ */ j(s, {
25
25
  className: "grid gap-1",
26
26
  children: [
27
27
  /* @__PURE__ */ A("p", {
28
28
  className: "font-medium",
29
- children: o(t.scope === "global" ? "bans.globalNotice" : "bans.ownerNotice")
29
+ children: i(t.scope === "global" ? "bans.globalNotice" : "bans.ownerNotice")
30
30
  }),
31
- t.reason && /* @__PURE__ */ A("p", { children: o("bans.reason", { reason: t.reason }) }),
32
- /* @__PURE__ */ A("p", { children: t.until ? o("bans.until", { date: C(a, t.until) }) : o("bans.untilLifted") })
31
+ t.reason && /* @__PURE__ */ A("p", { children: i("bans.reason", { reason: t.reason }) }),
32
+ /* @__PURE__ */ A("p", { children: t.until ? i("bans.until", { date: C(r, t.until) }) : i("bans.untilLifted") })
33
33
  ]
34
34
  })
35
35
  });
@@ -45,37 +45,37 @@ function I(e) {
45
45
  let t = (e) => String(e).padStart(2, "0");
46
46
  return `${e.getFullYear()}-${t(e.getMonth() + 1)}-${t(e.getDate())}T${t(e.getHours())}:${t(e.getMinutes())}`;
47
47
  }
48
- function L({ open: t, onOpenChange: r, user: i, scopes: f, ban: p, onSaved: m, client: h, onError: y }) {
49
- let { t: x } = e(), S = n(h), C = O(), T = p ? p.scope === "global" ? "global" : "owner" : f[0] ?? "owner", [E, M] = k(T), [N, L] = k(p ? p.until ? "custom" : "forever" : "week"), [R, z] = k(p?.until ? I(new Date(p.until)) : I(new Date(Date.now() + 7 * P))), [B, V] = k(p?.reason ?? ""), { run: H, pending: U, error: W, setError: G } = w("ban.save", y);
48
+ function L({ open: t, onOpenChange: r, user: i, scopes: a, ban: o, onSaved: s, client: h, onError: y }) {
49
+ let { t: x } = e(), S = n(h), C = O(), T = o ? o.scope === "global" ? "global" : "owner" : a[0] ?? "owner", [E, M] = k(T), [N, L] = k(o ? o.until ? "custom" : "forever" : "week"), [R, z] = k(o?.until ? I(new Date(o.until)) : I(new Date(Date.now() + 7 * P))), [B, V] = k(o?.reason ?? ""), { run: H, pending: U, error: W, setError: G } = w("ban.save", y);
50
50
  D(() => {
51
- t && (M(T), L(p ? p.until ? "custom" : "forever" : "week"), z(p?.until ? I(new Date(p.until)) : I(new Date(Date.now() + 7 * P))), V(p?.reason ?? ""), G(null));
51
+ t && (M(T), L(o ? o.until ? "custom" : "forever" : "week"), z(o?.until ? I(new Date(o.until)) : I(new Date(Date.now() + 7 * P))), V(o?.reason ?? ""), G(null));
52
52
  }, [t]);
53
53
  let K = i.name ?? i.id, q = async () => {
54
54
  let e = N === "forever" ? void 0 : N === "custom" ? new Date(R) : new Date(Date.now() + F[N]), t = await H(() => S.bans.ban(E, i.id, {
55
55
  reason: B.trim() || void 0,
56
56
  until: e?.toISOString()
57
57
  }));
58
- t && (m?.(t), r(!1));
58
+ t && (s?.(t), r(!1));
59
59
  };
60
- return /* @__PURE__ */ A(o, {
60
+ return /* @__PURE__ */ A(l, {
61
61
  open: t,
62
62
  onOpenChange: r,
63
- children: /* @__PURE__ */ j(s, {
63
+ children: /* @__PURE__ */ j(u, {
64
64
  "data-ckui": "comment-ban-dialog",
65
- children: [/* @__PURE__ */ j(u, { children: [/* @__PURE__ */ A(d, { children: x("bans.title", { name: K }) }), /* @__PURE__ */ A(c, { children: x(E === "global" ? "bans.globalHelp" : "bans.ownerHelp") })] }), /* @__PURE__ */ j("form", {
65
+ children: [/* @__PURE__ */ j(p, { children: [/* @__PURE__ */ A(m, { children: x("bans.title", { name: K }) }), /* @__PURE__ */ A(d, { children: x(E === "global" ? "bans.globalHelp" : "bans.ownerHelp") })] }), /* @__PURE__ */ j("form", {
66
66
  className: "grid gap-4",
67
67
  onSubmit: (e) => {
68
68
  e.preventDefault(), q();
69
69
  },
70
70
  children: [
71
- f.length > 1 && !p && /* @__PURE__ */ j("fieldset", {
71
+ a.length > 1 && !o && /* @__PURE__ */ j("fieldset", {
72
72
  className: "grid gap-2",
73
73
  children: [/* @__PURE__ */ A("legend", {
74
74
  className: "mb-1 text-sm font-medium",
75
75
  children: x("bans.scope")
76
76
  }), /* @__PURE__ */ A("div", {
77
77
  className: "flex flex-wrap gap-2",
78
- children: f.map((e) => /* @__PURE__ */ A(a, {
78
+ children: a.map((e) => /* @__PURE__ */ A(c, {
79
79
  type: "button",
80
80
  size: "sm",
81
81
  variant: E === e ? "default" : "outline",
@@ -100,7 +100,7 @@ function L({ open: t, onOpenChange: r, user: i, scopes: f, ban: p, onSaved: m, c
100
100
  "month",
101
101
  "forever",
102
102
  "custom"
103
- ].map((e) => /* @__PURE__ */ A(a, {
103
+ ].map((e) => /* @__PURE__ */ A(c, {
104
104
  type: "button",
105
105
  size: "sm",
106
106
  variant: N === e ? "default" : "outline",
@@ -140,33 +140,33 @@ function L({ open: t, onOpenChange: r, user: i, scopes: f, ban: p, onSaved: m, c
140
140
  })]
141
141
  }),
142
142
  /* @__PURE__ */ A(b, { error: W }),
143
- /* @__PURE__ */ j(l, { children: [/* @__PURE__ */ A(a, {
143
+ /* @__PURE__ */ j(f, { children: [/* @__PURE__ */ A(c, {
144
144
  type: "button",
145
145
  variant: "outline",
146
146
  onClick: () => r(!1),
147
147
  children: x("common.cancel")
148
- }), /* @__PURE__ */ A(a, {
148
+ }), /* @__PURE__ */ A(c, {
149
149
  type: "submit",
150
150
  variant: "destructive",
151
151
  disabled: U,
152
- children: x(U ? "common.saving" : p ? "bans.update" : "bans.save")
152
+ children: x(U ? "common.saving" : o ? "bans.update" : "bans.save")
153
153
  })] })
154
154
  ]
155
155
  })]
156
156
  })
157
157
  });
158
158
  }
159
- function R({ scope: n = "global", pageSize: r = 25, page: i, onPageChange: o, userHref: s, client: c, onError: l, className: u, appearance: d }) {
160
- let v = e(), { t: D } = v, { client: N, store: P, scope: F } = p(c), [I, R] = k(1), z = i ?? I, B = (e) => o ? o(e) : R(e), V = m(P, f("bans-page", F, n, r), {
159
+ function R({ scope: n = "global", pageSize: o = 25, page: s, onPageChange: l, userHref: u, client: d, onError: f, className: p, appearance: m }) {
160
+ let v = e(), { t: D } = v, { client: N, store: P, scope: F } = i(d), [I, R] = k(1), z = s ?? I, B = (e) => l ? l(e) : R(e), V = a(P, r("bans-page", F, n, o), {
161
161
  type: "bans",
162
162
  scope: n
163
- }, z, r, async (e, t) => (await N.bans.list(n, e, t)).map((e) => ({
163
+ }, z, o, async (e, t) => (await N.bans.list(n, e, t)).map((e) => ({
164
164
  ...e,
165
165
  id: e.user_id
166
- }))), H = O(), [U, W] = k(null), [G, K] = k(null), [q, J] = k(""), Y = w("ban.lift", l);
166
+ }))), H = O(), [U, W] = k(null), [G, K] = k(null), [q, J] = k(""), Y = w("ban.lift", f);
167
167
  return /* @__PURE__ */ j(t, {
168
- appearance: d,
169
- className: M("grid gap-4 text-sm", u),
168
+ appearance: m,
169
+ className: M("grid gap-4 text-sm", p),
170
170
  "data-ckui": "comment-bans",
171
171
  children: [
172
172
  /* @__PURE__ */ j("form", {
@@ -185,7 +185,7 @@ function R({ scope: n = "global", pageSize: r = 25, page: i, onPageChange: o, us
185
185
  placeholder: D("bans.userPlaceholder"),
186
186
  onChange: (e) => J(e.target.value)
187
187
  })]
188
- }), /* @__PURE__ */ A(a, {
188
+ }), /* @__PURE__ */ A(c, {
189
189
  type: "submit",
190
190
  variant: "outline",
191
191
  disabled: !q.trim(),
@@ -221,7 +221,7 @@ function R({ scope: n = "global", pageSize: r = 25, page: i, onPageChange: o, us
221
221
  children: [/* @__PURE__ */ A(S, {
222
222
  user: e.user,
223
223
  name: t,
224
- href: s
224
+ href: u
225
225
  }), /* @__PURE__ */ A(h, {
226
226
  variant: e.expired ? "outline" : "destructive",
227
227
  children: D(e.expired ? "bans.expired" : "bans.active")
@@ -243,7 +243,7 @@ function R({ scope: n = "global", pageSize: r = 25, page: i, onPageChange: o, us
243
243
  }),
244
244
  /* @__PURE__ */ j("div", {
245
245
  className: "flex gap-2",
246
- children: [/* @__PURE__ */ A(a, {
246
+ children: [/* @__PURE__ */ A(c, {
247
247
  size: "sm",
248
248
  variant: "outline",
249
249
  onClick: () => W({
@@ -254,7 +254,7 @@ function R({ scope: n = "global", pageSize: r = 25, page: i, onPageChange: o, us
254
254
  ban: e
255
255
  }),
256
256
  children: D("bans.update")
257
- }), /* @__PURE__ */ A(a, {
257
+ }), /* @__PURE__ */ A(c, {
258
258
  size: "sm",
259
259
  variant: "destructive",
260
260
  onClick: () => K(e),
@@ -278,7 +278,7 @@ function R({ scope: n = "global", pageSize: r = 25, page: i, onPageChange: o, us
278
278
  scopes: [n],
279
279
  ban: U.ban,
280
280
  client: N,
281
- onError: l,
281
+ onError: f,
282
282
  onSaved: () => J("")
283
283
  }),
284
284
  /* @__PURE__ */ A(y, {