@sudobility/consumables_pages 0.0.17 → 0.0.18

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.
@@ -1,4 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * @fileoverview Inline credit balance badge component for topbar integration.
4
+ * Displays a pill-shaped badge with a coin icon and the current balance.
5
+ * Renders as a button when onClick is provided, otherwise as a span.
6
+ */
7
+ import { colors, ui } from "@sudobility/design";
2
8
  /**
3
9
  * Renders a small inline badge showing the user's credit balance.
4
10
  * Blue when balance > 0, red when balance is 0. Returns null when balance is null.
@@ -6,12 +12,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
12
  */
7
13
  export function CreditBalanceBadge({ balance, isLoading, onClick, className, }) {
8
14
  if (isLoading) {
9
- return (_jsx("span", { className: `inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium text-gray-400 dark:text-gray-500 ${className || ""}`, role: "status", "aria-label": "Loading balance", "aria-busy": "true", children: _jsx("span", { className: "animate-pulse", children: "..." }) }));
15
+ return (_jsx("span", { className: `inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium ${ui.text.muted} ${className || ""}`, role: "status", "aria-label": "Loading balance", "aria-busy": "true", children: _jsx("span", { className: "animate-pulse", children: "..." }) }));
10
16
  }
11
17
  if (balance === null)
12
18
  return null;
13
19
  const Wrapper = onClick ? "button" : "span";
14
20
  return (_jsxs(Wrapper, { onClick: onClick, "aria-label": onClick ? `Credit balance: ${balance}` : undefined, className: `inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium ${balance > 0
15
- ? "bg-blue-100 text-blue-700 dark:bg-blue-900/50 dark:text-blue-300"
16
- : "bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-300"} ${onClick ? "cursor-pointer hover:opacity-80" : ""} ${className || ""}`, children: [_jsx("svg", { className: "w-3.5 h-3.5", fill: "currentColor", viewBox: "0 0 20 20", "aria-hidden": "true", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm1-13a1 1 0 10-2 0v.092a4.535 4.535 0 00-1.676.662C6.602 6.234 6 7.009 6 8c0 .99.602 1.765 1.324 2.246.48.32 1.054.545 1.676.662v1.941c-.391-.127-.68-.317-.843-.504a1 1 0 10-1.51 1.31c.562.649 1.413 1.076 2.353 1.253V15a1 1 0 102 0v-.092a4.535 4.535 0 001.676-.662C13.398 13.766 14 12.991 14 12c0-.99-.602-1.765-1.324-2.246A4.535 4.535 0 0011 9.092V7.151c.391.127.68.317.843.504a1 1 0 101.511-1.31c-.563-.649-1.413-1.076-2.354-1.253V5z", clipRule: "evenodd" }) }), balance] }));
21
+ ? `${colors.component.badge.primary.base} ${colors.component.badge.primary.dark}`
22
+ : `${colors.component.badge.error.base} ${colors.component.badge.error.dark}`} ${onClick ? "cursor-pointer hover:opacity-80" : ""} ${className || ""}`, children: [_jsx("svg", { className: "w-3.5 h-3.5", fill: "currentColor", viewBox: "0 0 20 20", "aria-hidden": "true", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm1-13a1 1 0 10-2 0v.092a4.535 4.535 0 00-1.676.662C6.602 6.234 6 7.009 6 8c0 .99.602 1.765 1.324 2.246.48.32 1.054.545 1.676.662v1.941c-.391-.127-.68-.317-.843-.504a1 1 0 10-1.51 1.31c.562.649 1.413 1.076 2.353 1.253V15a1 1 0 102 0v-.092a4.535 4.535 0 001.676-.662C13.398 13.766 14 12.991 14 12c0-.99-.602-1.765-1.324-2.246A4.535 4.535 0 0011 9.092V7.151c.391.127.68.317.843.504a1 1 0 101.511-1.31c-.563-.649-1.413-1.076-2.354-1.253V5z", clipRule: "evenodd" }) }), balance] }));
17
23
  }
@@ -4,6 +4,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  * a responsive grid of purchasable credit packages. Purely presentational --
5
5
  * all data and callbacks are passed via props.
6
6
  */
7
+ import { colors, ui } from "@sudobility/design";
7
8
  import { LoadingSpinner } from "./LoadingSpinner";
8
9
  /**
9
10
  * Renders a credit store with balance display, purchase packages grid,
@@ -11,7 +12,7 @@ import { LoadingSpinner } from "./LoadingSpinner";
11
12
  * @param props - See {@link CreditStorePageProps} for full prop documentation.
12
13
  */
13
14
  export function CreditStorePage({ isAuthenticated, balance, packages, isLoading, isPurchasing, error, onPurchase, onLoginClick, labels, formatters, className, }) {
14
- return (_jsxs("div", { className: className, children: [_jsx("h1", { className: "text-2xl font-bold mb-6 dark:text-white", children: labels.title }), isAuthenticated && balance !== null && (_jsxs("div", { className: "mb-8 p-4 bg-blue-50 dark:bg-blue-900/30 rounded-lg border border-blue-200 dark:border-blue-800", children: [_jsx("p", { className: "text-sm text-blue-600 dark:text-blue-400 font-medium", children: labels.currentBalanceLabel }), _jsx("p", { className: "text-3xl font-bold text-blue-900 dark:text-blue-100", children: formatters.formatCredits(balance) })] })), error && (_jsxs("div", { className: "mb-6 p-4 bg-red-50 dark:bg-red-900/30 rounded-lg border border-red-200 dark:border-red-800", role: "alert", children: [_jsx("p", { className: "text-sm font-medium text-red-800 dark:text-red-300", children: labels.errorTitle }), _jsx("p", { className: "text-sm text-red-600 dark:text-red-400", children: error })] })), !isAuthenticated && (_jsxs("div", { className: "mb-6 p-4 bg-yellow-50 dark:bg-yellow-900/30 rounded-lg border border-yellow-200 dark:border-yellow-800", children: [_jsx("p", { className: "text-sm text-yellow-800 dark:text-yellow-300", children: labels.loginRequired }), _jsx("button", { onClick: onLoginClick, className: "mt-2 px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 transition-colors", children: labels.loginButton ?? "Log in" })] })), isLoading && _jsx(LoadingSpinner, {}), !isLoading && packages.length === 0 && (_jsx("p", { className: "text-gray-500 dark:text-gray-400 text-center py-8", children: labels.noProducts })), !isLoading && packages.length > 0 && (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: packages.map((pkg) => (_jsx("div", { className: "p-6 bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 shadow-sm hover:shadow-md transition-shadow", children: _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-3xl font-bold text-gray-900 dark:text-gray-100", children: formatters.formatCredits(pkg.credits) }), formatters.getPackageDescription && (_jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400 mt-1", children: formatters.getPackageDescription(pkg.packageId) })), _jsx("p", { className: "text-xl font-semibold text-blue-600 dark:text-blue-400 mt-3", children: pkg.priceString }), _jsx("button", { onClick: () => onPurchase(pkg.packageId), disabled: isPurchasing || !isAuthenticated, className: "mt-4 w-full px-4 py-2.5 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 dark:bg-blue-500 dark:hover:bg-blue-600", children: isPurchasing
15
+ return (_jsxs("div", { className: className, children: [_jsx("h1", { className: "text-2xl font-bold mb-6 dark:text-white", children: labels.title }), isAuthenticated && balance !== null && (_jsxs("div", { className: `mb-8 p-4 rounded-lg border ${colors.component.alert.info.base} ${colors.component.alert.info.dark}`, children: [_jsx("p", { className: `text-sm font-medium ${colors.component.alert.info.icon}`, children: labels.currentBalanceLabel }), _jsx("p", { className: "text-3xl font-bold", children: formatters.formatCredits(balance) })] })), error && (_jsxs("div", { className: `mb-6 p-4 rounded-lg border ${colors.component.alert.error.base} ${colors.component.alert.error.dark}`, role: "alert", children: [_jsx("p", { className: "text-sm font-medium", children: labels.errorTitle }), _jsx("p", { className: `text-sm ${colors.component.alert.error.icon}`, children: error })] })), !isAuthenticated && (_jsxs("div", { className: `mb-6 p-4 rounded-lg border ${colors.component.alert.warning.base} ${colors.component.alert.warning.dark}`, children: [_jsx("p", { className: "text-sm", children: labels.loginRequired }), _jsx("button", { onClick: onLoginClick, className: `mt-2 px-4 py-2 text-sm font-medium rounded-lg transition-colors ${colors.component.button.primary.base} ${colors.component.button.primary.dark}`, children: labels.loginButton ?? "Log in" })] })), isLoading && _jsx(LoadingSpinner, {}), !isLoading && packages.length === 0 && (_jsx("p", { className: `${ui.text.muted} text-center py-8`, children: labels.noProducts })), !isLoading && packages.length > 0 && (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: packages.map((pkg) => (_jsx("div", { className: `p-6 rounded-xl border shadow-sm hover:shadow-md transition-shadow ${colors.component.card.default.base} ${colors.component.card.default.dark}`, children: _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-3xl font-bold text-gray-900 dark:text-gray-100", children: formatters.formatCredits(pkg.credits) }), formatters.getPackageDescription && (_jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400 mt-1", children: formatters.getPackageDescription(pkg.packageId) })), _jsx("p", { className: `text-xl font-semibold mt-3 ${colors.component.alert.info.icon}`, children: pkg.priceString }), _jsx("button", { onClick: () => onPurchase(pkg.packageId), disabled: isPurchasing || !isAuthenticated, className: `mt-4 w-full px-4 py-2.5 font-medium rounded-lg disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 ${colors.component.button.primary.base} ${colors.component.button.primary.dark}`, children: isPurchasing
15
16
  ? labels.purchasingButton
16
17
  : labels.purchaseButton })] }) }, pkg.packageId))) }))] }));
17
18
  }
@@ -4,10 +4,11 @@ import { jsx as _jsx } from "react/jsx-runtime";
4
4
  * components. Extracted to reduce markup duplication and centralize accessibility
5
5
  * attributes.
6
6
  */
7
+ import { colors } from "@sudobility/design";
7
8
  /**
8
9
  * Renders a centered spinning loading indicator with appropriate ARIA attributes.
9
10
  * Internal component -- not exported from the package barrel.
10
11
  */
11
12
  export function LoadingSpinner() {
12
- return (_jsx("div", { className: "flex justify-center py-12", role: "status", "aria-label": "Loading", "aria-busy": "true", children: _jsx("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 dark:border-blue-400" }) }));
13
+ return (_jsx("div", { className: "flex justify-center py-12", role: "status", "aria-label": "Loading", "aria-busy": "true", children: _jsx("div", { className: `animate-spin rounded-full h-8 w-8 border-b-2 ${colors.component.alert.info.icon.replace(/text-/g, "border-")}` }) }));
13
14
  }
@@ -1,4 +1,9 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * @fileoverview Purchase history page component with responsive table (desktop)
4
+ * and card (mobile) layouts. Supports load-more pagination.
5
+ */
6
+ import { colors, ui } from "@sudobility/design";
2
7
  import { LoadingSpinner } from "./LoadingSpinner";
3
8
  /**
4
9
  * Renders a paginated list of purchase records.
@@ -7,7 +12,7 @@ import { LoadingSpinner } from "./LoadingSpinner";
7
12
  * @param props - See {@link PurchaseHistoryPageProps} for full prop documentation.
8
13
  */
9
14
  export function PurchaseHistoryPage({ purchases, isLoading, error, onLoadMore, hasMore, labels, formatters, className, emptyStateComponent, }) {
10
- return (_jsxs("div", { className: className, children: [_jsx("h1", { className: "text-2xl font-bold mb-6 dark:text-white", children: labels.title }), error && (_jsx("div", { className: "mb-4 p-3 bg-red-50 dark:bg-red-900/30 rounded-lg border border-red-200 dark:border-red-800", role: "alert", children: _jsx("p", { className: "text-sm text-red-600 dark:text-red-400", children: error }) })), isLoading && _jsx(LoadingSpinner, {}), !isLoading && purchases.length === 0 && (_jsx(_Fragment, { children: emptyStateComponent ?? (_jsx("p", { className: "text-gray-500 dark:text-gray-400 text-center py-8", children: labels.noRecords })) })), !isLoading && purchases.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 border-gray-200 dark:border-gray-700", children: [_jsx("th", { className: "text-left py-3 px-4 font-medium text-gray-500 dark:text-gray-400", children: labels.columnDate }), _jsx("th", { className: "text-right py-3 px-4 font-medium text-gray-500 dark:text-gray-400", children: labels.columnCredits }), _jsx("th", { className: "text-left py-3 px-4 font-medium text-gray-500 dark:text-gray-400", children: labels.columnSource }), _jsx("th", { className: "text-right py-3 px-4 font-medium text-gray-500 dark:text-gray-400", children: labels.columnAmount })] }) }), _jsx("tbody", { children: purchases.map((purchase) => (_jsxs("tr", { className: "border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-800/50", children: [_jsx("td", { className: "py-3 px-4 text-gray-700 dark:text-gray-300", children: formatters.formatDate(purchase.created_at) }), _jsxs("td", { className: "py-3 px-4 text-right font-medium text-green-600 dark:text-green-400", children: ["+", purchase.credits] }), _jsx("td", { className: "py-3 px-4 text-gray-600 dark:text-gray-400", children: formatters.formatSource(purchase.source) }), _jsx("td", { className: "py-3 px-4 text-right text-gray-600 dark:text-gray-400", children: purchase.price_cents != null && purchase.currency
15
+ return (_jsxs("div", { className: className, children: [_jsx("h1", { className: "text-2xl font-bold mb-6 dark:text-white", 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 && purchases.length === 0 && (_jsx(_Fragment, { children: emptyStateComponent ?? (_jsx("p", { className: `${ui.text.muted} text-center py-8`, children: labels.noRecords })) })), !isLoading && purchases.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-right py-3 px-4 font-medium ${ui.text.muted}`, children: labels.columnCredits }), _jsx("th", { className: `text-left py-3 px-4 font-medium ${ui.text.muted}`, children: labels.columnSource }), _jsx("th", { className: `text-right py-3 px-4 font-medium ${ui.text.muted}`, children: labels.columnAmount })] }) }), _jsx("tbody", { children: purchases.map((purchase) => (_jsxs("tr", { className: `border-b ${ui.border.subtle} hover:bg-gray-50 dark:hover:bg-gray-800/50`, children: [_jsx("td", { className: "py-3 px-4 text-gray-700 dark:text-gray-300", children: formatters.formatDate(purchase.created_at) }), _jsxs("td", { className: "py-3 px-4 text-right font-medium text-green-600 dark:text-green-400", children: ["+", purchase.credits] }), _jsx("td", { className: "py-3 px-4 text-gray-600 dark:text-gray-400", children: formatters.formatSource(purchase.source) }), _jsx("td", { className: "py-3 px-4 text-right text-gray-600 dark:text-gray-400", children: purchase.price_cents != null && purchase.currency
11
16
  ? formatters.formatAmount(purchase.price_cents, purchase.currency)
12
- : "-" })] }, purchase.id))) })] }) }), _jsx("div", { className: "sm:hidden space-y-3", children: purchases.map((purchase) => (_jsx("div", { className: "p-4 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700", children: _jsxs("div", { className: "flex justify-between items-start", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: formatters.formatDate(purchase.created_at) }), _jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: formatters.formatSource(purchase.source) })] }), _jsxs("div", { className: "text-right", children: [_jsxs("p", { className: "font-medium text-green-600 dark:text-green-400", children: ["+", purchase.credits] }), purchase.price_cents != null && purchase.currency && (_jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: formatters.formatAmount(purchase.price_cents, purchase.currency) }))] })] }) }, purchase.id))) }), hasMore && onLoadMore && (_jsx("div", { className: "mt-4 text-center", children: _jsx("button", { onClick: onLoadMore, className: "px-4 py-2 text-sm text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 font-medium", children: labels.loadMore }) }))] }))] }));
17
+ : "-" })] }, purchase.id))) })] }) }), _jsx("div", { className: "sm:hidden space-y-3", children: purchases.map((purchase) => (_jsx("div", { className: `p-4 rounded-lg border ${colors.component.card.default.base} ${colors.component.card.default.dark}`, children: _jsxs("div", { className: "flex justify-between items-start", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: formatters.formatDate(purchase.created_at) }), _jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: formatters.formatSource(purchase.source) })] }), _jsxs("div", { className: "text-right", children: [_jsxs("p", { className: "font-medium text-green-600 dark:text-green-400", children: ["+", purchase.credits] }), purchase.price_cents != null && purchase.currency && (_jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: formatters.formatAmount(purchase.price_cents, purchase.currency) }))] })] }) }, purchase.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 }) }))] }))] }));
13
18
  }
@@ -3,6 +3,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
3
3
  * @fileoverview Usage history page component with responsive table (desktop)
4
4
  * and card (mobile) layouts. Supports load-more pagination.
5
5
  */
6
+ import { colors, ui } from "@sudobility/design";
6
7
  import { LoadingSpinner } from "./LoadingSpinner";
7
8
  /**
8
9
  * Renders a paginated list of usage records.
@@ -11,5 +12,5 @@ import { LoadingSpinner } from "./LoadingSpinner";
11
12
  * @param props - See {@link UsageHistoryPageProps} for full prop documentation.
12
13
  */
13
14
  export function UsageHistoryPage({ usages, isLoading, error, onLoadMore, hasMore, labels, formatters, className, emptyStateComponent, }) {
14
- return (_jsxs("div", { className: className, children: [_jsx("h1", { className: "text-2xl font-bold mb-6 dark:text-white", children: labels.title }), error && (_jsx("div", { className: "mb-4 p-3 bg-red-50 dark:bg-red-900/30 rounded-lg border border-red-200 dark:border-red-800", role: "alert", children: _jsx("p", { className: "text-sm text-red-600 dark:text-red-400", children: error }) })), isLoading && _jsx(LoadingSpinner, {}), !isLoading && usages.length === 0 && (_jsx(_Fragment, { children: emptyStateComponent ?? (_jsx("p", { className: "text-gray-500 dark:text-gray-400 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 border-gray-200 dark:border-gray-700", children: [_jsx("th", { className: "text-left py-3 px-4 font-medium text-gray-500 dark:text-gray-400", children: labels.columnDate }), _jsx("th", { className: "text-left py-3 px-4 font-medium text-gray-500 dark:text-gray-400", children: labels.columnFilename })] }) }), _jsx("tbody", { children: usages.map((usage) => (_jsxs("tr", { className: "border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-800/50", children: [_jsx("td", { className: "py-3 px-4 text-gray-700 dark:text-gray-300", children: formatters.formatDate(usage.created_at) }), _jsx("td", { className: "py-3 px-4 text-gray-600 dark:text-gray-400", children: usage.filename || "-" })] }, usage.id))) })] }) }), _jsx("div", { className: "sm:hidden space-y-3", children: usages.map((usage) => (_jsxs("div", { className: "p-4 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700", children: [_jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: formatters.formatDate(usage.created_at) }), _jsx("p", { className: "text-sm text-gray-700 dark:text-gray-300 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 text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 font-medium", children: labels.loadMore }) }))] }))] }));
15
+ return (_jsxs("div", { className: className, children: [_jsx("h1", { className: "text-2xl font-bold mb-6 dark:text-white", 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-gray-50 dark:hover:bg-gray-800/50`, children: [_jsx("td", { className: "py-3 px-4 text-gray-700 dark:text-gray-300", children: formatters.formatDate(usage.created_at) }), _jsx("td", { className: "py-3 px-4 text-gray-600 dark:text-gray-400", 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-gray-500 dark:text-gray-400", children: formatters.formatDate(usage.created_at) }), _jsx("p", { className: "text-sm text-gray-700 dark:text-gray-300 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
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sudobility/consumables_pages",
3
- "version": "0.0.17",
3
+ "version": "0.0.18",
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",
@@ -67,5 +67,8 @@
67
67
  "repository": {
68
68
  "type": "git",
69
69
  "url": "https://github.com/johnqh/consumables_pages.git"
70
+ },
71
+ "dependencies": {
72
+ "@sudobility/design": "^1.1.26"
70
73
  }
71
74
  }