@openrails/contentkit-ui 0.103.2 → 0.104.0-rc.2

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 (253) hide show
  1. package/README.md +111 -49
  2. package/dist/client/beacons.d.ts +3 -13
  3. package/dist/client/beacons.js +8 -46
  4. package/dist/client/beacons.js.map +1 -1
  5. package/dist/client/client.d.ts +3 -0
  6. package/dist/client/client.js +45 -43
  7. package/dist/client/client.js.map +1 -1
  8. package/dist/client/content/favorites.d.ts +2 -0
  9. package/dist/client/content/favorites.js.map +1 -1
  10. package/dist/client/content/types.d.ts +3 -0
  11. package/dist/client/content/types.js.map +1 -1
  12. package/dist/client/contents.d.ts +7 -1
  13. package/dist/client/contents.js +8 -0
  14. package/dist/client/contents.js.map +1 -1
  15. package/dist/client/discovery.d.ts +34 -5
  16. package/dist/client/discovery.js +23 -2
  17. package/dist/client/discovery.js.map +1 -1
  18. package/dist/client/engagement.d.ts +70 -0
  19. package/dist/client/engagement.js +191 -0
  20. package/dist/client/engagement.js.map +1 -0
  21. package/dist/client/generated/routes.d.ts +74 -35
  22. package/dist/client/generated/routes.js +119 -60
  23. package/dist/client/generated/routes.js.map +1 -1
  24. package/dist/client/generated/wire.d.ts +88 -85
  25. package/dist/client/generated/wire.js.map +1 -1
  26. package/dist/client/guest-reading-history.d.ts +40 -0
  27. package/dist/client/guest-reading-history.js +144 -0
  28. package/dist/client/guest-reading-history.js.map +1 -0
  29. package/dist/client/index.d.ts +5 -3
  30. package/dist/client/media/windows.d.ts +2 -0
  31. package/dist/client/media/windows.js +4 -1
  32. package/dist/client/media/windows.js.map +1 -1
  33. package/dist/client/stats.d.ts +4 -20
  34. package/dist/client/stats.js +0 -11
  35. package/dist/client/stats.js.map +1 -1
  36. package/dist/client/versions.d.ts +8 -6
  37. package/dist/client/versions.js +15 -10
  38. package/dist/client/versions.js.map +1 -1
  39. package/dist/client.js +24 -22
  40. package/dist/components/admin/bulk-drafts.d.ts +17 -0
  41. package/dist/components/admin/bulk-drafts.js +41 -0
  42. package/dist/components/admin/bulk-drafts.js.map +1 -0
  43. package/dist/components/admin/content-admin.d.ts +1 -1
  44. package/dist/components/admin/content-admin.js.map +1 -1
  45. package/dist/components/admin/content-manager.d.ts +11 -3
  46. package/dist/components/admin/content-manager.js +751 -394
  47. package/dist/components/admin/content-manager.js.map +1 -1
  48. package/dist/components/admin/group-manager.d.ts +8 -3
  49. package/dist/components/admin/group-manager.js +218 -146
  50. package/dist/components/admin/group-manager.js.map +1 -1
  51. package/dist/components/admin/page-notices.d.ts +16 -0
  52. package/dist/components/admin/page-notices.js +113 -0
  53. package/dist/components/admin/page-notices.js.map +1 -0
  54. package/dist/components/admin/page-picker.d.ts +38 -0
  55. package/dist/components/admin/page-picker.js +159 -0
  56. package/dist/components/admin/page-picker.js.map +1 -0
  57. package/dist/components/admin/quick-search.d.ts +14 -0
  58. package/dist/components/admin/quick-search.js +60 -0
  59. package/dist/components/admin/quick-search.js.map +1 -0
  60. package/dist/components/admin/reader-content-editor.js +382 -321
  61. package/dist/components/admin/reader-content-editor.js.map +1 -1
  62. package/dist/components/admin/reader-manifest.js +181 -179
  63. package/dist/components/admin/reader-manifest.js.map +1 -1
  64. package/dist/components/admin/shell.d.ts +10 -2
  65. package/dist/components/admin/shell.js +114 -42
  66. package/dist/components/admin/shell.js.map +1 -1
  67. package/dist/components/admin/stats-dashboard.d.ts +4 -9
  68. package/dist/components/admin/stats-dashboard.js +303 -207
  69. package/dist/components/admin/stats-dashboard.js.map +1 -1
  70. package/dist/components/admin/upload-queue.d.ts +14 -0
  71. package/dist/components/admin/upload-queue.js +115 -98
  72. package/dist/components/admin/upload-queue.js.map +1 -1
  73. package/dist/components/content/card.d.ts +31 -3
  74. package/dist/components/content/card.js +324 -158
  75. package/dist/components/content/card.js.map +1 -1
  76. package/dist/components/content/daily-releases.js +144 -190
  77. package/dist/components/content/daily-releases.js.map +1 -1
  78. package/dist/components/content/editor-save.js +27 -25
  79. package/dist/components/content/editor-save.js.map +1 -1
  80. package/dist/components/content/editors.js +274 -253
  81. package/dist/components/content/editors.js.map +1 -1
  82. package/dist/components/content/favorites.d.ts +6 -0
  83. package/dist/components/content/favorites.js +47 -0
  84. package/dist/components/content/favorites.js.map +1 -0
  85. package/dist/components/content/filter-dialog.js +19 -15
  86. package/dist/components/content/filter-dialog.js.map +1 -1
  87. package/dist/components/content/filters.d.ts +2 -0
  88. package/dist/components/content/filters.js +5 -1
  89. package/dist/components/content/filters.js.map +1 -1
  90. package/dist/components/content/grid.d.ts +44 -16
  91. package/dist/components/content/grid.js +308 -270
  92. package/dist/components/content/grid.js.map +1 -1
  93. package/dist/components/content/history.d.ts +6 -0
  94. package/dist/components/content/history.js +111 -0
  95. package/dist/components/content/history.js.map +1 -0
  96. package/dist/components/content/index.d.ts +6 -3
  97. package/dist/components/content/listing.d.ts +14 -3
  98. package/dist/components/content/listing.js +65 -56
  99. package/dist/components/content/listing.js.map +1 -1
  100. package/dist/components/content/offer-fields.js +6 -6
  101. package/dist/components/content/paged-grid.d.ts +10 -0
  102. package/dist/components/content/paged-grid.js +116 -0
  103. package/dist/components/content/paged-grid.js.map +1 -0
  104. package/dist/components/content/pagination.d.ts +19 -0
  105. package/dist/components/content/pagination.js +97 -0
  106. package/dist/components/content/pagination.js.map +1 -0
  107. package/dist/components/content/paywall.d.ts +9 -0
  108. package/dist/components/content/paywall.js +27 -3
  109. package/dist/components/content/paywall.js.map +1 -1
  110. package/dist/components/content/post-list.d.ts +37 -0
  111. package/dist/components/content/post-list.js +203 -0
  112. package/dist/components/content/post-list.js.map +1 -0
  113. package/dist/components/content/reader-settings.d.ts +2 -0
  114. package/dist/components/content/reader-settings.js +1 -1
  115. package/dist/components/content/reader-settings.js.map +1 -1
  116. package/dist/components/content/search.d.ts +11 -4
  117. package/dist/components/content/search.js +22 -11
  118. package/dist/components/content/search.js.map +1 -1
  119. package/dist/components/content/summary-tile.d.ts +14 -0
  120. package/dist/components/content/summary-tile.js +63 -0
  121. package/dist/components/content/summary-tile.js.map +1 -0
  122. package/dist/components/groups/banner.d.ts +6 -2
  123. package/dist/components/groups/banner.js +79 -61
  124. package/dist/components/groups/banner.js.map +1 -1
  125. package/dist/components/groups/directory.d.ts +12 -2
  126. package/dist/components/groups/directory.js +168 -105
  127. package/dist/components/groups/directory.js.map +1 -1
  128. package/dist/components/groups/editor.js +10 -10
  129. package/dist/components/groups/editor.js.map +1 -1
  130. package/dist/components/groups/entity-chips.d.ts +61 -0
  131. package/dist/components/groups/entity-chips.js +382 -0
  132. package/dist/components/groups/entity-chips.js.map +1 -0
  133. package/dist/components/groups/group-members.d.ts +29 -0
  134. package/dist/components/groups/group-members.js +474 -0
  135. package/dist/components/groups/group-members.js.map +1 -0
  136. package/dist/components/groups/header.js +53 -45
  137. package/dist/components/groups/header.js.map +1 -1
  138. package/dist/components/groups/index.d.ts +3 -1
  139. package/dist/components/groups/memberships.d.ts +3 -36
  140. package/dist/components/groups/memberships.js +105 -480
  141. package/dist/components/groups/memberships.js.map +1 -1
  142. package/dist/components/groups/scoped.d.ts +23 -0
  143. package/dist/components/groups/scoped.js +92 -0
  144. package/dist/components/groups/scoped.js.map +1 -0
  145. package/dist/components/media-folder-editor.d.ts +5 -0
  146. package/dist/components/media-folder-editor.js +419 -231
  147. package/dist/components/media-folder-editor.js.map +1 -1
  148. package/dist/components/sortable-list.d.ts +5 -1
  149. package/dist/components/sortable-list.js +97 -81
  150. package/dist/components/sortable-list.js.map +1 -1
  151. package/dist/components/video-mini-player.d.ts +4 -1
  152. package/dist/components/video-mini-player.js +77 -71
  153. package/dist/components/video-mini-player.js.map +1 -1
  154. package/dist/components/video-player.d.ts +4 -1
  155. package/dist/components/video-player.js +280 -276
  156. package/dist/components/video-player.js.map +1 -1
  157. package/dist/index.d.ts +2 -1
  158. package/dist/index.js +41 -34
  159. package/dist/locales/admin/de.js +80 -47
  160. package/dist/locales/admin/de.js.map +1 -1
  161. package/dist/locales/admin/en.d.ts +74 -41
  162. package/dist/locales/admin/en.js +80 -47
  163. package/dist/locales/admin/en.js.map +1 -1
  164. package/dist/locales/admin/es.js +80 -47
  165. package/dist/locales/admin/es.js.map +1 -1
  166. package/dist/locales/admin/ja.js +80 -47
  167. package/dist/locales/admin/ja.js.map +1 -1
  168. package/dist/locales/admin/ko.js +80 -47
  169. package/dist/locales/admin/ko.js.map +1 -1
  170. package/dist/locales/admin/zh.js +80 -47
  171. package/dist/locales/admin/zh.js.map +1 -1
  172. package/dist/locales/de.js +1 -0
  173. package/dist/locales/de.js.map +1 -1
  174. package/dist/locales/discovery/de.js +25 -2
  175. package/dist/locales/discovery/de.js.map +1 -1
  176. package/dist/locales/discovery/en.d.ts +24 -1
  177. package/dist/locales/discovery/en.js +25 -2
  178. package/dist/locales/discovery/en.js.map +1 -1
  179. package/dist/locales/discovery/es.js +25 -2
  180. package/dist/locales/discovery/es.js.map +1 -1
  181. package/dist/locales/discovery/ja.js +25 -2
  182. package/dist/locales/discovery/ja.js.map +1 -1
  183. package/dist/locales/discovery/ko.js +25 -2
  184. package/dist/locales/discovery/ko.js.map +1 -1
  185. package/dist/locales/discovery/zh.js +25 -2
  186. package/dist/locales/discovery/zh.js.map +1 -1
  187. package/dist/locales/en.d.ts +119 -44
  188. package/dist/locales/en.js +1 -0
  189. package/dist/locales/en.js.map +1 -1
  190. package/dist/locales/es.js +1 -0
  191. package/dist/locales/es.js.map +1 -1
  192. package/dist/locales/groups/de.js +22 -4
  193. package/dist/locales/groups/de.js.map +1 -1
  194. package/dist/locales/groups/en.d.ts +20 -2
  195. package/dist/locales/groups/en.js +22 -4
  196. package/dist/locales/groups/en.js.map +1 -1
  197. package/dist/locales/groups/es.js +22 -4
  198. package/dist/locales/groups/es.js.map +1 -1
  199. package/dist/locales/groups/ja.js +22 -4
  200. package/dist/locales/groups/ja.js.map +1 -1
  201. package/dist/locales/groups/ko.js +22 -4
  202. package/dist/locales/groups/ko.js.map +1 -1
  203. package/dist/locales/groups/zh.js +22 -4
  204. package/dist/locales/groups/zh.js.map +1 -1
  205. package/dist/locales/ja.js +1 -0
  206. package/dist/locales/ja.js.map +1 -1
  207. package/dist/locales/ko.js +1 -0
  208. package/dist/locales/ko.js.map +1 -1
  209. package/dist/locales/zh.js +1 -0
  210. package/dist/locales/zh.js.map +1 -1
  211. package/dist/react/discovery.d.ts +36 -17
  212. package/dist/react/discovery.js +305 -221
  213. package/dist/react/discovery.js.map +1 -1
  214. package/dist/react/groups.d.ts +19 -3
  215. package/dist/react/groups.js +49 -22
  216. package/dist/react/groups.js.map +1 -1
  217. package/dist/react/index.d.ts +7 -4
  218. package/dist/react/page-notices.d.ts +13 -0
  219. package/dist/react/page-notices.js +38 -0
  220. package/dist/react/page-notices.js.map +1 -0
  221. package/dist/react/post-reads.d.ts +23 -0
  222. package/dist/react/post-reads.js +90 -0
  223. package/dist/react/post-reads.js.map +1 -0
  224. package/dist/react/remembered-sort.d.ts +5 -0
  225. package/dist/react/remembered-sort.js +29 -0
  226. package/dist/react/remembered-sort.js.map +1 -0
  227. package/dist/react/resources.d.ts +3 -1
  228. package/dist/react/resources.js +6 -2
  229. package/dist/react/resources.js.map +1 -1
  230. package/dist/react/stats.d.ts +3 -7
  231. package/dist/react/stats.js +2 -6
  232. package/dist/react/stats.js.map +1 -1
  233. package/dist/react/use-engagement.d.ts +28 -0
  234. package/dist/react/use-engagement.js +226 -0
  235. package/dist/react/use-engagement.js.map +1 -0
  236. package/dist/react/use-resource.d.ts +4 -3
  237. package/dist/react/use-resource.js +2 -1
  238. package/dist/react/use-resource.js.map +1 -1
  239. package/dist/react.js +29 -26
  240. package/dist/styles.css +1 -1
  241. package/dist/ui/dialog.d.ts +2 -1
  242. package/dist/ui/dialog.js +23 -20
  243. package/dist/ui/dialog.js.map +1 -1
  244. package/dist/urls/index.d.ts +1 -1
  245. package/dist/urls.js +2 -2
  246. package/dist/urls.js.map +1 -1
  247. package/package.json +1 -1
  248. package/dist/components/admin/page-review.d.ts +0 -13
  249. package/dist/components/admin/page-review.js +0 -225
  250. package/dist/components/admin/page-review.js.map +0 -1
  251. package/dist/react/page-review.d.ts +0 -14
  252. package/dist/react/page-review.js +0 -37
  253. package/dist/react/page-review.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"editors.js","names":[],"sources":["../../../src/components/content/editors.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useCallback, useEffect, useId, useMemo, useRef, useState, type ReactNode, type SetStateAction } from \"react\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport { fromLocalInput, parseAttributes, toLocalInput } from \"../../client/group-fields.js\";\nimport type { Content, ContentModel, Listing, Rule, Segment, Version } from \"../../client/generated/wire.js\";\nimport { useLanguageName, useMessages } from \"../../i18n/context.js\";\nimport { useContentKitClient, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useKinds } from \"../../react/groups.js\";\nimport { useMediaRead } from \"../../react/read.js\";\nimport { usePresets } from \"../../react/public.js\";\nimport { useContentScope } from \"../../react/use-resource.js\";\nimport { Badge } from \"#ckui/ui/badge\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Input } from \"#ckui/ui/input\";\nimport { Label } from \"#ckui/ui/label\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"#ckui/ui/select\";\nimport { Switch } from \"#ckui/ui/switch\";\nimport { ReaderManifestEditor } from \"../admin/reader-manifest.js\";\nimport { PageReview } from \"../admin/page-review.js\";\nimport { VideoMediaEditor, videoPaths } from \"../admin/media-item-panel.js\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { MediaFolderEditor } from \"../media-folder-editor.js\";\nimport { SortableList } from \"../sortable-list.js\";\nimport { ErrorLine, useAction } from \"../social/parts.js\";\nimport { GroupPicker, labelOf, useGroupNames, type Labels } from \"../groups/parts.js\";\nimport { AttributeFields, formOf } from \"../groups/fields.js\";\nimport { MembershipEditor } from \"../groups/memberships.js\";\nimport { useDraft } from \"../../react/use-draft.js\";\nimport { useEditorSaveTask, readerMediaReady } from \"./editor-save.js\";\nimport { OfferFields } from \"./offer-fields.js\";\n\ninterface Common {\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n labels?: Labels;\n}\n\nconst NONE = \"__none__\";\nconst LISTINGS: readonly Listing[] = [\"listed\", \"members\", \"unlisted\"];\nconst COMMENTS = [\"open\", \"closed\", \"hidden\"] as const;\ntype Comments = (typeof COMMENTS)[number];\nconst LEVELS: readonly Rule[\"level\"][] = [\"public\", \"tier\", \"ppv\", \"group\", \"group_ppv\"];\nconst grouped = (l: Rule[\"level\"]) => l === \"group\" || l === \"group_ppv\";\n\nfunction Section({ title, ckui, children }: { title: ReactNode; ckui: string; children: ReactNode }) {\n return (\n <section className=\"grid gap-3 border-t border-border pt-4\" data-ckui={ckui}>\n <h3 className=\"font-medium\">{title}</h3>\n {children}\n </section>\n );\n}\n\nfunction Saved({ show }: { show: boolean }) {\n const { t } = useMessages();\n return show ? (\n <span role=\"status\" className=\"text-muted-foreground\">\n {t(\"contentEditor.saved\")}\n </span>\n ) : null;\n}\n\n/** The content model's kind, when it loaded. */\nfunction useKind(kind: string, client?: ContentKitClient): { model: ContentModel | null; spec: ContentModel[\"kinds\"][string] | undefined } {\n const { kinds } = useKinds({ client });\n return { model: kinds, spec: kinds?.kinds[kind] };\n}\n\n\nfunction useEditorKey(id: string, client: ContentKitClient, scope: string) {\n const [identity, setIdentity] = useState({ id, client, scope, key: 0 });\n if (identity.id !== id || identity.client !== client || identity.scope !== scope) {\n const next = { id, client, scope, key: identity.key + 1 };\n setIdentity(next);\n return next.key;\n }\n return identity.key;\n}\n\nfunction useEditorReload(content: Content, own?: ContentKitClient) {\n const { client, store, scope, language } = useContentScope(own);\n const mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => { mounted.current = false; };\n }, []);\n return async () => {\n const fresh = await client.contents.get(content.id, language ?? content.language);\n let latest = fresh;\n if (mounted.current) store.patch<Content | null>(\n (tag) => tag.type === \"content\" && tag.id === content.id && (tag.readScope ?? \"{}\") === scope,\n (current) => {\n if (current && current.revision > latest.revision) latest = current;\n return latest;\n },\n );\n return latest;\n };\n}\n\n/** Listing and the kind's declared attributes. */\nexport function ContentDetailsEditor(p: Common & { content: Content }) {\n const { client, scope } = useContentScope(p.client);\n const key = useEditorKey(p.content.id, client, scope);\n return <ContentDetailsForm key={key} {...p} client={client} />;\n}\n\nfunction ContentDetailsForm({ content, ...p }: Common & { content: Content }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const { spec } = useKind(content.kind, p.client);\n const declared = useMemo(() => spec?.attributes ?? {}, [spec]);\n const fields = useDraft(useMemo(() => ({ listing: content.listing, comments: content.comments }), [content.listing, content.comments]));\n const attrs = useDraft(useMemo(() => formOf(declared, content.attributes), [declared, content.attributes]));\n const { listing, comments } = fields.value;\n const reload = useEditorReload(content, p.client);\n const [invalid, setInvalid] = useState<string | null>(null);\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n return (\n <Section title={t(\"contentEditor.details\")} ckui=\"content-details\">\n <form\n className=\"grid gap-3\"\n onSubmit={(e) => {\n e.preventDefault();\n setInvalid(null);\n setSaved(false);\n let attributes: Record<string, unknown>;\n try {\n attributes = parseAttributes(declared, attrs.value);\n } catch (err) {\n return setInvalid((err as Error).message);\n }\n const settleFields = fields.checkpoint(), settleAttrs = attrs.checkpoint();\n void save.run(() => client.contents.update(content.id, { listing, comments, attributes, revision: content.revision })).then((d) => {\n if (!d) return;\n const cleanFields = settleFields({ listing: d.listing, comments: d.comments });\n const cleanAttrs = settleAttrs(formOf(declared, d.attributes));\n setSaved(cleanFields && cleanAttrs);\n });\n }}\n >\n <div className=\"grid gap-1.5 sm:max-w-xs\">\n <Label>{t(\"contentEditor.listing\")}</Label>\n <Select value={listing} onValueChange={(v) => { fields.edit((f) => ({ ...f, listing: v as Listing })); setSaved(false); }}>\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.listing\")}>\n <SelectValue>{(v: string) => t(`contentEditor.listing_${v as Listing}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {LISTINGS.map((l) => (\n <SelectItem key={l} value={l}>\n {t(`contentEditor.listing_${l}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5 sm:max-w-xs\">\n <Label>{t(\"contentEditor.comments\")}</Label>\n <Select value={comments} onValueChange={(v) => { fields.edit((f) => ({ ...f, comments: v as Comments })); setSaved(false); }}>\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.comments\")}>\n <SelectValue>{(v: string) => t(`contentEditor.comments_${v as Comments}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {COMMENTS.map((c) => (\n <SelectItem key={c} value={c}>\n {t(`contentEditor.comments_${c}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <AttributeFields declared={declared} form={attrs.value} onChange={(n, v) => { attrs.edit((a) => ({ ...a, [n]: v })); setSaved(false); }} labels={p.labels} />\n {invalid && <ErrorLine>{invalid}</ErrorLine>}\n <ErrorLine error={save.error} />\n <div className=\"flex items-center gap-3\">\n <Button type=\"submit\" size=\"sm\" disabled={save.pending}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" disabled={save.pending} onClick={() => {\n const settleFields = fields.checkpoint(), settleAttrs = attrs.checkpoint();\n void save.run(reload).then((d) => {\n if (!d) return;\n settleFields({ listing: d.listing, comments: d.comments });\n settleAttrs(formOf(declared, d.attributes));\n setInvalid(null);\n setSaved(false);\n });\n }}>{t(\"common.cancel\")}</Button>\n <Saved show={saved} />\n </div>\n </form>\n </Section>\n );\n}\n\n/** A rule's form: level, tiers, group (the content's owner group by default), the preview its kind has and when it turns free. */\nexport function RuleFields({ value, onChange, model, kind, owner, labels, client }: { value: Rule; onChange: (r: Rule) => void; model: ContentModel | null; kind: string; owner?: string; labels?: Labels; client: ContentKitClient }) {\n const { t } = useMessages();\n const id = useId();\n const tiers = model?.tiers ?? [];\n const spec = model?.kinds[kind];\n const groupKinds = Object.entries(model?.entity_kinds ?? {})\n .filter(([, g]) => g.sellable || g.auth_scope)\n .map(([k]) => k);\n // Picked once the model has loaded: its first group kind until one is chosen.\n const [chosenKind, setGroupKind] = useState<string>();\n const groupKind = chosenKind ?? groupKinds[0] ?? \"\";\n const named = useGroupNames(value.group_id ? [value.group_id] : [], { client });\n const group = value.group_id ? named.get(value.group_id) : undefined;\n const set = (patch: Partial<Rule>) => onChange({ ...value, ...patch });\n const pages = spec?.presentation === \"reader\";\n const segments = !!spec?.segments;\n return (\n <div className=\"grid gap-3\" data-ckui=\"rule-fields\">\n <div className=\"grid gap-1.5 sm:max-w-xs\">\n <Label>{t(\"contentEditor.access\")}</Label>\n <Select\n value={value.level}\n onValueChange={(v) => {\n const level = v as Rule[\"level\"];\n onChange({ level, group_id: grouped(level) ? value.group_id || owner : undefined, preview: value.preview, free_after: value.free_after });\n }}\n >\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.access\")}>\n <SelectValue>{(v: string) => t(`contentEditor.level_${v as Rule[\"level\"]}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {LEVELS.filter((l) => (l !== \"tier\" || tiers.length) && (!l.startsWith(\"group\") || groupKinds.length)).map((l) => (\n <SelectItem key={l} value={l}>\n {t(`contentEditor.level_${l}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {value.level === \"tier\" && (\n <fieldset className=\"flex flex-wrap gap-3\">\n <legend className=\"sr-only\">{t(\"contentEditor.tiers\")}</legend>\n {tiers.map((tier) => (\n <label key={tier} className=\"flex items-center gap-2\">\n <Switch\n checked={value.tiers?.includes(tier) ?? false}\n onCheckedChange={(on) => set({ tiers: on ? [...(value.tiers ?? []), tier] : (value.tiers ?? []).filter((x) => x !== tier) })}\n aria-label={labelOf(labels, tier)}\n />\n {labelOf(labels, tier)}\n </label>\n ))}\n </fieldset>\n )}\n {grouped(value.level) && (\n <div className=\"flex flex-wrap items-end gap-2\">\n {group || value.group_id ? (\n <span className=\"rounded-md border border-border px-2 py-0.5\" data-ckui=\"rule-group\">\n {group ? group.name || group.slug : value.group_id}\n </span>\n ) : null}\n {groupKinds.length > 1 && (\n <Select value={groupKind} onValueChange={(v) => setGroupKind(String(v))}>\n <SelectTrigger size=\"sm\" aria-label={t(\"groupEditor.edgeKind\")}>\n <SelectValue>{(v: string) => labelOf(labels, v)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {groupKinds.map((k) => (\n <SelectItem key={k} value={k}>\n {labelOf(labels, k)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n {groupKind && <GroupPicker key={groupKind} kind={groupKind} label={t(\"contentEditor.group\")} client={client} onPick={(g) => set({ group_id: g.id })} />}\n </div>\n )}\n {value.level !== \"public\" && (\n <div className=\"grid gap-3 sm:grid-cols-3\">\n {pages && (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-pages`}>{t(\"contentEditor.previewPages\")}</Label>\n <Input\n id={`${id}-pages`}\n className=\"h-8\"\n type=\"number\"\n min={0}\n value={value.preview?.pages ?? \"\"}\n onChange={(e) => set({ preview: { ...value.preview, pages: e.target.value ? Math.max(0, Math.trunc(Number(e.target.value))) : undefined } })}\n />\n </div>\n )}\n {segments && (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-segments`}>{t(\"contentEditor.previewSegments\")}</Label>\n <Input\n id={`${id}-segments`}\n className=\"h-8\"\n type=\"number\"\n min={0}\n value={value.preview?.segments ?? \"\"}\n onChange={(e) => set({ preview: { ...value.preview, segments: e.target.value ? Math.max(0, Math.trunc(Number(e.target.value))) : undefined } })}\n />\n </div>\n )}\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-free`}>{t(\"contentEditor.freeAfter\")}</Label>\n <Input id={`${id}-free`} className=\"h-8\" type=\"datetime-local\" value={toLocalInput(value.free_after)} onChange={(e) => set({ free_after: fromLocalInput(e.target.value) })} />\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/** A rule the server takes: a group level names its group. */\nexport const complete = (r: Rule) => !grouped(r.level) || !!r.group_id;\n\n/** A rule as stored: empty previews and absent fields left out. */\nexport function cleanRule(r: Rule): Rule {\n const preview = r.preview && (r.preview.pages || r.preview.segments) ? { pages: r.preview.pages || undefined, segments: r.preview.segments || undefined } : undefined;\n return {\n level: r.level,\n tiers: r.level === \"tier\" ? r.tiers : undefined,\n group_id: r.level === \"group\" || r.level === \"group_ppv\" ? r.group_id : undefined,\n preview: r.level === \"public\" ? undefined : preview,\n free_after: r.level === \"public\" ? undefined : r.free_after,\n };\n}\n\n/** Who may open the content and what it sells for. */\nexport function AccessEditor(p: Common & { content: Content }) {\n const { client, scope } = useContentScope(p.client);\n const key = useEditorKey(p.content.id, client, scope);\n return <AccessForm key={key} {...p} client={client} />;\n}\n\nfunction AccessForm({ content, ...p }: Common & { content: Content }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const { model } = useKind(content.kind, p.client);\n const rule = useDraft(content.access);\n const reload = useEditorReload(content, p.client);\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n const offer = useAction(\"offer.save\", p.onError);\n return (\n <Section title={t(\"contentEditor.accessTitle\")} ckui=\"access-editor\">\n <form\n className=\"grid gap-3\"\n onSubmit={(e) => {\n e.preventDefault();\n setSaved(false);\n const settle = rule.checkpoint();\n void save.run(() => client.contents.update(content.id, { access: cleanRule(rule.value), revision: content.revision })).then((d) => d && setSaved(settle(d.access)));\n }}\n >\n <RuleFields value={rule.value} onChange={(r) => { rule.edit(r); setSaved(false); }} model={model} kind={content.kind} owner={content.owner_group_id} labels={p.labels} client={client} />\n <ErrorLine error={save.error} />\n <div className=\"flex items-center gap-3\">\n <Button type=\"submit\" size=\"sm\" disabled={save.pending || !complete(rule.value)}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" disabled={save.pending} onClick={() => {\n const settle = rule.checkpoint();\n void save.run(reload).then((d) => {\n if (!d) return;\n settle(d.access);\n setSaved(false);\n });\n }}>{t(\"common.cancel\")}</Button>\n <Saved show={saved} />\n </div>\n </form>\n <OfferFields\n offer={content.offer}\n pending={offer.pending}\n onSell={(terms) => offer.run(() => client.offers.sell({ content: content.id }, terms))}\n onWithdraw={() => void offer.run(() => client.offers.withdraw({ content: content.id }))}\n />\n <ErrorLine error={offer.error} />\n </Section>\n );\n}\n\n/** A version's name in the editor: its label, else its languages and traits. */\nexport function versionLabel(v: Version, languageName: (l: string) => string, labels?: Labels): string {\n return v.label || [...v.languages.map(languageName), ...v.traits.map((x) => labelOf(labels, x))].join(\" · \");\n}\n\n/**\n * A content's versions: order, languages, traits, label, state and\n * schedule, an access override and its own offer, segments (chapters) and\n * the version's media folder; add and delete. A kind whose one version is\n * hidden shows only that version's segments and media.\n */\nexport function VersionsEditor({ content, media = true, activeVersion, ...p }: Common & { content: Content; media?: boolean; activeVersion?: string }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const languageName = useLanguageName();\n const { model, spec } = useKind(content.kind, p.client);\n const order = useAction(\"content.save\", p.onError);\n const add = useAction(\"content.save\", p.onError);\n const [open, setOpen] = useState<string | null>(null);\n const [opened, setOpened] = useState<string[]>([]);\n const reveal = (id: string) => { setOpen(id); setOpened((ids) => ids.includes(id) ? ids : [...ids,id]); };\n useEffect(() => { if (activeVersion) { setOpen(activeVersion); setOpened((ids)=>ids.includes(activeVersion)?ids:[...ids,activeVersion]); } }, [activeVersion]);\n useEditorSaveTask(`versions:${content.id}`, {label:t(\"contentEditor.versions\"),dirty:false,pending:order.pending||add.pending,valid:true,save:async()=>true});\n const versions = useMemo(() => [...content.versions].sort((a, b) => a.position - b.position), [content.versions]);\n if (!spec) return null;\n if (spec.versions.hidden) {\n const only = versions[0];\n if (!only || (!media && !spec.segments)) return null;\n return (\n <Section title={t(\"contentEditor.media\")} ckui=\"version-media\">\n {spec.segments && <SegmentsEditor content={content} version={only} {...p} />}\n {media && <VersionMedia content={content} version={only} model={model} {...p} />}\n </Section>\n );\n }\n const languages = model?.languages ?? [];\n return (\n <Section title={t(\"contentEditor.versions\")} ckui=\"versions-editor\">\n <SortableList\n items={versions}\n id={(v) => v.id}\n name={(v) => versionLabel(v, languageName, p.labels)}\n label={t(\"contentEditor.versions\")}\n disabled={order.pending || versions.length < 2}\n onMove={(from, to) => {\n const ids = versions.map((v) => v.id);\n const [moved] = ids.splice(from, 1);\n ids.splice(to, 0, moved!);\n void order.run(() => client.contents.orderVersions(content.id, ids));\n }}\n >\n {(v, handle) => (\n <div className=\"grid gap-2 rounded-md border border-border p-2\" data-ckui=\"version-row\" data-version={v.id}>\n <div className=\"flex flex-wrap items-center gap-2\">\n {versions.length > 1 && handle}\n <span className=\"min-w-0 flex-1 font-medium break-words\">{versionLabel(v, languageName, p.labels)}</span>\n <Badge variant={v.live ? \"default\" : \"outline\"}>{t(v.live ? \"contentEditor.live\" : v.state === \"draft\" ? \"contentManager.draft\" : \"contentManager.scheduled\")}</Badge>\n {v.access && <Badge variant=\"secondary\">{t(`contentEditor.level_${v.access.level}`)}</Badge>}\n {v.pages ? <span className=\"text-xs text-muted-foreground\">{t(\"contentEditor.pageCount\", { count: v.pages })}</span> : null}\n <Button type=\"button\" size=\"xs\" variant=\"ghost\" aria-expanded={open === v.id} onClick={() => open === v.id ? setOpen(null) : reveal(v.id)}>\n {t(open === v.id ? \"contentEditor.close\" : \"contentEditor.edit\")}\n </Button>\n </div>\n {opened.includes(v.id) && <div hidden={open !== v.id}><VersionForm content={content} version={v} model={model} media={media} {...p} /></div>}\n </div>\n )}\n </SortableList>\n <ErrorLine error={order.error} />\n <AddVersion\n languages={languages}\n many={spec?.versions.languages === \"many\"}\n pending={add.pending}\n // A new version is a draft: open it for its media.\n onAdd={(input) => void add.run(() => client.contents.addVersion(content.id, input)).then((v) => v && reveal(v.id))}\n />\n <ErrorLine error={add.error} />\n </Section>\n );\n}\n\nfunction LanguageFields({ languages, value, many, onChange }: { languages: readonly string[]; value: readonly string[]; many: boolean; onChange: (v: string[]) => void }) {\n const { t } = useMessages();\n const languageName = useLanguageName();\n if (!many)\n return (\n <Select value={value[0] ?? NONE} onValueChange={(v) => onChange(v === NONE ? [] : [String(v)])}>\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.versionLanguage\")}>\n <SelectValue>{(v: string) => (v === NONE ? t(\"contentEditor.chooseLanguage\") : languageName(v))}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {languages.map((l) => (\n <SelectItem key={l} value={l}>\n {languageName(l)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n return (\n <fieldset className=\"flex flex-wrap gap-3\">\n <legend className=\"sr-only\">{t(\"contentEditor.versionLanguages\")}</legend>\n {languages.map((l) => (\n <label key={l} className=\"flex items-center gap-1.5\">\n <Switch size=\"sm\" checked={value.includes(l)} onCheckedChange={(on) => onChange(on ? [...value, l] : value.filter((x) => x !== l))} aria-label={languageName(l)} />\n {languageName(l)}\n </label>\n ))}\n </fieldset>\n );\n}\n\nfunction AddVersion({ languages, many, pending, onAdd }: { languages: readonly string[]; many: boolean; pending: boolean; onAdd: (v: { languages: string[] }) => void }) {\n const { t } = useMessages();\n const [langs, setLangs] = useState<string[]>([]);\n return (\n <div className=\"flex flex-wrap items-center gap-2\" data-ckui=\"add-version\">\n <LanguageFields languages={languages} value={langs} many={many} onChange={setLangs} />\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={pending || !langs.length}\n onClick={() => {\n onAdd({ languages: langs });\n setLangs([]);\n }}\n >\n {t(\"contentEditor.addVersion\")}\n </Button>\n </div>\n );\n}\n\nfunction VersionForm({ content, version: v, model, media, ...p }: Common & { content: Content; version: Version; model: ContentModel | null; media: boolean }) {\n const { t } = useMessages();\n const id = useId();\n const client = useContentKitClient(p.client);\n const spec = model?.kinds[content.kind];\n const seed = useCallback((v: Version) => ({langs:v.languages,traits:v.traits,label:v.label??\"\",draft:v.state===\"draft\",at:toLocalInput(v.publish_at),own:!!v.access,rule:v.access??content.access}),[content.access]);\n const fields = useDraft(useMemo(()=>seed(v),[seed,v]));\n const {langs,traits,label,draft,at,own,rule}=fields.value;\n const edit=(patch:Partial<typeof fields.value>)=>{fields.edit((old)=>({...old,...patch}));setSaved(false);};\n const [invalid,setInvalid]=useState<string|null>(null);\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n const remove = useAction(\"content.save\", p.onError);\n const offer = useAction(\"offer.save\", p.onError);\n const valid=langs.length>0&&(!own||complete(rule));\n const submit=async()=>{\n if(!valid)return false;\n setInvalid(null);setSaved(false);\n if(spec?.presentation===\"reader\"&&v.state===\"draft\"&&!draft&&!(await readerMediaReady(client,{kind:content.kind,id:content.id,version:v.id}))){setInvalid(t(\"readerEditor.filesNotReady\"));return false;}\n const settle=fields.checkpoint();\n const out=await save.run(()=>client.contents.updateVersion(content.id,v.id,{languages:langs,traits,label:label.trim(),state:draft?\"draft\":\"published\",publish_at:fromLocalInput(at),...(own?{access:cleanRule(rule)}:{clear_access:!!v.access})}));\n if(!out)return false;\n const clean=settle(seed(out));setSaved(clean);return clean;\n };\n useEditorSaveTask(`version:${v.id}`,{label:t(\"contentEditor.versions\"),dirty:fields.dirty.length>0,pending:save.pending||remove.pending,valid,save:submit,order:10});\n return (\n <div className=\"grid gap-4 pt-2\">\n <form className=\"grid gap-3\" onSubmit={(event)=>{event.preventDefault();void submit();}}>\n <LanguageFields languages={model?.languages ?? []} value={langs} many={spec?.versions.languages === \"many\"} onChange={(langs)=>edit({langs})} />\n {!!spec?.versions.traits?.length && (\n <fieldset className=\"flex flex-wrap gap-3\">\n <legend className=\"sr-only\">{t(\"contentEditor.traits\")}</legend>\n {spec.versions.traits.map((x) => (\n <label key={x} className=\"flex items-center gap-1.5\">\n <Switch size=\"sm\" checked={traits.includes(x)} onCheckedChange={(on) => edit({traits:on ? [...traits, x] : traits.filter((y) => y !== x)})} aria-label={labelOf(p.labels, x)} />\n {labelOf(p.labels, x)}\n </label>\n ))}\n </fieldset>\n )}\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-label`}>{t(\"contentEditor.versionLabel\")}</Label>\n <Input id={`${id}-label`} className=\"h-8\" value={label} onChange={(e)=>edit({label:e.target.value})} />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-at`}>{t(\"contentEditor.versionPublishAt\")}</Label>\n <Input id={`${id}-at`} className=\"h-8\" type=\"datetime-local\" value={at} onChange={(e)=>edit({at:e.target.value})} />\n </div>\n </div>\n <label className=\"flex items-center gap-2\">\n <Switch size=\"sm\" checked={draft} onCheckedChange={(draft)=>edit({draft})} />\n {t(\"contentEditor.versionDraft\")}\n </label>\n <label className=\"flex items-center gap-2\">\n <Switch size=\"sm\" checked={own} onCheckedChange={(own)=>edit({own})} />\n {t(\"contentEditor.ownAccess\")}\n </label>\n {own && <RuleFields value={rule} onChange={(rule)=>edit({rule})} model={model} kind={content.kind} owner={content.owner_group_id} labels={p.labels} client={client} />}\n {invalid&&<ErrorLine>{invalid}</ErrorLine>}\n <ErrorLine error={save.error} />\n <div className=\"flex flex-wrap items-center gap-3\">\n <Button type=\"submit\" size=\"sm\" disabled={save.pending || !langs.length || (own && !complete(rule))}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Saved show={saved} />\n <Button type=\"button\" size=\"sm\" variant=\"destructive\" className=\"ms-auto\" disabled={remove.pending} onClick={() => void remove.run(() => client.contents.removeVersion(content.id, v.id))}>\n {t(\"contentEditor.deleteVersion\")}\n </Button>\n </div>\n <ErrorLine error={remove.error} />\n </form>\n <OfferFields\n offer={v.offer}\n pending={offer.pending}\n onSell={(terms) => offer.run(() => client.offers.sell({ content: content.id, version: v.id }, terms))}\n onWithdraw={() => void offer.run(() => client.offers.withdraw({ content: content.id, version: v.id }))}\n />\n <ErrorLine error={offer.error} />\n {spec?.segments && <SegmentsEditor content={content} version={v} {...p} />}\n {media && <VersionCover content={content} version={v} {...p} />}\n {media && <VersionMedia content={content} version={v} model={model} {...p} />}\n {media && spec?.presentation === \"reader\" && <ReaderManifestEditor content={content.id} version={v.id} client={p.client} onError={p.onError} />}\n </div>\n );\n}\n\n/**\n * A version's own cover, where its kind has covers: the cover upload its\n * editors selected, else its first. Versions share no files.\n */\nexport function VersionCover({ content, version: v, ...p }: Common & { content: Content; version: Version }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const { presets } = usePresets({ client });\n const save = useAction(\"content.save\", p.onError);\n const input = useRef<HTMLInputElement>(null);\n const [fresh, setFresh] = useState<string | null>(null);\n useEffect(() => () => void (fresh && URL.revokeObjectURL(fresh)), [fresh]);\n if (!presets.some((r) => r.kind === content.kind && r.name === \"cover\")) return null;\n const src = fresh ?? v.cover?.url;\n const pick = (file: File | null) =>\n void save.run(async () => {\n if (!file) {\n setFresh(null);\n return client.contents.setCover(content.id, v.id, null);\n }\n const ref = { kind: content.kind, id: content.id, version: v.id };\n const up = await client.media.uploadNamed(ref, file, { path: await client.media.presetPath(content.kind, \"cover\", file) });\n const saved = await client.contents.setCover(content.id, v.id, up.name);\n if (typeof URL.createObjectURL === \"function\") setFresh(URL.createObjectURL(file));\n return saved;\n });\n return (\n <div className=\"grid gap-1.5\" data-ckui=\"version-cover\">\n <span className=\"text-sm font-medium\">{t(\"contentManager.cover\")}</span>\n <div className=\"flex flex-wrap items-center gap-3\">\n {src ? <img src={src} alt=\"\" className=\"h-20 w-36 rounded-md border border-border object-cover\" /> : <span className=\"text-muted-foreground\">{t(\"contentManager.noCover\")}</span>}\n <Button type=\"button\" size=\"sm\" variant=\"outline\" disabled={save.pending} onClick={() => input.current?.click()}>\n {t(src ? \"pollEditor.replaceImage\" : \"contentManager.addCover\")}\n </Button>\n {v.cover?.image && (\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" disabled={save.pending} onClick={() => pick(null)}>\n {t(\"pollEditor.removeImage\")}\n </Button>\n )}\n <input\n ref={input}\n type=\"file\"\n accept=\"image/*\"\n hidden\n aria-label={t(\"contentManager.cover\")}\n onChange={(e) => {\n const f = e.target.files?.[0];\n e.target.value = \"\";\n if (f) pick(f);\n }}\n />\n </div>\n <ErrorLine error={save.error} />\n </div>\n );\n}\n\n/**\n * A version's media: a video kind's source, poster and subtitles (by its\n * upload rules), else its upload folders. Uploads to a version that is not\n * live are added as they finish; a live one's wait for \"Add\".\n */\nfunction VersionMedia({ content, version, model, ...p }: Common & { content: Content; version: Version; model: ContentModel | null }) {\n const { t } = useMessages();\n const languageName = useLanguageName();\n const item = useMemo(() => ({ kind: content.kind, id: content.id, version: version.id }), [content.kind, content.id, version.id]);\n const r = useMediaRead(item, { editor: true, client: p.client });\n const languages = useMemo(() => (model?.languages ?? []).map((l) => ({ value: l, label: languageName(l) })), [model, languageName]);\n if (!r.read && r.loading) return <Skeleton className=\"h-24 w-full\" />;\n if (r.read?.uploads && videoPaths(r.read.uploads).source) return <VideoMediaEditor item={item} languages={languages} client={p.client} onError={p.onError} />;\n return <>\n <MediaFolderEditor item={item} commit={version.live ? \"manual\" : \"auto\"} label={t(\"contentEditor.media\")} client={p.client} onError={p.onError} />\n {model?.kinds[content.kind]?.presentation === \"reader\" && <PageReview content={content.id} version={version.id} client={p.client} onError={p.onError} />}\n </>;\n}\n\ntype Row = { title: string; start: string; end: string; release: string };\nconst segmentRows=(version:Version):Row[]=>version.segments.map((s)=>({title:s.title??\"\",start:String(s.start),end:String(s.end),release:toLocalInput(s.release_at)}));\n\n/** A version's segments (chapters): page ranges with titles and release times. */\nexport function SegmentsEditor({ content, version, ...p }: Common & { content: Content; version: Version }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const fields=useDraft(useMemo(()=>({rows:segmentRows(version)}),[version]));\n const rows=fields.value.rows;\n const setRows=(next:SetStateAction<Row[]>)=>fields.edit((old)=>({rows:typeof next===\"function\"?next(old.rows):next}));\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n const set = (i: number, patch: Partial<Row>) => {\n setSaved(false);\n setRows((r) => r.map((x, j) => (j === i ? { ...x, ...patch } : x)));\n };\n const valid = rows.every((r) => /^\\d+$/.test(r.start) && /^\\d+$/.test(r.end) && Number(r.end) > Number(r.start));\n const submit=async()=>{\n if(!valid)return false;\n setSaved(false);const settle=fields.checkpoint();\n const segments:Segment[]=rows.map((r,i)=>({position:i+1,title:r.title.trim()||undefined,start:Number(r.start),end:Number(r.end),release_at:fromLocalInput(r.release),released:false}));\n const out=await save.run(()=>client.contents.setSegments(content.id,version.id,segments));\n if(!out)return false;const clean=settle({rows:segmentRows(out)});setSaved(clean);return clean;\n };\n useEditorSaveTask(`segments:${version.id}`,{label:t(\"contentEditor.segments\"),dirty:fields.dirty.length>0,pending:save.pending,valid,save:submit,order:20});\n return (\n <div className=\"grid gap-2\" data-ckui=\"segments-editor\">\n <h4 className=\"text-sm font-medium\">{t(\"contentEditor.segments\")}</h4>\n {rows.length === 0 && <p className=\"text-muted-foreground\">{t(\"contentEditor.noSegments\")}</p>}\n {rows.map((r, i) => (\n <div key={i} className=\"flex flex-wrap items-center gap-2\" data-ckui=\"segment-row\">\n <span className=\"w-6 text-xs text-muted-foreground tabular-nums\">{i + 1}</span>\n <Input className=\"h-8 w-40\" aria-label={t(\"contentEditor.segmentTitle\", { n: i + 1 })} placeholder={t(\"contentEditor.segmentTitlePlaceholder\")} value={r.title} onChange={(e) => set(i, { title: e.target.value })} />\n <Input className=\"h-8 w-20\" type=\"number\" min={0} aria-label={t(\"contentEditor.segmentStart\", { n: i + 1 })} value={r.start} onChange={(e) => set(i, { start: e.target.value })} />\n <span aria-hidden>–</span>\n <Input className=\"h-8 w-20\" type=\"number\" min={1} aria-label={t(\"contentEditor.segmentEnd\", { n: i + 1 })} value={r.end} onChange={(e) => set(i, { end: e.target.value })} />\n <Input className=\"h-8 w-48\" type=\"datetime-local\" aria-label={t(\"contentEditor.segmentRelease\", { n: i + 1 })} value={r.release} onChange={(e) => set(i, { release: e.target.value })} />\n <Button type=\"button\" size=\"xs\" variant=\"ghost\" onClick={() => setRows((x) => x.filter((_, j) => j !== i))}>\n {t(\"common.remove\")}\n </Button>\n </div>\n ))}\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n const last = rows.at(-1);\n const start = last ? Number(last.end) || 0 : 0;\n setRows((x) => [...x, { title: \"\", start: String(start), end: String(start + 1), release: \"\" }]);\n }}\n >\n {t(\"contentEditor.addSegment\")}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n disabled={save.pending || !valid}\n onClick={()=>void submit()}\n >\n {t(\"contentEditor.saveSegments\")}\n </Button>\n <Saved show={saved} />\n </div>\n <ErrorLine error={save.error} />\n </div>\n );\n}\n\n/** Every editor section of an existing content: details, access and price, versions, groups. */\nexport function ContentSections({ content, ...p }: Common & { content: Content; media?: boolean; className?: string; management?: boolean }) {\n const languageName = useLanguageName();\n const versions = useMemo(() => content.versions.map((v) => ({ id: v.id, label: versionLabel(v, languageName, p.labels) })), [content.versions, languageName, p.labels]);\n const { spec } = useKind(content.kind, p.client);\n return (\n <div className={cn(\"grid gap-6\", p.className)} data-ckui=\"content-sections\">\n <ContentDetailsEditor content={content} {...p} />\n <AccessEditor content={content} {...p} />\n <VersionsEditor content={content} {...p} />\n {!!spec?.entities?.length && (\n <section className=\"grid gap-3 border-t border-border pt-4\" data-ckui=\"content-groups\">\n <MembershipEditor management={p.management} content={content.id} contentKind={content.kind} versions={spec.versions.hidden ? undefined : versions} labels={p.labels} client={p.client} onError={p.onError} />\n </section>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"editors.js","names":[],"sources":["../../../src/components/content/editors.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useCallback, useEffect, useId, useMemo, useRef, useState, type ReactNode, type SetStateAction } from \"react\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport { fromLocalInput, parseAttributes, toLocalInput } from \"../../client/group-fields.js\";\nimport type { Content, ContentModel, Listing, Rule, Segment, Version } from \"../../client/generated/wire.js\";\nimport { useLanguageName, useMessages } from \"../../i18n/context.js\";\nimport { useContentKitClient, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useKinds } from \"../../react/groups.js\";\nimport { useMediaRead } from \"../../react/read.js\";\nimport { usePresets } from \"../../react/public.js\";\nimport { useContentScope } from \"../../react/use-resource.js\";\nimport { Badge } from \"#ckui/ui/badge\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Input } from \"#ckui/ui/input\";\nimport { Label } from \"#ckui/ui/label\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"#ckui/ui/select\";\nimport { Switch } from \"#ckui/ui/switch\";\nimport { ReaderManifestEditor } from \"../admin/reader-manifest.js\";\nimport { PageNotices } from \"../admin/page-notices.js\";\nimport { PagePicker, usePlanMedia } from \"../admin/page-picker.js\";\nimport { useReaderPlan } from \"../../react/versions.js\";\nimport { VideoMediaEditor, videoPaths } from \"../admin/media-item-panel.js\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { MediaFolderEditor } from \"../media-folder-editor.js\";\nimport { SortableList } from \"../sortable-list.js\";\nimport { ErrorLine, useAction } from \"../social/parts.js\";\nimport { GroupPicker, labelOf, useGroupNames, type Labels } from \"../groups/parts.js\";\nimport { AttributeFields, formOf } from \"../groups/fields.js\";\nimport { MembershipEditor } from \"../groups/memberships.js\";\nimport { useDraft } from \"../../react/use-draft.js\";\nimport { useEditorSaveTask, readerMediaReady } from \"./editor-save.js\";\nimport { OfferFields } from \"./offer-fields.js\";\n\ninterface Common {\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n labels?: Labels;\n}\n\nconst NONE = \"__none__\";\nconst LISTINGS: readonly Listing[] = [\"listed\", \"members\", \"unlisted\"];\nconst COMMENTS = [\"open\", \"closed\", \"hidden\"] as const;\ntype Comments = (typeof COMMENTS)[number];\nconst LEVELS: readonly Rule[\"level\"][] = [\"public\", \"tier\", \"ppv\", \"group\", \"group_ppv\"];\nconst grouped = (l: Rule[\"level\"]) => l === \"group\" || l === \"group_ppv\";\n\nfunction Section({ title, ckui, children }: { title: ReactNode; ckui: string; children: ReactNode }) {\n return (\n <section className=\"grid gap-3 border-t border-border pt-4\" data-ckui={ckui}>\n <h3 className=\"font-medium\">{title}</h3>\n {children}\n </section>\n );\n}\n\nfunction Saved({ show }: { show: boolean }) {\n const { t } = useMessages();\n return show ? (\n <span role=\"status\" className=\"text-muted-foreground\">\n {t(\"contentEditor.saved\")}\n </span>\n ) : null;\n}\n\n/** The content model's kind, when it loaded. */\nfunction useKind(kind: string, client?: ContentKitClient): { model: ContentModel | null; spec: ContentModel[\"kinds\"][string] | undefined } {\n const { kinds } = useKinds({ client });\n return { model: kinds, spec: kinds?.kinds[kind] };\n}\n\n\nfunction useEditorKey(id: string, client: ContentKitClient, scope: string) {\n const [identity, setIdentity] = useState({ id, client, scope, key: 0 });\n if (identity.id !== id || identity.client !== client || identity.scope !== scope) {\n const next = { id, client, scope, key: identity.key + 1 };\n setIdentity(next);\n return next.key;\n }\n return identity.key;\n}\n\nfunction useEditorReload(content: Content, own?: ContentKitClient) {\n const { client, store, scope, language } = useContentScope(own);\n const mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => { mounted.current = false; };\n }, []);\n return async () => {\n const fresh = await client.contents.get(content.id, language ?? content.language);\n let latest = fresh;\n if (mounted.current) store.patch<Content | null>(\n (tag) => tag.type === \"content\" && tag.id === content.id && (tag.readScope ?? \"{}\") === scope,\n (current) => {\n if (current && current.revision > latest.revision) latest = current;\n return latest;\n },\n );\n return latest;\n };\n}\n\n/** Listing and the kind's declared attributes. */\nexport function ContentDetailsEditor(p: Common & { content: Content }) {\n const { client, scope } = useContentScope(p.client);\n const key = useEditorKey(p.content.id, client, scope);\n return <ContentDetailsForm key={key} {...p} client={client} />;\n}\n\nfunction ContentDetailsForm({ content, ...p }: Common & { content: Content }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const { spec } = useKind(content.kind, p.client);\n const declared = useMemo(() => spec?.attributes ?? {}, [spec]);\n const fields = useDraft(useMemo(() => ({ listing: content.listing, comments: content.comments }), [content.listing, content.comments]));\n const attrs = useDraft(useMemo(() => formOf(declared, content.attributes), [declared, content.attributes]));\n const { listing, comments } = fields.value;\n const reload = useEditorReload(content, p.client);\n const [invalid, setInvalid] = useState<string | null>(null);\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n return (\n <Section title={t(\"contentEditor.details\")} ckui=\"content-details\">\n <form\n className=\"grid gap-3\"\n onSubmit={(e) => {\n e.preventDefault();\n setInvalid(null);\n setSaved(false);\n let attributes: Record<string, unknown>;\n try {\n attributes = parseAttributes(declared, attrs.value);\n } catch (err) {\n return setInvalid((err as Error).message);\n }\n const settleFields = fields.checkpoint(), settleAttrs = attrs.checkpoint();\n void save.run(() => client.contents.update(content.id, { listing, comments, attributes, revision: content.revision })).then((d) => {\n if (!d) return;\n const cleanFields = settleFields({ listing: d.listing, comments: d.comments });\n const cleanAttrs = settleAttrs(formOf(declared, d.attributes));\n setSaved(cleanFields && cleanAttrs);\n });\n }}\n >\n <div className=\"grid gap-1.5 sm:max-w-xs\">\n <Label>{t(\"contentEditor.listing\")}</Label>\n <Select value={listing} onValueChange={(v) => { fields.edit((f) => ({ ...f, listing: v as Listing })); setSaved(false); }}>\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.listing\")}>\n <SelectValue>{(v: string) => t(`contentEditor.listing_${v as Listing}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {LISTINGS.map((l) => (\n <SelectItem key={l} value={l}>\n {t(`contentEditor.listing_${l}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5 sm:max-w-xs\">\n <Label>{t(\"contentEditor.comments\")}</Label>\n <Select value={comments} onValueChange={(v) => { fields.edit((f) => ({ ...f, comments: v as Comments })); setSaved(false); }}>\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.comments\")}>\n <SelectValue>{(v: string) => t(`contentEditor.comments_${v as Comments}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {COMMENTS.map((c) => (\n <SelectItem key={c} value={c}>\n {t(`contentEditor.comments_${c}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <AttributeFields declared={declared} form={attrs.value} onChange={(n, v) => { attrs.edit((a) => ({ ...a, [n]: v })); setSaved(false); }} labels={p.labels} />\n {invalid && <ErrorLine>{invalid}</ErrorLine>}\n <ErrorLine error={save.error} />\n <div className=\"flex items-center gap-3\">\n <Button type=\"submit\" size=\"sm\" disabled={save.pending}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" disabled={save.pending} onClick={() => {\n const settleFields = fields.checkpoint(), settleAttrs = attrs.checkpoint();\n void save.run(reload).then((d) => {\n if (!d) return;\n settleFields({ listing: d.listing, comments: d.comments });\n settleAttrs(formOf(declared, d.attributes));\n setInvalid(null);\n setSaved(false);\n });\n }}>{t(\"common.cancel\")}</Button>\n <Saved show={saved} />\n </div>\n </form>\n </Section>\n );\n}\n\n/** A rule's form: level, tiers, group (the content's owner group by default), the preview its kind has and when it turns free. */\nexport function RuleFields({ value, onChange, model, kind, owner, labels, client }: { value: Rule; onChange: (r: Rule) => void; model: ContentModel | null; kind: string; owner?: string; labels?: Labels; client: ContentKitClient }) {\n const { t } = useMessages();\n const id = useId();\n const tiers = model?.tiers ?? [];\n const spec = model?.kinds[kind];\n const groupKinds = Object.entries(model?.entity_kinds ?? {})\n .filter(([, g]) => g.sellable || g.auth_scope)\n .map(([k]) => k);\n // Picked once the model has loaded: its first group kind until one is chosen.\n const [chosenKind, setGroupKind] = useState<string>();\n const groupKind = chosenKind ?? groupKinds[0] ?? \"\";\n const named = useGroupNames(value.group_id ? [value.group_id] : [], { client });\n const group = value.group_id ? named.get(value.group_id) : undefined;\n const set = (patch: Partial<Rule>) => onChange({ ...value, ...patch });\n const pages = spec?.presentation === \"reader\";\n const segments = !!spec?.segments;\n return (\n <div className=\"grid gap-3\" data-ckui=\"rule-fields\">\n <div className=\"grid gap-1.5 sm:max-w-xs\">\n <Label>{t(\"contentEditor.access\")}</Label>\n <Select\n value={value.level}\n onValueChange={(v) => {\n const level = v as Rule[\"level\"];\n onChange({ level, group_id: grouped(level) ? value.group_id || owner : undefined, preview: value.preview, free_after: value.free_after });\n }}\n >\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.access\")}>\n <SelectValue>{(v: string) => t(`contentEditor.level_${v as Rule[\"level\"]}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {LEVELS.filter((l) => (l !== \"tier\" || tiers.length) && (!l.startsWith(\"group\") || groupKinds.length)).map((l) => (\n <SelectItem key={l} value={l}>\n {t(`contentEditor.level_${l}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {value.level === \"tier\" && (\n <fieldset className=\"flex flex-wrap gap-3\">\n <legend className=\"sr-only\">{t(\"contentEditor.tiers\")}</legend>\n {tiers.map((tier) => (\n <label key={tier} className=\"flex items-center gap-2\">\n <Switch\n checked={value.tiers?.includes(tier) ?? false}\n onCheckedChange={(on) => set({ tiers: on ? [...(value.tiers ?? []), tier] : (value.tiers ?? []).filter((x) => x !== tier) })}\n aria-label={labelOf(labels, tier)}\n />\n {labelOf(labels, tier)}\n </label>\n ))}\n </fieldset>\n )}\n {grouped(value.level) && (\n <div className=\"flex flex-wrap items-end gap-2\">\n {group || value.group_id ? (\n <span className=\"rounded-md border border-border px-2 py-0.5\" data-ckui=\"rule-group\">\n {group ? group.name || group.slug : value.group_id}\n </span>\n ) : null}\n {groupKinds.length > 1 && (\n <Select value={groupKind} onValueChange={(v) => setGroupKind(String(v))}>\n <SelectTrigger size=\"sm\" aria-label={t(\"groupEditor.edgeKind\")}>\n <SelectValue>{(v: string) => labelOf(labels, v)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {groupKinds.map((k) => (\n <SelectItem key={k} value={k}>\n {labelOf(labels, k)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n {groupKind && <GroupPicker key={groupKind} kind={groupKind} label={t(\"contentEditor.group\")} client={client} onPick={(g) => set({ group_id: g.id })} />}\n </div>\n )}\n {value.level !== \"public\" && (\n <div className=\"grid gap-3 sm:grid-cols-3\">\n {pages && (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-pages`}>{t(\"contentEditor.previewPages\")}</Label>\n <Input\n id={`${id}-pages`}\n className=\"h-8\"\n type=\"number\"\n min={0}\n value={value.preview?.pages ?? \"\"}\n onChange={(e) => set({ preview: { ...value.preview, pages: e.target.value ? Math.max(0, Math.trunc(Number(e.target.value))) : undefined } })}\n />\n </div>\n )}\n {segments && (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-segments`}>{t(\"contentEditor.previewSegments\")}</Label>\n <Input\n id={`${id}-segments`}\n className=\"h-8\"\n type=\"number\"\n min={0}\n value={value.preview?.segments ?? \"\"}\n onChange={(e) => set({ preview: { ...value.preview, segments: e.target.value ? Math.max(0, Math.trunc(Number(e.target.value))) : undefined } })}\n />\n </div>\n )}\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-free`}>{t(\"contentEditor.freeAfter\")}</Label>\n <Input id={`${id}-free`} className=\"h-8\" type=\"datetime-local\" value={toLocalInput(value.free_after)} onChange={(e) => set({ free_after: fromLocalInput(e.target.value) })} />\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/** A rule the server takes: a group level names its group. */\nexport const complete = (r: Rule) => !grouped(r.level) || !!r.group_id;\n\n/** A rule as stored: empty previews and absent fields left out. */\nexport function cleanRule(r: Rule): Rule {\n const preview = r.preview && (r.preview.pages || r.preview.segments) ? { pages: r.preview.pages || undefined, segments: r.preview.segments || undefined } : undefined;\n return {\n level: r.level,\n tiers: r.level === \"tier\" ? r.tiers : undefined,\n group_id: r.level === \"group\" || r.level === \"group_ppv\" ? r.group_id : undefined,\n preview: r.level === \"public\" ? undefined : preview,\n free_after: r.level === \"public\" ? undefined : r.free_after,\n };\n}\n\n/** Who may open the content and what it sells for. */\nexport function AccessEditor(p: Common & { content: Content }) {\n const { client, scope } = useContentScope(p.client);\n const key = useEditorKey(p.content.id, client, scope);\n return <AccessForm key={key} {...p} client={client} />;\n}\n\nfunction AccessForm({ content, ...p }: Common & { content: Content }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const { model } = useKind(content.kind, p.client);\n const rule = useDraft(content.access);\n const reload = useEditorReload(content, p.client);\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n const offer = useAction(\"offer.save\", p.onError);\n return (\n <Section title={t(\"contentEditor.accessTitle\")} ckui=\"access-editor\">\n <form\n className=\"grid gap-3\"\n onSubmit={(e) => {\n e.preventDefault();\n setSaved(false);\n const settle = rule.checkpoint();\n void save.run(() => client.contents.update(content.id, { access: cleanRule(rule.value), revision: content.revision })).then((d) => d && setSaved(settle(d.access)));\n }}\n >\n <RuleFields value={rule.value} onChange={(r) => { rule.edit(r); setSaved(false); }} model={model} kind={content.kind} owner={content.owner_group_id} labels={p.labels} client={client} />\n <ErrorLine error={save.error} />\n <div className=\"flex items-center gap-3\">\n <Button type=\"submit\" size=\"sm\" disabled={save.pending || !complete(rule.value)}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" disabled={save.pending} onClick={() => {\n const settle = rule.checkpoint();\n void save.run(reload).then((d) => {\n if (!d) return;\n settle(d.access);\n setSaved(false);\n });\n }}>{t(\"common.cancel\")}</Button>\n <Saved show={saved} />\n </div>\n </form>\n <OfferFields\n offer={content.offer}\n pending={offer.pending}\n onSell={(terms) => offer.run(() => client.offers.sell({ content: content.id }, terms))}\n onWithdraw={() => void offer.run(() => client.offers.withdraw({ content: content.id }))}\n />\n <ErrorLine error={offer.error} />\n </Section>\n );\n}\n\n/** A version's name in the editor: its label, else its languages and traits. */\nexport function versionLabel(v: Version, languageName: (l: string) => string, labels?: Labels): string {\n return v.label || [...v.languages.map(languageName), ...v.traits.map((x) => labelOf(labels, x))].join(\" · \");\n}\n\n/**\n * A content's versions: order, languages, traits, label, state and\n * schedule, an access override and its own offer, segments (chapters) and\n * the version's media folder; add and delete. A kind whose one version is\n * hidden shows only that version's segments and media.\n */\nexport function VersionsEditor({ content, media = true, activeVersion, ...p }: Common & { content: Content; media?: boolean; activeVersion?: string }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const languageName = useLanguageName();\n const { model, spec } = useKind(content.kind, p.client);\n const order = useAction(\"content.save\", p.onError);\n const add = useAction(\"content.save\", p.onError);\n const [open, setOpen] = useState<string | null>(null);\n const [opened, setOpened] = useState<string[]>([]);\n const reveal = (id: string) => { setOpen(id); setOpened((ids) => ids.includes(id) ? ids : [...ids,id]); };\n useEffect(() => { if (activeVersion) { setOpen(activeVersion); setOpened((ids)=>ids.includes(activeVersion)?ids:[...ids,activeVersion]); } }, [activeVersion]);\n useEditorSaveTask(`versions:${content.id}`, {label:t(\"contentEditor.versions\"),dirty:false,pending:order.pending||add.pending,valid:true,save:async()=>true});\n const versions = useMemo(() => [...content.versions].sort((a, b) => a.position - b.position), [content.versions]);\n if (!spec) return null;\n if (spec.versions.hidden) {\n const only = versions[0];\n if (!only || (!media && !spec.segments)) return null;\n return (\n <Section title={t(\"contentEditor.media\")} ckui=\"version-media\">\n {spec.segments && <SegmentsEditor content={content} version={only} {...p} />}\n {media && <VersionMedia content={content} version={only} model={model} {...p} />}\n </Section>\n );\n }\n const languages = model?.languages ?? [];\n return (\n <Section title={t(\"contentEditor.versions\")} ckui=\"versions-editor\">\n <SortableList\n items={versions}\n id={(v) => v.id}\n name={(v) => versionLabel(v, languageName, p.labels)}\n label={t(\"contentEditor.versions\")}\n disabled={order.pending || versions.length < 2}\n onMove={(from, to) => {\n const ids = versions.map((v) => v.id);\n const [moved] = ids.splice(from, 1);\n ids.splice(to, 0, moved!);\n void order.run(() => client.contents.orderVersions(content.id, ids));\n }}\n >\n {(v, handle) => (\n <div className=\"grid gap-2 rounded-md border border-border p-2\" data-ckui=\"version-row\" data-version={v.id}>\n <div className=\"flex flex-wrap items-center gap-2\">\n {versions.length > 1 && handle}\n <span className=\"min-w-0 flex-1 font-medium break-words\">{versionLabel(v, languageName, p.labels)}</span>\n <Badge variant={v.live ? \"default\" : \"outline\"}>{t(v.live ? \"contentEditor.live\" : v.state === \"draft\" ? \"contentManager.draft\" : \"contentManager.scheduled\")}</Badge>\n {v.access && <Badge variant=\"secondary\">{t(`contentEditor.level_${v.access.level}`)}</Badge>}\n {v.pages ? <span className=\"text-xs text-muted-foreground\">{t(\"contentEditor.pageCount\", { count: v.pages })}</span> : null}\n <Button type=\"button\" size=\"xs\" variant=\"ghost\" aria-expanded={open === v.id} onClick={() => open === v.id ? setOpen(null) : reveal(v.id)}>\n {t(open === v.id ? \"contentEditor.close\" : \"contentEditor.edit\")}\n </Button>\n </div>\n {opened.includes(v.id) && <div hidden={open !== v.id}><VersionForm content={content} version={v} model={model} media={media} {...p} /></div>}\n </div>\n )}\n </SortableList>\n <ErrorLine error={order.error} />\n <AddVersion\n languages={languages}\n many={spec?.versions.languages === \"many\"}\n pending={add.pending}\n // A new version is a draft: open it for its media.\n onAdd={(input) => void add.run(() => client.contents.addVersion(content.id, input)).then((v) => v && reveal(v.id))}\n />\n <ErrorLine error={add.error} />\n </Section>\n );\n}\n\nfunction LanguageFields({ languages, value, many, onChange }: { languages: readonly string[]; value: readonly string[]; many: boolean; onChange: (v: string[]) => void }) {\n const { t } = useMessages();\n const languageName = useLanguageName();\n if (!many)\n return (\n <Select value={value[0] ?? NONE} onValueChange={(v) => onChange(v === NONE ? [] : [String(v)])}>\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.versionLanguage\")}>\n <SelectValue>{(v: string) => (v === NONE ? t(\"contentEditor.chooseLanguage\") : languageName(v))}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {languages.map((l) => (\n <SelectItem key={l} value={l}>\n {languageName(l)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n return (\n <fieldset className=\"flex flex-wrap gap-3\">\n <legend className=\"sr-only\">{t(\"contentEditor.versionLanguages\")}</legend>\n {languages.map((l) => (\n <label key={l} className=\"flex items-center gap-1.5\">\n <Switch size=\"sm\" checked={value.includes(l)} onCheckedChange={(on) => onChange(on ? [...value, l] : value.filter((x) => x !== l))} aria-label={languageName(l)} />\n {languageName(l)}\n </label>\n ))}\n </fieldset>\n );\n}\n\nfunction AddVersion({ languages, many, pending, onAdd }: { languages: readonly string[]; many: boolean; pending: boolean; onAdd: (v: { languages: string[] }) => void }) {\n const { t } = useMessages();\n const [langs, setLangs] = useState<string[]>([]);\n return (\n <div className=\"flex flex-wrap items-center gap-2\" data-ckui=\"add-version\">\n <LanguageFields languages={languages} value={langs} many={many} onChange={setLangs} />\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={pending || !langs.length}\n onClick={() => {\n onAdd({ languages: langs });\n setLangs([]);\n }}\n >\n {t(\"contentEditor.addVersion\")}\n </Button>\n </div>\n );\n}\n\nfunction VersionForm({ content, version: v, model, media, ...p }: Common & { content: Content; version: Version; model: ContentModel | null; media: boolean }) {\n const { t } = useMessages();\n const id = useId();\n const client = useContentKitClient(p.client);\n const spec = model?.kinds[content.kind];\n const seed = useCallback((v: Version) => ({langs:v.languages,traits:v.traits,label:v.label??\"\",draft:v.state===\"draft\",at:toLocalInput(v.publish_at),own:!!v.access,rule:v.access??content.access}),[content.access]);\n const fields = useDraft(useMemo(()=>seed(v),[seed,v]));\n const {langs,traits,label,draft,at,own,rule}=fields.value;\n const edit=(patch:Partial<typeof fields.value>)=>{fields.edit((old)=>({...old,...patch}));setSaved(false);};\n const [invalid,setInvalid]=useState<string|null>(null);\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n const remove = useAction(\"content.save\", p.onError);\n const offer = useAction(\"offer.save\", p.onError);\n const valid=langs.length>0&&(!own||complete(rule));\n const submit=async()=>{\n if(!valid)return false;\n setInvalid(null);setSaved(false);\n if(spec?.presentation===\"reader\"&&v.state===\"draft\"&&!draft&&!(await readerMediaReady(client,{kind:content.kind,id:content.id,version:v.id}))){setInvalid(t(\"readerEditor.filesNotReady\"));return false;}\n const settle=fields.checkpoint();\n const out=await save.run(()=>client.contents.updateVersion(content.id,v.id,{languages:langs,traits,label:label.trim(),state:draft?\"draft\":\"published\",publish_at:fromLocalInput(at),...(own?{access:cleanRule(rule)}:{clear_access:!!v.access})}));\n if(!out)return false;\n const clean=settle(seed(out));setSaved(clean);return clean;\n };\n useEditorSaveTask(`version:${v.id}`,{label:t(\"contentEditor.versions\"),dirty:fields.dirty.length>0,pending:save.pending||remove.pending,valid,save:submit,order:10});\n return (\n <div className=\"grid gap-4 pt-2\">\n <form className=\"grid gap-3\" onSubmit={(event)=>{event.preventDefault();void submit();}}>\n <LanguageFields languages={model?.languages ?? []} value={langs} many={spec?.versions.languages === \"many\"} onChange={(langs)=>edit({langs})} />\n {!!spec?.versions.traits?.length && (\n <fieldset className=\"flex flex-wrap gap-3\">\n <legend className=\"sr-only\">{t(\"contentEditor.traits\")}</legend>\n {spec.versions.traits.map((x) => (\n <label key={x} className=\"flex items-center gap-1.5\">\n <Switch size=\"sm\" checked={traits.includes(x)} onCheckedChange={(on) => edit({traits:on ? [...traits, x] : traits.filter((y) => y !== x)})} aria-label={labelOf(p.labels, x)} />\n {labelOf(p.labels, x)}\n </label>\n ))}\n </fieldset>\n )}\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-label`}>{t(\"contentEditor.versionLabel\")}</Label>\n <Input id={`${id}-label`} className=\"h-8\" value={label} onChange={(e)=>edit({label:e.target.value})} />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-at`}>{t(\"contentEditor.versionPublishAt\")}</Label>\n <Input id={`${id}-at`} className=\"h-8\" type=\"datetime-local\" value={at} onChange={(e)=>edit({at:e.target.value})} />\n </div>\n </div>\n <label className=\"flex items-center gap-2\">\n <Switch size=\"sm\" checked={draft} onCheckedChange={(draft)=>edit({draft})} />\n {t(\"contentEditor.versionDraft\")}\n </label>\n <label className=\"flex items-center gap-2\">\n <Switch size=\"sm\" checked={own} onCheckedChange={(own)=>edit({own})} />\n {t(\"contentEditor.ownAccess\")}\n </label>\n {own && <RuleFields value={rule} onChange={(rule)=>edit({rule})} model={model} kind={content.kind} owner={content.owner_group_id} labels={p.labels} client={client} />}\n {invalid&&<ErrorLine>{invalid}</ErrorLine>}\n <ErrorLine error={save.error} />\n <div className=\"flex flex-wrap items-center gap-3\">\n <Button type=\"submit\" size=\"sm\" disabled={save.pending || !langs.length || (own && !complete(rule))}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Saved show={saved} />\n <Button type=\"button\" size=\"sm\" variant=\"destructive\" className=\"ms-auto\" disabled={remove.pending} onClick={() => void remove.run(() => client.contents.removeVersion(content.id, v.id))}>\n {t(\"contentEditor.deleteVersion\")}\n </Button>\n </div>\n <ErrorLine error={remove.error} />\n </form>\n <OfferFields\n offer={v.offer}\n pending={offer.pending}\n onSell={(terms) => offer.run(() => client.offers.sell({ content: content.id, version: v.id }, terms))}\n onWithdraw={() => void offer.run(() => client.offers.withdraw({ content: content.id, version: v.id }))}\n />\n <ErrorLine error={offer.error} />\n {spec?.segments && <SegmentsEditor content={content} version={v} {...p} />}\n {media && <VersionCover content={content} version={v} {...p} />}\n {media && <VersionMedia content={content} version={v} model={model} {...p} />}\n {media && spec?.presentation === \"reader\" && <ReaderManifestEditor content={content.id} version={v.id} client={p.client} onError={p.onError} />}\n </div>\n );\n}\n\n/**\n * A version's own cover, where its kind has covers: the cover upload its\n * editors selected, else its first. Versions share no files.\n */\nexport function VersionCover({ content, version: v, ...p }: Common & { content: Content; version: Version }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const { presets } = usePresets({ client });\n const save = useAction(\"content.save\", p.onError);\n const input = useRef<HTMLInputElement>(null);\n const [fresh, setFresh] = useState<string | null>(null);\n useEffect(() => () => void (fresh && URL.revokeObjectURL(fresh)), [fresh]);\n if (!presets.some((r) => r.kind === content.kind && r.name === \"cover\")) return null;\n const src = fresh ?? v.cover?.url;\n const pick = (file: File | null) =>\n void save.run(async () => {\n if (!file) {\n setFresh(null);\n return client.contents.setCover(content.id, v.id, null);\n }\n const ref = { kind: content.kind, id: content.id, version: v.id };\n const up = await client.media.uploadNamed(ref, file, { path: await client.media.presetPath(content.kind, \"cover\", file) });\n const saved = await client.contents.setCover(content.id, v.id, up.name);\n if (typeof URL.createObjectURL === \"function\") setFresh(URL.createObjectURL(file));\n return saved;\n });\n return (\n <div className=\"grid gap-1.5\" data-ckui=\"version-cover\">\n <span className=\"text-sm font-medium\">{t(\"contentManager.cover\")}</span>\n <div className=\"flex flex-wrap items-center gap-3\">\n {src ? <img src={src} alt=\"\" className=\"h-20 w-36 rounded-md border border-border object-cover\" /> : <span className=\"text-muted-foreground\">{t(\"contentManager.noCover\")}</span>}\n <Button type=\"button\" size=\"sm\" variant=\"outline\" disabled={save.pending} onClick={() => input.current?.click()}>\n {t(src ? \"pollEditor.replaceImage\" : \"contentManager.addCover\")}\n </Button>\n {v.cover?.image && (\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" disabled={save.pending} onClick={() => pick(null)}>\n {t(\"pollEditor.removeImage\")}\n </Button>\n )}\n <input\n ref={input}\n type=\"file\"\n accept=\"image/*\"\n hidden\n aria-label={t(\"contentManager.cover\")}\n onChange={(e) => {\n const f = e.target.files?.[0];\n e.target.value = \"\";\n if (f) pick(f);\n }}\n />\n </div>\n <ErrorLine error={save.error} />\n </div>\n );\n}\n\n/**\n * A version's media: a video kind's source, poster and subtitles (by its\n * upload rules), else its upload folders. Uploads to a version that is not\n * live are added as they finish; a live one's wait for \"Add\".\n */\nfunction VersionMedia({ content, version, model, ...p }: Common & { content: Content; version: Version; model: ContentModel | null }) {\n const { t } = useMessages();\n const languageName = useLanguageName();\n const item = useMemo(() => ({ kind: content.kind, id: content.id, version: version.id }), [content.kind, content.id, version.id]);\n const r = useMediaRead(item, { editor: true, client: p.client });\n const languages = useMemo(() => (model?.languages ?? []).map((l) => ({ value: l, label: languageName(l) })), [model, languageName]);\n if (!r.read && r.loading) return <Skeleton className=\"h-24 w-full\" />;\n if (r.read?.uploads && videoPaths(r.read.uploads).source) return <VideoMediaEditor item={item} languages={languages} client={p.client} onError={p.onError} />;\n return <>\n <MediaFolderEditor item={item} commit={version.live ? \"manual\" : \"auto\"} label={t(\"contentEditor.media\")} client={p.client} onError={p.onError} />\n {model?.kinds[content.kind]?.presentation === \"reader\" && <PageNotices content={content.id} version={version.id} client={p.client} onError={p.onError} />}\n </>;\n}\n\ntype Row = { title: string; start: string; end: string; release: string };\nconst segmentRows=(version:Version):Row[]=>version.segments.map((s)=>({title:s.title??\"\",start:String(s.start),end:String(s.end),release:toLocalInput(s.release_at)}));\n\n/** A version's segments (chapters): page ranges with titles and release times. */\nexport function SegmentsEditor({ content, version, ...p }: Common & { content: Content; version: Version }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const fields=useDraft(useMemo(()=>({rows:segmentRows(version)}),[version]));\n const rows=fields.value.rows;\n const setRows=(next:SetStateAction<Row[]>)=>fields.edit((old)=>({rows:typeof next===\"function\"?next(old.rows):next}));\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n // Published pages pick ranges by thumbnail; before a publication, numbers.\n const plan = useReaderPlan(content.id, version.id, { client });\n const { pages } = usePlanMedia(plan.plan, client);\n const set = (i: number, patch: Partial<Row>) => {\n setSaved(false);\n setRows((r) => r.map((x, j) => (j === i ? { ...x, ...patch } : x)));\n };\n const valid = rows.every((r) => /^\\d+$/.test(r.start) && /^\\d+$/.test(r.end) && Number(r.end) > Number(r.start));\n const submit=async()=>{\n if(!valid)return false;\n setSaved(false);const settle=fields.checkpoint();\n const segments:Segment[]=rows.map((r,i)=>({position:i+1,title:r.title.trim()||undefined,start:Number(r.start),end:Number(r.end),release_at:fromLocalInput(r.release),released:false}));\n const out=await save.run(()=>client.contents.setSegments(content.id,version.id,segments));\n if(!out)return false;const clean=settle({rows:segmentRows(out)});setSaved(clean);return clean;\n };\n useEditorSaveTask(`segments:${version.id}`,{label:t(\"contentEditor.segments\"),dirty:fields.dirty.length>0,pending:save.pending,valid,save:submit,order:20});\n return (\n <div className=\"grid gap-2\" data-ckui=\"segments-editor\">\n <h4 className=\"text-sm font-medium\">{t(\"contentEditor.segments\")}</h4>\n {rows.length === 0 && <p className=\"text-muted-foreground\">{t(\"contentEditor.noSegments\")}</p>}\n {rows.map((r, i) => (\n <div key={i} className=\"flex flex-wrap items-center gap-2\" data-ckui=\"segment-row\">\n <span className=\"w-6 text-xs text-muted-foreground tabular-nums\">{i + 1}</span>\n <Input className=\"h-8 w-40\" aria-label={t(\"contentEditor.segmentTitle\", { n: i + 1 })} placeholder={t(\"contentEditor.segmentTitlePlaceholder\")} value={r.title} onChange={(e) => set(i, { title: e.target.value })} />\n {pages.length ? (\n <>\n <PagePicker label={t(\"contentEditor.segmentStart\", { n: i + 1 })} pages={pages} value={pages[Number(r.start)]?.name ?? \"\"}\n onChange={(name) => set(i, { start: String(pages.findIndex((x) => x.name === name)) })} />\n <span aria-hidden>–</span>\n {/* end is exclusive: the picker names the segment's last page. */}\n <PagePicker label={t(\"contentEditor.segmentEnd\", { n: i + 1 })} pages={pages} value={pages[Number(r.end) - 1]?.name ?? \"\"}\n onChange={(name) => set(i, { end: String(pages.findIndex((x) => x.name === name) + 1) })} />\n </>\n ) : (\n <>\n <Input className=\"h-8 w-20\" type=\"number\" min={0} aria-label={t(\"contentEditor.segmentStart\", { n: i + 1 })} value={r.start} onChange={(e) => set(i, { start: e.target.value })} />\n <span aria-hidden>–</span>\n <Input className=\"h-8 w-20\" type=\"number\" min={1} aria-label={t(\"contentEditor.segmentEnd\", { n: i + 1 })} value={r.end} onChange={(e) => set(i, { end: e.target.value })} />\n </>\n )}\n <Input className=\"h-8 w-48\" type=\"datetime-local\" aria-label={t(\"contentEditor.segmentRelease\", { n: i + 1 })} value={r.release} onChange={(e) => set(i, { release: e.target.value })} />\n <Button type=\"button\" size=\"xs\" variant=\"ghost\" onClick={() => setRows((x) => x.filter((_, j) => j !== i))}>\n {t(\"common.remove\")}\n </Button>\n </div>\n ))}\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n const last = rows.at(-1);\n const start = last ? Number(last.end) || 0 : 0;\n setRows((x) => [...x, { title: \"\", start: String(start), end: String(start + 1), release: \"\" }]);\n }}\n >\n {t(\"contentEditor.addSegment\")}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n disabled={save.pending || !valid}\n onClick={()=>void submit()}\n >\n {t(\"contentEditor.saveSegments\")}\n </Button>\n <Saved show={saved} />\n </div>\n <ErrorLine error={save.error} />\n </div>\n );\n}\n\n/** Every editor section of an existing content: details, access and price, versions, groups. */\nexport function ContentSections({ content, ...p }: Common & { content: Content; media?: boolean; className?: string; management?: boolean }) {\n const languageName = useLanguageName();\n const versions = useMemo(() => content.versions.map((v) => ({ id: v.id, label: versionLabel(v, languageName, p.labels) })), [content.versions, languageName, p.labels]);\n const { spec } = useKind(content.kind, p.client);\n return (\n <div className={cn(\"grid gap-6\", p.className)} data-ckui=\"content-sections\">\n <ContentDetailsEditor content={content} {...p} />\n <AccessEditor content={content} {...p} />\n <VersionsEditor content={content} {...p} />\n {!!spec?.entities?.length && (\n <section className=\"grid gap-3 border-t border-border pt-4\" data-ckui=\"content-groups\">\n <MembershipEditor management={p.management} content={content.id} contentKind={content.kind} versions={spec.versions.hidden ? undefined : versions} labels={p.labels} client={p.client} onError={p.onError} />\n </section>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { MineQuery } from '../../client/content/favorites.js';
2
+ import { CardListProps } from './grid.js';
3
+ /** Favorite contents, with the same filtering, paid previews and pagination as public lists; signed out, a way to sign in. */
4
+ export declare function ContentFavorites({ query, ...p }: CardListProps & {
5
+ query?: Omit<MineQuery, "target">;
6
+ }): import('react').JSX.Element;
@@ -0,0 +1,47 @@
1
+ import { useMessages as e } from "../../i18n/context.js";
2
+ import { ContentKitUiRoot as t } from "../../scope.js";
3
+ import { ContentKitContext as n } from "../../react/context.js";
4
+ import { Button as r } from "../../ui/button.js";
5
+ import { useMyFavorites as i } from "../../react/discovery.js";
6
+ import { CardGrid as a, cardListMode as o } from "./grid.js";
7
+ import { useContext as s, useMemo as c } from "react";
8
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
9
+ import { cn as d } from "cn";
10
+ //#region src/components/content/favorites.tsx
11
+ function f({ query: f = {}, ...p }) {
12
+ let m = c(() => ({
13
+ ...f,
14
+ target: "contents",
15
+ mode: o(p.locked, f.mode),
16
+ summary: f.summary ?? !0,
17
+ limit: f.limit ?? p.pageSize
18
+ }), [
19
+ f,
20
+ p.pageSize,
21
+ p.locked
22
+ ]), h = i(m, { client: p.client }), g = c(() => h.items.flatMap((e) => e.content ? [e.content] : []), [h.items]), _ = s(n), { t: v } = e();
23
+ return _?.viewer === null ? /* @__PURE__ */ u(t, {
24
+ appearance: p.appearance,
25
+ className: d("grid justify-items-start gap-3 text-sm text-muted-foreground", p.className),
26
+ "data-ckui": "favorites-signed-out",
27
+ children: [/* @__PURE__ */ l("p", { children: v("favorites.signIn") }), _.onSignIn && /* @__PURE__ */ l(r, {
28
+ size: "sm",
29
+ onClick: _.onSignIn,
30
+ children: v("paywall.signIn")
31
+ })]
32
+ }) : /* @__PURE__ */ l(a, {
33
+ surface: "favorites",
34
+ ...p,
35
+ list: {
36
+ ...h,
37
+ items: g
38
+ },
39
+ render: JSON.stringify(m),
40
+ filterKinds: m.kind ? [m.kind] : void 0,
41
+ filterLanguage: m.display_language ?? m.language
42
+ });
43
+ }
44
+ //#endregion
45
+ export { f as ContentFavorites };
46
+
47
+ //# sourceMappingURL=favorites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"favorites.js","names":[],"sources":["../../../src/components/content/favorites.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useContext, useMemo } from \"react\";\nimport type { MineQuery } from \"../../client/content/favorites.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { ContentKitContext } from \"../../react/context.js\";\nimport { useMyFavorites } from \"../../react/discovery.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Button } from \"#ckui/ui/button\";\nimport { CardGrid, cardListMode, type CardListProps } from \"./grid.js\";\n\n/** Favorite contents, with the same filtering, paid previews and pagination as public lists; signed out, a way to sign in. */\nexport function ContentFavorites({ query = {}, ...p }: CardListProps & { query?: Omit<MineQuery, \"target\"> }) {\n const q = useMemo(\n () => ({ ...query, target: \"contents\" as const, mode: cardListMode(p.locked, query.mode), summary: query.summary ?? true, limit: query.limit ?? p.pageSize }),\n [query, p.pageSize, p.locked],\n );\n const favorites = useMyFavorites(q, { client: p.client });\n const items = useMemo(() => favorites.items.flatMap((item) => (item.content ? [item.content] : [])), [favorites.items]);\n const ctx = useContext(ContentKitContext);\n const { t } = useMessages();\n if (ctx?.viewer === null) {\n return (\n <ContentKitUiRoot appearance={p.appearance} className={cn(\"grid justify-items-start gap-3 text-sm text-muted-foreground\", p.className)} data-ckui=\"favorites-signed-out\">\n <p>{t(\"favorites.signIn\")}</p>\n {ctx.onSignIn && (\n <Button size=\"sm\" onClick={ctx.onSignIn}>\n {t(\"paywall.signIn\")}\n </Button>\n )}\n </ContentKitUiRoot>\n );\n }\n return (\n <CardGrid\n surface=\"favorites\"\n {...p}\n list={{ ...favorites, items }}\n render={JSON.stringify(q)}\n filterKinds={q.kind ? [q.kind] : undefined}\n filterLanguage={q.display_language ?? q.language}\n />\n );\n}\n"],"mappings":";;;;;;;;;;AAWA,SAAgB,EAAiB,EAAE,WAAQ,CAAC,GAAG,GAAG,KAA4D;CAC5G,IAAM,IAAI,SACD;EAAE,GAAG;EAAO,QAAQ;EAAqB,MAAM,EAAa,EAAE,QAAQ,EAAM,IAAI;EAAG,SAAS,EAAM,WAAW;EAAM,OAAO,EAAM,SAAS,EAAE;CAAS,IAC3J;EAAC;EAAO,EAAE;EAAU,EAAE;CAAM,CAC9B,GACM,IAAY,EAAe,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,GAClD,IAAQ,QAAc,EAAU,MAAM,SAAS,MAAU,EAAK,UAAU,CAAC,EAAK,OAAO,IAAI,CAAC,CAAE,GAAG,CAAC,EAAU,KAAK,CAAC,GAChH,IAAM,EAAW,CAAiB,GAClC,EAAE,SAAM,EAAY;CAa1B,OAZI,GAAK,WAAW,OAEhB,kBAAC,GAAD;EAAkB,YAAY,EAAE;EAAY,WAAW,EAAG,gEAAgE,EAAE,SAAS;EAAG,aAAU;EAAlJ,UAAA,CACE,kBAAC,KAAD,EAAA,UAAI,EAAE,kBAAkB,EAAK,CAAA,GAC5B,EAAI,YACH,kBAAC,GAAD;GAAQ,MAAK;GAAK,SAAS,EAAI;GAC5B,UAAA,EAAE,gBAAgB;EACb,CAAA,CAEM;MAIpB,kBAAC,GAAD;EACE,SAAQ;EACR,GAAI;EACJ,MAAM;GAAE,GAAG;GAAW;EAAM;EAC5B,QAAQ,KAAK,UAAU,CAAC;EACxB,aAAa,EAAE,OAAO,CAAC,EAAE,IAAI,IAAI,KAAA;EACjC,gBAAgB,EAAE,oBAAoB,EAAE;CACzC,CAAA;AAEL"}
@@ -2,28 +2,32 @@ import { useMessages as e } from "../../i18n/context.js";
2
2
  import { AppearanceContext as t } from "../../scope.js";
3
3
  import { Dialog as n, DialogContent as r, DialogDescription as i, DialogHeader as a, DialogTitle as o } from "../../ui/dialog.js";
4
4
  import { ContentFilterSettings as s } from "./filters.js";
5
- import { useContext as c } from "react";
6
- import { jsx as l, jsxs as u } from "react/jsx-runtime";
5
+ import { useContext as c, useState as l } from "react";
6
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
7
7
  //#region src/components/content/filter-dialog.tsx
8
- function d({ open: d, onOpenChange: f, description: p, returnFocus: m, ...h }) {
9
- let { t: g } = e(), _ = c(t);
10
- return /* @__PURE__ */ l(t.Provider, {
11
- value: h.appearance ?? _,
12
- children: /* @__PURE__ */ l(n, {
13
- open: d,
14
- onOpenChange: f,
15
- children: /* @__PURE__ */ u(r, {
16
- finalFocus: m,
8
+ function f({ open: f, onOpenChange: p, description: m, returnFocus: h, ...g }) {
9
+ let { t: _ } = e(), v = c(t), [y, b] = l({ open: !1 }), x = y;
10
+ return y.open !== f && (x = {
11
+ open: f,
12
+ container: f ? h?.()?.closest("dialog[open]") ?? void 0 : y.container
13
+ }, b(x)), /* @__PURE__ */ u(t.Provider, {
14
+ value: g.appearance ?? v,
15
+ children: /* @__PURE__ */ u(n, {
16
+ open: f,
17
+ onOpenChange: (e) => p(e),
18
+ children: /* @__PURE__ */ d(r, {
19
+ finalFocus: h,
20
+ portalContainer: x.container,
17
21
  className: "max-h-[calc(100dvh-2rem)] overflow-y-auto",
18
- children: [/* @__PURE__ */ u(a, { children: [/* @__PURE__ */ l(o, { children: g("readerSettings.filterTitle") }), /* @__PURE__ */ l(i, { children: p ?? g("readerSettings.filterDescription") })] }), /* @__PURE__ */ l(s, {
19
- ...h,
20
- includeDeleted: h.includeDeleted ?? !1
22
+ children: [/* @__PURE__ */ d(a, { children: [/* @__PURE__ */ u(o, { children: _("readerSettings.filterTitle") }), /* @__PURE__ */ u(i, { children: m ?? _("readerSettings.filterDescription") })] }), /* @__PURE__ */ u(s, {
23
+ ...g,
24
+ includeDeleted: g.includeDeleted ?? !1
21
25
  })]
22
26
  })
23
27
  })
24
28
  });
25
29
  }
26
30
  //#endregion
27
- export { d as ContentFilterDialog };
31
+ export { f as ContentFilterDialog };
28
32
 
29
33
  //# sourceMappingURL=filter-dialog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter-dialog.js","names":[],"sources":["../../../src/components/content/filter-dialog.tsx"],"sourcesContent":["import { useContext, type ReactNode } from \"react\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { AppearanceContext } from \"../../scope.js\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"#ckui/ui/dialog\";\nimport { ContentFilterSettings, type ContentFilterSettingsProps } from \"./filters.js\";\n\nexport interface ContentFilterDialogProps extends ContentFilterSettingsProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n description?: ReactNode;\n /** A stable focus target when a preference change removes the opening tile. */\n returnFocus?: () => HTMLElement | null;\n}\n\n/** The same filter controls as ReaderSettings, without another language picker. */\nexport function ContentFilterDialog({ open, onOpenChange, description, returnFocus, ...settings }: ContentFilterDialogProps) {\n const { t } = useMessages();\n const inheritedAppearance = useContext(AppearanceContext);\n return <AppearanceContext.Provider value={settings.appearance ?? inheritedAppearance}>\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent finalFocus={returnFocus} className=\"max-h-[calc(100dvh-2rem)] overflow-y-auto\">\n <DialogHeader>\n <DialogTitle>{t(\"readerSettings.filterTitle\")}</DialogTitle>\n <DialogDescription>{description ?? t(\"readerSettings.filterDescription\")}</DialogDescription>\n </DialogHeader>\n <ContentFilterSettings {...settings} includeDeleted={settings.includeDeleted ?? false} />\n </DialogContent>\n </Dialog>\n </AppearanceContext.Provider>;\n}\n"],"mappings":";;;;;;;AAeA,SAAgB,EAAoB,EAAE,SAAM,iBAAc,gBAAa,gBAAa,GAAG,KAAsC;CAC3H,IAAM,EAAE,SAAM,EAAY,GACpB,IAAsB,EAAW,CAAiB;CACxD,OAAO,kBAAC,EAAkB,UAAnB;EAA4B,OAAO,EAAS,cAAc;EAC/D,UAAA,kBAAC,GAAD;GAAc;GAAoB;GAChC,UAAA,kBAAC,GAAD;IAAe,YAAY;IAAa,WAAU;IAAlD,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAc,EAAE,4BAA4B,EAAe,CAAA,GAC3D,kBAAC,GAAD,EAAA,UAAoB,KAAe,EAAE,kCAAkC,EAAqB,CAAA,CAChF,EAAA,CAAA,GACd,kBAAC,GAAD;KAAuB,GAAI;KAAU,gBAAgB,EAAS,kBAAkB;IAAQ,CAAA,CAC3E;;EACT,CAAA;CACkB,CAAA;AAC9B"}
1
+ {"version":3,"file":"filter-dialog.js","names":[],"sources":["../../../src/components/content/filter-dialog.tsx"],"sourcesContent":["import { useContext, useState, type ReactNode } from \"react\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { AppearanceContext } from \"../../scope.js\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"#ckui/ui/dialog\";\nimport { ContentFilterSettings, type ContentFilterSettingsProps } from \"./filters.js\";\n\nexport interface ContentFilterDialogProps extends ContentFilterSettingsProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n description?: ReactNode;\n /** A stable focus target when a preference change removes the opening tile. */\n returnFocus?: () => HTMLElement | null;\n}\n\n/** The same filter controls as ReaderSettings, without another language picker. */\nexport function ContentFilterDialog({ open, onOpenChange, description, returnFocus, ...settings }: ContentFilterDialogProps) {\n const { t } = useMessages();\n const inheritedAppearance = useContext(AppearanceContext);\n // Native modal dialogs live above body portals. Keep the opening surface\n // through preference reloads, even when they remove the triggering tile.\n const [portal, setPortal] = useState<{ open: boolean; container?: HTMLDialogElement }>({ open: false });\n let placement = portal;\n if (portal.open !== open) {\n placement = { open, container: open ? returnFocus?.()?.closest<HTMLDialogElement>(\"dialog[open]\") ?? undefined : portal.container };\n setPortal(placement);\n }\n return <AppearanceContext.Provider value={settings.appearance ?? inheritedAppearance}>\n <Dialog open={open} onOpenChange={(next) => onOpenChange(next)}>\n <DialogContent\n finalFocus={returnFocus}\n portalContainer={placement.container}\n className=\"max-h-[calc(100dvh-2rem)] overflow-y-auto\"\n >\n <DialogHeader>\n <DialogTitle>{t(\"readerSettings.filterTitle\")}</DialogTitle>\n <DialogDescription>{description ?? t(\"readerSettings.filterDescription\")}</DialogDescription>\n </DialogHeader>\n <ContentFilterSettings {...settings} includeDeleted={settings.includeDeleted ?? false} />\n </DialogContent>\n </Dialog>\n </AppearanceContext.Provider>;\n}\n"],"mappings":";;;;;;;AAeA,SAAgB,EAAoB,EAAE,SAAM,iBAAc,gBAAa,gBAAa,GAAG,KAAsC;CAC3H,IAAM,EAAE,SAAM,EAAY,GACpB,IAAsB,EAAW,CAAiB,GAGlD,CAAC,GAAQ,KAAa,EAA2D,EAAE,MAAM,GAAM,CAAC,GAClG,IAAY;CAKhB,OAJI,EAAO,SAAS,MAClB,IAAY;EAAE;EAAM,WAAW,IAAO,IAAc,CAAC,EAAE,QAA2B,cAAc,KAAK,KAAA,IAAY,EAAO;CAAU,GAClI,EAAU,CAAS,IAEd,kBAAC,EAAkB,UAAnB;EAA4B,OAAO,EAAS,cAAc;EAC/D,UAAA,kBAAC,GAAD;GAAc;GAAM,eAAe,MAAS,EAAa,CAAI;GAC3D,UAAA,kBAAC,GAAD;IACE,YAAY;IACZ,iBAAiB,EAAU;IAC3B,WAAU;IAHZ,UAAA,CAKE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAc,EAAE,4BAA4B,EAAe,CAAA,GAC3D,kBAAC,GAAD,EAAA,UAAoB,KAAe,EAAE,kCAAkC,EAAqB,CAAA,CAChF,EAAA,CAAA,GACd,kBAAC,GAAD;KAAuB,GAAI;KAAU,gBAAgB,EAAS,kBAAkB;IAAQ,CAAA,CAC3E;;EACT,CAAA;CACkB,CAAA;AAC9B"}
@@ -16,6 +16,8 @@ export interface ContentFilterSettingsProps {
16
16
  language?: string;
17
17
  /** Currently excluded matches in this listing/day; omitted shows no counts. */
18
18
  counts?: readonly ContentFilterCount[];
19
+ /** Counts cover a bounded candidate set, so each displayed count is a lower bound. */
20
+ countsLowerBound?: boolean;
19
21
  /** Offer listing deleted content the reader holds. Default true. */
20
22
  includeDeleted?: boolean;
21
23
  client?: ContentKitClient;
@@ -41,7 +41,11 @@ function v(r) {
41
41
  className: "min-w-0 flex-1",
42
42
  children: [e.entity.name || e.entity.slug, r.counts !== void 0 && /* @__PURE__ */ g("span", {
43
43
  className: "tabular-nums",
44
- children: [": ", new Intl.NumberFormat(d.language).format(r.counts.filter((t) => t.entity.id === e.entity.id).reduce((e, t) => e + t.count, 0))]
44
+ children: [
45
+ ": ",
46
+ r.countsLowerBound ? "≥ " : "",
47
+ new Intl.NumberFormat(d.language).format(r.counts.filter((t) => t.entity.id === e.entity.id).reduce((e, t) => e + t.count, 0))
48
+ ]
45
49
  })]
46
50
  })]
47
51
  }, e.entity.id))
@@ -1 +1 @@
1
- {"version":3,"file":"filters.js","names":[],"sources":["../../../src/components/content/filters.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useContext, useId } from \"react\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport type { GroupCard } from \"../../client/generated/wire.js\";\nimport type { ReleaseDatesQuery } from \"../../client/discovery.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { ContentKitContext, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useContentFilters, useReleaseDates } from \"../../react/discovery.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Label } from \"#ckui/ui/label\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { Switch } from \"#ckui/ui/switch\";\nimport { contentError, ErrorLine, useAction } from \"../social/parts.js\";\n\n/** Counts for one concrete listing selection, aggregated by entity.\n * Only rows offered by the current domain's filter inventory are displayed. */\nexport interface ContentFilterCount {\n entity: Pick<GroupCard, \"id\">;\n count: number;\n}\n\nexport interface ContentFilterSettingsProps {\n /** Listing context; shows shared controls when any kind is in applies_to. */\n kinds?: readonly string[];\n /** Entity names in this language; default the provider's. */\n language?: string;\n /** Currently excluded matches in this listing/day; omitted shows no counts. */\n counts?: readonly ContentFilterCount[];\n /** Offer listing deleted content the reader holds. Default true. */\n includeDeleted?: boolean;\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** Show or hide configured content for this browser or signed-in account. */\nexport function ContentFilterSettings(p: ContentFilterSettingsProps) {\n const m = useMessages();\n const { t } = m;\n const id = useId();\n const ctx = useContext(ContentKitContext);\n const f = useContentFilters({ language: p.language, client: p.client });\n const save = useAction(\"filters.save\", p.onError);\n const root = (children: React.ReactNode) => (\n <ContentKitUiRoot appearance={p.appearance} className={cn(\"grid gap-3 text-sm\", p.className)} data-ckui=\"content-filters\">\n {children}\n </ContentKitUiRoot>\n );\n if (!f.filters) {\n if (f.error) return root(<ErrorLine>{contentError(m, f.error)}</ErrorLine>);\n return root(<Skeleton className=\"h-24 w-full\" />);\n }\n const filters = f.filters;\n const rows = !p.kinds || p.kinds.some((kind) => filters.applies_to.includes(kind)) ? filters.filters : [];\n if (!rows.length && p.includeDeleted === false) return null;\n return root(\n <>\n {rows.length > 0 && (\n <ul className=\"grid divide-y divide-border rounded-lg border border-border\">\n {rows.map((x) => (\n <li key={x.entity.id} className=\"flex flex-wrap items-center gap-3 p-3\" data-ckui=\"content-filter\" data-slug={x.entity.slug} data-visible={x.visible}>\n <Switch id={`${id}-${x.entity.id}`} checked={x.visible} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setVisible(x.entity.id, v))} />\n <Label htmlFor={`${id}-${x.entity.id}`} className=\"min-w-0 flex-1\">\n {x.entity.name || x.entity.slug}\n {p.counts !== undefined && (\n <span className=\"tabular-nums\">: {new Intl.NumberFormat(m.language).format(p.counts.filter((entry) => entry.entity.id === x.entity.id).reduce((n, entry) => n + entry.count, 0))}</span>\n )}\n </Label>\n </li>\n ))}\n </ul>\n )}\n {p.includeDeleted !== false && ctx?.viewer !== null && (\n <div className=\"flex items-center gap-3\">\n <Switch id={`${id}-deleted`} checked={filters.include_deleted} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setIncludeDeleted(v))} />\n <Label htmlFor={`${id}-deleted`}>{t(\"contents.includeDeleted\")}</Label>\n </div>\n )}\n <ErrorLine error={save.error} />\n </>,\n );\n}\n\nexport interface ReleaseDateIndexProps {\n /** Which contents count: the listing's filters. */\n query?: ReleaseDatesQuery;\n /** The bucket chosen (a day YYYY-MM-DD or month YYYY-MM): list with released_on set to it. */\n selected?: string;\n onSelect?: (date: string) => void;\n client?: ContentKitClient;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** The release date index: per month or day, newest first, how many contents and how many free. */\nexport function ReleaseDateIndex({ query = {}, selected, onSelect, client, className, appearance }: ReleaseDateIndexProps) {\n const m = useMessages();\n const { t } = m;\n const dates = useReleaseDates(query, { client });\n const label = (date: string) => {\n const [y, mo, d] = date.split(\"-\").map(Number);\n const at = new Date(Date.UTC(y!, (mo ?? 1) - 1, d ?? 1));\n return new Intl.DateTimeFormat(m.language, d ? { dateStyle: \"medium\", timeZone: \"UTC\" } : { year: \"numeric\", month: \"long\", timeZone: \"UTC\" }).format(at);\n };\n return (\n <ContentKitUiRoot appearance={appearance} className={cn(\"grid gap-2 text-sm\", className)} data-ckui=\"release-dates\">\n {dates.loading && !dates.items.length ? (\n <Skeleton className=\"h-24 w-full\" />\n ) : dates.error && !dates.items.length ? (\n <div role=\"alert\" className=\"grid justify-items-start gap-2\">\n <p className=\"text-destructive\">{contentError(m, dates.error)}</p>\n <Button size=\"sm\" variant=\"outline\" onClick={dates.reload}>\n {t(\"common.retry\")}\n </Button>\n </div>\n ) : !dates.items.length ? (\n <p className=\"text-muted-foreground\">{t(\"contents.noDates\")}</p>\n ) : (\n <ul className=\"grid gap-1\">\n {dates.items.map((d) => (\n <li key={d.date}>\n <button\n type=\"button\"\n aria-pressed={selected === d.date}\n className={cn(\"flex w-full items-center justify-between gap-3 rounded-md px-2 py-1.5 text-start hover:bg-muted\", selected === d.date && \"bg-muted font-medium\")}\n onClick={() => onSelect?.(d.date)}\n data-ckui=\"release-date\"\n data-date={d.date}\n >\n <span>{label(d.date)}</span>\n <span className=\"text-xs text-muted-foreground tabular-nums\">\n {m.plural(\"contents.items\", d.count)}\n {d.free < d.count && ` · ${m.plural(\"contents.free\", d.free)}`}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n {dates.hasMore && (\n <div className=\"grid justify-items-center gap-2\">\n {dates.error && <p role=\"alert\" className=\"text-destructive\">{contentError(m, dates.error)}</p>}\n <Button variant=\"outline\" size=\"sm\" disabled={dates.loadingMore} onClick={() => void dates.loadMore()}>\n {dates.loadingMore ? t(\"contents.loading\") : dates.error ? t(\"common.retry\") : t(\"contents.loadMore\")}\n </Button>\n </div>\n )}\n </ContentKitUiRoot>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"filters.js","names":[],"sources":["../../../src/components/content/filters.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useContext, useId } from \"react\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport type { GroupCard } from \"../../client/generated/wire.js\";\nimport type { ReleaseDatesQuery } from \"../../client/discovery.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { ContentKitContext, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useContentFilters, useReleaseDates } from \"../../react/discovery.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Label } from \"#ckui/ui/label\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { Switch } from \"#ckui/ui/switch\";\nimport { contentError, ErrorLine, useAction } from \"../social/parts.js\";\n\n/** Counts for one concrete listing selection, aggregated by entity.\n * Only rows offered by the current domain's filter inventory are displayed. */\nexport interface ContentFilterCount {\n entity: Pick<GroupCard, \"id\">;\n count: number;\n}\n\nexport interface ContentFilterSettingsProps {\n /** Listing context; shows shared controls when any kind is in applies_to. */\n kinds?: readonly string[];\n /** Entity names in this language; default the provider's. */\n language?: string;\n /** Currently excluded matches in this listing/day; omitted shows no counts. */\n counts?: readonly ContentFilterCount[];\n /** Counts cover a bounded candidate set, so each displayed count is a lower bound. */\n countsLowerBound?: boolean;\n /** Offer listing deleted content the reader holds. Default true. */\n includeDeleted?: boolean;\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** Show or hide configured content for this browser or signed-in account. */\nexport function ContentFilterSettings(p: ContentFilterSettingsProps) {\n const m = useMessages();\n const { t } = m;\n const id = useId();\n const ctx = useContext(ContentKitContext);\n const f = useContentFilters({ language: p.language, client: p.client });\n const save = useAction(\"filters.save\", p.onError);\n const root = (children: React.ReactNode) => (\n <ContentKitUiRoot appearance={p.appearance} className={cn(\"grid gap-3 text-sm\", p.className)} data-ckui=\"content-filters\">\n {children}\n </ContentKitUiRoot>\n );\n if (!f.filters) {\n if (f.error) return root(<ErrorLine>{contentError(m, f.error)}</ErrorLine>);\n return root(<Skeleton className=\"h-24 w-full\" />);\n }\n const filters = f.filters;\n const rows = !p.kinds || p.kinds.some((kind) => filters.applies_to.includes(kind)) ? filters.filters : [];\n if (!rows.length && p.includeDeleted === false) return null;\n return root(\n <>\n {rows.length > 0 && (\n <ul className=\"grid divide-y divide-border rounded-lg border border-border\">\n {rows.map((x) => (\n <li key={x.entity.id} className=\"flex flex-wrap items-center gap-3 p-3\" data-ckui=\"content-filter\" data-slug={x.entity.slug} data-visible={x.visible}>\n <Switch id={`${id}-${x.entity.id}`} checked={x.visible} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setVisible(x.entity.id, v))} />\n <Label htmlFor={`${id}-${x.entity.id}`} className=\"min-w-0 flex-1\">\n {x.entity.name || x.entity.slug}\n {p.counts !== undefined && (\n <span className=\"tabular-nums\">: {p.countsLowerBound ? \"≥ \" : \"\"}{new Intl.NumberFormat(m.language).format(p.counts.filter((entry) => entry.entity.id === x.entity.id).reduce((n, entry) => n + entry.count, 0))}</span>\n )}\n </Label>\n </li>\n ))}\n </ul>\n )}\n {p.includeDeleted !== false && ctx?.viewer !== null && (\n <div className=\"flex items-center gap-3\">\n <Switch id={`${id}-deleted`} checked={filters.include_deleted} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setIncludeDeleted(v))} />\n <Label htmlFor={`${id}-deleted`}>{t(\"contents.includeDeleted\")}</Label>\n </div>\n )}\n <ErrorLine error={save.error} />\n </>,\n );\n}\n\nexport interface ReleaseDateIndexProps {\n /** Which contents count: the listing's filters. */\n query?: ReleaseDatesQuery;\n /** The bucket chosen (a day YYYY-MM-DD or month YYYY-MM): list with released_on set to it. */\n selected?: string;\n onSelect?: (date: string) => void;\n client?: ContentKitClient;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** The release date index: per month or day, newest first, how many contents and how many free. */\nexport function ReleaseDateIndex({ query = {}, selected, onSelect, client, className, appearance }: ReleaseDateIndexProps) {\n const m = useMessages();\n const { t } = m;\n const dates = useReleaseDates(query, { client });\n const label = (date: string) => {\n const [y, mo, d] = date.split(\"-\").map(Number);\n const at = new Date(Date.UTC(y!, (mo ?? 1) - 1, d ?? 1));\n return new Intl.DateTimeFormat(m.language, d ? { dateStyle: \"medium\", timeZone: \"UTC\" } : { year: \"numeric\", month: \"long\", timeZone: \"UTC\" }).format(at);\n };\n return (\n <ContentKitUiRoot appearance={appearance} className={cn(\"grid gap-2 text-sm\", className)} data-ckui=\"release-dates\">\n {dates.loading && !dates.items.length ? (\n <Skeleton className=\"h-24 w-full\" />\n ) : dates.error && !dates.items.length ? (\n <div role=\"alert\" className=\"grid justify-items-start gap-2\">\n <p className=\"text-destructive\">{contentError(m, dates.error)}</p>\n <Button size=\"sm\" variant=\"outline\" onClick={dates.reload}>\n {t(\"common.retry\")}\n </Button>\n </div>\n ) : !dates.items.length ? (\n <p className=\"text-muted-foreground\">{t(\"contents.noDates\")}</p>\n ) : (\n <ul className=\"grid gap-1\">\n {dates.items.map((d) => (\n <li key={d.date}>\n <button\n type=\"button\"\n aria-pressed={selected === d.date}\n className={cn(\"flex w-full items-center justify-between gap-3 rounded-md px-2 py-1.5 text-start hover:bg-muted\", selected === d.date && \"bg-muted font-medium\")}\n onClick={() => onSelect?.(d.date)}\n data-ckui=\"release-date\"\n data-date={d.date}\n >\n <span>{label(d.date)}</span>\n <span className=\"text-xs text-muted-foreground tabular-nums\">\n {m.plural(\"contents.items\", d.count)}\n {d.free < d.count && ` · ${m.plural(\"contents.free\", d.free)}`}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n {dates.hasMore && (\n <div className=\"grid justify-items-center gap-2\">\n {dates.error && <p role=\"alert\" className=\"text-destructive\">{contentError(m, dates.error)}</p>}\n <Button variant=\"outline\" size=\"sm\" disabled={dates.loadingMore} onClick={() => void dates.loadMore()}>\n {dates.loadingMore ? t(\"contents.loading\") : dates.error ? t(\"common.retry\") : t(\"contents.loadMore\")}\n </Button>\n </div>\n )}\n </ContentKitUiRoot>\n );\n}\n"],"mappings":"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"}