@sudobility/consumables_pages 0.0.39 → 0.0.41

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.
@@ -3,10 +3,10 @@
3
3
  * Displays a pill-shaped badge with a coin icon and the current balance.
4
4
  * Renders as a button when onClick is provided, otherwise as a span.
5
5
  */
6
- import type { CreditBalanceBadgeProps } from './types';
6
+ import type { CreditBalanceBadgeProps } from './types.js';
7
7
  /**
8
8
  * Renders a small inline badge showing the user's credit balance.
9
9
  * Blue when balance > 0, red when balance is 0. Returns null when balance is null.
10
10
  * @param props - See {@link CreditBalanceBadgeProps} for full prop documentation.
11
11
  */
12
- export declare function CreditBalanceBadge({ balance, isLoading, onClick, className, }: CreditBalanceBadgeProps): import("react/jsx-runtime").JSX.Element | null;
12
+ export declare function CreditBalanceBadge({ balance, isLoading, onClick, className, }: CreditBalanceBadgeProps): import("react").JSX.Element | null;
@@ -3,10 +3,10 @@
3
3
  * a responsive grid of purchasable credit packages. Purely presentational --
4
4
  * all data and callbacks are passed via props.
5
5
  */
6
- import type { CreditStorePageProps } from './types';
6
+ import type { CreditStorePageProps } from './types.js';
7
7
  /**
8
8
  * Renders a credit store with balance display, purchase packages grid,
9
9
  * loading/error states, and a login prompt for unauthenticated users.
10
10
  * @param props - See {@link CreditStorePageProps} for full prop documentation.
11
11
  */
12
- export declare function CreditStorePage({ isAuthenticated, balance, packages, isLoading, isPurchasing, error, onPurchase, onLoginClick, labels, formatters, className, }: CreditStorePageProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function CreditStorePage({ isAuthenticated, balance, packages, isLoading, isPurchasing, error, onPurchase, onLoginClick, labels, formatters, className, }: CreditStorePageProps): import("react").JSX.Element;
@@ -5,7 +5,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  * all data and callbacks are passed via props.
6
6
  */
7
7
  import { colors, ui } from '@sudobility/design';
8
- import { LoadingSpinner } from './LoadingSpinner';
8
+ import { LoadingSpinner } from './LoadingSpinner.js';
9
9
  /**
10
10
  * Renders a credit store with balance display, purchase packages grid,
11
11
  * loading/error states, and a login prompt for unauthenticated users.
@@ -7,4 +7,4 @@
7
7
  * Renders a centered spinning loading indicator with appropriate ARIA attributes.
8
8
  * Internal component -- not exported from the package barrel.
9
9
  */
10
- export declare function LoadingSpinner(): import("react/jsx-runtime").JSX.Element;
10
+ export declare function LoadingSpinner(): import("react").JSX.Element;
@@ -2,11 +2,11 @@
2
2
  * @fileoverview Purchase history page component with responsive table (desktop)
3
3
  * and card (mobile) layouts. Supports load-more pagination.
4
4
  */
5
- import type { PurchaseHistoryPageProps } from './types';
5
+ import type { PurchaseHistoryPageProps } from './types.js';
6
6
  /**
7
7
  * Renders a paginated list of purchase records.
8
8
  * Desktop: table with date, credits, source, and amount columns.
9
9
  * Mobile: compact card layout.
10
10
  * @param props - See {@link PurchaseHistoryPageProps} for full prop documentation.
11
11
  */
12
- export declare function PurchaseHistoryPage({ purchases, isLoading, error, onLoadMore, hasMore, labels, formatters, className, emptyStateComponent, }: PurchaseHistoryPageProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function PurchaseHistoryPage({ purchases, isLoading, error, onLoadMore, hasMore, labels, formatters, className, emptyStateComponent, }: PurchaseHistoryPageProps): import("react").JSX.Element;
@@ -4,7 +4,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
4
4
  * and card (mobile) layouts. Supports load-more pagination.
5
5
  */
6
6
  import { colors, ui } from '@sudobility/design';
7
- import { LoadingSpinner } from './LoadingSpinner';
7
+ import { LoadingSpinner } from './LoadingSpinner.js';
8
8
  /**
9
9
  * Renders a paginated list of purchase records.
10
10
  * Desktop: table with date, credits, source, and amount columns.
@@ -2,11 +2,11 @@
2
2
  * @fileoverview Usage history page component with responsive table (desktop)
3
3
  * and card (mobile) layouts. Supports load-more pagination.
4
4
  */
5
- import type { UsageHistoryPageProps } from './types';
5
+ import type { UsageHistoryPageProps } from './types.js';
6
6
  /**
7
7
  * Renders a paginated list of usage records.
8
- * Desktop: table with date and filename columns.
8
+ * Desktop: table with date, description and (optionally) credits columns.
9
9
  * Mobile: compact card layout.
10
10
  * @param props - See {@link UsageHistoryPageProps} for full prop documentation.
11
11
  */
12
- export declare function UsageHistoryPage({ usages, isLoading, error, onLoadMore, hasMore, labels, formatters, className, emptyStateComponent, }: UsageHistoryPageProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function UsageHistoryPage({ usages, isLoading, error, onLoadMore, hasMore, labels, formatters, className, emptyStateComponent, }: UsageHistoryPageProps): import("react").JSX.Element;
@@ -4,13 +4,20 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
4
4
  * and card (mobile) layouts. Supports load-more pagination.
5
5
  */
6
6
  import { colors, ui } from '@sudobility/design';
7
- import { LoadingSpinner } from './LoadingSpinner';
7
+ import { LoadingSpinner } from './LoadingSpinner.js';
8
8
  /**
9
9
  * Renders a paginated list of usage records.
10
- * Desktop: table with date and filename columns.
10
+ * Desktop: table with date, description and (optionally) credits columns.
11
11
  * Mobile: compact card layout.
12
12
  * @param props - See {@link UsageHistoryPageProps} for full prop documentation.
13
13
  */
14
14
  export function UsageHistoryPage({ usages, isLoading, error, onLoadMore, hasMore, labels, formatters, className, emptyStateComponent, }) {
15
- return (_jsxs("div", { className: className, children: [_jsx("h1", { className: 'text-2xl font-bold mb-6 text-foreground', children: labels.title }), error && (_jsx("div", { className: `mb-4 p-3 rounded-lg border ${colors.component.alert.error.base} ${colors.component.alert.error.dark}`, role: 'alert', children: _jsx("p", { className: `text-sm ${colors.component.alert.error.icon}`, children: error }) })), isLoading && _jsx(LoadingSpinner, {}), !isLoading && usages.length === 0 && (_jsx(_Fragment, { children: emptyStateComponent ?? (_jsx("p", { className: `${ui.text.muted} text-center py-8`, children: labels.noRecords })) })), !isLoading && usages.length > 0 && (_jsxs(_Fragment, { children: [_jsx("div", { className: 'hidden sm:block overflow-x-auto', children: _jsxs("table", { className: 'w-full text-sm', "aria-label": labels.title, children: [_jsx("thead", { children: _jsxs("tr", { className: `border-b ${ui.border.default}`, children: [_jsx("th", { className: `text-left py-3 px-4 font-medium ${ui.text.muted}`, children: labels.columnDate }), _jsx("th", { className: `text-left py-3 px-4 font-medium ${ui.text.muted}`, children: labels.columnFilename })] }) }), _jsx("tbody", { children: usages.map(usage => (_jsxs("tr", { className: `border-b ${ui.border.subtle} hover:bg-accent`, children: [_jsx("td", { className: 'py-3 px-4 text-foreground', children: formatters.formatDate(usage.created_at) }), _jsx("td", { className: 'py-3 px-4 text-muted-foreground', children: usage.filename || '-' })] }, usage.id))) })] }) }), _jsx("div", { className: 'sm:hidden space-y-3', children: usages.map(usage => (_jsxs("div", { className: `p-4 rounded-lg border ${colors.component.card.default.base} ${colors.component.card.default.dark}`, children: [_jsx("p", { className: 'text-sm text-muted-foreground', children: formatters.formatDate(usage.created_at) }), _jsx("p", { className: 'text-sm text-foreground font-medium', children: usage.filename || '-' })] }, usage.id))) }), hasMore && onLoadMore && (_jsx("div", { className: 'mt-4 text-center', children: _jsx("button", { onClick: onLoadMore, className: `px-4 py-2 text-sm font-medium ${ui.text.link}`, children: labels.loadMore }) }))] }))] }));
15
+ // Whichever the product sets. A file-based product fills `filename`; one that
16
+ // spends credits on something else fills `reference`.
17
+ const describe = (usage) => usage.reference || usage.filename || '-';
18
+ // Absent means one, never zero: rows written before variable amounts existed
19
+ // spent exactly one credit.
20
+ const spent = (usage) => usage.credits ?? 1;
21
+ const showCredits = labels.columnCredits !== undefined;
22
+ return (_jsxs("div", { className: className, children: [_jsx("h1", { className: 'text-2xl font-bold mb-6 text-foreground', children: labels.title }), error && (_jsx("div", { className: `mb-4 p-3 rounded-lg border ${colors.component.alert.error.base} ${colors.component.alert.error.dark}`, role: 'alert', children: _jsx("p", { className: `text-sm ${colors.component.alert.error.icon}`, children: error }) })), isLoading && _jsx(LoadingSpinner, {}), !isLoading && usages.length === 0 && (_jsx(_Fragment, { children: emptyStateComponent ?? (_jsx("p", { className: `${ui.text.muted} text-center py-8`, children: labels.noRecords })) })), !isLoading && usages.length > 0 && (_jsxs(_Fragment, { children: [_jsx("div", { className: 'hidden sm:block overflow-x-auto', children: _jsxs("table", { className: 'w-full text-sm', "aria-label": labels.title, children: [_jsx("thead", { children: _jsxs("tr", { className: `border-b ${ui.border.default}`, children: [_jsx("th", { className: `text-left py-3 px-4 font-medium ${ui.text.muted}`, children: labels.columnDate }), _jsx("th", { className: `text-left py-3 px-4 font-medium ${ui.text.muted}`, children: labels.columnFilename }), showCredits && (_jsx("th", { className: `text-right py-3 px-4 font-medium ${ui.text.muted}`, children: labels.columnCredits }))] }) }), _jsx("tbody", { children: usages.map(usage => (_jsxs("tr", { className: `border-b ${ui.border.subtle} hover:bg-accent`, children: [_jsx("td", { className: 'py-3 px-4 text-foreground', children: formatters.formatDate(usage.created_at) }), _jsx("td", { className: 'py-3 px-4 text-muted-foreground', children: describe(usage) }), showCredits && (_jsx("td", { className: 'py-3 px-4 text-right text-foreground tabular-nums', children: spent(usage) }))] }, usage.id))) })] }) }), _jsx("div", { className: 'sm:hidden space-y-3', children: usages.map(usage => (_jsxs("div", { className: `p-4 rounded-lg border ${colors.component.card.default.base} ${colors.component.card.default.dark}`, children: [_jsx("p", { className: 'text-sm text-muted-foreground', children: formatters.formatDate(usage.created_at) }), _jsx("p", { className: 'text-sm text-foreground font-medium', children: describe(usage) }), showCredits && (_jsxs("p", { className: 'text-sm text-muted-foreground', children: [labels.columnCredits, ": ", spent(usage)] }))] }, usage.id))) }), hasMore && onLoadMore && (_jsx("div", { className: 'mt-4 text-center', children: _jsx("button", { onClick: onLoadMore, className: `px-4 py-2 text-sm font-medium ${ui.text.link}`, children: labels.loadMore }) }))] }))] }));
16
23
  }
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export { CreditStorePage } from './CreditStorePage';
2
- export { PurchaseHistoryPage } from './PurchaseHistoryPage';
3
- export { UsageHistoryPage } from './UsageHistoryPage';
4
- export { CreditBalanceBadge } from './CreditBalanceBadge';
5
- export type { CreditStorePageProps, CreditStorePageLabels, CreditStorePageFormatters, PurchaseHistoryPageProps, PurchaseHistoryPageLabels, PurchaseHistoryPageFormatters, UsageHistoryPageProps, UsageHistoryPageLabels, UsageHistoryPageFormatters, CreditBalanceBadgeProps, } from './types';
1
+ export { CreditStorePage } from './CreditStorePage.js';
2
+ export { PurchaseHistoryPage } from './PurchaseHistoryPage.js';
3
+ export { UsageHistoryPage } from './UsageHistoryPage.js';
4
+ export { CreditBalanceBadge } from './CreditBalanceBadge.js';
5
+ export type { CreditStorePageProps, CreditStorePageLabels, CreditStorePageFormatters, PurchaseHistoryPageProps, PurchaseHistoryPageLabels, PurchaseHistoryPageFormatters, UsageHistoryPageProps, UsageHistoryPageLabels, UsageHistoryPageFormatters, CreditBalanceBadgeProps, } from './types.js';
6
6
  export type { ConsumableSource } from '@sudobility/types';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { CreditStorePage } from './CreditStorePage';
2
- export { PurchaseHistoryPage } from './PurchaseHistoryPage';
3
- export { UsageHistoryPage } from './UsageHistoryPage';
4
- export { CreditBalanceBadge } from './CreditBalanceBadge';
1
+ export { CreditStorePage } from './CreditStorePage.js';
2
+ export { PurchaseHistoryPage } from './PurchaseHistoryPage.js';
3
+ export { UsageHistoryPage } from './UsageHistoryPage.js';
4
+ export { CreditBalanceBadge } from './CreditBalanceBadge.js';
package/dist/types.d.ts CHANGED
@@ -73,6 +73,13 @@ export interface UsageHistoryPageLabels {
73
73
  title: string;
74
74
  columnDate: string;
75
75
  columnFilename: string;
76
+ /**
77
+ * Header for the credits-spent column.
78
+ *
79
+ * Opt-in: the column is rendered only when this is set, so a product that
80
+ * spends exactly one credit per use gains no empty column on upgrade.
81
+ */
82
+ columnCredits?: string;
76
83
  noRecords: string;
77
84
  loadMore: string;
78
85
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sudobility/consumables_pages",
3
- "version": "0.0.39",
3
+ "version": "0.0.41",
4
4
  "description": "Web UI components for consumable credits (credit store, purchase history, usage history)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "peerDependencies": {
33
33
  "@sudobility/consumables_client": "^0.0.18",
34
- "@sudobility/types": "^1.9.64",
34
+ "@sudobility/types": "1.9.65",
35
35
  "react": "^18.0.0 || ^19.0.0",
36
36
  "react-dom": "^18.0.0 || ^19.0.0"
37
37
  },