@wopr-network/platform-ui-core 1.27.8 → 1.27.9
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/next.config.ts +1 -2
- package/package.json +17 -17
- package/src/__tests__/account-switcher.test.tsx +21 -20
- package/src/__tests__/activity-page.test.tsx +2 -6
- package/src/__tests__/add-payment-method-dialog.test.tsx +9 -32
- package/src/__tests__/admin-api.test.ts +1 -6
- package/src/__tests__/admin-gpu-api.test.ts +1 -3
- package/src/__tests__/admin-marketplace-api.test.ts +1 -4
- package/src/__tests__/admin-middleware.test.ts +76 -83
- package/src/__tests__/affiliate-dashboard.test.tsx +3 -3
- package/src/__tests__/api-401-redirect.test.ts +46 -9
- package/src/__tests__/api-client.test.ts +3 -5
- package/src/__tests__/api-config.test.ts +22 -42
- package/src/__tests__/api-fleet-resources.test.ts +1 -2
- package/src/__tests__/api-fleet-trpc.test.ts +2 -8
- package/src/__tests__/api-null-guards.test.ts +3 -1
- package/src/__tests__/audit-log-table-pagination.test.tsx +2 -6
- package/src/__tests__/auth-password-reset.test.tsx +7 -21
- package/src/__tests__/auth-redirect.test.tsx +8 -2
- package/src/__tests__/auth.test.tsx +25 -23
- package/src/__tests__/auto-topup-card.test.tsx +4 -12
- package/src/__tests__/backups-tab.test.tsx +3 -4
- package/src/__tests__/billing-layout-nav-hidden.test.tsx +5 -37
- package/src/__tests__/billing-payment-org-invoices.test.tsx +2 -18
- package/src/__tests__/billing.test.tsx +8 -39
- package/src/__tests__/bot-settings/resources-tab.test.tsx +1 -3
- package/src/__tests__/bot-settings/storage-tab.test.tsx +1 -3
- package/src/__tests__/bot-settings/vps-upgrade-card.test.tsx +1 -3
- package/src/__tests__/bot-settings-restart.test.tsx +1 -3
- package/src/__tests__/bot-settings.test.tsx +2 -6
- package/src/__tests__/brand.test.ts +6 -26
- package/src/__tests__/buy-credits-panel.test.tsx +1 -3
- package/src/__tests__/buy-crypto-credits-panel.test.tsx +101 -119
- package/src/__tests__/capability-conflicts.test.ts +2 -8
- package/src/__tests__/capability-resolver.test.tsx +2 -12
- package/src/__tests__/channel-wizard.test.tsx +4 -17
- package/src/__tests__/chat/chat-panel.test.tsx +1 -4
- package/src/__tests__/chat-store.test.ts +5 -15
- package/src/__tests__/command-center.test.tsx +10 -12
- package/src/__tests__/compliance-retention-edit.test.tsx +3 -6
- package/src/__tests__/confirmation-tracker.test.tsx +3 -18
- package/src/__tests__/coupon-input.test.tsx +1 -3
- package/src/__tests__/create-instance.test.tsx +1 -3
- package/src/__tests__/credit-balance.test.tsx +4 -12
- package/src/__tests__/credits.test.tsx +32 -85
- package/src/__tests__/email-verification-banner.test.tsx +2 -6
- package/src/__tests__/error-boundaries.test.tsx +0 -1
- package/src/__tests__/fetch-pricing.test.ts +2 -1
- package/src/__tests__/field-oauth.test.tsx +2 -6
- package/src/__tests__/fixtures/mock-manifests-data.js +1 -3
- package/src/__tests__/fixtures/mock-manifests.ts +2 -4
- package/src/__tests__/fleet-health-timestamp.test.tsx +1 -8
- package/src/__tests__/fleet-health-update.test.tsx +1 -8
- package/src/__tests__/gpu-dashboard.test.tsx +2 -6
- package/src/__tests__/instance-detail.test.tsx +3 -9
- package/src/__tests__/instance-list.test.tsx +1 -5
- package/src/__tests__/layout-snapshots.test.tsx +64 -11
- package/src/__tests__/marketplace-admin.test.tsx +2 -6
- package/src/__tests__/marketplace.test.tsx +11 -35
- package/src/__tests__/merge-api-rates.test.ts +1 -6
- package/src/__tests__/middleware.test.ts +32 -219
- package/src/__tests__/next-config-headers.test.ts +1 -3
- package/src/__tests__/notifications.test.tsx +4 -11
- package/src/__tests__/oauth-buttons.test.tsx +36 -59
- package/src/__tests__/oauth-error-mapping.test.tsx +2 -6
- package/src/__tests__/observability.test.tsx +23 -36
- package/src/__tests__/onboarding-page.test.tsx +4 -6
- package/src/__tests__/org-billing-api.test.tsx +1 -6
- package/src/__tests__/plugin-install-flow.test.tsx +28 -58
- package/src/__tests__/plugin-registry.test.tsx +3 -11
- package/src/__tests__/plugin-tool-sync.test.ts +1 -3
- package/src/__tests__/plugins-catalog-error.test.tsx +2 -6
- package/src/__tests__/plugins-toggle-race.test.tsx +3 -5
- package/src/__tests__/portfolio-chart.test.tsx +2 -6
- package/src/__tests__/promotion-form.test.tsx +2 -6
- package/src/__tests__/promotions-list.test.tsx +1 -3
- package/src/__tests__/provider-key-api.test.ts +2 -1
- package/src/__tests__/resend-verification-button.test.tsx +8 -24
- package/src/__tests__/secrets-audit-pagination.test.tsx +1 -3
- package/src/__tests__/settings.test.tsx +11 -21
- package/src/__tests__/setup-checklist.test.tsx +3 -9
- package/src/__tests__/setup.ts +25 -6
- package/src/__tests__/snapshot-api.test.ts +2 -1
- package/src/__tests__/step-superpowers.test.tsx +1 -3
- package/src/__tests__/tenant-context.test.tsx +1 -6
- package/src/__tests__/tenant-keys-api.test.ts +3 -4
- package/src/__tests__/tenant-table-pagination.test.tsx +2 -6
- package/src/__tests__/terminal-log-cleanup.test.tsx +0 -1
- package/src/__tests__/transaction-history.test.tsx +190 -238
- package/src/__tests__/trpc-types.test.ts +2 -6
- package/src/__tests__/use-chat.test.ts +1 -3
- package/src/__tests__/use-plugin-setup-chat-stale-closure.test.ts +1 -4
- package/src/__tests__/use-sidecar-bridge.test.tsx +105 -0
- package/src/__tests__/use-webmcp.test.ts +1 -3
- package/src/__tests__/validate-elevenlabs-key.test.ts +2 -1
- package/src/__tests__/verify-page.test.tsx +4 -13
- package/src/__tests__/verify-redirect.test.tsx +2 -6
- package/src/app/(auth)/error.tsx +1 -7
- package/src/app/(auth)/forgot-password/page.tsx +4 -18
- package/src/app/(auth)/login/page.tsx +5 -22
- package/src/app/(auth)/reset-password/page.tsx +2 -12
- package/src/app/(auth)/signup/page.tsx +10 -44
- package/src/app/(auth)/verify/page.tsx +47 -0
- package/src/app/(dashboard)/billing/credits/page.tsx +14 -67
- package/src/app/(dashboard)/billing/error.tsx +2 -10
- package/src/app/(dashboard)/billing/layout.tsx +12 -62
- package/src/app/(dashboard)/billing/payment/page.tsx +17 -68
- package/src/app/(dashboard)/billing/plans/page.tsx +3 -9
- package/src/app/(dashboard)/billing/usage/hosted/page.tsx +8 -25
- package/src/app/(dashboard)/billing/usage/page.tsx +63 -103
- package/src/app/(dashboard)/changesets/[id]/changeset-detail-client.tsx +9 -27
- package/src/app/(dashboard)/changesets/[id]/error.tsx +2 -6
- package/src/app/(dashboard)/changesets/error.tsx +1 -7
- package/src/app/(dashboard)/chat/page.tsx +2 -6
- package/src/app/(dashboard)/dashboard/network/page.tsx +5 -19
- package/src/app/(dashboard)/error.tsx +1 -7
- package/src/app/(dashboard)/layout.tsx +15 -36
- package/src/app/(dashboard)/marketplace/[plugin]/page.tsx +14 -51
- package/src/app/(dashboard)/marketplace/error.tsx +1 -7
- package/src/app/(dashboard)/marketplace/page.tsx +6 -27
- package/src/app/(dashboard)/not-found.tsx +2 -5
- package/src/app/(dashboard)/onboarding/page.tsx +5 -22
- package/src/app/(dashboard)/settings/account/page.tsx +1 -6
- package/src/app/(dashboard)/settings/activity/page.tsx +8 -34
- package/src/app/(dashboard)/settings/api-keys/page.tsx +15 -60
- package/src/app/(dashboard)/settings/brain/page.tsx +9 -31
- package/src/app/(dashboard)/settings/error.tsx +2 -10
- package/src/app/(dashboard)/settings/notifications/page.tsx +2 -6
- package/src/app/(dashboard)/settings/org/page.tsx +13 -56
- package/src/app/(dashboard)/settings/page.tsx +1 -0
- package/src/app/(dashboard)/settings/profile/page.tsx +126 -73
- package/src/app/(dashboard)/settings/providers/page.tsx +21 -78
- package/src/app/(dashboard)/settings/secrets/page.tsx +13 -58
- package/src/app/(dashboard)/settings/security/page.tsx +31 -111
- package/src/app/admin/email-templates/email-templates-client.tsx +15 -58
- package/src/app/admin/error.tsx +1 -7
- package/src/app/admin/fleet-updates/error.tsx +1 -7
- package/src/app/admin/fleet-updates/fleet-updates-client.tsx +10 -50
- package/src/app/admin/layout.tsx +4 -0
- package/src/app/admin/payment-methods/page.tsx +9 -38
- package/src/app/admin/products/error.tsx +2 -7
- package/src/app/admin/products/page.tsx +1 -4
- package/src/app/admin/promotions/[id]/page.tsx +9 -38
- package/src/app/admin/promotions/page.tsx +9 -36
- package/src/app/admin/rate-overrides/page.tsx +9 -45
- package/src/app/auth/callback/[provider]/page.tsx +1 -8
- package/src/app/auth/verify/page.tsx +9 -36
- package/src/app/channels/error.tsx +2 -10
- package/src/app/channels/layout.tsx +9 -0
- package/src/app/channels/page.tsx +8 -20
- package/src/app/channels/setup/[plugin]/page.tsx +3 -5
- package/src/app/error.tsx +1 -7
- package/src/app/fleet/error.tsx +1 -7
- package/src/app/fleet/layout.tsx +5 -0
- package/src/app/fleet/settings/page.tsx +1 -3
- package/src/app/global-error.tsx +2 -10
- package/src/app/globals.css +1 -4
- package/src/app/instances/[id]/instance-detail-client.tsx +51 -125
- package/src/app/instances/error.tsx +2 -10
- package/src/app/instances/instance-list-client.tsx +20 -69
- package/src/app/instances/layout.tsx +9 -0
- package/src/app/instances/new/create-instance-client.tsx +10 -31
- package/src/app/layout.tsx +2 -10
- package/src/app/not-found.tsx +1 -3
- package/src/app/page.tsx +1 -2
- package/src/app/plugins/error.tsx +2 -10
- package/src/app/plugins/layout.tsx +5 -0
- package/src/app/plugins/page.tsx +16 -48
- package/src/app/pricing/error.tsx +1 -7
- package/src/app/privacy/page.tsx +93 -150
- package/src/app/status/error.tsx +1 -7
- package/src/app/terms/page.tsx +89 -144
- package/src/components/account-switcher.tsx +25 -52
- package/src/components/admin/accounting-dashboard.tsx +1 -3
- package/src/components/admin/admin-guard.tsx +1 -3
- package/src/components/admin/admin-nav.tsx +1 -3
- package/src/components/admin/affiliate-dashboard.tsx +25 -94
- package/src/components/admin/audit-log-table.tsx +13 -49
- package/src/components/admin/billing-health-dashboard.tsx +7 -25
- package/src/components/admin/bulk-actions-bar.test.tsx +1 -7
- package/src/components/admin/bulk-actions-bar.tsx +1 -3
- package/src/components/admin/bulk-export-dialog.test.tsx +1 -7
- package/src/components/admin/bulk-export-dialog.tsx +6 -32
- package/src/components/admin/bulk-grant-dialog.test.tsx +2 -6
- package/src/components/admin/bulk-grant-dialog.tsx +4 -15
- package/src/components/admin/bulk-preview-dialog.tsx +3 -12
- package/src/components/admin/bulk-reactivate-dialog.tsx +1 -7
- package/src/components/admin/bulk-select-all-banner.tsx +1 -6
- package/src/components/admin/bulk-suspend-dialog.tsx +5 -12
- package/src/components/admin/bulk-undo-toast.tsx +1 -2
- package/src/components/admin/compliance-dashboard.tsx +31 -101
- package/src/components/admin/gpu-dashboard.tsx +21 -70
- package/src/components/admin/grant-credits-dialog.tsx +4 -17
- package/src/components/admin/incident-dashboard.tsx +10 -25
- package/src/components/admin/inference-dashboard.tsx +14 -54
- package/src/components/admin/marketplace-admin.tsx +18 -60
- package/src/components/admin/migrations-dashboard.tsx +9 -42
- package/src/components/admin/onboarding-dashboard.tsx +14 -64
- package/src/components/admin/pool-config-dashboard.tsx +4 -10
- package/src/components/admin/products/fleet-form.tsx +2 -11
- package/src/components/admin/products/nav-editor.tsx +3 -10
- package/src/components/admin/promotions/promotion-form.tsx +9 -42
- package/src/components/admin/roles-dashboard.tsx +7 -34
- package/src/components/admin/suspend-dialog.tsx +4 -11
- package/src/components/admin/tenant-notes-panel.tsx +1 -3
- package/src/components/admin/tenant-row-actions.tsx +4 -20
- package/src/components/admin/tenant-table.tsx +12 -49
- package/src/components/auth/auth-redirect.tsx +11 -3
- package/src/components/auth/email-verification-result-banner.tsx +1 -3
- package/src/components/auth/resend-verification-button.tsx +2 -10
- package/src/components/auth/wopr-wordmark.tsx +1 -3
- package/src/components/billing/add-payment-method-dialog.tsx +1 -2
- package/src/components/billing/affiliate-dashboard.tsx +4 -16
- package/src/components/billing/amount-selector.tsx +1 -3
- package/src/components/billing/auto-topup-card.tsx +2 -11
- package/src/components/billing/buy-credits-panel.tsx +4 -14
- package/src/components/billing/byok-callout.tsx +6 -8
- package/src/components/billing/confirmation-tracker.tsx +4 -14
- package/src/components/billing/credit-balance-badge.tsx +22 -0
- package/src/components/billing/credit-balance.tsx +3 -9
- package/src/components/billing/crypto-checkout.tsx +5 -24
- package/src/components/billing/degraded-state-banner.tsx +1 -3
- package/src/components/billing/deposit-view.tsx +301 -41
- package/src/components/billing/dividend-banner.tsx +1 -3
- package/src/components/billing/dividend-eligibility.tsx +3 -12
- package/src/components/billing/dividend-pool-stats.tsx +6 -20
- package/src/components/billing/first-dividend-dialog.tsx +2 -2
- package/src/components/billing/org-billing-page.tsx +8 -31
- package/src/components/billing/payment-method-picker.tsx +2 -10
- package/src/components/billing/suspension-banner.tsx +2 -7
- package/src/components/billing/transaction-history.tsx +10 -58
- package/src/components/billing/unified-checkout.tsx +547 -0
- package/src/components/bot-settings/backups-tab.tsx +9 -33
- package/src/components/bot-settings/bot-settings-client.tsx +32 -134
- package/src/components/bot-settings/resources-tab.tsx +2 -9
- package/src/components/bot-settings/storage-tab.tsx +19 -48
- package/src/components/bot-settings/vps-info-panel.tsx +3 -11
- package/src/components/bot-settings/vps-upgrade-card.tsx +3 -4
- package/src/components/brand-hydrator.tsx +13 -0
- package/src/components/channel-wizard/field-interactive.tsx +1 -3
- package/src/components/channel-wizard/field-qr.tsx +10 -39
- package/src/components/channel-wizard/step-renderer.tsx +5 -28
- package/src/components/channel-wizard/wizard.tsx +6 -31
- package/src/components/chat/chat-message.tsx +1 -4
- package/src/components/chat/chat-panel.tsx +4 -18
- package/src/components/chat/chat-widget.tsx +3 -14
- package/src/components/dashboard/command-center.tsx +15 -61
- package/src/components/fleet/update-settings-card.tsx +7 -23
- package/src/components/instance-update-banner.tsx +130 -0
- package/src/components/instances/friends-tab.test.tsx +2 -9
- package/src/components/instances/friends-tab.tsx +18 -74
- package/src/components/instances/update-available-badge.tsx +2 -11
- package/src/components/landing/hero.tsx +3 -9
- package/src/components/landing/landing-page.tsx +1 -3
- package/src/components/landing/portfolio-chart.tsx +4 -9
- package/src/components/landing/story-sections.tsx +1 -3
- package/src/components/landing/terminal-sequence.tsx +4 -17
- package/src/components/marketplace/empty-state.tsx +2 -6
- package/src/components/marketplace/first-visit-hero.tsx +1 -3
- package/src/components/marketplace/install-wizard.tsx +20 -77
- package/src/components/marketplace/marketplace-tabs.tsx +1 -4
- package/src/components/marketplace/plugin-card.tsx +2 -9
- package/src/components/marketplace/superpower-content.tsx +1 -3
- package/src/components/marketplace/terminal-search.tsx +2 -8
- package/src/components/oauth-buttons.tsx +29 -14
- package/src/components/observability/fleet-health.tsx +5 -18
- package/src/components/observability/health-overview.tsx +7 -20
- package/src/components/observability/logs-viewer.tsx +8 -32
- package/src/components/observability/metrics-dashboard.tsx +2 -15
- package/src/components/onboarding/fallback-setup.tsx +6 -25
- package/src/components/onboarding/setup-checklist.tsx +18 -51
- package/src/components/onboarding/step-superpowers.tsx +1 -4
- package/src/components/plugin-setup/setup-chat-panel.tsx +6 -22
- package/src/components/pricing/dividend-calculator.tsx +6 -12
- package/src/components/pricing/dividend-stats.tsx +5 -17
- package/src/components/pricing/pricing-page.tsx +17 -36
- package/src/components/settings/create-org-wizard.tsx +2 -5
- package/src/components/sidebar.tsx +7 -42
- package/src/components/sidecar-frame.tsx +78 -0
- package/src/components/status/status-page.tsx +6 -28
- package/src/components/ui/alert-dialog.tsx +8 -25
- package/src/components/ui/badge.tsx +2 -8
- package/src/components/ui/banner.tsx +1 -6
- package/src/components/ui/card.tsx +5 -24
- package/src/components/ui/checkbox.tsx +1 -5
- package/src/components/ui/collapsible.tsx +3 -8
- package/src/components/ui/dialog.tsx +4 -10
- package/src/components/ui/dropdown-menu.tsx +9 -18
- package/src/components/ui/form.tsx +2 -16
- package/src/components/ui/popover.tsx +3 -23
- package/src/components/ui/progress.tsx +1 -5
- package/src/components/ui/radio-group.tsx +3 -15
- package/src/components/ui/select.tsx +4 -17
- package/src/components/ui/sheet.tsx +5 -19
- package/src/components/ui/skeleton.tsx +1 -7
- package/src/components/ui/table.tsx +5 -22
- package/src/components/ui/tabs.tsx +3 -13
- package/src/components/ui/tooltip.tsx +1 -1
- package/src/components/unified-sidebar.tsx +493 -0
- package/src/hooks/__tests__/use-fleet-sse.test.ts +1 -4
- package/src/hooks/__tests__/use-save-queue.test.ts +2 -8
- package/src/hooks/use-credit-balance.ts +27 -0
- package/src/hooks/use-my-org-role.ts +1 -3
- package/src/hooks/use-plugin-registry.ts +8 -14
- package/src/hooks/use-plugin-setup-chat.ts +2 -5
- package/src/hooks/use-sidecar-bridge.tsx +148 -0
- package/src/hooks/use-webmcp.ts +1 -4
- package/src/lib/__tests__/admin-api.test.ts +1 -3
- package/src/lib/__tests__/api-bot-crud.test.ts +8 -18
- package/src/lib/__tests__/api-fetch.test.ts +4 -16
- package/src/lib/__tests__/org-billing-api.test.ts +1 -3
- package/src/lib/__tests__/pricing-data.test.ts +0 -8
- package/src/lib/__tests__/settings-api.test.ts +1 -3
- package/src/lib/admin-affiliate-api.ts +2 -7
- package/src/lib/admin-api.ts +6 -26
- package/src/lib/admin-incident-api.ts +11 -19
- package/src/lib/admin-marketplace-api.ts +1 -5
- package/src/lib/api-config.test.ts +5 -50
- package/src/lib/api.ts +143 -122
- package/src/lib/auth-client.ts +1 -2
- package/src/lib/bot-settings-data.ts +11 -36
- package/src/lib/brand-config.ts +56 -115
- package/src/lib/brand.ts +2 -15
- package/src/lib/chat/use-chat.ts +2 -7
- package/src/lib/cost-comparison-data.test.ts +1 -3
- package/src/lib/cost-comparison-data.ts +1 -4
- package/src/lib/errors.ts +1 -4
- package/src/lib/fetch-utils.test.ts +26 -9
- package/src/lib/fetch-utils.ts +40 -11
- package/src/lib/logger.ts +2 -0
- package/src/lib/marketplace-data.ts +3 -11
- package/src/lib/oauth-errors.ts +2 -4
- package/src/lib/onboarding-data.ts +3 -11
- package/src/lib/org-api.ts +2 -10
- package/src/lib/org-billing-api.ts +5 -19
- package/src/lib/plugin/tool-definitions.ts +1 -2
- package/src/lib/require-auth.ts +57 -0
- package/src/lib/settings-api.ts +1 -4
- package/src/lib/sidecar-routes.ts +43 -0
- package/src/lib/trpc-server.ts +49 -0
- package/src/lib/trpc-types.ts +4 -6
- package/src/lib/trpc.tsx +12 -4
- package/src/lib/validate-redirect-url.ts +1 -4
- package/src/lib/webmcp/marketplace-onboarding-tools.ts +6 -16
- package/src/lib/webmcp/register.ts +1 -4
- package/src/lib/webmcp/tools.ts +2 -9
- package/src/proxy.ts +35 -212
- package/src/types/missing-deps.d.ts +2 -8
- package/tsconfig.json +1 -8
- package/biome.json +0 -52
- package/src/__tests__/__snapshots__/layout-snapshots.test.tsx.snap +0 -741
- package/src/__tests__/billing-byok-callout.test.tsx +0 -76
- package/src/lib/__tests__/__snapshots__/pricing-data.test.ts.snap +0 -112
|
@@ -38,13 +38,7 @@ async function deriveXpubFromMnemonic(mnemonic: string, coinType: number): Promi
|
|
|
38
38
|
return xpub;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
function MnemonicDeriveSection({
|
|
42
|
-
chain,
|
|
43
|
-
onXpubDerived,
|
|
44
|
-
}: {
|
|
45
|
-
chain: string;
|
|
46
|
-
onXpubDerived: (xpub: string) => void;
|
|
47
|
-
}) {
|
|
41
|
+
function MnemonicDeriveSection({ chain, onXpubDerived }: { chain: string; onXpubDerived: (xpub: string) => void }) {
|
|
48
42
|
const [mnemonic, setMnemonic] = useState("");
|
|
49
43
|
const [deriving, setDeriving] = useState(false);
|
|
50
44
|
const [error, setError] = useState<string | null>(null);
|
|
@@ -72,9 +66,7 @@ function MnemonicDeriveSection({
|
|
|
72
66
|
if (derived) {
|
|
73
67
|
return (
|
|
74
68
|
<div className="col-span-2 rounded-md border border-green-500/30 bg-green-500/5 p-3">
|
|
75
|
-
<p className="text-xs text-green-500">
|
|
76
|
-
xpub derived and set. Mnemonic was cleared from memory.
|
|
77
|
-
</p>
|
|
69
|
+
<p className="text-xs text-green-500">xpub derived and set. Mnemonic was cleared from memory.</p>
|
|
78
70
|
</div>
|
|
79
71
|
);
|
|
80
72
|
}
|
|
@@ -98,13 +90,7 @@ function MnemonicDeriveSection({
|
|
|
98
90
|
spellCheck={false}
|
|
99
91
|
/>
|
|
100
92
|
{error && <p className="text-xs text-destructive">{error}</p>}
|
|
101
|
-
<Button
|
|
102
|
-
type="button"
|
|
103
|
-
variant="outline"
|
|
104
|
-
size="sm"
|
|
105
|
-
onClick={handleDerive}
|
|
106
|
-
disabled={deriving || !mnemonic.trim()}
|
|
107
|
-
>
|
|
93
|
+
<Button type="button" variant="outline" size="sm" onClick={handleDerive} disabled={deriving || !mnemonic.trim()}>
|
|
108
94
|
{deriving ? "Deriving..." : "Derive xpub"}
|
|
109
95
|
</Button>
|
|
110
96
|
</div>
|
|
@@ -248,9 +234,7 @@ function AddMethodForm({ onSaved }: { onSaved: () => void }) {
|
|
|
248
234
|
/>
|
|
249
235
|
</label>
|
|
250
236
|
<label className="col-span-2 space-y-1">
|
|
251
|
-
<span className="text-xs text-muted-foreground">
|
|
252
|
-
Oracle Address (Chainlink feed — empty for stablecoins)
|
|
253
|
-
</span>
|
|
237
|
+
<span className="text-xs text-muted-foreground">Oracle Address (Chainlink feed — empty for stablecoins)</span>
|
|
254
238
|
<input
|
|
255
239
|
className="w-full rounded-md border bg-background px-3 py-1.5 text-sm font-mono"
|
|
256
240
|
placeholder="0x..."
|
|
@@ -260,10 +244,7 @@ function AddMethodForm({ onSaved }: { onSaved: () => void }) {
|
|
|
260
244
|
</label>
|
|
261
245
|
|
|
262
246
|
{/* --- xpub: paste directly or derive from mnemonic --- */}
|
|
263
|
-
<MnemonicDeriveSection
|
|
264
|
-
chain={form.chain}
|
|
265
|
-
onXpubDerived={(xpub) => setForm((f) => ({ ...f, xpub }))}
|
|
266
|
-
/>
|
|
247
|
+
<MnemonicDeriveSection chain={form.chain} onXpubDerived={(xpub) => setForm((f) => ({ ...f, xpub }))} />
|
|
267
248
|
<label className="col-span-2 space-y-1">
|
|
268
249
|
<span className="text-xs text-muted-foreground">
|
|
269
250
|
xpub (auto-filled from mnemonic above, or paste directly)
|
|
@@ -372,29 +353,19 @@ export default function AdminPaymentMethodsPage() {
|
|
|
372
353
|
<td className="py-2 pr-4 font-mono text-xs">
|
|
373
354
|
{m.contractAddress ? `${m.contractAddress.slice(0, 10)}...` : "—"}
|
|
374
355
|
</td>
|
|
375
|
-
<td className="py-2 pr-4 font-mono text-xs">
|
|
376
|
-
|
|
377
|
-
</td>
|
|
378
|
-
<td className="py-2 pr-4 font-mono text-xs">
|
|
379
|
-
{m.rpcUrl ? `${m.rpcUrl.slice(0, 20)}...` : "—"}
|
|
380
|
-
</td>
|
|
356
|
+
<td className="py-2 pr-4 font-mono text-xs">{m.xpub ? `${m.xpub.slice(0, 12)}...` : "—"}</td>
|
|
357
|
+
<td className="py-2 pr-4 font-mono text-xs">{m.rpcUrl ? `${m.rpcUrl.slice(0, 20)}...` : "—"}</td>
|
|
381
358
|
<td className="py-2 pr-4">
|
|
382
359
|
<span
|
|
383
360
|
className={
|
|
384
|
-
m.enabled
|
|
385
|
-
? "text-xs font-medium text-green-500"
|
|
386
|
-
: "text-xs font-medium text-red-500"
|
|
361
|
+
m.enabled ? "text-xs font-medium text-green-500" : "text-xs font-medium text-red-500"
|
|
387
362
|
}
|
|
388
363
|
>
|
|
389
364
|
{m.enabled ? "Enabled" : "Disabled"}
|
|
390
365
|
</span>
|
|
391
366
|
</td>
|
|
392
367
|
<td className="py-2">
|
|
393
|
-
<Button
|
|
394
|
-
variant="ghost"
|
|
395
|
-
size="sm"
|
|
396
|
-
onClick={() => handleToggle(m.id, !m.enabled)}
|
|
397
|
-
>
|
|
368
|
+
<Button variant="ghost" size="sm" onClick={() => handleToggle(m.id, !m.enabled)}>
|
|
398
369
|
{m.enabled ? "Disable" : "Enable"}
|
|
399
370
|
</Button>
|
|
400
371
|
</td>
|
|
@@ -3,14 +3,9 @@
|
|
|
3
3
|
import { useEffect } from "react";
|
|
4
4
|
import { Button } from "@/components/ui/button";
|
|
5
5
|
|
|
6
|
-
export default function ProductsError({
|
|
7
|
-
error,
|
|
8
|
-
reset,
|
|
9
|
-
}: {
|
|
10
|
-
error: Error & { digest?: string };
|
|
11
|
-
reset: () => void;
|
|
12
|
-
}) {
|
|
6
|
+
export default function ProductsError({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
|
|
13
7
|
useEffect(() => {
|
|
8
|
+
// biome-ignore lint/suspicious/noConsole: error boundary diagnostic logging
|
|
14
9
|
console.error("Admin products page error:", error);
|
|
15
10
|
}, [error]);
|
|
16
11
|
|
|
@@ -215,10 +215,7 @@ export default function AdminProductsPage() {
|
|
|
215
215
|
</TabsContent>
|
|
216
216
|
|
|
217
217
|
<TabsContent value="features">
|
|
218
|
-
<FeaturesForm
|
|
219
|
-
initial={config.features ?? DEFAULT_FEATURES}
|
|
220
|
-
onSave={mutateProductConfig}
|
|
221
|
-
/>
|
|
218
|
+
<FeaturesForm initial={config.features ?? DEFAULT_FEATURES} onSave={mutateProductConfig} />
|
|
222
219
|
</TabsContent>
|
|
223
220
|
|
|
224
221
|
<TabsContent value="fleet">
|
|
@@ -7,24 +7,11 @@ import { useCallback, useEffect, useState } from "react";
|
|
|
7
7
|
import { Badge } from "@/components/ui/badge";
|
|
8
8
|
import { Button } from "@/components/ui/button";
|
|
9
9
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
10
|
-
import {
|
|
11
|
-
Dialog,
|
|
12
|
-
DialogContent,
|
|
13
|
-
DialogHeader,
|
|
14
|
-
DialogTitle,
|
|
15
|
-
DialogTrigger,
|
|
16
|
-
} from "@/components/ui/dialog";
|
|
10
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
|
|
17
11
|
import { Input } from "@/components/ui/input";
|
|
18
12
|
import { Progress } from "@/components/ui/progress";
|
|
19
13
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
20
|
-
import {
|
|
21
|
-
Table,
|
|
22
|
-
TableBody,
|
|
23
|
-
TableCell,
|
|
24
|
-
TableHead,
|
|
25
|
-
TableHeader,
|
|
26
|
-
TableRow,
|
|
27
|
-
} from "@/components/ui/table";
|
|
14
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
|
28
15
|
import type { Promotion, Redemption } from "@/lib/promotions-types";
|
|
29
16
|
import { trpcVanilla } from "@/lib/trpc";
|
|
30
17
|
import { cn } from "@/lib/utils";
|
|
@@ -142,9 +129,7 @@ export default function PromotionDetailPage() {
|
|
|
142
129
|
}
|
|
143
130
|
|
|
144
131
|
const budgetUsedPercent =
|
|
145
|
-
promo.budgetCap && promo.budgetCap > 0
|
|
146
|
-
? Math.min(100, (promo.totalCreditsGranted / promo.budgetCap) * 100)
|
|
147
|
-
: null;
|
|
132
|
+
promo.budgetCap && promo.budgetCap > 0 ? Math.min(100, (promo.totalCreditsGranted / promo.budgetCap) * 100) : null;
|
|
148
133
|
|
|
149
134
|
return (
|
|
150
135
|
<div className="p-6 space-y-6">
|
|
@@ -171,18 +156,14 @@ export default function PromotionDetailPage() {
|
|
|
171
156
|
<div className="text-2xl font-bold tabular-nums">
|
|
172
157
|
{promo.totalUses}
|
|
173
158
|
{promo.totalUseLimit !== null && (
|
|
174
|
-
<span className="text-sm text-muted-foreground font-normal">
|
|
175
|
-
/{promo.totalUseLimit}
|
|
176
|
-
</span>
|
|
159
|
+
<span className="text-sm text-muted-foreground font-normal">/{promo.totalUseLimit}</span>
|
|
177
160
|
)}
|
|
178
161
|
</div>
|
|
179
162
|
</CardContent>
|
|
180
163
|
</Card>
|
|
181
164
|
<Card>
|
|
182
165
|
<CardHeader className="pb-2">
|
|
183
|
-
<CardTitle className="text-xs text-muted-foreground font-normal">
|
|
184
|
-
Credits Granted
|
|
185
|
-
</CardTitle>
|
|
166
|
+
<CardTitle className="text-xs text-muted-foreground font-normal">Credits Granted</CardTitle>
|
|
186
167
|
</CardHeader>
|
|
187
168
|
<CardContent>
|
|
188
169
|
<div className="text-2xl font-bold tabular-nums text-terminal">
|
|
@@ -192,9 +173,7 @@ export default function PromotionDetailPage() {
|
|
|
192
173
|
</Card>
|
|
193
174
|
<Card>
|
|
194
175
|
<CardHeader className="pb-2">
|
|
195
|
-
<CardTitle className="text-xs text-muted-foreground font-normal">
|
|
196
|
-
Budget Remaining
|
|
197
|
-
</CardTitle>
|
|
176
|
+
<CardTitle className="text-xs text-muted-foreground font-normal">Budget Remaining</CardTitle>
|
|
198
177
|
</CardHeader>
|
|
199
178
|
<CardContent>
|
|
200
179
|
{promo.budgetCap !== null ? (
|
|
@@ -211,9 +190,7 @@ export default function PromotionDetailPage() {
|
|
|
211
190
|
</Card>
|
|
212
191
|
<Card>
|
|
213
192
|
<CardHeader className="pb-2">
|
|
214
|
-
<CardTitle className="text-xs text-muted-foreground font-normal">
|
|
215
|
-
Time Remaining
|
|
216
|
-
</CardTitle>
|
|
193
|
+
<CardTitle className="text-xs text-muted-foreground font-normal">Time Remaining</CardTitle>
|
|
217
194
|
</CardHeader>
|
|
218
195
|
<CardContent>
|
|
219
196
|
<div className="text-2xl font-bold">{timeRemaining(promo.endsAt)}</div>
|
|
@@ -252,11 +229,7 @@ export default function PromotionDetailPage() {
|
|
|
252
229
|
/>
|
|
253
230
|
</div>
|
|
254
231
|
{genResult && <p className="text-sm text-muted-foreground">{genResult}</p>}
|
|
255
|
-
<Button
|
|
256
|
-
onClick={handleGenerate}
|
|
257
|
-
disabled={generating || genCount < 1}
|
|
258
|
-
className="w-full"
|
|
259
|
-
>
|
|
232
|
+
<Button onClick={handleGenerate} disabled={generating || genCount < 1} className="w-full">
|
|
260
233
|
{generating ? "Generating..." : `Generate ${genCount} codes`}
|
|
261
234
|
</Button>
|
|
262
235
|
</div>
|
|
@@ -286,9 +259,7 @@ export default function PromotionDetailPage() {
|
|
|
286
259
|
<TableBody>
|
|
287
260
|
{redemptions.map((r) => (
|
|
288
261
|
<TableRow key={r.id}>
|
|
289
|
-
<TableCell className="font-mono text-xs">
|
|
290
|
-
{r.tenantId.slice(0, 12)}...
|
|
291
|
-
</TableCell>
|
|
262
|
+
<TableCell className="font-mono text-xs">{r.tenantId.slice(0, 12)}...</TableCell>
|
|
292
263
|
<TableCell className="text-right tabular-nums text-terminal">
|
|
293
264
|
{formatCreditCount(r.creditsGranted)}
|
|
294
265
|
</TableCell>
|
|
@@ -11,22 +11,9 @@ import {
|
|
|
11
11
|
DropdownMenuItem,
|
|
12
12
|
DropdownMenuTrigger,
|
|
13
13
|
} from "@/components/ui/dropdown-menu";
|
|
14
|
-
import {
|
|
15
|
-
Select,
|
|
16
|
-
SelectContent,
|
|
17
|
-
SelectItem,
|
|
18
|
-
SelectTrigger,
|
|
19
|
-
SelectValue,
|
|
20
|
-
} from "@/components/ui/select";
|
|
14
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
|
21
15
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
22
|
-
import {
|
|
23
|
-
Table,
|
|
24
|
-
TableBody,
|
|
25
|
-
TableCell,
|
|
26
|
-
TableHead,
|
|
27
|
-
TableHeader,
|
|
28
|
-
TableRow,
|
|
29
|
-
} from "@/components/ui/table";
|
|
16
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
|
30
17
|
import { toUserMessage } from "@/lib/errors";
|
|
31
18
|
import type { Promotion, PromotionStatus, PromotionType } from "@/lib/promotions-types";
|
|
32
19
|
import { trpcVanilla } from "@/lib/trpc";
|
|
@@ -53,8 +40,7 @@ const TYPE_LABELS: Record<PromotionType, string> = {
|
|
|
53
40
|
};
|
|
54
41
|
|
|
55
42
|
function formatWindow(startsAt: string | null, endsAt: string | null): string {
|
|
56
|
-
const fmt = (d: string) =>
|
|
57
|
-
new Date(d).toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
43
|
+
const fmt = (d: string) => new Date(d).toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
58
44
|
if (!startsAt) return "Immediate";
|
|
59
45
|
if (!endsAt) return `${fmt(startsAt)} — no end`;
|
|
60
46
|
return `${fmt(startsAt)} — ${fmt(endsAt)}`;
|
|
@@ -168,9 +154,7 @@ export default function PromotionsListPage() {
|
|
|
168
154
|
))}
|
|
169
155
|
</div>
|
|
170
156
|
) : promotions.length === 0 ? (
|
|
171
|
-
<div className="flex h-40 items-center justify-center text-sm text-muted-foreground">
|
|
172
|
-
No promotions found.
|
|
173
|
-
</div>
|
|
157
|
+
<div className="flex h-40 items-center justify-center text-sm text-muted-foreground">No promotions found.</div>
|
|
174
158
|
) : (
|
|
175
159
|
<Table>
|
|
176
160
|
<TableHeader>
|
|
@@ -193,22 +177,16 @@ export default function PromotionsListPage() {
|
|
|
193
177
|
{p.name}
|
|
194
178
|
</Link>
|
|
195
179
|
</TableCell>
|
|
196
|
-
<TableCell className="text-sm text-muted-foreground">
|
|
197
|
-
{TYPE_LABELS[p.type]}
|
|
198
|
-
</TableCell>
|
|
180
|
+
<TableCell className="text-sm text-muted-foreground">{TYPE_LABELS[p.type]}</TableCell>
|
|
199
181
|
<TableCell>
|
|
200
182
|
<Badge variant="secondary" className={cn("text-xs", STATUS_COLORS[p.status])}>
|
|
201
183
|
{p.status}
|
|
202
184
|
</Badge>
|
|
203
185
|
</TableCell>
|
|
204
|
-
<TableCell className="text-sm text-muted-foreground">
|
|
205
|
-
{formatWindow(p.startsAt, p.endsAt)}
|
|
206
|
-
</TableCell>
|
|
186
|
+
<TableCell className="text-sm text-muted-foreground">{formatWindow(p.startsAt, p.endsAt)}</TableCell>
|
|
207
187
|
<TableCell className="text-right tabular-nums">
|
|
208
188
|
{p.totalUses}
|
|
209
|
-
{p.totalUseLimit !== null &&
|
|
210
|
-
<span className="text-muted-foreground">/{p.totalUseLimit}</span>
|
|
211
|
-
)}
|
|
189
|
+
{p.totalUseLimit !== null && <span className="text-muted-foreground">/{p.totalUseLimit}</span>}
|
|
212
190
|
</TableCell>
|
|
213
191
|
<TableCell className="text-right tabular-nums text-terminal">
|
|
214
192
|
{formatCreditCount(p.totalCreditsGranted)}
|
|
@@ -230,9 +208,7 @@ export default function PromotionsListPage() {
|
|
|
230
208
|
View Detail
|
|
231
209
|
</Link>
|
|
232
210
|
</DropdownMenuItem>
|
|
233
|
-
{(p.status === "draft" ||
|
|
234
|
-
p.status === "scheduled" ||
|
|
235
|
-
p.status === "paused") && (
|
|
211
|
+
{(p.status === "draft" || p.status === "scheduled" || p.status === "paused") && (
|
|
236
212
|
<DropdownMenuItem onClick={() => handleAction(p.id, "activate")}>
|
|
237
213
|
<Play className="h-4 w-4 mr-2" />
|
|
238
214
|
Activate
|
|
@@ -245,10 +221,7 @@ export default function PromotionsListPage() {
|
|
|
245
221
|
</DropdownMenuItem>
|
|
246
222
|
)}
|
|
247
223
|
{p.status !== "cancelled" && p.status !== "expired" && (
|
|
248
|
-
<DropdownMenuItem
|
|
249
|
-
onClick={() => handleAction(p.id, "cancel")}
|
|
250
|
-
className="text-destructive"
|
|
251
|
-
>
|
|
224
|
+
<DropdownMenuItem onClick={() => handleAction(p.id, "cancel")} className="text-destructive">
|
|
252
225
|
<XCircle className="h-4 w-4 mr-2" />
|
|
253
226
|
Cancel
|
|
254
227
|
</DropdownMenuItem>
|
|
@@ -6,23 +6,10 @@ import { Badge } from "@/components/ui/badge";
|
|
|
6
6
|
import { Button } from "@/components/ui/button";
|
|
7
7
|
import { Input } from "@/components/ui/input";
|
|
8
8
|
import { Label } from "@/components/ui/label";
|
|
9
|
-
import {
|
|
10
|
-
Select,
|
|
11
|
-
SelectContent,
|
|
12
|
-
SelectItem,
|
|
13
|
-
SelectTrigger,
|
|
14
|
-
SelectValue,
|
|
15
|
-
} from "@/components/ui/select";
|
|
9
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
|
16
10
|
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";
|
|
17
11
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
18
|
-
import {
|
|
19
|
-
Table,
|
|
20
|
-
TableBody,
|
|
21
|
-
TableCell,
|
|
22
|
-
TableHead,
|
|
23
|
-
TableHeader,
|
|
24
|
-
TableRow,
|
|
25
|
-
} from "@/components/ui/table";
|
|
12
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
|
26
13
|
import { Textarea } from "@/components/ui/textarea";
|
|
27
14
|
import { toUserMessage } from "@/lib/errors";
|
|
28
15
|
import type { AdapterRateOverride, RateOverrideStatus } from "@/lib/promotions-types";
|
|
@@ -33,14 +20,7 @@ import { cn } from "@/lib/utils";
|
|
|
33
20
|
// Constants
|
|
34
21
|
// ---------------------------------------------------------------------------
|
|
35
22
|
|
|
36
|
-
const ADAPTER_IDS = [
|
|
37
|
-
"nano-banana",
|
|
38
|
-
"elevenlabs",
|
|
39
|
-
"deepgram",
|
|
40
|
-
"openrouter",
|
|
41
|
-
"replicate",
|
|
42
|
-
"gemini",
|
|
43
|
-
] as const;
|
|
23
|
+
const ADAPTER_IDS = ["nano-banana", "elevenlabs", "deepgram", "openrouter", "replicate", "gemini"] as const;
|
|
44
24
|
|
|
45
25
|
const STATUS_COLORS: Record<RateOverrideStatus, string> = {
|
|
46
26
|
active: "bg-terminal/15 text-terminal border border-terminal/20",
|
|
@@ -50,8 +30,7 @@ const STATUS_COLORS: Record<RateOverrideStatus, string> = {
|
|
|
50
30
|
};
|
|
51
31
|
|
|
52
32
|
function formatWindow(startsAt: string, endsAt: string | null): string {
|
|
53
|
-
const fmt = (d: string) =>
|
|
54
|
-
new Date(d).toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
33
|
+
const fmt = (d: string) => new Date(d).toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
55
34
|
if (!endsAt) return `${fmt(startsAt)} — no end`;
|
|
56
35
|
return `${fmt(startsAt)} — ${fmt(endsAt)}`;
|
|
57
36
|
}
|
|
@@ -181,9 +160,7 @@ export default function RateOverridesPage() {
|
|
|
181
160
|
value={formDiscount}
|
|
182
161
|
onChange={(e) => setFormDiscount(Number(e.target.value))}
|
|
183
162
|
/>
|
|
184
|
-
<p className="text-xs text-muted-foreground mt-1">
|
|
185
|
-
100% = free for users — platform absorbs full cost
|
|
186
|
-
</p>
|
|
163
|
+
<p className="text-xs text-muted-foreground mt-1">100% = free for users — platform absorbs full cost</p>
|
|
187
164
|
</div>
|
|
188
165
|
<div>
|
|
189
166
|
<Label htmlFor="ro-starts">Starts At</Label>
|
|
@@ -205,19 +182,10 @@ export default function RateOverridesPage() {
|
|
|
205
182
|
</div>
|
|
206
183
|
<div>
|
|
207
184
|
<Label htmlFor="ro-notes">Notes</Label>
|
|
208
|
-
<Textarea
|
|
209
|
-
id="ro-notes"
|
|
210
|
-
value={formNotes}
|
|
211
|
-
onChange={(e) => setFormNotes(e.target.value)}
|
|
212
|
-
rows={2}
|
|
213
|
-
/>
|
|
185
|
+
<Textarea id="ro-notes" value={formNotes} onChange={(e) => setFormNotes(e.target.value)} rows={2} />
|
|
214
186
|
</div>
|
|
215
187
|
{formError && <p className="text-sm text-destructive">{formError}</p>}
|
|
216
|
-
<Button
|
|
217
|
-
onClick={handleCreate}
|
|
218
|
-
disabled={creating || !formName || !formStartsAt}
|
|
219
|
-
className="w-full"
|
|
220
|
-
>
|
|
188
|
+
<Button onClick={handleCreate} disabled={creating || !formName || !formStartsAt} className="w-full">
|
|
221
189
|
{creating ? "Creating..." : "Create Override"}
|
|
222
190
|
</Button>
|
|
223
191
|
</div>
|
|
@@ -257,17 +225,13 @@ export default function RateOverridesPage() {
|
|
|
257
225
|
<TableCell className="font-mono text-xs">{o.adapterId}</TableCell>
|
|
258
226
|
<TableCell className="font-medium">{o.name}</TableCell>
|
|
259
227
|
<TableCell className="text-right tabular-nums">{o.discountPercent}%</TableCell>
|
|
260
|
-
<TableCell className="text-sm text-muted-foreground">
|
|
261
|
-
{formatWindow(o.startsAt, o.endsAt)}
|
|
262
|
-
</TableCell>
|
|
228
|
+
<TableCell className="text-sm text-muted-foreground">{formatWindow(o.startsAt, o.endsAt)}</TableCell>
|
|
263
229
|
<TableCell>
|
|
264
230
|
<Badge variant="secondary" className={cn("text-xs", STATUS_COLORS[o.status])}>
|
|
265
231
|
{o.status}
|
|
266
232
|
</Badge>
|
|
267
233
|
</TableCell>
|
|
268
|
-
<TableCell className="text-sm text-muted-foreground">
|
|
269
|
-
{o.createdBy ?? "—"}
|
|
270
|
-
</TableCell>
|
|
234
|
+
<TableCell className="text-sm text-muted-foreground">{o.createdBy ?? "—"}</TableCell>
|
|
271
235
|
<TableCell>
|
|
272
236
|
{o.status !== "cancelled" && o.status !== "expired" && (
|
|
273
237
|
<Button
|
|
@@ -5,14 +5,7 @@ import Link from "next/link";
|
|
|
5
5
|
import { useParams, useRouter, useSearchParams } from "next/navigation";
|
|
6
6
|
import { Suspense, useEffect, useState } from "react";
|
|
7
7
|
import { AuthShell } from "@/components/auth/auth-shell";
|
|
8
|
-
import {
|
|
9
|
-
Card,
|
|
10
|
-
CardContent,
|
|
11
|
-
CardDescription,
|
|
12
|
-
CardFooter,
|
|
13
|
-
CardHeader,
|
|
14
|
-
CardTitle,
|
|
15
|
-
} from "@/components/ui/card";
|
|
8
|
+
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
|
|
16
9
|
import { getOAuthErrorMessage } from "@/lib/oauth-errors";
|
|
17
10
|
import { sanitizeRedirectUrl } from "@/lib/utils";
|
|
18
11
|
|
|
@@ -8,14 +8,7 @@ import { Suspense, useEffect, useState } from "react";
|
|
|
8
8
|
import { AuthShell } from "@/components/auth/auth-shell";
|
|
9
9
|
import { ResendVerificationButton } from "@/components/auth/resend-verification-button";
|
|
10
10
|
import { Button } from "@/components/ui/button";
|
|
11
|
-
import {
|
|
12
|
-
Card,
|
|
13
|
-
CardContent,
|
|
14
|
-
CardDescription,
|
|
15
|
-
CardFooter,
|
|
16
|
-
CardHeader,
|
|
17
|
-
CardTitle,
|
|
18
|
-
} from "@/components/ui/card";
|
|
11
|
+
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
|
|
19
12
|
|
|
20
13
|
function SuccessContent() {
|
|
21
14
|
const router = useRouter();
|
|
@@ -50,14 +43,11 @@ function SuccessContent() {
|
|
|
50
43
|
<CardTitle className="text-sm font-medium uppercase tracking-widest text-terminal text-center">
|
|
51
44
|
Email verified
|
|
52
45
|
</CardTitle>
|
|
53
|
-
<CardDescription className="text-center">
|
|
54
|
-
Your email has been verified successfully.
|
|
55
|
-
</CardDescription>
|
|
46
|
+
<CardDescription className="text-center">Your email has been verified successfully.</CardDescription>
|
|
56
47
|
</CardHeader>
|
|
57
48
|
<CardContent className="flex flex-col gap-3">
|
|
58
49
|
<p className="text-sm text-center text-muted-foreground">
|
|
59
|
-
Your <span className="text-terminal font-medium">$5 signup credit</span> has been applied
|
|
60
|
-
to your account.
|
|
50
|
+
Your <span className="text-terminal font-medium">$5 signup credit</span> has been applied to your account.
|
|
61
51
|
</p>
|
|
62
52
|
<p className="text-sm text-center text-muted-foreground">
|
|
63
53
|
Redirecting in <span className="text-terminal font-medium tabular-nums">{countdown}</span>
|
|
@@ -65,10 +55,7 @@ function SuccessContent() {
|
|
|
65
55
|
</p>
|
|
66
56
|
</CardContent>
|
|
67
57
|
<CardFooter className="justify-center">
|
|
68
|
-
<Link
|
|
69
|
-
href="/onboarding"
|
|
70
|
-
className="text-sm text-terminal-dim underline underline-offset-4 hover:text-terminal"
|
|
71
|
-
>
|
|
58
|
+
<Link href="/onboarding" className="text-sm text-terminal-dim underline underline-offset-4 hover:text-terminal">
|
|
72
59
|
Continue to setup
|
|
73
60
|
</Link>
|
|
74
61
|
</CardFooter>
|
|
@@ -141,9 +128,7 @@ function ErrorContent({
|
|
|
141
128
|
</div>
|
|
142
129
|
);
|
|
143
130
|
title = "Verification failed";
|
|
144
|
-
description = status
|
|
145
|
-
? "Something went wrong verifying your email."
|
|
146
|
-
: "No verification status provided.";
|
|
131
|
+
description = status ? "Something went wrong verifying your email." : "No verification status provided.";
|
|
147
132
|
footer = null;
|
|
148
133
|
break;
|
|
149
134
|
}
|
|
@@ -151,17 +136,11 @@ function ErrorContent({
|
|
|
151
136
|
const titleColor = reason === "already-verified" ? "text-terminal" : "text-destructive";
|
|
152
137
|
const footerLink =
|
|
153
138
|
reason === "already-verified" ? (
|
|
154
|
-
<Link
|
|
155
|
-
href="/login"
|
|
156
|
-
className="text-sm text-terminal-dim underline underline-offset-4 hover:text-terminal"
|
|
157
|
-
>
|
|
139
|
+
<Link href="/login" className="text-sm text-terminal-dim underline underline-offset-4 hover:text-terminal">
|
|
158
140
|
Sign in
|
|
159
141
|
</Link>
|
|
160
142
|
) : (
|
|
161
|
-
<Link
|
|
162
|
-
href="/login"
|
|
163
|
-
className="text-sm text-terminal-dim underline underline-offset-4 hover:text-terminal"
|
|
164
|
-
>
|
|
143
|
+
<Link href="/login" className="text-sm text-terminal-dim underline underline-offset-4 hover:text-terminal">
|
|
165
144
|
Back to sign in
|
|
166
145
|
</Link>
|
|
167
146
|
);
|
|
@@ -176,9 +155,7 @@ function ErrorContent({
|
|
|
176
155
|
>
|
|
177
156
|
{icon}
|
|
178
157
|
</motion.div>
|
|
179
|
-
<CardTitle
|
|
180
|
-
className={`text-sm font-medium uppercase tracking-widest ${titleColor} text-center`}
|
|
181
|
-
>
|
|
158
|
+
<CardTitle className={`text-sm font-medium uppercase tracking-widest ${titleColor} text-center`}>
|
|
182
159
|
{title}
|
|
183
160
|
</CardTitle>
|
|
184
161
|
<CardDescription className="text-center">{description}</CardDescription>
|
|
@@ -204,11 +181,7 @@ function VerifyContent() {
|
|
|
204
181
|
</div>
|
|
205
182
|
<div className="relative z-10 w-full max-w-sm">
|
|
206
183
|
<AuthShell>
|
|
207
|
-
{isSuccess ?
|
|
208
|
-
<SuccessContent />
|
|
209
|
-
) : (
|
|
210
|
-
<ErrorContent status={status} reason={reason} email={emailParam} />
|
|
211
|
-
)}
|
|
184
|
+
{isSuccess ? <SuccessContent /> : <ErrorContent status={status} reason={reason} email={emailParam} />}
|
|
212
185
|
</AuthShell>
|
|
213
186
|
</div>
|
|
214
187
|
</div>
|
|
@@ -8,13 +8,7 @@ import { logger } from "@/lib/logger";
|
|
|
8
8
|
|
|
9
9
|
const log = logger("error-boundary:channels");
|
|
10
10
|
|
|
11
|
-
export default function ChannelsError({
|
|
12
|
-
error,
|
|
13
|
-
reset,
|
|
14
|
-
}: {
|
|
15
|
-
error: Error & { digest?: string };
|
|
16
|
-
reset: () => void;
|
|
17
|
-
}) {
|
|
11
|
+
export default function ChannelsError({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
|
|
18
12
|
const [showDetails, setShowDetails] = useState(false);
|
|
19
13
|
const isDev = process.env.NODE_ENV === "development";
|
|
20
14
|
|
|
@@ -32,9 +26,7 @@ export default function ChannelsError({
|
|
|
32
26
|
</div>
|
|
33
27
|
</CardHeader>
|
|
34
28
|
<CardContent className="space-y-4">
|
|
35
|
-
<p className="text-muted-foreground">
|
|
36
|
-
Something went wrong loading channels. This may be a temporary issue.
|
|
37
|
-
</p>
|
|
29
|
+
<p className="text-muted-foreground">Something went wrong loading channels. This may be a temporary issue.</p>
|
|
38
30
|
{isDev && (
|
|
39
31
|
<Button
|
|
40
32
|
type="button"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useRequireAuth } from "@/lib/require-auth";
|
|
4
|
+
|
|
5
|
+
export default function ChannelsLayout({ children }: { children: React.ReactNode }) {
|
|
6
|
+
const { isPending, isAuthed } = useRequireAuth();
|
|
7
|
+
if (isPending || !isAuthed) return null;
|
|
8
|
+
return <>{children}</>;
|
|
9
|
+
}
|
|
@@ -66,16 +66,14 @@ export default function ChannelsPage() {
|
|
|
66
66
|
<div className="mb-8">
|
|
67
67
|
<h1 className="text-2xl font-bold tracking-widest uppercase">COMMS CHANNELS</h1>
|
|
68
68
|
<p className="mt-1 text-sm text-muted-foreground">
|
|
69
|
-
Connect messaging platforms to your {getBrandConfig().productName}. Each channel is driven
|
|
70
|
-
|
|
69
|
+
Connect messaging platforms to your {getBrandConfig().productName}. Each channel is driven by a plugin
|
|
70
|
+
manifest.
|
|
71
71
|
</p>
|
|
72
72
|
</div>
|
|
73
73
|
|
|
74
74
|
{loading && (
|
|
75
75
|
<section className="mb-10">
|
|
76
|
-
<h2 className="mb-4 text-sm font-semibold uppercase tracking-wider text-terminal">
|
|
77
|
-
LINKED
|
|
78
|
-
</h2>
|
|
76
|
+
<h2 className="mb-4 text-sm font-semibold uppercase tracking-wider text-terminal">LINKED</h2>
|
|
79
77
|
<p className="mb-4 font-mono text-sm text-terminal/60">
|
|
80
78
|
> QUERYING CHANNEL STATUS...
|
|
81
79
|
<span className="animate-[pulse-dot_1s_step-end_infinite]">_</span>
|
|
@@ -122,9 +120,7 @@ export default function ChannelsPage() {
|
|
|
122
120
|
{!loading && !error && (
|
|
123
121
|
<>
|
|
124
122
|
<section className="mb-10">
|
|
125
|
-
<h2 className="mb-4 text-sm font-semibold uppercase tracking-wider text-terminal">
|
|
126
|
-
LINKED
|
|
127
|
-
</h2>
|
|
123
|
+
<h2 className="mb-4 text-sm font-semibold uppercase tracking-wider text-terminal">LINKED</h2>
|
|
128
124
|
{instances.some((inst) => inst.channels.length > 0) ? (
|
|
129
125
|
<motion.div
|
|
130
126
|
variants={staggerContainer}
|
|
@@ -168,9 +164,7 @@ export default function ChannelsPage() {
|
|
|
168
164
|
</CardHeader>
|
|
169
165
|
<CardContent>
|
|
170
166
|
<Button variant="ghost" size="sm" asChild>
|
|
171
|
-
<Link href={`/instances/${inst.id}?tab=channels`}>
|
|
172
|
-
View Details
|
|
173
|
-
</Link>
|
|
167
|
+
<Link href={`/instances/${inst.id}?tab=channels`}>View Details</Link>
|
|
174
168
|
</Button>
|
|
175
169
|
</CardContent>
|
|
176
170
|
</Card>
|
|
@@ -182,17 +176,13 @@ export default function ChannelsPage() {
|
|
|
182
176
|
</motion.div>
|
|
183
177
|
) : (
|
|
184
178
|
<div className="flex h-40 items-center justify-center rounded-sm border border-dashed border-terminal/20">
|
|
185
|
-
<p className="font-mono text-sm text-terminal/60">
|
|
186
|
-
> NO CHANNELS LINKED. YOUR BOT IS ISOLATED.
|
|
187
|
-
</p>
|
|
179
|
+
<p className="font-mono text-sm text-terminal/60">> NO CHANNELS LINKED. YOUR BOT IS ISOLATED.</p>
|
|
188
180
|
</div>
|
|
189
181
|
)}
|
|
190
182
|
</section>
|
|
191
183
|
|
|
192
184
|
<section>
|
|
193
|
-
<h2 className="mb-4 text-sm font-semibold uppercase tracking-wider text-muted-foreground">
|
|
194
|
-
AVAILABLE
|
|
195
|
-
</h2>
|
|
185
|
+
<h2 className="mb-4 text-sm font-semibold uppercase tracking-wider text-muted-foreground">AVAILABLE</h2>
|
|
196
186
|
<motion.div
|
|
197
187
|
variants={staggerContainer}
|
|
198
188
|
initial="hidden"
|
|
@@ -235,9 +225,7 @@ export default function ChannelsPage() {
|
|
|
235
225
|
<CardContent className="mt-auto">
|
|
236
226
|
{singleBotId ? (
|
|
237
227
|
<Button variant="terminal" className="w-full" asChild>
|
|
238
|
-
<Link href={`/channels/setup/${manifest.id}?botId=${singleBotId}`}>
|
|
239
|
-
Connect
|
|
240
|
-
</Link>
|
|
228
|
+
<Link href={`/channels/setup/${manifest.id}?botId=${singleBotId}`}>Connect</Link>
|
|
241
229
|
</Button>
|
|
242
230
|
) : instances.length > 1 ? (
|
|
243
231
|
<Button variant="terminal" className="w-full" asChild>
|