@openrails/contentkit-ui 0.88.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.
- package/dist/client/generated/routes.d.ts +1 -1
- package/dist/client/generated/routes.js +1 -1
- package/dist/client/generated/routes.js.map +1 -1
- package/dist/client/generated/wire.d.ts +6 -0
- package/dist/client/generated/wire.js.map +1 -1
- package/dist/client/media/rules.js +1 -1
- package/dist/client/media/rules.js.map +1 -1
- package/dist/client/public.d.ts +2 -1
- package/dist/client/public.js +2 -2
- package/dist/client/public.js.map +1 -1
- package/dist/client/stats.d.ts +1 -1
- package/dist/client/stats.js.map +1 -1
- package/dist/components/billing-notification.d.ts +11 -0
- package/dist/components/billing-notification.js +70 -0
- package/dist/components/billing-notification.js.map +1 -0
- package/dist/components/content/filters.d.ts +1 -1
- package/dist/components/content/filters.js +2 -5
- package/dist/components/content/filters.js.map +1 -1
- package/dist/components/content/reader-stats.d.ts +11 -3
- package/dist/components/content/reader-stats.js +41 -23
- package/dist/components/content/reader-stats.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -2
- package/dist/locales/content/de.js +4 -0
- package/dist/locales/content/de.js.map +1 -1
- package/dist/locales/content/en.d.ts +4 -0
- package/dist/locales/content/en.js +4 -0
- package/dist/locales/content/en.js.map +1 -1
- package/dist/locales/content/es.js +4 -0
- package/dist/locales/content/es.js.map +1 -1
- package/dist/locales/content/ja.js +4 -0
- package/dist/locales/content/ja.js.map +1 -1
- package/dist/locales/content/ko.js +4 -0
- package/dist/locales/content/ko.js.map +1 -1
- package/dist/locales/content/zh.js +4 -0
- package/dist/locales/content/zh.js.map +1 -1
- package/dist/locales/en.d.ts +34 -0
- package/dist/locales/social/de.js +30 -0
- package/dist/locales/social/de.js.map +1 -1
- package/dist/locales/social/en.d.ts +30 -0
- package/dist/locales/social/en.js +30 -0
- package/dist/locales/social/en.js.map +1 -1
- package/dist/locales/social/es.js +30 -0
- package/dist/locales/social/es.js.map +1 -1
- package/dist/locales/social/ja.js +30 -0
- package/dist/locales/social/ja.js.map +1 -1
- package/dist/locales/social/ko.js +30 -0
- package/dist/locales/social/ko.js.map +1 -1
- package/dist/locales/social/zh.js +30 -0
- package/dist/locales/social/zh.js.map +1 -1
- package/dist/react/public.d.ts +3 -3
- package/dist/react/public.js +64 -25
- package/dist/react/public.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +5 -5
|
@@ -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 {
|
|
8
|
-
import { cn as
|
|
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
|
|
11
|
-
let
|
|
12
|
-
appearance:
|
|
13
|
-
className:
|
|
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 (
|
|
17
|
+
if (b.error) return x(/* @__PURE__ */ s("p", {
|
|
18
18
|
role: "alert",
|
|
19
19
|
className: "text-destructive",
|
|
20
|
-
children: r(
|
|
20
|
+
children: r(v, b.error)
|
|
21
21
|
}));
|
|
22
|
-
if (!
|
|
23
|
-
let
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
|
30
|
-
className: "grid grid-cols-2 gap-3
|
|
31
|
-
children:
|
|
32
|
-
className: "grid gap-
|
|
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
|
-
|
|
47
|
+
title: n,
|
|
48
|
+
children: [/* @__PURE__ */ s("dt", {
|
|
35
49
|
className: "text-xs text-muted-foreground",
|
|
36
50
|
children: e
|
|
37
|
-
}), /* @__PURE__ */
|
|
38
|
-
className: "text-
|
|
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 {
|
|
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
|
|
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';
|