@openrails/contentkit-ui 0.83.0 → 0.85.1
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.
- package/README.md +11 -3
- package/dist/client/beacons.d.ts +8 -5
- package/dist/client/beacons.js +15 -7
- package/dist/client/beacons.js.map +1 -1
- package/dist/client/content/moderation.d.ts +14 -2
- package/dist/client/content/moderation.js +34 -0
- package/dist/client/content/moderation.js.map +1 -1
- package/dist/client/content/types.d.ts +13 -0
- package/dist/client/content/types.js.map +1 -1
- package/dist/client/discovery.d.ts +6 -0
- package/dist/client/discovery.js.map +1 -1
- package/dist/client/generated/error-codes.d.ts +1 -1
- package/dist/client/generated/error-codes.js +8 -0
- package/dist/client/generated/error-codes.js.map +1 -1
- package/dist/client/generated/routes.d.ts +77 -12
- package/dist/client/generated/routes.js +106 -1
- package/dist/client/generated/routes.js.map +1 -1
- package/dist/client/generated/wire.d.ts +52 -0
- package/dist/client/generated/wire.js.map +1 -1
- package/dist/client/index.d.ts +2 -1
- package/dist/client/reader-meta.d.ts +27 -0
- package/dist/client/reader-meta.js +99 -0
- package/dist/client/reader-meta.js.map +1 -0
- package/dist/client/versions.d.ts +1 -1
- package/dist/client/versions.js +7 -2
- package/dist/client/versions.js.map +1 -1
- package/dist/client.js +2 -1
- package/dist/components/admin/reader-manifest.d.ts +18 -0
- package/dist/components/admin/reader-manifest.js +490 -0
- package/dist/components/admin/reader-manifest.js.map +1 -0
- package/dist/components/content/card.js +1 -1
- package/dist/components/content/card.js.map +1 -1
- package/dist/components/content/editors.d.ts +2 -1
- package/dist/components/content/editors.js +291 -256
- package/dist/components/content/editors.js.map +1 -1
- package/dist/components/groups/banner.d.ts +1 -1
- package/dist/components/groups/banner.js +1 -1
- package/dist/components/groups/banner.js.map +1 -1
- package/dist/components/groups/editor.js +3 -3
- package/dist/components/groups/editor.js.map +1 -1
- package/dist/components/groups/parts.d.ts +2 -2
- package/dist/components/groups/parts.js +71 -72
- package/dist/components/groups/parts.js.map +1 -1
- package/dist/components/social/comments.js +59 -45
- package/dist/components/social/comments.js.map +1 -1
- package/dist/components/social/index.d.ts +1 -0
- package/dist/components/social/moderation.d.ts +5 -4
- package/dist/components/social/moderation.js +143 -130
- package/dist/components/social/moderation.js.map +1 -1
- package/dist/components/social/parts.js +22 -14
- package/dist/components/social/parts.js.map +1 -1
- package/dist/components/social/rules.d.ts +23 -0
- package/dist/components/social/rules.js +261 -0
- package/dist/components/social/rules.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +26 -24
- package/dist/locales/admin/de.js +78 -0
- package/dist/locales/admin/de.js.map +1 -1
- package/dist/locales/admin/en.d.ts +78 -0
- package/dist/locales/admin/en.js +78 -0
- package/dist/locales/admin/en.js.map +1 -1
- package/dist/locales/admin/es.js +78 -0
- package/dist/locales/admin/es.js.map +1 -1
- package/dist/locales/admin/ja.js +78 -0
- package/dist/locales/admin/ja.js.map +1 -1
- package/dist/locales/admin/ko.js +78 -0
- package/dist/locales/admin/ko.js.map +1 -1
- package/dist/locales/admin/zh.js +78 -0
- package/dist/locales/admin/zh.js.map +1 -1
- package/dist/locales/de.js +3 -1
- package/dist/locales/de.js.map +1 -1
- package/dist/locales/discovery/de.js +1 -0
- package/dist/locales/discovery/de.js.map +1 -1
- package/dist/locales/discovery/en.d.ts +1 -0
- package/dist/locales/discovery/en.js +1 -0
- package/dist/locales/discovery/en.js.map +1 -1
- package/dist/locales/discovery/es.js +1 -0
- package/dist/locales/discovery/es.js.map +1 -1
- package/dist/locales/discovery/ja.js +1 -0
- package/dist/locales/discovery/ja.js.map +1 -1
- package/dist/locales/discovery/ko.js +1 -0
- package/dist/locales/discovery/ko.js.map +1 -1
- package/dist/locales/discovery/zh.js +1 -0
- package/dist/locales/discovery/zh.js.map +1 -1
- package/dist/locales/en.d.ts +84 -0
- package/dist/locales/en.js +3 -1
- package/dist/locales/en.js.map +1 -1
- package/dist/locales/es.js +3 -1
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/ja.js +3 -1
- package/dist/locales/ja.js.map +1 -1
- package/dist/locales/ko.js +3 -1
- package/dist/locales/ko.js.map +1 -1
- package/dist/locales/social/de.js +3 -0
- package/dist/locales/social/de.js.map +1 -1
- package/dist/locales/social/en.d.ts +3 -0
- package/dist/locales/social/en.js +3 -0
- package/dist/locales/social/en.js.map +1 -1
- package/dist/locales/social/es.js +3 -0
- package/dist/locales/social/es.js.map +1 -1
- package/dist/locales/social/ja.js +3 -0
- package/dist/locales/social/ja.js.map +1 -1
- package/dist/locales/social/ko.js +3 -0
- package/dist/locales/social/ko.js.map +1 -1
- package/dist/locales/social/zh.js +3 -0
- package/dist/locales/social/zh.js.map +1 -1
- package/dist/locales/zh.js +3 -1
- package/dist/locales/zh.js.map +1 -1
- package/dist/react/admin.d.ts +1 -1
- package/dist/react/admin.js +2 -0
- package/dist/react/admin.js.map +1 -1
- package/dist/react/comments.d.ts +29 -1
- package/dist/react/comments.js +30 -2
- package/dist/react/comments.js.map +1 -1
- package/dist/react/context.d.ts +1 -1
- package/dist/react/context.js.map +1 -1
- package/dist/react/discovery.js +1 -1
- package/dist/react/discovery.js.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/resources.js +6 -0
- package/dist/react/resources.js.map +1 -1
- package/dist/react.js +14 -14
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editors.js","names":[],"sources":["../../../src/components/content/editors.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useEffect, useId, useMemo, useState, type ReactNode } 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 { useMessages } from \"../../i18n/context.js\";\nimport { useContentKitClient, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useKinds } from \"../../react/groups.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 { MediaFolderEditor } from \"../media-folder-editor.js\";\nimport { SortableList } from \"../sortable-list.js\";\nimport { ErrorLine, useAction } from \"../social/parts.js\";\nimport { GroupPicker, labelOf, useGroupNames, useLanguageName, type Labels } from \"../groups/parts.js\";\nimport { AttributeFields, formOf } from \"../groups/fields.js\";\nimport { MembershipEditor } from \"../groups/memberships.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\"];\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/** Listing and the kind's declared attributes. */\nexport function ContentDetailsEditor({ 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 [listing, setListing] = useState<Listing>(content.listing);\n const [comments, setComments] = useState(content.comments);\n const [attrs, setAttrs] = useState<Record<string, string | boolean>>({});\n useEffect(() => {\n setListing(content.listing);\n setComments(content.comments);\n setAttrs(formOf(declared, content.attributes));\n }, [content.revision, content.listing, content.comments, content.attributes, declared]);\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);\n } catch (err) {\n return setInvalid((err as Error).message);\n }\n void save.run(() => client.contents.update(content.id, { listing, comments, attributes, revision: content.revision })).then((d) => d && setSaved(true));\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) => setListing(v as Listing)}>\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) => setComments(v as Comments)}>\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} onChange={(n, v) => setAttrs((a) => ({ ...a, [n]: v }))} 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 <Saved show={saved} />\n </div>\n </form>\n </Section>\n );\n}\n\n/** A rule's form: level, tiers, group, preview and when it turns free. */\nfunction RuleFields({ value, onChange, model, labels, client }: { value: Rule; onChange: (r: Rule) => void; model: ContentModel | null; labels?: Labels; client: ContentKitClient }) {\n const { t } = useMessages();\n const id = useId();\n const tiers = model?.tiers ?? [];\n const groupKinds = Object.entries(model?.group_kinds ?? {})\n .filter(([, g]) => g.sellable || g.auth_scope)\n .map(([k]) => k);\n const [groupKind, setGroupKind] = useState(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 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 value={value.level} onValueChange={(v) => onChange({ level: v as Rule[\"level\"], preview: value.preview, free_after: value.free_after })}>\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 {(value.level === \"group\" || value.level === \"group_ppv\") && (\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 <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 <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 <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 as stored: empty previews and absent fields left out. */\nfunction 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({ 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, setRule] = useState<Rule>(content.access);\n useEffect(() => setRule(content.access), [content.revision, content.access]);\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 void save.run(() => client.contents.update(content.id, { access: cleanRule(rule), revision: content.revision })).then((d) => d && setSaved(true));\n }}\n >\n <RuleFields value={rule} onChange={setRule} model={model} 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}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Saved show={saved} />\n </div>\n </form>\n <OfferFields\n offer={content.offer}\n pending={offer.pending}\n onSell={(terms) => void 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.\n */\nexport function VersionsEditor({ content, media = true, ...p }: Common & { content: Content; media?: boolean }) {\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 versions = useMemo(() => [...content.versions].sort((a, b) => a.position - b.position), [content.versions]);\n if (spec?.versions.hidden) return null;\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={() => setOpen(open === v.id ? null : v.id)}>\n {t(open === v.id ? \"contentEditor.close\" : \"contentEditor.edit\")}\n </Button>\n </div>\n {open === v.id && <VersionForm content={content} version={v} model={model} media={media} {...p} />}\n </div>\n )}\n </SortableList>\n <ErrorLine error={order.error} />\n <AddVersion languages={languages} many={spec?.versions.languages === \"many\"} pending={add.pending} onAdd={(input) => void add.run(() => client.contents.addVersion(content.id, input))} />\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 [langs, setLangs] = useState<string[]>(v.languages);\n const [traits, setTraits] = useState<string[]>(v.traits);\n const [label, setLabel] = useState(v.label ?? \"\");\n const [draft, setDraft] = useState(v.state === \"draft\");\n const [at, setAt] = useState(toLocalInput(v.publish_at));\n const [own, setOwn] = useState(!!v.access);\n const [rule, setRule] = useState<Rule>(v.access ?? content.access);\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 return (\n <div className=\"grid gap-4 pt-2\">\n <form\n className=\"grid gap-3\"\n onSubmit={(e) => {\n e.preventDefault();\n setSaved(false);\n void save\n .run(() =>\n client.contents.updateVersion(content.id, v.id, {\n languages: langs,\n traits,\n label: label.trim(),\n state: draft ? \"draft\" : \"published\",\n publish_at: fromLocalInput(at),\n ...(own ? { access: cleanRule(rule) } : { clear_access: !!v.access }),\n }),\n )\n .then((d) => d && setSaved(true));\n }}\n >\n <LanguageFields languages={model?.languages ?? []} value={langs} many={spec?.versions.languages === \"many\"} onChange={setLangs} />\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) => setTraits(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) => setLabel(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) => setAt(e.target.value)} />\n </div>\n </div>\n <label className=\"flex items-center gap-2\">\n <Switch size=\"sm\" checked={draft} onCheckedChange={setDraft} />\n {t(\"contentEditor.versionDraft\")}\n </label>\n <label className=\"flex items-center gap-2\">\n <Switch size=\"sm\" checked={own} onCheckedChange={setOwn} />\n {t(\"contentEditor.ownAccess\")}\n </label>\n {own && <RuleFields value={rule} onChange={setRule} model={model} labels={p.labels} client={client} />}\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}>\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) => void 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 && <MediaFolderEditor item={{ kind: content.kind, id: content.id, version: v.id }} label={t(\"contentEditor.media\")} />}\n </div>\n );\n}\n\ntype Row = { title: string; start: string; end: string; release: string };\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 seed = () => version.segments.map((s) => ({ title: s.title ?? \"\", start: String(s.start), end: String(s.end), release: toLocalInput(s.release_at) }));\n const [rows, setRows] = useState<Row[]>(seed);\n // Seeded again when the stored segments change.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => setRows(seed()), [JSON.stringify(version.segments)]);\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 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={() => {\n setSaved(false);\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 void save.run(() => client.contents.setSegments(content.id, version.id, segments)).then((d) => d && setSaved(true));\n }}\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 }) {\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?.groups?.length && (\n <section className=\"grid gap-3 border-t border-border pt-4\" data-ckui=\"content-groups\">\n <MembershipEditor 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 { useEffect, useId, useMemo, useState, type ReactNode } 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 { useMessages } from \"../../i18n/context.js\";\nimport { useContentKitClient, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useKinds } from \"../../react/groups.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 { MediaFolderEditor } from \"../media-folder-editor.js\";\nimport { SortableList } from \"../sortable-list.js\";\nimport { ErrorLine, useAction } from \"../social/parts.js\";\nimport { GroupPicker, labelOf, useGroupNames, useLanguageName, type Labels } from \"../groups/parts.js\";\nimport { AttributeFields, formOf } from \"../groups/fields.js\";\nimport { MembershipEditor } from \"../groups/memberships.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/** Listing and the kind's declared attributes. */\nexport function ContentDetailsEditor({ 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 [listing, setListing] = useState<Listing>(content.listing);\n const [comments, setComments] = useState(content.comments);\n const [attrs, setAttrs] = useState<Record<string, string | boolean>>({});\n useEffect(() => {\n setListing(content.listing);\n setComments(content.comments);\n setAttrs(formOf(declared, content.attributes));\n }, [content.revision, content.listing, content.comments, content.attributes, declared]);\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);\n } catch (err) {\n return setInvalid((err as Error).message);\n }\n void save.run(() => client.contents.update(content.id, { listing, comments, attributes, revision: content.revision })).then((d) => d && setSaved(true));\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) => setListing(v as Listing)}>\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) => setComments(v as Comments)}>\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} onChange={(n, v) => setAttrs((a) => ({ ...a, [n]: v }))} 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 <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. */\nfunction 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?.group_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. */\nconst complete = (r: Rule) => !grouped(r.level) || !!r.group_id;\n\n/** A rule as stored: empty previews and absent fields left out. */\nfunction 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({ 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, setRule] = useState<Rule>(content.access);\n useEffect(() => setRule(content.access), [content.revision, content.access]);\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 void save.run(() => client.contents.update(content.id, { access: cleanRule(rule), revision: content.revision })).then((d) => d && setSaved(true));\n }}\n >\n <RuleFields value={rule} onChange={setRule} 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)}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Saved show={saved} />\n </div>\n </form>\n <OfferFields\n offer={content.offer}\n pending={offer.pending}\n onSell={(terms) => void 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, ...p }: Common & { content: Content; media?: boolean }) {\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 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 && <MediaFolderEditor item={{ kind: content.kind, id: content.id, version: only.id }} label={t(\"contentEditor.media\")} />}\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={() => setOpen(open === v.id ? null : v.id)}>\n {t(open === v.id ? \"contentEditor.close\" : \"contentEditor.edit\")}\n </Button>\n </div>\n {open === v.id && <VersionForm content={content} version={v} model={model} media={media} {...p} />}\n </div>\n )}\n </SortableList>\n <ErrorLine error={order.error} />\n <AddVersion languages={languages} many={spec?.versions.languages === \"many\"} pending={add.pending} onAdd={(input) => void add.run(() => client.contents.addVersion(content.id, input))} />\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 [langs, setLangs] = useState<string[]>(v.languages);\n const [traits, setTraits] = useState<string[]>(v.traits);\n const [label, setLabel] = useState(v.label ?? \"\");\n const [draft, setDraft] = useState(v.state === \"draft\");\n const [at, setAt] = useState(toLocalInput(v.publish_at));\n const [own, setOwn] = useState(!!v.access);\n const [rule, setRule] = useState<Rule>(v.access ?? content.access);\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 return (\n <div className=\"grid gap-4 pt-2\">\n <form\n className=\"grid gap-3\"\n onSubmit={(e) => {\n e.preventDefault();\n setSaved(false);\n void save\n .run(() =>\n client.contents.updateVersion(content.id, v.id, {\n languages: langs,\n traits,\n label: label.trim(),\n state: draft ? \"draft\" : \"published\",\n publish_at: fromLocalInput(at),\n ...(own ? { access: cleanRule(rule) } : { clear_access: !!v.access }),\n }),\n )\n .then((d) => d && setSaved(true));\n }}\n >\n <LanguageFields languages={model?.languages ?? []} value={langs} many={spec?.versions.languages === \"many\"} onChange={setLangs} />\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) => setTraits(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) => setLabel(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) => setAt(e.target.value)} />\n </div>\n </div>\n <label className=\"flex items-center gap-2\">\n <Switch size=\"sm\" checked={draft} onCheckedChange={setDraft} />\n {t(\"contentEditor.versionDraft\")}\n </label>\n <label className=\"flex items-center gap-2\">\n <Switch size=\"sm\" checked={own} onCheckedChange={setOwn} />\n {t(\"contentEditor.ownAccess\")}\n </label>\n {own && <RuleFields value={rule} onChange={setRule} model={model} kind={content.kind} owner={content.owner_group_id} labels={p.labels} client={client} />}\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) => void 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 && <MediaFolderEditor item={{ kind: content.kind, id: content.id, version: v.id }} label={t(\"contentEditor.media\")} />}\n {media && spec?.presentation === \"reader\" && <ReaderManifestEditor content={content.id} version={v.id} client={p.client} onError={p.onError} />}\n </div>\n );\n}\n\ntype Row = { title: string; start: string; end: string; release: string };\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 seed = () => version.segments.map((s) => ({ title: s.title ?? \"\", start: String(s.start), end: String(s.end), release: toLocalInput(s.release_at) }));\n const [rows, setRows] = useState<Row[]>(seed);\n // Seeded again when the stored segments change.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => setRows(seed()), [JSON.stringify(version.segments)]);\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 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={() => {\n setSaved(false);\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 void save.run(() => client.contents.setSegments(content.id, version.id, segments)).then((d) => d && setSaved(true));\n }}\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 }) {\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?.groups?.length && (\n <section className=\"grid gap-3 border-t border-border pt-4\" data-ckui=\"content-groups\">\n <MembershipEditor 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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"}
|
|
@@ -21,7 +21,7 @@ export interface MembershipBoxProps {
|
|
|
21
21
|
className?: string;
|
|
22
22
|
appearance?: ContentKitUiAppearance;
|
|
23
23
|
}
|
|
24
|
-
/** A group's membership for the reader: member, join free, or join for its price. */
|
|
24
|
+
/** A group's membership for the reader: member, join free, or join for its price; nothing to join while it sells no membership. */
|
|
25
25
|
export declare function MembershipBox({ group, onCheckout, onSignIn, client: own, onError, className, appearance }: MembershipBoxProps): import('react').JSX.Element | null;
|
|
26
26
|
export interface GroupBannerProps {
|
|
27
27
|
/** The group the host already read; or give id. */
|
|
@@ -16,7 +16,7 @@ import { cn as x } from "cn";
|
|
|
16
16
|
//#region src/components/groups/banner.tsx
|
|
17
17
|
function S({ group: i, onCheckout: o, onSignIn: c, client: f, onError: p, className: m, appearance: _ }) {
|
|
18
18
|
let v = e(), { t: S } = v, C = r(f), w = g(n), T = d("membership.join", p), E = i.access;
|
|
19
|
-
if (!E || E.editor) return null;
|
|
19
|
+
if (!E || E.editor || !E.offer && !E.member && !E.unknown) return null;
|
|
20
20
|
let D = w?.viewer === null, O = c ?? w?.onSignIn, k = E.offer && Number(E.offer.terms.amount) > 0 ? E.offer : void 0;
|
|
21
21
|
return /* @__PURE__ */ b(t, {
|
|
22
22
|
appearance: _,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"banner.js","names":[],"sources":["../../../src/components/groups/banner.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useContext, useRef, useState, type ReactNode } from \"react\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport type { Edit, GroupAccess, GroupDetail, Sale } from \"../../client/generated/wire.js\";\nimport type { GroupImageSlot } from \"../../client/groups.js\";\nimport { decodeImage, type CropSource } from \"../../client/image.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { ContentKitContext, useContentKitClient, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useGroup } from \"../../react/groups.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Badge } from \"#ckui/ui/badge\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { ImageCropDialog } from \"../image-crop-dialog.js\";\nimport { contentError, ErrorLine, useAction } from \"../social/parts.js\";\nimport { priceLabel } from \"../content/paywall.js\";\nimport { GroupAvatar, GroupCover, type GroupLike } from \"./parts.js\";\n\nexport interface MembershipBoxProps {\n group: Pick<GroupDetail, \"id\" | \"kind\" | \"name\"> & { access?: GroupAccess };\n /** Buys a sold membership: the host creates the order through billing-ui. */\n onCheckout?: (o: { key: string; offer: Sale }) => void;\n /** Asks a signed-out visitor to sign in; default the provider's. */\n onSignIn?: () => void;\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** A group's membership for the reader: member, join free, or join for its price. */\nexport function MembershipBox({ group, onCheckout, onSignIn, client: own, onError, className, appearance }: MembershipBoxProps) {\n const m = useMessages();\n const { t } = m;\n const client = useContentKitClient(own);\n const ctx = useContext(ContentKitContext);\n const join = useAction(\"membership.join\", onError);\n const a = group.access;\n if (!a || a.editor) return null;\n const signedOut = ctx?.viewer === null;\n const signIn = onSignIn ?? ctx?.onSignIn;\n const offer: Sale | undefined = a.offer && Number(a.offer.terms.amount) > 0 ? a.offer : undefined;\n return (\n <ContentKitUiRoot appearance={appearance} className={cn(\"grid gap-2 rounded-lg border border-border p-3 text-sm\", className)} data-ckui=\"membership-box\" data-member={a.member}>\n {a.unknown ? (\n <p className=\"text-muted-foreground\">{t(\"membership.unknown\")}</p>\n ) : a.member ? (\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge>{t(\"membership.member\")}</Badge>\n {!offer && (\n <Button size=\"sm\" variant=\"ghost\" disabled={join.pending} onClick={() => void join.run(() => client.offers.join(group.id, false))}>\n {t(\"membership.leave\")}\n </Button>\n )}\n </div>\n ) : (\n <div className=\"grid gap-2\">\n <p className=\"text-muted-foreground\">{t(offer ? \"membership.paidPitch\" : \"membership.freePitch\")}</p>\n <Button\n size=\"sm\"\n className=\"justify-self-start\"\n disabled={join.pending || (!!offer && !onCheckout)}\n onClick={() => {\n if (signedOut && signIn) return signIn();\n if (offer) return onCheckout?.({ key: a.key, offer });\n void join.run(() => client.offers.join(group.id));\n }}\n >\n {offer ? t(\"membership.joinFor\", { price: priceLabel(m, offer.terms) }) : t(\"membership.join\")}\n </Button>\n </div>\n )}\n {join.error && <ErrorLine>{contentError(m, join.error)}</ErrorLine>}\n </ContentKitUiRoot>\n );\n}\n\nexport interface GroupBannerProps {\n /** The group the host already read; or give id. */\n group?: GroupDetail;\n id?: string;\n language?: string;\n onCheckout?: MembershipBoxProps[\"onCheckout\"];\n /** Beside the membership box: the host's actions (follow, share, edit). */\n children?: ReactNode;\n client?: ContentKitClient;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** A group's page head: its cover across, its avatar, name, description, content count and membership. */\nexport function GroupBanner(p: GroupBannerProps) {\n const m = useMessages();\n const read = useGroup(p.group ? null : p.id, { language: p.language, client: p.client });\n const g = p.group ?? read.group;\n if (!g) return read.error ? <ErrorLine>{contentError(m, read.error)}</ErrorLine> : <Skeleton className=\"h-48 w-full\" />;\n const text = g.text.find((x) => x.language === (p.language ?? g.name_language)) ?? g.text.find((x) => x.description);\n const count = g.counts.filter((c) => c.language === (p.language ?? \"\")).reduce((n, c) => n + c.count, 0);\n return (\n <ContentKitUiRoot appearance={p.appearance} className={cn(\"grid gap-3 text-sm\", p.className)} data-ckui=\"group-banner\" data-kind={g.kind}>\n <GroupCover group={g} className=\"aspect-[3/1] w-full\" />\n <div className=\"flex flex-wrap items-end gap-4 px-2 sm:px-4\">\n <GroupAvatar group={g} className=\"-mt-12 size-20 border-4 border-background sm:-mt-16 sm:size-28\" />\n <div className=\"grid min-w-0 flex-1 gap-1\">\n <h1 className=\"text-xl font-semibold break-words\">{g.name || g.slug}</h1>\n <p className=\"text-xs text-muted-foreground tabular-nums\">{m.plural(\"groups.items\", count)}</p>\n </div>\n <div className=\"flex flex-wrap items-start gap-2\">\n <MembershipBox group={g} onCheckout={p.onCheckout} client={p.client} />\n {p.children}\n </div>\n </div>\n {text?.description && <p className=\"px-2 break-words whitespace-pre-line sm:px-4\">{text.description}</p>}\n </ContentKitUiRoot>\n );\n}\n\nexport interface GroupImageEditorProps {\n group: GroupLike;\n /** The cover, or a user-owned kind's avatar. */\n slot: GroupImageSlot;\n /** Crop before uploading. Default true. */\n crop?: boolean;\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n className?: string;\n}\n\n/** A group's cover or avatar for its editors: pick (and crop) an image, upload it and select it; or go back to none (a cover: automatic). */\nexport function GroupImageEditor({ group, slot, crop = true, client, onError, className }: GroupImageEditorProps) {\n const { t } = useMessages();\n const g = useGroup(group.id, { client });\n const input = useRef<HTMLInputElement>(null);\n const save = useAction(\"group.save\", onError);\n const [source, setSource] = useState<CropSource | null>(null);\n const [file, setFile] = useState<File | null>(null);\n const shown = g.group ?? group;\n const set = slot === \"cover\" ? !!shown.cover?.image || (!!shown.cover?.content_id && !shown.cover.auto) : !!shown.avatar?.image;\n const upload = (f: Blob & { name?: string }, edit?: Edit) => save.run(() => g.uploadImage(slot, f, { wait: false, edit }));\n const close = () => {\n source?.revoke?.();\n setSource(null);\n setFile(null);\n };\n return (\n <div className={cn(\"flex flex-wrap items-center gap-3\", className)} data-ckui=\"group-image-editor\" data-slot={slot}>\n {slot === \"avatar\" ? <GroupAvatar group={shown} src={g.previews.avatar} className=\"size-16\" /> : <GroupCover group={shown} src={g.previews.cover} className=\"aspect-[3/1] w-48\" />}\n <div className=\"grid gap-2\">\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" size=\"sm\" variant=\"outline\" disabled={save.pending} onClick={() => input.current?.click()}>\n {save.pending ? t(\"groupEditor.uploading\") : t(slot === \"avatar\" ? \"groupEditor.uploadAvatar\" : \"groupEditor.uploadCover\")}\n </Button>\n {set && (\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" disabled={save.pending} onClick={() => void save.run(() => g.update(slot === \"cover\" ? { cover: {} } : { avatar: {} }))}>\n {t(slot === \"avatar\" ? \"groupEditor.removeAvatar\" : \"groupEditor.coverUseAuto\")}\n </Button>\n )}\n </div>\n <input\n ref={input}\n type=\"file\"\n accept=\"image/*\"\n hidden\n aria-label={t(slot === \"avatar\" ? \"groupEditor.uploadAvatar\" : \"groupEditor.uploadCover\")}\n onChange={(e) => {\n const f = e.target.files?.[0];\n e.target.value = \"\";\n if (!f) return;\n if (!crop) return void upload(f);\n decodeImage(f).then(\n (s) => {\n setFile(f);\n setSource(s);\n },\n () => void upload(f),\n );\n }}\n />\n <ErrorLine error={save.error} />\n </div>\n <ImageCropDialog\n open={!!source}\n onOpenChange={(open) => !open && close()}\n source={source}\n aspect={slot === \"avatar\" ? \"1:1\" : \"3:1\"}\n aspects={slot === \"avatar\" ? undefined : [\"3:1\", \"16:9\", \"\"]}\n round={slot === \"avatar\"}\n onConfirm={(edit) => {\n const f = file;\n close();\n if (f) void upload(f, edit ?? undefined);\n }}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"banner.js","names":[],"sources":["../../../src/components/groups/banner.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useContext, useRef, useState, type ReactNode } from \"react\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport type { Edit, GroupAccess, GroupDetail, Sale } from \"../../client/generated/wire.js\";\nimport type { GroupImageSlot } from \"../../client/groups.js\";\nimport { decodeImage, type CropSource } from \"../../client/image.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { ContentKitContext, useContentKitClient, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useGroup } from \"../../react/groups.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Badge } from \"#ckui/ui/badge\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { ImageCropDialog } from \"../image-crop-dialog.js\";\nimport { contentError, ErrorLine, useAction } from \"../social/parts.js\";\nimport { priceLabel } from \"../content/paywall.js\";\nimport { GroupAvatar, GroupCover, type GroupLike } from \"./parts.js\";\n\nexport interface MembershipBoxProps {\n group: Pick<GroupDetail, \"id\" | \"kind\" | \"name\"> & { access?: GroupAccess };\n /** Buys a sold membership: the host creates the order through billing-ui. */\n onCheckout?: (o: { key: string; offer: Sale }) => void;\n /** Asks a signed-out visitor to sign in; default the provider's. */\n onSignIn?: () => void;\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** A group's membership for the reader: member, join free, or join for its price; nothing to join while it sells no membership. */\nexport function MembershipBox({ group, onCheckout, onSignIn, client: own, onError, className, appearance }: MembershipBoxProps) {\n const m = useMessages();\n const { t } = m;\n const client = useContentKitClient(own);\n const ctx = useContext(ContentKitContext);\n const join = useAction(\"membership.join\", onError);\n const a = group.access;\n if (!a || a.editor || (!a.offer && !a.member && !a.unknown)) return null;\n const signedOut = ctx?.viewer === null;\n const signIn = onSignIn ?? ctx?.onSignIn;\n const offer: Sale | undefined = a.offer && Number(a.offer.terms.amount) > 0 ? a.offer : undefined;\n return (\n <ContentKitUiRoot appearance={appearance} className={cn(\"grid gap-2 rounded-lg border border-border p-3 text-sm\", className)} data-ckui=\"membership-box\" data-member={a.member}>\n {a.unknown ? (\n <p className=\"text-muted-foreground\">{t(\"membership.unknown\")}</p>\n ) : a.member ? (\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge>{t(\"membership.member\")}</Badge>\n {!offer && (\n <Button size=\"sm\" variant=\"ghost\" disabled={join.pending} onClick={() => void join.run(() => client.offers.join(group.id, false))}>\n {t(\"membership.leave\")}\n </Button>\n )}\n </div>\n ) : (\n <div className=\"grid gap-2\">\n <p className=\"text-muted-foreground\">{t(offer ? \"membership.paidPitch\" : \"membership.freePitch\")}</p>\n <Button\n size=\"sm\"\n className=\"justify-self-start\"\n disabled={join.pending || (!!offer && !onCheckout)}\n onClick={() => {\n if (signedOut && signIn) return signIn();\n if (offer) return onCheckout?.({ key: a.key, offer });\n void join.run(() => client.offers.join(group.id));\n }}\n >\n {offer ? t(\"membership.joinFor\", { price: priceLabel(m, offer.terms) }) : t(\"membership.join\")}\n </Button>\n </div>\n )}\n {join.error && <ErrorLine>{contentError(m, join.error)}</ErrorLine>}\n </ContentKitUiRoot>\n );\n}\n\nexport interface GroupBannerProps {\n /** The group the host already read; or give id. */\n group?: GroupDetail;\n id?: string;\n language?: string;\n onCheckout?: MembershipBoxProps[\"onCheckout\"];\n /** Beside the membership box: the host's actions (follow, share, edit). */\n children?: ReactNode;\n client?: ContentKitClient;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** A group's page head: its cover across, its avatar, name, description, content count and membership. */\nexport function GroupBanner(p: GroupBannerProps) {\n const m = useMessages();\n const read = useGroup(p.group ? null : p.id, { language: p.language, client: p.client });\n const g = p.group ?? read.group;\n if (!g) return read.error ? <ErrorLine>{contentError(m, read.error)}</ErrorLine> : <Skeleton className=\"h-48 w-full\" />;\n const text = g.text.find((x) => x.language === (p.language ?? g.name_language)) ?? g.text.find((x) => x.description);\n const count = g.counts.filter((c) => c.language === (p.language ?? \"\")).reduce((n, c) => n + c.count, 0);\n return (\n <ContentKitUiRoot appearance={p.appearance} className={cn(\"grid gap-3 text-sm\", p.className)} data-ckui=\"group-banner\" data-kind={g.kind}>\n <GroupCover group={g} className=\"aspect-[3/1] w-full\" />\n <div className=\"flex flex-wrap items-end gap-4 px-2 sm:px-4\">\n <GroupAvatar group={g} className=\"-mt-12 size-20 border-4 border-background sm:-mt-16 sm:size-28\" />\n <div className=\"grid min-w-0 flex-1 gap-1\">\n <h1 className=\"text-xl font-semibold break-words\">{g.name || g.slug}</h1>\n <p className=\"text-xs text-muted-foreground tabular-nums\">{m.plural(\"groups.items\", count)}</p>\n </div>\n <div className=\"flex flex-wrap items-start gap-2\">\n <MembershipBox group={g} onCheckout={p.onCheckout} client={p.client} />\n {p.children}\n </div>\n </div>\n {text?.description && <p className=\"px-2 break-words whitespace-pre-line sm:px-4\">{text.description}</p>}\n </ContentKitUiRoot>\n );\n}\n\nexport interface GroupImageEditorProps {\n group: GroupLike;\n /** The cover, or a user-owned kind's avatar. */\n slot: GroupImageSlot;\n /** Crop before uploading. Default true. */\n crop?: boolean;\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n className?: string;\n}\n\n/** A group's cover or avatar for its editors: pick (and crop) an image, upload it and select it; or go back to none (a cover: automatic). */\nexport function GroupImageEditor({ group, slot, crop = true, client, onError, className }: GroupImageEditorProps) {\n const { t } = useMessages();\n const g = useGroup(group.id, { client });\n const input = useRef<HTMLInputElement>(null);\n const save = useAction(\"group.save\", onError);\n const [source, setSource] = useState<CropSource | null>(null);\n const [file, setFile] = useState<File | null>(null);\n const shown = g.group ?? group;\n const set = slot === \"cover\" ? !!shown.cover?.image || (!!shown.cover?.content_id && !shown.cover.auto) : !!shown.avatar?.image;\n const upload = (f: Blob & { name?: string }, edit?: Edit) => save.run(() => g.uploadImage(slot, f, { wait: false, edit }));\n const close = () => {\n source?.revoke?.();\n setSource(null);\n setFile(null);\n };\n return (\n <div className={cn(\"flex flex-wrap items-center gap-3\", className)} data-ckui=\"group-image-editor\" data-slot={slot}>\n {slot === \"avatar\" ? <GroupAvatar group={shown} src={g.previews.avatar} className=\"size-16\" /> : <GroupCover group={shown} src={g.previews.cover} className=\"aspect-[3/1] w-48\" />}\n <div className=\"grid gap-2\">\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" size=\"sm\" variant=\"outline\" disabled={save.pending} onClick={() => input.current?.click()}>\n {save.pending ? t(\"groupEditor.uploading\") : t(slot === \"avatar\" ? \"groupEditor.uploadAvatar\" : \"groupEditor.uploadCover\")}\n </Button>\n {set && (\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" disabled={save.pending} onClick={() => void save.run(() => g.update(slot === \"cover\" ? { cover: {} } : { avatar: {} }))}>\n {t(slot === \"avatar\" ? \"groupEditor.removeAvatar\" : \"groupEditor.coverUseAuto\")}\n </Button>\n )}\n </div>\n <input\n ref={input}\n type=\"file\"\n accept=\"image/*\"\n hidden\n aria-label={t(slot === \"avatar\" ? \"groupEditor.uploadAvatar\" : \"groupEditor.uploadCover\")}\n onChange={(e) => {\n const f = e.target.files?.[0];\n e.target.value = \"\";\n if (!f) return;\n if (!crop) return void upload(f);\n decodeImage(f).then(\n (s) => {\n setFile(f);\n setSource(s);\n },\n () => void upload(f),\n );\n }}\n />\n <ErrorLine error={save.error} />\n </div>\n <ImageCropDialog\n open={!!source}\n onOpenChange={(open) => !open && close()}\n source={source}\n aspect={slot === \"avatar\" ? \"1:1\" : \"3:1\"}\n aspects={slot === \"avatar\" ? undefined : [\"3:1\", \"16:9\", \"\"]}\n round={slot === \"avatar\"}\n onConfirm={(edit) => {\n const f = file;\n close();\n if (f) void upload(f, edit ?? undefined);\n }}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgCA,SAAgB,EAAc,EAAE,UAAO,eAAY,aAAU,QAAQ,GAAK,YAAS,cAAW,iBAAkC;CAC9H,IAAM,IAAI,EAAY,GAChB,EAAE,SAAM,GACR,IAAS,EAAoB,CAAG,GAChC,IAAM,EAAW,CAAiB,GAClC,IAAO,EAAU,mBAAmB,CAAO,GAC3C,IAAI,EAAM;CAChB,IAAI,CAAC,KAAK,EAAE,UAAW,CAAC,EAAE,SAAS,CAAC,EAAE,UAAU,CAAC,EAAE,SAAU,OAAO;CACpE,IAAM,IAAY,GAAK,WAAW,MAC5B,IAAS,KAAY,GAAK,UAC1B,IAA0B,EAAE,SAAS,OAAO,EAAE,MAAM,MAAM,MAAM,IAAI,IAAI,EAAE,QAAQ,KAAA;CACxF,OACE,kBAAC,GAAD;EAA8B;EAAY,WAAW,EAAG,0DAA0D,CAAS;EAAG,aAAU;EAAiB,eAAa,EAAE;EAAxK,UAAA,CACG,EAAE,UACD,kBAAC,KAAD;GAAG,WAAU;GAAyB,UAAA,EAAE,oBAAoB;EAAK,CAAA,IAC/D,EAAE,SACJ,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,kBAAC,GAAD,EAAA,UAAQ,EAAE,mBAAmB,EAAS,CAAA,GACrC,CAAC,KACA,kBAAC,GAAD;IAAQ,MAAK;IAAK,SAAQ;IAAQ,UAAU,EAAK;IAAS,eAAe,KAAK,EAAK,UAAU,EAAO,OAAO,KAAK,EAAM,IAAI,EAAK,CAAC;IAC7H,UAAA,EAAE,kBAAkB;GACf,CAAA,CAEP;EAEL,CAAA,IAAA,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,kBAAC,KAAD;IAAG,WAAU;IAAyB,UAAA,EAAE,IAAQ,yBAAyB,sBAAsB;GAAK,CAAA,GACpG,kBAAC,GAAD;IACE,MAAK;IACL,WAAU;IACV,UAAU,EAAK,WAAY,CAAC,CAAC,KAAS,CAAC;IACvC,eAAe;KACb,IAAI,KAAa,GAAQ,OAAO,EAAO;KACvC,IAAI,GAAO,OAAO,IAAa;MAAE,KAAK,EAAE;MAAK;KAAM,CAAC;KACpD,EAAU,UAAU,EAAO,OAAO,KAAK,EAAM,EAAE,CAAC;IAClD;IAEC,UAAA,IAAQ,EAAE,sBAAsB,EAAE,OAAO,EAAW,GAAG,EAAM,KAAK,EAAE,CAAC,IAAI,EAAE,iBAAiB;GACvF,CAAA,CACL;EAEN,CAAA,GAAA,EAAK,SAAS,kBAAC,GAAD,EAAA,UAAY,EAAa,GAAG,EAAK,KAAK,EAAa,CAAA,CAClD;;AAEtB;AAgBA,SAAgB,EAAY,GAAqB;CAC/C,IAAM,IAAI,EAAY,GAChB,IAAO,EAAS,EAAE,QAAQ,OAAO,EAAE,IAAI;EAAE,UAAU,EAAE;EAAU,QAAQ,EAAE;CAAO,CAAC,GACjF,IAAI,EAAE,SAAS,EAAK;CAC1B,IAAI,CAAC,GAAG,OAAO,EAAK,QAAQ,kBAAC,GAAD,EAAA,UAAY,EAAa,GAAG,EAAK,KAAK,EAAa,CAAA,IAAI,kBAAC,GAAD,EAAU,WAAU,cAAe,CAAA;CACtH,IAAM,IAAO,EAAE,KAAK,MAAM,MAAM,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,KAAK,EAAE,KAAK,MAAM,MAAM,EAAE,WAAW,GAC7G,IAAQ,EAAE,OAAO,QAAQ,MAAM,EAAE,cAAc,EAAE,YAAY,GAAG,CAAC,CAAC,QAAQ,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC;CACvG,OACE,kBAAC,GAAD;EAAkB,YAAY,EAAE;EAAY,WAAW,EAAG,sBAAsB,EAAE,SAAS;EAAG,aAAU;EAAe,aAAW,EAAE;EAApI,UAAA;GACE,kBAAC,GAAD;IAAY,OAAO;IAAG,WAAU;GAAuB,CAAA;GACvD,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,kBAAC,GAAD;MAAa,OAAO;MAAG,WAAU;KAAkE,CAAA;KACnG,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC,MAAD;OAAI,WAAU;OAAqC,UAAA,EAAE,QAAQ,EAAE;MAAS,CAAA,GACxE,kBAAC,KAAD;OAAG,WAAU;OAA8C,UAAA,EAAE,OAAO,gBAAgB,CAAK;MAAK,CAAA,CAC3F;;KACL,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC,GAAD;OAAe,OAAO;OAAG,YAAY,EAAE;OAAY,QAAQ,EAAE;MAAS,CAAA,GACrE,EAAE,QACA;;IACF;;GACJ,GAAM,eAAe,kBAAC,KAAD;IAAG,WAAU;IAAgD,UAAA,EAAK;GAAe,CAAA;EACvF;;AAEtB;AAcA,SAAgB,EAAiB,EAAE,UAAO,SAAM,UAAO,IAAM,WAAQ,YAAS,gBAAoC;CAChH,IAAM,EAAE,SAAM,EAAY,GACpB,IAAI,EAAS,EAAM,IAAI,EAAE,UAAO,CAAC,GACjC,IAAQ,EAAyB,IAAI,GACrC,IAAO,EAAU,cAAc,CAAO,GACtC,CAAC,GAAQ,KAAa,EAA4B,IAAI,GACtD,CAAC,GAAM,KAAW,EAAsB,IAAI,GAC5C,IAAQ,EAAE,SAAS,GACnB,IAAM,MAAS,UAAU,CAAC,CAAC,EAAM,OAAO,SAAU,CAAC,CAAC,EAAM,OAAO,cAAc,CAAC,EAAM,MAAM,OAAQ,CAAC,CAAC,EAAM,QAAQ,OACpH,KAAU,GAA6B,MAAgB,EAAK,UAAU,EAAE,YAAY,GAAM,GAAG;EAAE,MAAM;EAAO;CAAK,CAAC,CAAC,GACnH,UAAc;EAGlB,AAFA,GAAQ,SAAS,GACjB,EAAU,IAAI,GACd,EAAQ,IAAI;CACd;CACA,OACE,kBAAC,OAAD;EAAK,WAAW,EAAG,qCAAqC,CAAS;EAAG,aAAU;EAAqB,aAAW;EAA9G,UAAA;GACG,MAAS,WAAW,kBAAC,GAAD;IAAa,OAAO;IAAO,KAAK,EAAE,SAAS;IAAQ,WAAU;GAAW,CAAA,IAAI,kBAAC,GAAD;IAAY,OAAO;IAAO,KAAK,EAAE,SAAS;IAAO,WAAU;GAAqB,CAAA;GACjL,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC,GAAD;OAAQ,MAAK;OAAS,MAAK;OAAK,SAAQ;OAAU,UAAU,EAAK;OAAS,eAAe,EAAM,SAAS,MAAM;OAC3G,UAAA,EAAK,UAAU,EAAE,uBAAuB,IAAI,EAAE,MAAS,WAAW,6BAA6B,yBAAyB;MACnH,CAAA,GACP,KACC,kBAAC,GAAD;OAAQ,MAAK;OAAS,MAAK;OAAK,SAAQ;OAAQ,UAAU,EAAK;OAAS,eAAe,KAAK,EAAK,UAAU,EAAE,OAAO,MAAS,UAAU,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;OACnK,UAAA,EAAE,MAAS,WAAW,6BAA6B,0BAA0B;MACxE,CAAA,CAEP;;KACL,kBAAC,SAAD;MACE,KAAK;MACL,MAAK;MACL,QAAO;MACP,QAAA;MACA,cAAY,EAAE,MAAS,WAAW,6BAA6B,yBAAyB;MACxF,WAAW,MAAM;OACf,IAAM,IAAI,EAAE,OAAO,QAAQ;OAC3B,MAAE,OAAO,QAAQ,IACZ,GACL;YAAI,CAAC,GAAM,OAAO,KAAK,EAAO,CAAC;QAC/B,EAAY,CAAC,CAAC,CAAC,MACZ,MAAM;SAEL,AADA,EAAQ,CAAC,GACT,EAAU,CAAC;QACb,SACM,KAAK,EAAO,CAAC,CACrB;OAP+B;MAQjC;KACD,CAAA;KACD,kBAAC,GAAD,EAAW,OAAO,EAAK,MAAQ,CAAA;IAC5B;;GACL,kBAAC,GAAD;IACE,MAAM,CAAC,CAAC;IACR,eAAe,MAAS,CAAC,KAAQ,EAAM;IAC/B;IACR,QAAQ,MAAS,WAAW,QAAQ;IACpC,SAAS,MAAS,WAAW,KAAA,IAAY;KAAC;KAAO;KAAQ;IAAE;IAC3D,OAAO,MAAS;IAChB,YAAY,MAAS;KACnB,IAAM,IAAI;KAEV,AADA,EAAM,GACF,KAAG,EAAY,GAAG,KAAQ,KAAA,CAAS;IACzC;GACD,CAAA;EACE;;AAET"}
|
|
@@ -746,16 +746,16 @@ function ne({ group: e, spec: n, onError: r, client: i }) {
|
|
|
746
746
|
});
|
|
747
747
|
}
|
|
748
748
|
function re({ group: e, onError: n, client: i }) {
|
|
749
|
-
let { t: a } = t(), o = r(i), s = C("offer.save", n)
|
|
749
|
+
let { t: a } = t(), o = r(i), s = C("offer.save", n);
|
|
750
750
|
return /* @__PURE__ */ U(q, {
|
|
751
751
|
title: a("groupEditor.membershipPrice"),
|
|
752
752
|
ckui: "group-offer",
|
|
753
753
|
children: [/* @__PURE__ */ H(M, {
|
|
754
|
-
offer:
|
|
754
|
+
offer: e.offer,
|
|
755
755
|
pending: s.pending,
|
|
756
756
|
onSell: (t) => void s.run(() => o.offers.sellGroup(e.id, t)),
|
|
757
757
|
onWithdraw: () => void s.run(() => o.offers.withdrawGroup(e.id))
|
|
758
|
-
}), /* @__PURE__ */ H(x, { error: s.error })]
|
|
758
|
+
}, e.offer?.revision), /* @__PURE__ */ H(x, { error: s.error })]
|
|
759
759
|
});
|
|
760
760
|
}
|
|
761
761
|
var ie = /^[a-z][a-z0-9_]*$/;
|