@openrails/contentkit-ui 0.87.0 → 0.89.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/client/generated/routes.d.ts +1 -1
  2. package/dist/client/generated/routes.js +1 -1
  3. package/dist/client/generated/routes.js.map +1 -1
  4. package/dist/client/generated/wire.d.ts +7 -0
  5. package/dist/client/generated/wire.js.map +1 -1
  6. package/dist/client/media/rules.js +1 -1
  7. package/dist/client/media/rules.js.map +1 -1
  8. package/dist/client/public.d.ts +2 -1
  9. package/dist/client/public.js +2 -2
  10. package/dist/client/public.js.map +1 -1
  11. package/dist/client/stats.d.ts +1 -1
  12. package/dist/client/stats.js.map +1 -1
  13. package/dist/components/billing-notification.d.ts +11 -0
  14. package/dist/components/billing-notification.js +70 -0
  15. package/dist/components/billing-notification.js.map +1 -0
  16. package/dist/components/content/card.d.ts +1 -1
  17. package/dist/components/content/card.js +132 -120
  18. package/dist/components/content/card.js.map +1 -1
  19. package/dist/components/content/filters.d.ts +1 -1
  20. package/dist/components/content/filters.js +2 -5
  21. package/dist/components/content/filters.js.map +1 -1
  22. package/dist/components/content/reader-stats.d.ts +11 -3
  23. package/dist/components/content/reader-stats.js +41 -23
  24. package/dist/components/content/reader-stats.js.map +1 -1
  25. package/dist/index.d.ts +1 -0
  26. package/dist/index.js +3 -2
  27. package/dist/locales/content/de.js +4 -0
  28. package/dist/locales/content/de.js.map +1 -1
  29. package/dist/locales/content/en.d.ts +4 -0
  30. package/dist/locales/content/en.js +4 -0
  31. package/dist/locales/content/en.js.map +1 -1
  32. package/dist/locales/content/es.js +4 -0
  33. package/dist/locales/content/es.js.map +1 -1
  34. package/dist/locales/content/ja.js +4 -0
  35. package/dist/locales/content/ja.js.map +1 -1
  36. package/dist/locales/content/ko.js +4 -0
  37. package/dist/locales/content/ko.js.map +1 -1
  38. package/dist/locales/content/zh.js +4 -0
  39. package/dist/locales/content/zh.js.map +1 -1
  40. package/dist/locales/en.d.ts +34 -0
  41. package/dist/locales/social/de.js +30 -0
  42. package/dist/locales/social/de.js.map +1 -1
  43. package/dist/locales/social/en.d.ts +30 -0
  44. package/dist/locales/social/en.js +30 -0
  45. package/dist/locales/social/en.js.map +1 -1
  46. package/dist/locales/social/es.js +30 -0
  47. package/dist/locales/social/es.js.map +1 -1
  48. package/dist/locales/social/ja.js +30 -0
  49. package/dist/locales/social/ja.js.map +1 -1
  50. package/dist/locales/social/ko.js +30 -0
  51. package/dist/locales/social/ko.js.map +1 -1
  52. package/dist/locales/social/zh.js +30 -0
  53. package/dist/locales/social/zh.js.map +1 -1
  54. package/dist/react/public.d.ts +3 -3
  55. package/dist/react/public.js +64 -25
  56. package/dist/react/public.js.map +1 -1
  57. package/dist/styles.css +1 -1
  58. package/package.json +5 -5
@@ -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 { 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\nexport interface ContentFilterSettingsProps {\n /** Labels and group names in this language; default the provider's. */\n language?: string;\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/** The signed-in reader's content filters: show or hide each configured group, and go back to its default. */\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 (ctx?.viewer === null) return root(<p className=\"text-muted-foreground\">{t(\"contents.filtersSignedOut\")}</p>);\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 return root(\n <>\n {filters.filters.length ? (\n <ul className=\"grid divide-y divide-border rounded-lg border border-border\">\n {filters.filters.map((x) => (\n <li key={x.group.id} className=\"flex flex-wrap items-center gap-3 p-3\" data-ckui=\"content-filter\" data-slug={x.group.slug} data-visible={x.visible}>\n <Switch id={`${id}-${x.group.id}`} checked={x.visible} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setVisible(x.group.id, v))} />\n <Label htmlFor={`${id}-${x.group.id}`} className=\"min-w-0 flex-1\">\n {x.label || x.group.name}\n </Label>\n <span className=\"text-xs text-muted-foreground\">{t(x.visible ? \"contents.shown\" : \"contents.hidden\")}</span>\n {x.overridden && (\n <Button\n size=\"xs\"\n variant=\"ghost\"\n disabled={save.pending}\n onClick={() =>\n void save.run(() =>\n f.save({\n filters: filters.filters.filter((y) => y.overridden && y.group.id !== x.group.id).map((y) => ({ group_id: y.group.id, visible: y.visible })),\n include_deleted: filters.include_deleted,\n }),\n )\n }\n >\n {t(\"contents.useDefault\")}\n </Button>\n )}\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-muted-foreground\">{t(\"contents.noFilters\")}</p>\n )}\n {p.includeDeleted !== false && (\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 <ErrorLine>{contentError(m, dates.error)}</ErrorLine>\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 <Button variant=\"outline\" size=\"sm\" className=\"justify-self-center\" disabled={dates.loadingMore} onClick={() => void dates.loadMore()}>\n {t(\"contents.loadMore\")}\n </Button>\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 { 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\nexport interface ContentFilterSettingsProps {\n /** Labels and group names in this language; default the provider's. */\n language?: string;\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/** The signed-in reader's content filters: show or hide each configured group, and go back to its default. */\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 (ctx?.viewer === null) return root(<p className=\"text-muted-foreground\">{t(\"contents.filtersSignedOut\")}</p>);\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 if (!filters.filters.length && p.includeDeleted === false) return null;\n return root(\n <>\n {filters.filters.length ? (\n <ul className=\"grid divide-y divide-border rounded-lg border border-border\">\n {filters.filters.map((x) => (\n <li key={x.group.id} className=\"flex flex-wrap items-center gap-3 p-3\" data-ckui=\"content-filter\" data-slug={x.group.slug} data-visible={x.visible}>\n <Switch id={`${id}-${x.group.id}`} checked={x.visible} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setVisible(x.group.id, v))} />\n <Label htmlFor={`${id}-${x.group.id}`} className=\"min-w-0 flex-1\">\n {x.label || x.group.name}\n </Label>\n <span className=\"text-xs text-muted-foreground\">{t(x.visible ? \"contents.shown\" : \"contents.hidden\")}</span>\n {x.overridden && (\n <Button\n size=\"xs\"\n variant=\"ghost\"\n disabled={save.pending}\n onClick={() =>\n void save.run(() =>\n f.save({\n filters: filters.filters.filter((y) => y.overridden && y.group.id !== x.group.id).map((y) => ({ group_id: y.group.id, visible: y.visible })),\n include_deleted: filters.include_deleted,\n }),\n )\n }\n >\n {t(\"contents.useDefault\")}\n </Button>\n )}\n </li>\n ))}\n </ul>\n ) : null}\n {p.includeDeleted !== false && (\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 <ErrorLine>{contentError(m, dates.error)}</ErrorLine>\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 <Button variant=\"outline\" size=\"sm\" className=\"justify-self-center\" disabled={dates.loadingMore} onClick={() => void dates.loadMore()}>\n {t(\"contents.loadMore\")}\n </Button>\n )}\n </ContentKitUiRoot>\n );\n}\n"],"mappings":"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"}
@@ -2,11 +2,19 @@ import { ContentKitUiAppearance } from '../../appearance.js';
2
2
  import { ContentKitClient } from '../../client/client.js';
3
3
  import { Labels } from '../groups/parts.js';
4
4
  export interface ReaderStatsProps {
5
- /** Display names of content kinds by identifier. */
5
+ /** Display names of content kinds and access tiers by identifier. */
6
6
  labels?: Labels;
7
+ /** Complete labels for finished-content counts, e.g. {gallery: "Galleries read"}. */
8
+ completedLabels?: Labels;
9
+ /** Content kinds to show, including an unavailable placeholder. Default: returned kinds. */
10
+ kinds?: readonly string[];
11
+ /** Access tiers to show, including an unavailable placeholder. Default: returned tiers. */
12
+ tiers?: readonly string[];
13
+ /** Include received dislikes. Defaults to true. */
14
+ showDislikes?: boolean;
7
15
  client?: ContentKitClient;
8
16
  appearance?: ContentKitUiAppearance;
9
17
  className?: string;
10
18
  }
11
- /** The signed-in reader's activity: contents finished per kind, their comments and the reactions those received. Nothing signed out. */
12
- export declare function ReaderStats({ labels, client, appearance, className }: ReaderStatsProps): import('react').JSX.Element | null;
19
+ /** The signed-in reader's activity and elapsed tier access. Nothing signed out. */
20
+ export declare function ReaderStats({ labels, completedLabels, kinds, tiers, showDislikes, client, appearance, className }: ReaderStatsProps): import('react').JSX.Element | null;
@@ -4,44 +4,62 @@ import { Skeleton as n } from "../../ui/skeleton.js";
4
4
  import { contentError as r } from "../social/parts.js";
5
5
  import { labelOf as i } from "../groups/parts.js";
6
6
  import { useMyStats as a } from "../../react/stats.js";
7
- import { jsx as o, jsxs as s } from "react/jsx-runtime";
8
- import { cn as c } from "cn";
7
+ import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
8
+ import { cn as l } from "cn";
9
9
  //#region src/components/content/reader-stats.tsx
10
- function l({ labels: l, client: u, appearance: d, className: f }) {
11
- let p = e(), { t: m } = p, h = a({ client: u }), g = (e) => /* @__PURE__ */ o(t, {
12
- appearance: d,
13
- className: c("grid gap-3 text-sm", f),
10
+ function u({ labels: u, completedLabels: d, kinds: f, tiers: p, showDislikes: m = !0, client: h, appearance: g, className: _ }) {
11
+ let v = e(), { t: y } = v, b = a({ client: h }), x = (e) => /* @__PURE__ */ s(t, {
12
+ appearance: g,
13
+ className: l("grid gap-3 text-sm", _),
14
14
  "data-ckui": "reader-stats",
15
15
  children: e
16
16
  });
17
- if (h.error) return g(/* @__PURE__ */ o("p", {
17
+ if (b.error) return x(/* @__PURE__ */ s("p", {
18
18
  role: "alert",
19
19
  className: "text-destructive",
20
- children: r(p, h.error)
20
+ children: r(v, b.error)
21
21
  }));
22
- if (!h.data) return h.loading ? g(/* @__PURE__ */ o(n, { className: "h-16 w-full" })) : null;
23
- let _ = [
24
- ...Object.entries(h.data.completed).map(([e, t]) => [m("myStats.completed", { kind: i(l, e) }), t]),
25
- [m("myStats.comments"), h.data.comments],
26
- [m("myStats.likes"), h.data.comment_likes],
27
- [m("myStats.dislikes"), h.data.comment_dislikes]
22
+ if (!b.data) return b.loading ? x(/* @__PURE__ */ s(n, { className: "h-16 w-full" })) : null;
23
+ let S = b.data, C = (e) => e === void 0 ? "—" : new Intl.NumberFormat(v.language).format(e), w = 86400, T = 30 * w, E = (e) => {
24
+ if (e === void 0) return "—";
25
+ let t = e < T ? "day" : "month", n = Math.max(+(e > 0), Math.floor(e / (t === "day" ? w : T)));
26
+ return new Intl.NumberFormat(v.language, {
27
+ style: "unit",
28
+ unit: t,
29
+ unitDisplay: "long"
30
+ }).format(n);
31
+ }, D = f ?? Object.keys(S.completed), O = p ?? Object.keys(S.access_seconds ?? {}), k = D.some((e) => S.completed[e] === void 0) || O.some((e) => S.access_seconds?.[e] === void 0), A = [
32
+ ...O.map((e) => [
33
+ y("myStats.accessFor", { tier: i(u, e) }),
34
+ E(S.access_seconds?.[e]),
35
+ y("myStats.accessDescription")
36
+ ]),
37
+ ...D.map((e) => [d?.[e] ?? y("myStats.completed", { kind: i(u, e) }), C(S.completed[e])]),
38
+ [y("myStats.comments"), C(S.comments)],
39
+ [y("myStats.likes"), C(S.comment_likes)],
40
+ ...m ? [[y("myStats.dislikes"), C(S.comment_dislikes)]] : []
28
41
  ];
29
- return g(/* @__PURE__ */ o("dl", {
30
- className: "grid grid-cols-2 gap-3 sm:grid-cols-4",
31
- children: _.map(([e, t]) => /* @__PURE__ */ s("div", {
32
- className: "grid gap-0.5 rounded-lg border border-border p-3",
42
+ return x(/* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s("dl", {
43
+ className: l("grid grid-cols-2 gap-3", A.length === 4 ? "lg:grid-cols-4" : "sm:grid-cols-3 lg:grid-cols-5"),
44
+ children: A.map(([e, t, n]) => /* @__PURE__ */ c("div", {
45
+ className: "grid gap-1 rounded-lg border border-border p-4",
33
46
  "data-ckui": "reader-stat",
34
- children: [/* @__PURE__ */ o("dt", {
47
+ title: n,
48
+ children: [/* @__PURE__ */ s("dt", {
35
49
  className: "text-xs text-muted-foreground",
36
50
  children: e
37
- }), /* @__PURE__ */ o("dd", {
38
- className: "text-lg font-semibold tabular-nums",
51
+ }), /* @__PURE__ */ s("dd", {
52
+ className: "text-xl font-semibold tabular-nums",
39
53
  children: t
40
54
  })]
41
55
  }, e))
42
- }));
56
+ }), k ? /* @__PURE__ */ s("p", {
57
+ className: "text-xs text-muted-foreground",
58
+ role: "status",
59
+ children: y("myStats.unavailable")
60
+ }) : null] }));
43
61
  }
44
62
  //#endregion
45
- export { l as ReaderStats };
63
+ export { u as ReaderStats };
46
64
 
47
65
  //# sourceMappingURL=reader-stats.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reader-stats.js","names":[],"sources":["../../../src/components/content/reader-stats.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport type { ReactNode } from \"react\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { useMyStats } from \"../../react/stats.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { labelOf, type Labels } from \"../groups/parts.js\";\nimport { contentError } from \"../social/parts.js\";\n\nexport interface ReaderStatsProps {\n /** Display names of content kinds by identifier. */\n labels?: Labels;\n client?: ContentKitClient;\n appearance?: ContentKitUiAppearance;\n className?: string;\n}\n\n/** The signed-in reader's activity: contents finished per kind, their comments and the reactions those received. Nothing signed out. */\nexport function ReaderStats({ labels, client, appearance, className }: ReaderStatsProps) {\n const m = useMessages();\n const { t } = m;\n const s = useMyStats({ client });\n const root = (children: ReactNode) => (\n <ContentKitUiRoot appearance={appearance} className={cn(\"grid gap-3 text-sm\", className)} data-ckui=\"reader-stats\">\n {children}\n </ContentKitUiRoot>\n );\n if (s.error) return root(<p role=\"alert\" className=\"text-destructive\">{contentError(m, s.error)}</p>);\n if (!s.data) return s.loading ? root(<Skeleton className=\"h-16 w-full\" />) : null;\n const stats: [string, number][] = [\n ...Object.entries(s.data.completed).map(([kind, n]): [string, number] => [t(\"myStats.completed\", { kind: labelOf(labels, kind) }), n]),\n [t(\"myStats.comments\"), s.data.comments],\n [t(\"myStats.likes\"), s.data.comment_likes],\n [t(\"myStats.dislikes\"), s.data.comment_dislikes],\n ];\n return root(\n <dl className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n {stats.map(([label, n]) => (\n <div key={label} className=\"grid gap-0.5 rounded-lg border border-border p-3\" data-ckui=\"reader-stat\">\n <dt className=\"text-xs text-muted-foreground\">{label}</dt>\n <dd className=\"text-lg font-semibold tabular-nums\">{n}</dd>\n </div>\n ))}\n </dl>,\n );\n}\n"],"mappings":";;;;;;;;;AAoBA,SAAgB,EAAY,EAAE,WAAQ,WAAQ,eAAY,gBAA+B;CACvF,IAAM,IAAI,EAAY,GAChB,EAAE,SAAM,GACR,IAAI,EAAW,EAAE,UAAO,CAAC,GACzB,KAAQ,MACZ,kBAAC,GAAD;EAA8B;EAAY,WAAW,EAAG,sBAAsB,CAAS;EAAG,aAAU;EACjG;CACe,CAAA;CAEpB,IAAI,EAAE,OAAO,OAAO,EAAK,kBAAC,KAAD;EAAG,MAAK;EAAQ,WAAU;EAAoB,UAAA,EAAa,GAAG,EAAE,KAAK;CAAK,CAAA,CAAC;CACpG,IAAI,CAAC,EAAE,MAAM,OAAO,EAAE,UAAU,EAAK,kBAAC,GAAD,EAAU,WAAU,cAAe,CAAA,CAAC,IAAI;CAC7E,IAAM,IAA4B;EAChC,GAAG,OAAO,QAAQ,EAAE,KAAK,SAAS,CAAC,CAAC,KAAK,CAAC,GAAM,OAAyB,CAAC,EAAE,qBAAqB,EAAE,MAAM,EAAQ,GAAQ,CAAI,EAAE,CAAC,GAAG,CAAC,CAAC;EACrI,CAAC,EAAE,kBAAkB,GAAG,EAAE,KAAK,QAAQ;EACvC,CAAC,EAAE,eAAe,GAAG,EAAE,KAAK,aAAa;EACzC,CAAC,EAAE,kBAAkB,GAAG,EAAE,KAAK,gBAAgB;CACjD;CACA,OAAO,EACL,kBAAC,MAAD;EAAI,WAAU;EACX,UAAA,EAAM,KAAK,CAAC,GAAO,OAClB,kBAAC,OAAD;GAAiB,WAAU;GAAmD,aAAU;GAAxF,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;IAAiC,UAAA;GAAU,CAAA,GACzD,kBAAC,MAAD;IAAI,WAAU;IAAsC,UAAA;GAAM,CAAA,CACvD;EAHK,GAAA,CAGL,CACN;CACC,CAAA,CACN;AACF"}
1
+ {"version":3,"file":"reader-stats.js","names":[],"sources":["../../../src/components/content/reader-stats.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport type { ReactNode } from \"react\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { useMyStats } from \"../../react/stats.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { labelOf, type Labels } from \"../groups/parts.js\";\nimport { contentError } from \"../social/parts.js\";\n\nexport interface ReaderStatsProps {\n /** Display names of content kinds and access tiers by identifier. */\n labels?: Labels;\n /** Complete labels for finished-content counts, e.g. {gallery: \"Galleries read\"}. */\n completedLabels?: Labels;\n /** Content kinds to show, including an unavailable placeholder. Default: returned kinds. */\n kinds?: readonly string[];\n /** Access tiers to show, including an unavailable placeholder. Default: returned tiers. */\n tiers?: readonly string[];\n /** Include received dislikes. Defaults to true. */\n showDislikes?: boolean;\n client?: ContentKitClient;\n appearance?: ContentKitUiAppearance;\n className?: string;\n}\n\n/** The signed-in reader's activity and elapsed tier access. Nothing signed out. */\nexport function ReaderStats({ labels, completedLabels, kinds, tiers, showDislikes = true, client, appearance, className }: ReaderStatsProps) {\n const m = useMessages();\n const { t } = m;\n const s = useMyStats({ client });\n const root = (children: ReactNode) => (\n <ContentKitUiRoot appearance={appearance} className={cn(\"grid gap-3 text-sm\", className)} data-ckui=\"reader-stats\">\n {children}\n </ContentKitUiRoot>\n );\n if (s.error) return root(<p role=\"alert\" className=\"text-destructive\">{contentError(m, s.error)}</p>);\n if (!s.data) return s.loading ? root(<Skeleton className=\"h-16 w-full\" />) : null;\n const data = s.data;\n const number = (value: number | undefined) => value === undefined ? \"—\" : new Intl.NumberFormat(m.language).format(value);\n const daySeconds = 24 * 60 * 60;\n const monthSeconds = 30 * daySeconds;\n const tenure = (seconds: number | undefined) => {\n if (seconds === undefined) return \"—\";\n const unit = seconds < monthSeconds ? \"day\" : \"month\";\n const count = Math.max(seconds > 0 ? 1 : 0, Math.floor(seconds / (unit === \"day\" ? daySeconds : monthSeconds)));\n return new Intl.NumberFormat(m.language, { style: \"unit\", unit, unitDisplay: \"long\" }).format(count);\n };\n const showKinds = kinds ?? Object.keys(data.completed);\n const showTiers = tiers ?? Object.keys(data.access_seconds ?? {});\n const unavailable = showKinds.some((kind) => data.completed[kind] === undefined) || showTiers.some((tier) => data.access_seconds?.[tier] === undefined);\n const stats: [string, string, string?][] = [\n ...showTiers.map((tier): [string, string, string] => [t(\"myStats.accessFor\", { tier: labelOf(labels, tier) }), tenure(data.access_seconds?.[tier]), t(\"myStats.accessDescription\")]),\n ...showKinds.map((kind): [string, string] => [completedLabels?.[kind] ?? t(\"myStats.completed\", { kind: labelOf(labels, kind) }), number(data.completed[kind])]),\n [t(\"myStats.comments\"), number(data.comments)],\n [t(\"myStats.likes\"), number(data.comment_likes)],\n ...(showDislikes ? [[t(\"myStats.dislikes\"), number(data.comment_dislikes)] as [string, string]] : []),\n ];\n return root(\n <>\n <dl className={cn(\"grid grid-cols-2 gap-3\", stats.length === 4 ? \"lg:grid-cols-4\" : \"sm:grid-cols-3 lg:grid-cols-5\")}>\n {stats.map(([label, value, description]) => (\n <div key={label} className=\"grid gap-1 rounded-lg border border-border p-4\" data-ckui=\"reader-stat\" title={description}>\n <dt className=\"text-xs text-muted-foreground\">{label}</dt>\n <dd className=\"text-xl font-semibold tabular-nums\">{value}</dd>\n </div>\n ))}\n </dl>\n {unavailable ? <p className=\"text-xs text-muted-foreground\" role=\"status\">{t(\"myStats.unavailable\")}</p> : null}\n </>,\n );\n}\n"],"mappings":";;;;;;;;;AA4BA,SAAgB,EAAY,EAAE,WAAQ,oBAAiB,UAAO,UAAO,kBAAe,IAAM,WAAQ,eAAY,gBAA+B;CAC3I,IAAM,IAAI,EAAY,GAChB,EAAE,SAAM,GACR,IAAI,EAAW,EAAE,UAAO,CAAC,GACzB,KAAQ,MACZ,kBAAC,GAAD;EAA8B;EAAY,WAAW,EAAG,sBAAsB,CAAS;EAAG,aAAU;EACjG;CACe,CAAA;CAEpB,IAAI,EAAE,OAAO,OAAO,EAAK,kBAAC,KAAD;EAAG,MAAK;EAAQ,WAAU;EAAoB,UAAA,EAAa,GAAG,EAAE,KAAK;CAAK,CAAA,CAAC;CACpG,IAAI,CAAC,EAAE,MAAM,OAAO,EAAE,UAAU,EAAK,kBAAC,GAAD,EAAU,WAAU,cAAe,CAAA,CAAC,IAAI;CAC7E,IAAM,IAAO,EAAE,MACT,KAAU,MAA8B,MAAU,KAAA,IAAY,MAAM,IAAI,KAAK,aAAa,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAK,GAClH,IAAa,OACb,IAAe,KAAK,GACpB,KAAU,MAAgC;EAC9C,IAAI,MAAY,KAAA,GAAW,OAAO;EAClC,IAAM,IAAO,IAAU,IAAe,QAAQ,SACxC,IAAQ,KAAK,IAAI,MAAU,IAAW,KAAK,MAAM,KAAW,MAAS,QAAQ,IAAa,EAAa,CAAC;EAC9G,OAAO,IAAI,KAAK,aAAa,EAAE,UAAU;GAAE,OAAO;GAAQ;GAAM,aAAa;EAAO,CAAC,CAAC,CAAC,OAAO,CAAK;CACrG,GACM,IAAY,KAAS,OAAO,KAAK,EAAK,SAAS,GAC/C,IAAY,KAAS,OAAO,KAAK,EAAK,kBAAkB,CAAC,CAAC,GAC1D,IAAc,EAAU,MAAM,MAAS,EAAK,UAAU,OAAU,KAAA,CAAS,KAAK,EAAU,MAAM,MAAS,EAAK,iBAAiB,OAAU,KAAA,CAAS,GAChJ,IAAqC;EACzC,GAAG,EAAU,KAAK,MAAmC;GAAC,EAAE,qBAAqB,EAAE,MAAM,EAAQ,GAAQ,CAAI,EAAE,CAAC;GAAG,EAAO,EAAK,iBAAiB,EAAK;GAAG,EAAE,2BAA2B;EAAC,CAAC;EACnL,GAAG,EAAU,KAAK,MAA2B,CAAC,IAAkB,MAAS,EAAE,qBAAqB,EAAE,MAAM,EAAQ,GAAQ,CAAI,EAAE,CAAC,GAAG,EAAO,EAAK,UAAU,EAAK,CAAC,CAAC;EAC/J,CAAC,EAAE,kBAAkB,GAAG,EAAO,EAAK,QAAQ,CAAC;EAC7C,CAAC,EAAE,eAAe,GAAG,EAAO,EAAK,aAAa,CAAC;EAC/C,GAAI,IAAe,CAAC,CAAC,EAAE,kBAAkB,GAAG,EAAO,EAAK,gBAAgB,CAAC,CAAqB,IAAI,CAAC;CACrG;CACA,OAAO,EACL,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,MAAD;EAAI,WAAW,EAAG,0BAA0B,EAAM,WAAW,IAAI,mBAAmB,+BAA+B;EAChH,UAAA,EAAM,KAAK,CAAC,GAAO,GAAO,OACzB,kBAAC,OAAD;GAAiB,WAAU;GAAiD,aAAU;GAAc,OAAO;GAA3G,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;IAAiC,UAAA;GAAU,CAAA,GACzD,kBAAC,MAAD;IAAI,WAAU;IAAsC,UAAA;GAAU,CAAA,CAC3D;EAHK,GAAA,CAGL,CACN;CACC,CAAA,GACH,IAAc,kBAAC,KAAD;EAAG,WAAU;EAAgC,MAAK;EAAU,UAAA,EAAE,qBAAqB;CAAK,CAAA,IAAI,IAC3G,EAAA,CAAA,CACJ;AACF"}
package/dist/index.d.ts CHANGED
@@ -34,3 +34,4 @@ export type { AdminNavigation, ContentKitAuth, StaffAccess, StaffArea } from './
34
34
  export { createTranslator, defaultMessages, defineMessages, resolveMessages, type MessageKey, type MessageVars, type Translator, type ContentKitUiMessageBundle, type ContentKitUiMessages, type ContentKitUiTranslate, } from './i18n/messages.js';
35
35
  export { useMessages } from './i18n/context.js';
36
36
  export { NotificationInbox, NotificationBell, type NotificationInboxProps, type NotificationBellProps } from './components/notifications.js';
37
+ export { BillingNotification, isBillingNotification, billingNotificationAction, type BillingNotificationActions, type BillingNotificationAction } from './components/billing-notification.js';