@wopr-network/platform-ui-core 1.0.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/.env.paperclip +18 -0
- package/.env.wopr +18 -0
- package/README.md +36 -0
- package/biome.json +52 -0
- package/next.config.ts +45 -0
- package/package.json +84 -0
- package/postcss.config.mjs +7 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/window.svg +1 -0
- package/src/__tests__/__snapshots__/layout-snapshots.test.tsx.snap +741 -0
- package/src/__tests__/account-page-redirect.test.tsx +73 -0
- package/src/__tests__/account-switcher.test.tsx +85 -0
- package/src/__tests__/activity-page.test.tsx +176 -0
- package/src/__tests__/add-payment-method-dialog.test.tsx +160 -0
- package/src/__tests__/admin-api.test.ts +244 -0
- package/src/__tests__/admin-gpu-api.test.ts +188 -0
- package/src/__tests__/admin-guard.test.tsx +79 -0
- package/src/__tests__/admin-marketplace-api.test.ts +179 -0
- package/src/__tests__/admin-middleware.test.ts +157 -0
- package/src/__tests__/admin-tenant-table.test.tsx +95 -0
- package/src/__tests__/affiliate-dashboard.test.tsx +178 -0
- package/src/__tests__/api-401-redirect.test.ts +78 -0
- package/src/__tests__/api-client.test.ts +316 -0
- package/src/__tests__/api-config.test.ts +89 -0
- package/src/__tests__/api-control-instance.test.ts +69 -0
- package/src/__tests__/api-fleet-resources.test.ts +52 -0
- package/src/__tests__/api-fleet-trpc.test.ts +252 -0
- package/src/__tests__/api-get-instance-config.test.ts +41 -0
- package/src/__tests__/api-null-guards.test.ts +244 -0
- package/src/__tests__/api-rename-instance.test.ts +60 -0
- package/src/__tests__/api-update-instance-config.test.ts +60 -0
- package/src/__tests__/audit-log-table-pagination.test.tsx +136 -0
- package/src/__tests__/auth-client.test.ts +87 -0
- package/src/__tests__/auth-password-reset.test.tsx +435 -0
- package/src/__tests__/auth-redirect.test.tsx +60 -0
- package/src/__tests__/auth.test.tsx +269 -0
- package/src/__tests__/auto-topup-card.test.tsx +257 -0
- package/src/__tests__/backups-tab.test.tsx +221 -0
- package/src/__tests__/billing-byok-callout.test.tsx +76 -0
- package/src/__tests__/billing-layout-nav-hidden.test.tsx +47 -0
- package/src/__tests__/billing-payment-org-invoices.test.tsx +123 -0
- package/src/__tests__/billing.test.tsx +509 -0
- package/src/__tests__/bot-settings/resources-tab.test.tsx +119 -0
- package/src/__tests__/bot-settings/storage-tab.test.tsx +80 -0
- package/src/__tests__/bot-settings/vps-info-panel.test.tsx +108 -0
- package/src/__tests__/bot-settings/vps-upgrade-card.test.tsx +52 -0
- package/src/__tests__/bot-settings-data-control.test.ts +49 -0
- package/src/__tests__/bot-settings-restart.test.tsx +149 -0
- package/src/__tests__/bot-settings.test.tsx +678 -0
- package/src/__tests__/brand.test.ts +335 -0
- package/src/__tests__/buy-credits-panel.test.tsx +249 -0
- package/src/__tests__/buy-crypto-credits-panel.test.tsx +178 -0
- package/src/__tests__/capability-conflicts.test.ts +88 -0
- package/src/__tests__/capability-resolver.test.tsx +173 -0
- package/src/__tests__/changeset-detail.test.tsx +156 -0
- package/src/__tests__/channel-setup-logger.test.ts +22 -0
- package/src/__tests__/channel-setup-toast.test.tsx +60 -0
- package/src/__tests__/channel-wizard.test.tsx +505 -0
- package/src/__tests__/chat/ambient-dot.test.tsx +35 -0
- package/src/__tests__/chat/chat-input.test.tsx +78 -0
- package/src/__tests__/chat/chat-message.test.tsx +45 -0
- package/src/__tests__/chat/chat-panel.test.tsx +111 -0
- package/src/__tests__/chat/chat-widget.test.tsx +82 -0
- package/src/__tests__/chat-store.test.ts +87 -0
- package/src/__tests__/command-center.test.tsx +246 -0
- package/src/__tests__/compliance-retention-edit.test.tsx +134 -0
- package/src/__tests__/coupon-input.test.tsx +119 -0
- package/src/__tests__/create-instance.test.tsx +96 -0
- package/src/__tests__/create-org-wizard.test.tsx +200 -0
- package/src/__tests__/credit-balance.test.tsx +103 -0
- package/src/__tests__/credits.test.tsx +376 -0
- package/src/__tests__/csrf-middleware.test.ts +198 -0
- package/src/__tests__/degraded-state-banner.test.tsx +130 -0
- package/src/__tests__/dividend-calculator.test.tsx +20 -0
- package/src/__tests__/dividend-stats.test.tsx +64 -0
- package/src/__tests__/dividend.test.tsx +169 -0
- package/src/__tests__/dockerfile.test.ts +110 -0
- package/src/__tests__/email-verification-banner.test.tsx +64 -0
- package/src/__tests__/env-example.test.ts +25 -0
- package/src/__tests__/error-boundaries.test.tsx +64 -0
- package/src/__tests__/fetch-pricing.test.ts +121 -0
- package/src/__tests__/field-oauth.test.tsx +302 -0
- package/src/__tests__/fixtures/mock-manifests-data.js +372 -0
- package/src/__tests__/fixtures/mock-manifests.ts +24 -0
- package/src/__tests__/fleet-health-timestamp.test.tsx +101 -0
- package/src/__tests__/fleet-health-update.test.tsx +83 -0
- package/src/__tests__/format-credit.test.ts +58 -0
- package/src/__tests__/gpu-dashboard.test.tsx +236 -0
- package/src/__tests__/hosted-usage-date-range.test.tsx +54 -0
- package/src/__tests__/instance-detail.test.tsx +571 -0
- package/src/__tests__/instance-list.test.tsx +230 -0
- package/src/__tests__/landing-hero.test.tsx +27 -0
- package/src/__tests__/landing-nav.test.tsx +24 -0
- package/src/__tests__/layout-snapshots.test.tsx +167 -0
- package/src/__tests__/logger.test.ts +54 -0
- package/src/__tests__/login-page-redirect.test.tsx +142 -0
- package/src/__tests__/manifest-validation.test.ts +126 -0
- package/src/__tests__/marketplace-admin.test.tsx +151 -0
- package/src/__tests__/marketplace.test.tsx +609 -0
- package/src/__tests__/merge-api-rates.test.ts +70 -0
- package/src/__tests__/middleware.test.ts +690 -0
- package/src/__tests__/network-page.test.tsx +100 -0
- package/src/__tests__/next-config-headers.test.ts +28 -0
- package/src/__tests__/not-found.test.tsx +26 -0
- package/src/__tests__/notifications.test.tsx +128 -0
- package/src/__tests__/oauth-buttons.test.tsx +101 -0
- package/src/__tests__/oauth-error-mapping.test.tsx +97 -0
- package/src/__tests__/observability.test.tsx +541 -0
- package/src/__tests__/onboarding-data.test.ts +363 -0
- package/src/__tests__/onboarding-page.test.tsx +113 -0
- package/src/__tests__/onboarding-store.test.ts +121 -0
- package/src/__tests__/org-billing-api.test.tsx +70 -0
- package/src/__tests__/org-billing-null-guards.test.ts +64 -0
- package/src/__tests__/org-billing-page.test.tsx +124 -0
- package/src/__tests__/plugin-definition.test.ts +43 -0
- package/src/__tests__/plugin-install-flow.test.tsx +535 -0
- package/src/__tests__/plugin-registry.test.tsx +475 -0
- package/src/__tests__/plugin-setup/setup-chat-panel.test.ts +142 -0
- package/src/__tests__/plugin-setup/use-plugin-setup-chat.test.ts +49 -0
- package/src/__tests__/plugin-tool-definitions.test.ts +51 -0
- package/src/__tests__/plugin-tool-sync.test.ts +59 -0
- package/src/__tests__/portfolio-chart.test.tsx +24 -0
- package/src/__tests__/pricing.test.tsx +107 -0
- package/src/__tests__/promotion-form.test.tsx +180 -0
- package/src/__tests__/promotions-list.test.tsx +194 -0
- package/src/__tests__/provider-key-api.test.ts +134 -0
- package/src/__tests__/resend-verification-button.test.tsx +104 -0
- package/src/__tests__/sanitize-redirect-url.test.ts +47 -0
- package/src/__tests__/secrets-audit-pagination.test.tsx +139 -0
- package/src/__tests__/settings.test.tsx +937 -0
- package/src/__tests__/setup-checklist.test.tsx +274 -0
- package/src/__tests__/setup.ts +82 -0
- package/src/__tests__/smoke.test.tsx +10 -0
- package/src/__tests__/snapshot-api.test.ts +104 -0
- package/src/__tests__/status-api.test.ts +46 -0
- package/src/__tests__/status-badge.test.tsx +33 -0
- package/src/__tests__/status-colors.test.ts +83 -0
- package/src/__tests__/status-page.test.tsx +86 -0
- package/src/__tests__/step-superpowers.test.tsx +218 -0
- package/src/__tests__/story-sections.test.tsx +24 -0
- package/src/__tests__/superpower-content-sanitize.test.tsx +87 -0
- package/src/__tests__/superpower-content.test.tsx +44 -0
- package/src/__tests__/suspension-banner.test.tsx +140 -0
- package/src/__tests__/tenant-context.test.tsx +146 -0
- package/src/__tests__/tenant-keys-api.test.ts +114 -0
- package/src/__tests__/tenant-table-pagination.test.tsx +124 -0
- package/src/__tests__/terminal-log-cleanup.test.tsx +51 -0
- package/src/__tests__/terminal-sequence.test.tsx +28 -0
- package/src/__tests__/transaction-history.test.tsx +325 -0
- package/src/__tests__/trpc-types.test.ts +102 -0
- package/src/__tests__/use-capability-meta.test.ts +161 -0
- package/src/__tests__/use-chat.test.ts +616 -0
- package/src/__tests__/use-has-org.test.ts +44 -0
- package/src/__tests__/use-image-status.test.ts +77 -0
- package/src/__tests__/use-pagination-params.test.ts +88 -0
- package/src/__tests__/use-plugin-setup-chat-stale-closure.test.ts +53 -0
- package/src/__tests__/use-webmcp.test.ts +119 -0
- package/src/__tests__/validate-elevenlabs-key.test.ts +95 -0
- package/src/__tests__/validate-redirect-url.test.ts +61 -0
- package/src/__tests__/verify-page.test.tsx +140 -0
- package/src/__tests__/verify-redirect.test.tsx +41 -0
- package/src/__tests__/verify-result-banner.test.tsx +66 -0
- package/src/__tests__/webmcp-feature-detect.test.ts +54 -0
- package/src/__tests__/webmcp-hook.test.tsx +72 -0
- package/src/__tests__/webmcp-marketplace-onboarding-tools.test.ts +185 -0
- package/src/__tests__/webmcp-register.test.ts +103 -0
- package/src/__tests__/webmcp-set-provider.test.ts +47 -0
- package/src/__tests__/webmcp-tools.test.ts +348 -0
- package/src/app/(auth)/error.tsx +72 -0
- package/src/app/(auth)/forgot-password/page.tsx +137 -0
- package/src/app/(auth)/layout.tsx +14 -0
- package/src/app/(auth)/loading.tsx +26 -0
- package/src/app/(auth)/login/page.tsx +188 -0
- package/src/app/(auth)/reset-password/page.tsx +169 -0
- package/src/app/(auth)/signup/page.tsx +309 -0
- package/src/app/(dashboard)/billing/credits/page.tsx +209 -0
- package/src/app/(dashboard)/billing/error.tsx +72 -0
- package/src/app/(dashboard)/billing/layout.tsx +73 -0
- package/src/app/(dashboard)/billing/loading.tsx +41 -0
- package/src/app/(dashboard)/billing/payment/page.tsx +639 -0
- package/src/app/(dashboard)/billing/plans/page.tsx +58 -0
- package/src/app/(dashboard)/billing/referrals/page.tsx +7 -0
- package/src/app/(dashboard)/billing/usage/hosted/page.tsx +348 -0
- package/src/app/(dashboard)/billing/usage/page.tsx +663 -0
- package/src/app/(dashboard)/changesets/[id]/changeset-detail-client.tsx +400 -0
- package/src/app/(dashboard)/changesets/[id]/error.tsx +57 -0
- package/src/app/(dashboard)/changesets/[id]/loading.tsx +23 -0
- package/src/app/(dashboard)/changesets/[id]/page.tsx +10 -0
- package/src/app/(dashboard)/changesets/error.tsx +72 -0
- package/src/app/(dashboard)/changesets/page.tsx +10 -0
- package/src/app/(dashboard)/chat/page.tsx +74 -0
- package/src/app/(dashboard)/dashboard/bots/[id]/settings/page.tsx +10 -0
- package/src/app/(dashboard)/dashboard/network/page.tsx +97 -0
- package/src/app/(dashboard)/dashboard/page.tsx +13 -0
- package/src/app/(dashboard)/error.tsx +72 -0
- package/src/app/(dashboard)/layout.tsx +113 -0
- package/src/app/(dashboard)/loading.tsx +27 -0
- package/src/app/(dashboard)/marketplace/[plugin]/page.tsx +548 -0
- package/src/app/(dashboard)/marketplace/error.tsx +72 -0
- package/src/app/(dashboard)/marketplace/loading.tsx +27 -0
- package/src/app/(dashboard)/marketplace/page.tsx +268 -0
- package/src/app/(dashboard)/not-found.tsx +46 -0
- package/src/app/(dashboard)/onboarding/page.tsx +267 -0
- package/src/app/(dashboard)/settings/account/page.tsx +132 -0
- package/src/app/(dashboard)/settings/activity/page.tsx +280 -0
- package/src/app/(dashboard)/settings/api-keys/page.tsx +530 -0
- package/src/app/(dashboard)/settings/brain/page.tsx +412 -0
- package/src/app/(dashboard)/settings/error.tsx +72 -0
- package/src/app/(dashboard)/settings/layout.tsx +114 -0
- package/src/app/(dashboard)/settings/loading.tsx +31 -0
- package/src/app/(dashboard)/settings/notifications/page.tsx +216 -0
- package/src/app/(dashboard)/settings/org/page.tsx +617 -0
- package/src/app/(dashboard)/settings/profile/page.tsx +510 -0
- package/src/app/(dashboard)/settings/providers/page.tsx +842 -0
- package/src/app/(dashboard)/settings/secrets/page.tsx +658 -0
- package/src/app/(dashboard)/settings/security/page.tsx +1133 -0
- package/src/app/admin/accounting/loading.tsx +32 -0
- package/src/app/admin/accounting/page.tsx +5 -0
- package/src/app/admin/affiliates/loading.tsx +32 -0
- package/src/app/admin/affiliates/page.tsx +5 -0
- package/src/app/admin/audit/loading.tsx +32 -0
- package/src/app/admin/audit/page.tsx +5 -0
- package/src/app/admin/billing-health/loading.tsx +17 -0
- package/src/app/admin/billing-health/page.tsx +10 -0
- package/src/app/admin/compliance/page.tsx +5 -0
- package/src/app/admin/error.tsx +72 -0
- package/src/app/admin/gpu/loading.tsx +38 -0
- package/src/app/admin/gpu/page.tsx +5 -0
- package/src/app/admin/incidents/page.tsx +10 -0
- package/src/app/admin/inference/loading.tsx +32 -0
- package/src/app/admin/inference/page.tsx +5 -0
- package/src/app/admin/layout.tsx +44 -0
- package/src/app/admin/loading.tsx +32 -0
- package/src/app/admin/marketplace/loading.tsx +32 -0
- package/src/app/admin/marketplace/page.tsx +5 -0
- package/src/app/admin/migrations/loading.tsx +22 -0
- package/src/app/admin/migrations/page.tsx +5 -0
- package/src/app/admin/onboarding/loading.tsx +18 -0
- package/src/app/admin/onboarding/page.tsx +5 -0
- package/src/app/admin/promotions/[id]/edit/loading.tsx +16 -0
- package/src/app/admin/promotions/[id]/edit/page.tsx +56 -0
- package/src/app/admin/promotions/[id]/loading.tsx +15 -0
- package/src/app/admin/promotions/[id]/page.tsx +311 -0
- package/src/app/admin/promotions/loading.tsx +21 -0
- package/src/app/admin/promotions/new/loading.tsx +16 -0
- package/src/app/admin/promotions/new/page.tsx +12 -0
- package/src/app/admin/promotions/page.tsx +266 -0
- package/src/app/admin/rate-overrides/loading.tsx +17 -0
- package/src/app/admin/rate-overrides/page.tsx +290 -0
- package/src/app/admin/roles/loading.tsx +27 -0
- package/src/app/admin/roles/page.tsx +5 -0
- package/src/app/admin/tenants/loading.tsx +32 -0
- package/src/app/admin/tenants/page.tsx +5 -0
- package/src/app/apple-icon.tsx +32 -0
- package/src/app/auth/callback/[provider]/page.tsx +104 -0
- package/src/app/auth/verify/page.tsx +224 -0
- package/src/app/channels/error.tsx +72 -0
- package/src/app/channels/loading.tsx +29 -0
- package/src/app/channels/page.tsx +262 -0
- package/src/app/channels/setup/[plugin]/page.tsx +136 -0
- package/src/app/error.tsx +72 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/fleet/error.tsx +72 -0
- package/src/app/fleet/health/page.tsx +9 -0
- package/src/app/fleet/layout.tsx +14 -0
- package/src/app/fleet/loading.tsx +33 -0
- package/src/app/fleet/page.tsx +5 -0
- package/src/app/global-error.tsx +96 -0
- package/src/app/globals.css +251 -0
- package/src/app/icon.svg +4 -0
- package/src/app/instances/[id]/instance-detail-client.tsx +1298 -0
- package/src/app/instances/[id]/page.tsx +10 -0
- package/src/app/instances/error.tsx +72 -0
- package/src/app/instances/instance-list-client.tsx +540 -0
- package/src/app/instances/loading.tsx +33 -0
- package/src/app/instances/new/create-instance-client.tsx +377 -0
- package/src/app/instances/new/page.tsx +9 -0
- package/src/app/instances/page.tsx +9 -0
- package/src/app/layout.tsx +83 -0
- package/src/app/not-found.tsx +38 -0
- package/src/app/og/route.tsx +50 -0
- package/src/app/page.tsx +39 -0
- package/src/app/plugins/error.tsx +72 -0
- package/src/app/plugins/layout.tsx +14 -0
- package/src/app/plugins/loading.tsx +30 -0
- package/src/app/plugins/page.tsx +555 -0
- package/src/app/pricing/error.tsx +72 -0
- package/src/app/pricing/loading.tsx +25 -0
- package/src/app/pricing/page.tsx +20 -0
- package/src/app/privacy/page.tsx +406 -0
- package/src/app/robots.ts +9 -0
- package/src/app/sitemap.ts +11 -0
- package/src/app/status/error.tsx +72 -0
- package/src/app/status/loading.tsx +21 -0
- package/src/app/status/page.tsx +20 -0
- package/src/app/terms/page.tsx +414 -0
- package/src/components/account-switcher.tsx +82 -0
- package/src/components/admin/accounting-dashboard.tsx +190 -0
- package/src/components/admin/admin-guard.tsx +36 -0
- package/src/components/admin/admin-nav.tsx +71 -0
- package/src/components/admin/affiliate-dashboard.tsx +564 -0
- package/src/components/admin/audit-log-table.tsx +336 -0
- package/src/components/admin/billing-health-dashboard.test.tsx +40 -0
- package/src/components/admin/billing-health-dashboard.tsx +416 -0
- package/src/components/admin/bulk-actions-bar.test.tsx +92 -0
- package/src/components/admin/bulk-actions-bar.tsx +80 -0
- package/src/components/admin/bulk-export-dialog.test.tsx +75 -0
- package/src/components/admin/bulk-export-dialog.tsx +189 -0
- package/src/components/admin/bulk-grant-dialog.test.tsx +81 -0
- package/src/components/admin/bulk-grant-dialog.tsx +147 -0
- package/src/components/admin/bulk-preview-dialog.test.tsx +72 -0
- package/src/components/admin/bulk-preview-dialog.tsx +106 -0
- package/src/components/admin/bulk-reactivate-dialog.test.tsx +51 -0
- package/src/components/admin/bulk-reactivate-dialog.tsx +55 -0
- package/src/components/admin/bulk-select-all-banner.test.tsx +36 -0
- package/src/components/admin/bulk-select-all-banner.tsx +44 -0
- package/src/components/admin/bulk-suspend-dialog.test.tsx +77 -0
- package/src/components/admin/bulk-suspend-dialog.tsx +129 -0
- package/src/components/admin/bulk-undo-toast.test.tsx +66 -0
- package/src/components/admin/bulk-undo-toast.tsx +121 -0
- package/src/components/admin/compliance-dashboard.tsx +1341 -0
- package/src/components/admin/gpu-dashboard.tsx +552 -0
- package/src/components/admin/grant-credits-dialog.tsx +121 -0
- package/src/components/admin/incident-dashboard.test.tsx +44 -0
- package/src/components/admin/incident-dashboard.tsx +717 -0
- package/src/components/admin/inference-dashboard.tsx +415 -0
- package/src/components/admin/marketplace-admin.tsx +765 -0
- package/src/components/admin/migrations-dashboard.tsx +404 -0
- package/src/components/admin/onboarding-dashboard.tsx +422 -0
- package/src/components/admin/promotions/promotion-form.tsx +440 -0
- package/src/components/admin/roles-dashboard.tsx +278 -0
- package/src/components/admin/suspend-dialog.tsx +98 -0
- package/src/components/admin/tenant-notes-panel.tsx +134 -0
- package/src/components/admin/tenant-row-actions.tsx +78 -0
- package/src/components/admin/tenant-table.tsx +339 -0
- package/src/components/auth/auth-error.tsx +22 -0
- package/src/components/auth/auth-redirect.tsx +18 -0
- package/src/components/auth/auth-shell.tsx +25 -0
- package/src/components/auth/email-verification-banner.tsx +25 -0
- package/src/components/auth/email-verification-result-banner.tsx +70 -0
- package/src/components/auth/resend-verification-button.tsx +94 -0
- package/src/components/auth/wopr-wordmark.tsx +19 -0
- package/src/components/billing/add-payment-method-dialog.tsx +267 -0
- package/src/components/billing/affiliate-dashboard.tsx +300 -0
- package/src/components/billing/auto-topup-card.tsx +432 -0
- package/src/components/billing/buy-credits-panel.tsx +180 -0
- package/src/components/billing/buy-crypto-credits-panel.tsx +96 -0
- package/src/components/billing/byok-callout.tsx +87 -0
- package/src/components/billing/coupon-input.tsx +86 -0
- package/src/components/billing/credit-balance.tsx +79 -0
- package/src/components/billing/degraded-state-banner.tsx +95 -0
- package/src/components/billing/dividend-banner.tsx +97 -0
- package/src/components/billing/dividend-eligibility.tsx +86 -0
- package/src/components/billing/dividend-pool-stats.tsx +86 -0
- package/src/components/billing/first-dividend-dialog.tsx +109 -0
- package/src/components/billing/low-balance-banner.tsx +50 -0
- package/src/components/billing/org-billing-page.tsx +360 -0
- package/src/components/billing/suspension-banner.tsx +53 -0
- package/src/components/billing/transaction-history.tsx +239 -0
- package/src/components/bot-settings/__tests__/bot-settings-client.test.tsx +205 -0
- package/src/components/bot-settings/backups-tab.tsx +377 -0
- package/src/components/bot-settings/bot-settings-client.tsx +1712 -0
- package/src/components/bot-settings/resources-tab.tsx +203 -0
- package/src/components/bot-settings/storage-tab.tsx +248 -0
- package/src/components/bot-settings/vps-info-panel.tsx +132 -0
- package/src/components/bot-settings/vps-upgrade-card.tsx +110 -0
- package/src/components/capability/CapabilityResolver.tsx +113 -0
- package/src/components/channel-wizard/field-interactive.tsx +48 -0
- package/src/components/channel-wizard/field-oauth.tsx +181 -0
- package/src/components/channel-wizard/field-paste.tsx +47 -0
- package/src/components/channel-wizard/field-qr.tsx +302 -0
- package/src/components/channel-wizard/index.ts +6 -0
- package/src/components/channel-wizard/step-renderer.tsx +103 -0
- package/src/components/channel-wizard/wizard.tsx +200 -0
- package/src/components/chat/ambient-dot.tsx +32 -0
- package/src/components/chat/chat-input.tsx +56 -0
- package/src/components/chat/chat-message.tsx +36 -0
- package/src/components/chat/chat-panel.tsx +138 -0
- package/src/components/chat/chat-widget.tsx +41 -0
- package/src/components/chat/index.ts +5 -0
- package/src/components/dashboard/command-center.tsx +614 -0
- package/src/components/instances/friends-tab.test.tsx +265 -0
- package/src/components/instances/friends-tab.tsx +721 -0
- package/src/components/landing/hero.tsx +53 -0
- package/src/components/landing/landing-nav.tsx +21 -0
- package/src/components/landing/landing-page.tsx +71 -0
- package/src/components/landing/portfolio-chart.tsx +349 -0
- package/src/components/landing/story-sections.tsx +50 -0
- package/src/components/landing/terminal-lines.ts +99 -0
- package/src/components/landing/terminal-sequence.tsx +453 -0
- package/src/components/landing/typing-effect.tsx +43 -0
- package/src/components/marketplace/category-filter.tsx +61 -0
- package/src/components/marketplace/empty-state.tsx +61 -0
- package/src/components/marketplace/featured-heroes.tsx +84 -0
- package/src/components/marketplace/first-visit-hero.tsx +110 -0
- package/src/components/marketplace/index.ts +9 -0
- package/src/components/marketplace/install-wizard.tsx +782 -0
- package/src/components/marketplace/marketplace-tabs.tsx +54 -0
- package/src/components/marketplace/plugin-card.tsx +129 -0
- package/src/components/marketplace/superpower-card.tsx +104 -0
- package/src/components/marketplace/superpower-content.tsx +117 -0
- package/src/components/marketplace/terminal-search.tsx +67 -0
- package/src/components/oauth-buttons.tsx +75 -0
- package/src/components/observability/fleet-health.tsx +370 -0
- package/src/components/observability/health-overview.tsx +246 -0
- package/src/components/observability/logs-viewer.tsx +215 -0
- package/src/components/observability/metrics-dashboard.tsx +288 -0
- package/src/components/onboarding/fallback-setup.tsx +137 -0
- package/src/components/onboarding/index.ts +3 -0
- package/src/components/onboarding/setup-checklist.tsx +333 -0
- package/src/components/onboarding/step-superpowers.tsx +122 -0
- package/src/components/plugin-setup/index.ts +1 -0
- package/src/components/plugin-setup/setup-chat-panel.tsx +188 -0
- package/src/components/pricing/dividend-calculator.tsx +47 -0
- package/src/components/pricing/dividend-stats.tsx +117 -0
- package/src/components/pricing/pricing-page.tsx +229 -0
- package/src/components/settings/create-org-wizard.tsx +225 -0
- package/src/components/sidebar.tsx +202 -0
- package/src/components/status/status-page.tsx +209 -0
- package/src/components/status-badge.tsx +28 -0
- package/src/components/theme-provider.tsx +8 -0
- package/src/components/ui/alert-dialog.tsx +141 -0
- package/src/components/ui/badge.tsx +47 -0
- package/src/components/ui/banner.tsx +36 -0
- package/src/components/ui/button.tsx +64 -0
- package/src/components/ui/card.tsx +75 -0
- package/src/components/ui/checkbox.tsx +52 -0
- package/src/components/ui/collapsible.tsx +31 -0
- package/src/components/ui/credit-detailed.tsx +33 -0
- package/src/components/ui/dialog.tsx +143 -0
- package/src/components/ui/dropdown-menu.tsx +228 -0
- package/src/components/ui/form.tsx +151 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/label.tsx +21 -0
- package/src/components/ui/popover.tsx +74 -0
- package/src/components/ui/progress.tsx +28 -0
- package/src/components/ui/radio-group.tsx +45 -0
- package/src/components/ui/select.tsx +175 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/sheet.tsx +125 -0
- package/src/components/ui/skeleton.tsx +15 -0
- package/src/components/ui/switch.tsx +35 -0
- package/src/components/ui/table.tsx +92 -0
- package/src/components/ui/tabs.tsx +81 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/components/ui/tooltip.tsx +44 -0
- package/src/config/provider-docs.ts +17 -0
- package/src/hooks/__tests__/use-async.test.ts +127 -0
- package/src/hooks/__tests__/use-count-up.test.ts +129 -0
- package/src/hooks/__tests__/use-debounce.test.ts +105 -0
- package/src/hooks/__tests__/use-fleet-sse.test.ts +216 -0
- package/src/hooks/__tests__/use-local-storage.test.ts +74 -0
- package/src/hooks/__tests__/use-mobile.test.ts +86 -0
- package/src/hooks/__tests__/use-save-queue.test.ts +159 -0
- package/src/hooks/use-async.ts +54 -0
- package/src/hooks/use-capability-meta.ts +99 -0
- package/src/hooks/use-count-up.ts +23 -0
- package/src/hooks/use-debounce.ts +12 -0
- package/src/hooks/use-fleet-sse.ts +47 -0
- package/src/hooks/use-has-org.ts +18 -0
- package/src/hooks/use-image-status.ts +36 -0
- package/src/hooks/use-local-storage.ts +36 -0
- package/src/hooks/use-mobile.ts +17 -0
- package/src/hooks/use-page-context.ts +24 -0
- package/src/hooks/use-pagination-params.ts +30 -0
- package/src/hooks/use-plugin-registry.ts +247 -0
- package/src/hooks/use-plugin-setup-chat.ts +211 -0
- package/src/hooks/use-save-queue.ts +54 -0
- package/src/hooks/use-webmcp.ts +40 -0
- package/src/lib/__tests__/__snapshots__/pricing-data.test.ts.snap +112 -0
- package/src/lib/__tests__/admin-api.test.ts +487 -0
- package/src/lib/__tests__/api-bot-crud.test.ts +391 -0
- package/src/lib/__tests__/api-fetch.test.ts +196 -0
- package/src/lib/__tests__/bot-settings-data.test.ts +352 -0
- package/src/lib/__tests__/org-api.test.ts +281 -0
- package/src/lib/__tests__/org-billing-api.test.ts +242 -0
- package/src/lib/__tests__/pricing-data.test.ts +32 -0
- package/src/lib/__tests__/settings-api.test.ts +272 -0
- package/src/lib/admin-affiliate-api.ts +51 -0
- package/src/lib/admin-api.ts +325 -0
- package/src/lib/admin-compliance-api.ts +127 -0
- package/src/lib/admin-gpu-api.ts +82 -0
- package/src/lib/admin-incident-api.ts +121 -0
- package/src/lib/admin-inference-api.ts +47 -0
- package/src/lib/admin-marketplace-api.ts +97 -0
- package/src/lib/api-config.test.ts +111 -0
- package/src/lib/api-config.ts +65 -0
- package/src/lib/api-errors.test.ts +43 -0
- package/src/lib/api.ts +2011 -0
- package/src/lib/auth-client.ts +11 -0
- package/src/lib/bot-settings-data.ts +342 -0
- package/src/lib/brand-config.ts +145 -0
- package/src/lib/brand.ts +669 -0
- package/src/lib/changeset-api.ts +29 -0
- package/src/lib/changeset-types.ts +56 -0
- package/src/lib/channel-manifests.ts +50 -0
- package/src/lib/chat/chat-context.tsx +70 -0
- package/src/lib/chat/chat-store.ts +62 -0
- package/src/lib/chat/types.ts +35 -0
- package/src/lib/chat/use-chat.ts +255 -0
- package/src/lib/cost-comparison-data.test.ts +95 -0
- package/src/lib/cost-comparison-data.ts +54 -0
- package/src/lib/errors.test.ts +64 -0
- package/src/lib/errors.ts +52 -0
- package/src/lib/fetch-utils.test.ts +57 -0
- package/src/lib/fetch-utils.ts +25 -0
- package/src/lib/format-credit.test.ts +66 -0
- package/src/lib/format-credit.ts +24 -0
- package/src/lib/format.test.ts +62 -0
- package/src/lib/format.ts +17 -0
- package/src/lib/logger.ts +28 -0
- package/src/lib/marketplace-data.ts +346 -0
- package/src/lib/oauth-errors.ts +19 -0
- package/src/lib/onboarding-data.ts +1265 -0
- package/src/lib/onboarding-store.ts +233 -0
- package/src/lib/org-api.ts +74 -0
- package/src/lib/org-billing-api.ts +81 -0
- package/src/lib/page-prompts.test.ts +32 -0
- package/src/lib/page-prompts.ts +23 -0
- package/src/lib/plugin/index.ts +32 -0
- package/src/lib/plugin/tool-definitions.ts +306 -0
- package/src/lib/pricing-data.ts +115 -0
- package/src/lib/promotions-types.ts +58 -0
- package/src/lib/settings-api.ts +63 -0
- package/src/lib/status-colors.ts +38 -0
- package/src/lib/tenant-context.tsx +134 -0
- package/src/lib/trpc-types.ts +173 -0
- package/src/lib/trpc.tsx +86 -0
- package/src/lib/utils.test.ts +55 -0
- package/src/lib/utils.ts +18 -0
- package/src/lib/validate-redirect-url.ts +39 -0
- package/src/lib/webmcp/feature-detect.ts +13 -0
- package/src/lib/webmcp/marketplace-onboarding-tools.ts +202 -0
- package/src/lib/webmcp/register.ts +44 -0
- package/src/lib/webmcp/tools.ts +422 -0
- package/src/proxy.ts +258 -0
- package/src/types/missing-deps.d.ts +160 -0
- package/src/types/motion-dom.d.ts +162 -0
- package/src/types/vitest-matchers.d.ts +40 -0
- package/src/types/web-mcp.d.ts +22 -0
- package/tsconfig.json +34 -0
- package/vitest.config.ts +26 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function AdminAccountingLoading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="space-y-6 p-6">
|
|
6
|
+
<div className="space-y-2">
|
|
7
|
+
<Skeleton className="h-8 w-40" />
|
|
8
|
+
<Skeleton className="h-4 w-56" />
|
|
9
|
+
</div>
|
|
10
|
+
<div className="rounded-md border">
|
|
11
|
+
<div className="border-b px-4 py-3">
|
|
12
|
+
<div className="flex items-center gap-4">
|
|
13
|
+
<Skeleton className="h-4 w-24" />
|
|
14
|
+
<Skeleton className="h-4 w-32" />
|
|
15
|
+
<Skeleton className="h-4 w-20" />
|
|
16
|
+
<Skeleton className="h-4 w-28" />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div className="space-y-0">
|
|
20
|
+
{Array.from({ length: 8 }, (_, n) => `sk-${n}`).map((skId) => (
|
|
21
|
+
<div key={skId} className="flex items-center gap-4 border-b px-4 py-3 last:border-b-0">
|
|
22
|
+
<Skeleton className="h-4 w-32" />
|
|
23
|
+
<Skeleton className="h-4 w-40" />
|
|
24
|
+
<Skeleton className="h-5 w-16" />
|
|
25
|
+
<Skeleton className="h-4 w-24" />
|
|
26
|
+
</div>
|
|
27
|
+
))}
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function AdminAffiliatesLoading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="space-y-6 p-6">
|
|
6
|
+
<div className="space-y-2">
|
|
7
|
+
<Skeleton className="h-8 w-40" />
|
|
8
|
+
<Skeleton className="h-4 w-56" />
|
|
9
|
+
</div>
|
|
10
|
+
<div className="rounded-md border">
|
|
11
|
+
<div className="border-b px-4 py-3">
|
|
12
|
+
<div className="flex items-center gap-4">
|
|
13
|
+
<Skeleton className="h-4 w-24" />
|
|
14
|
+
<Skeleton className="h-4 w-32" />
|
|
15
|
+
<Skeleton className="h-4 w-20" />
|
|
16
|
+
<Skeleton className="h-4 w-28" />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div className="space-y-0">
|
|
20
|
+
{Array.from({ length: 8 }, (_, n) => `sk-${n}`).map((skId) => (
|
|
21
|
+
<div key={skId} className="flex items-center gap-4 border-b px-4 py-3 last:border-b-0">
|
|
22
|
+
<Skeleton className="h-4 w-32" />
|
|
23
|
+
<Skeleton className="h-4 w-40" />
|
|
24
|
+
<Skeleton className="h-5 w-16" />
|
|
25
|
+
<Skeleton className="h-4 w-24" />
|
|
26
|
+
</div>
|
|
27
|
+
))}
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function AdminAuditLoading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="space-y-6 p-6">
|
|
6
|
+
<div className="space-y-2">
|
|
7
|
+
<Skeleton className="h-8 w-40" />
|
|
8
|
+
<Skeleton className="h-4 w-56" />
|
|
9
|
+
</div>
|
|
10
|
+
<div className="rounded-md border">
|
|
11
|
+
<div className="border-b px-4 py-3">
|
|
12
|
+
<div className="flex items-center gap-4">
|
|
13
|
+
<Skeleton className="h-4 w-24" />
|
|
14
|
+
<Skeleton className="h-4 w-32" />
|
|
15
|
+
<Skeleton className="h-4 w-20" />
|
|
16
|
+
<Skeleton className="h-4 w-28" />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div className="space-y-0">
|
|
20
|
+
{Array.from({ length: 8 }, (_, n) => `sk-${n}`).map((skId) => (
|
|
21
|
+
<div key={skId} className="flex items-center gap-4 border-b px-4 py-3 last:border-b-0">
|
|
22
|
+
<Skeleton className="h-4 w-32" />
|
|
23
|
+
<Skeleton className="h-4 w-40" />
|
|
24
|
+
<Skeleton className="h-5 w-16" />
|
|
25
|
+
<Skeleton className="h-4 w-24" />
|
|
26
|
+
</div>
|
|
27
|
+
))}
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function AdminBillingHealthLoading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="space-y-6 p-6">
|
|
6
|
+
<div className="space-y-2">
|
|
7
|
+
<Skeleton className="h-8 w-40" />
|
|
8
|
+
<Skeleton className="h-4 w-56" />
|
|
9
|
+
</div>
|
|
10
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
11
|
+
{Array.from({ length: 6 }, (_, i) => `card-sk-${i}`).map((skId) => (
|
|
12
|
+
<Skeleton key={skId} className="h-32" />
|
|
13
|
+
))}
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BillingHealthDashboard } from "@/components/admin/billing-health-dashboard";
|
|
2
|
+
|
|
3
|
+
export default function BillingHealthPage() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="p-6">
|
|
6
|
+
<h1 className="text-2xl font-bold mb-6">Billing Health</h1>
|
|
7
|
+
<BillingHealthDashboard />
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
10
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { AlertTriangleIcon, HomeIcon, RefreshCwIcon } from "lucide-react";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import { Button } from "@/components/ui/button";
|
|
6
|
+
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
|
|
7
|
+
import { logger } from "@/lib/logger";
|
|
8
|
+
|
|
9
|
+
const log = logger("error-boundary:admin");
|
|
10
|
+
|
|
11
|
+
export default function AdminError({
|
|
12
|
+
error,
|
|
13
|
+
reset,
|
|
14
|
+
}: {
|
|
15
|
+
error: Error & { digest?: string };
|
|
16
|
+
reset: () => void;
|
|
17
|
+
}) {
|
|
18
|
+
const [showDetails, setShowDetails] = useState(false);
|
|
19
|
+
const isDev = process.env.NODE_ENV === "development";
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
log.error("Admin error", error);
|
|
23
|
+
}, [error]);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className="flex h-full items-center justify-center p-6">
|
|
27
|
+
<Card className="w-full max-w-lg">
|
|
28
|
+
<CardHeader>
|
|
29
|
+
<div className="flex items-center gap-3">
|
|
30
|
+
<AlertTriangleIcon className="size-6 text-destructive" />
|
|
31
|
+
<CardTitle className="text-xl">Admin Error</CardTitle>
|
|
32
|
+
</div>
|
|
33
|
+
</CardHeader>
|
|
34
|
+
<CardContent className="space-y-4">
|
|
35
|
+
<p className="text-muted-foreground">
|
|
36
|
+
Something went wrong loading the admin panel. This may be a temporary issue.
|
|
37
|
+
</p>
|
|
38
|
+
{isDev && (
|
|
39
|
+
<Button
|
|
40
|
+
type="button"
|
|
41
|
+
variant="link"
|
|
42
|
+
size="sm"
|
|
43
|
+
onClick={() => setShowDetails((v) => !v)}
|
|
44
|
+
className="h-auto p-0 text-muted-foreground"
|
|
45
|
+
>
|
|
46
|
+
{showDetails ? "Hide" : "Show"} error details
|
|
47
|
+
</Button>
|
|
48
|
+
)}
|
|
49
|
+
{isDev && showDetails && (
|
|
50
|
+
<pre className="max-h-48 overflow-auto rounded-md border bg-muted p-3 text-xs">
|
|
51
|
+
{error.message}
|
|
52
|
+
{error.stack && `\n\n${error.stack}`}
|
|
53
|
+
{error.digest && `\n\nDigest: ${error.digest}`}
|
|
54
|
+
</pre>
|
|
55
|
+
)}
|
|
56
|
+
</CardContent>
|
|
57
|
+
<CardFooter className="gap-3">
|
|
58
|
+
<Button onClick={reset}>
|
|
59
|
+
<RefreshCwIcon />
|
|
60
|
+
Try Again
|
|
61
|
+
</Button>
|
|
62
|
+
<Button variant="outline" asChild>
|
|
63
|
+
<a href="/admin">
|
|
64
|
+
<HomeIcon />
|
|
65
|
+
Admin Home
|
|
66
|
+
</a>
|
|
67
|
+
</Button>
|
|
68
|
+
</CardFooter>
|
|
69
|
+
</Card>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function AdminGpuLoading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="space-y-6 p-6">
|
|
6
|
+
<div className="space-y-2">
|
|
7
|
+
<Skeleton className="h-8 w-48" />
|
|
8
|
+
<Skeleton className="h-4 w-64" />
|
|
9
|
+
</div>
|
|
10
|
+
<div className="grid grid-cols-4 gap-3">
|
|
11
|
+
{Array.from({ length: 4 }, (_, n) => `kpi-${n}`).map((id) => (
|
|
12
|
+
<Skeleton key={id} className="h-24 rounded-sm" />
|
|
13
|
+
))}
|
|
14
|
+
</div>
|
|
15
|
+
<div className="rounded-sm border">
|
|
16
|
+
<div className="border-b px-4 py-3">
|
|
17
|
+
<div className="flex items-center gap-4">
|
|
18
|
+
<Skeleton className="h-4 w-24" />
|
|
19
|
+
<Skeleton className="h-4 w-32" />
|
|
20
|
+
<Skeleton className="h-4 w-20" />
|
|
21
|
+
<Skeleton className="h-4 w-28" />
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
<div className="space-y-0">
|
|
25
|
+
{Array.from({ length: 5 }, (_, n) => `row-${n}`).map((id) => (
|
|
26
|
+
<div key={id} className="flex items-center gap-4 border-b px-4 py-3 last:border-b-0">
|
|
27
|
+
<Skeleton className="h-4 w-32" />
|
|
28
|
+
<Skeleton className="h-4 w-40" />
|
|
29
|
+
<Skeleton className="h-5 w-16" />
|
|
30
|
+
<Skeleton className="h-4 w-24" />
|
|
31
|
+
<Skeleton className="h-4 w-20" />
|
|
32
|
+
</div>
|
|
33
|
+
))}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IncidentDashboard } from "@/components/admin/incident-dashboard";
|
|
2
|
+
|
|
3
|
+
export default function IncidentsPage() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="p-6">
|
|
6
|
+
<h1 className="text-2xl font-bold mb-6">Incident Response</h1>
|
|
7
|
+
<IncidentDashboard />
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
10
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function AdminInferenceLoading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="space-y-6 p-6">
|
|
6
|
+
<div className="space-y-2">
|
|
7
|
+
<Skeleton className="h-8 w-40" />
|
|
8
|
+
<Skeleton className="h-4 w-56" />
|
|
9
|
+
</div>
|
|
10
|
+
<div className="rounded-md border">
|
|
11
|
+
<div className="border-b px-4 py-3">
|
|
12
|
+
<div className="flex items-center gap-4">
|
|
13
|
+
<Skeleton className="h-4 w-24" />
|
|
14
|
+
<Skeleton className="h-4 w-32" />
|
|
15
|
+
<Skeleton className="h-4 w-20" />
|
|
16
|
+
<Skeleton className="h-4 w-28" />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div className="space-y-0">
|
|
20
|
+
{Array.from({ length: 8 }, (_, n) => `sk-${n}`).map((skId) => (
|
|
21
|
+
<div key={skId} className="flex items-center gap-4 border-b px-4 py-3 last:border-b-0">
|
|
22
|
+
<Skeleton className="h-4 w-32" />
|
|
23
|
+
<Skeleton className="h-4 w-40" />
|
|
24
|
+
<Skeleton className="h-5 w-16" />
|
|
25
|
+
<Skeleton className="h-4 w-24" />
|
|
26
|
+
</div>
|
|
27
|
+
))}
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { AnimatePresence, motion } from "framer-motion";
|
|
4
|
+
import { usePathname } from "next/navigation";
|
|
5
|
+
import { AdminGuard } from "@/components/admin/admin-guard";
|
|
6
|
+
import { AdminNav } from "@/components/admin/admin-nav";
|
|
7
|
+
import { Sidebar } from "@/components/sidebar";
|
|
8
|
+
|
|
9
|
+
export default function AdminLayout({ children }: { children: React.ReactNode }) {
|
|
10
|
+
const pathname = usePathname();
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<>
|
|
14
|
+
{/* Desktop only -- admin requires 1024px+ */}
|
|
15
|
+
<div className="hidden lg:flex h-screen">
|
|
16
|
+
<Sidebar />
|
|
17
|
+
<div className="flex flex-1 flex-col overflow-auto">
|
|
18
|
+
<AdminGuard>
|
|
19
|
+
<AdminNav />
|
|
20
|
+
<AnimatePresence mode="wait">
|
|
21
|
+
<motion.main
|
|
22
|
+
key={pathname}
|
|
23
|
+
initial={{ opacity: 0 }}
|
|
24
|
+
animate={{ opacity: 1 }}
|
|
25
|
+
exit={{ opacity: 0 }}
|
|
26
|
+
transition={{ duration: 0.2, ease: "easeOut" }}
|
|
27
|
+
className="flex-1 overflow-auto"
|
|
28
|
+
>
|
|
29
|
+
{children}
|
|
30
|
+
</motion.main>
|
|
31
|
+
</AnimatePresence>
|
|
32
|
+
</AdminGuard>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
{/* Mobile/tablet -- show desktop-required message */}
|
|
37
|
+
<div className="flex lg:hidden h-screen items-center justify-center p-6">
|
|
38
|
+
<p className="text-center text-sm text-muted-foreground">
|
|
39
|
+
Admin panel requires desktop. Minimum width: 1024px.
|
|
40
|
+
</p>
|
|
41
|
+
</div>
|
|
42
|
+
</>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function AdminLoading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="space-y-6 p-6">
|
|
6
|
+
<div className="space-y-2">
|
|
7
|
+
<Skeleton className="h-8 w-40" />
|
|
8
|
+
<Skeleton className="h-4 w-56" />
|
|
9
|
+
</div>
|
|
10
|
+
<div className="rounded-md border">
|
|
11
|
+
<div className="border-b px-4 py-3">
|
|
12
|
+
<div className="flex items-center gap-4">
|
|
13
|
+
<Skeleton className="h-4 w-24" />
|
|
14
|
+
<Skeleton className="h-4 w-32" />
|
|
15
|
+
<Skeleton className="h-4 w-20" />
|
|
16
|
+
<Skeleton className="h-4 w-28" />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div className="space-y-0">
|
|
20
|
+
{Array.from({ length: 8 }, (_, n) => `sk-${n}`).map((skId) => (
|
|
21
|
+
<div key={skId} className="flex items-center gap-4 border-b px-4 py-3 last:border-b-0">
|
|
22
|
+
<Skeleton className="h-4 w-32" />
|
|
23
|
+
<Skeleton className="h-4 w-40" />
|
|
24
|
+
<Skeleton className="h-5 w-16" />
|
|
25
|
+
<Skeleton className="h-4 w-24" />
|
|
26
|
+
</div>
|
|
27
|
+
))}
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function AdminMarketplaceLoading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="space-y-6 p-6">
|
|
6
|
+
<div className="space-y-2">
|
|
7
|
+
<Skeleton className="h-8 w-40" />
|
|
8
|
+
<Skeleton className="h-4 w-56" />
|
|
9
|
+
</div>
|
|
10
|
+
<div className="rounded-md border">
|
|
11
|
+
<div className="border-b px-4 py-3">
|
|
12
|
+
<div className="flex items-center gap-4">
|
|
13
|
+
<Skeleton className="h-4 w-24" />
|
|
14
|
+
<Skeleton className="h-4 w-32" />
|
|
15
|
+
<Skeleton className="h-4 w-20" />
|
|
16
|
+
<Skeleton className="h-4 w-28" />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div className="space-y-0">
|
|
20
|
+
{Array.from({ length: 8 }, (_, n) => `sk-${n}`).map((skId) => (
|
|
21
|
+
<div key={skId} className="flex items-center gap-4 border-b px-4 py-3 last:border-b-0">
|
|
22
|
+
<Skeleton className="h-4 w-32" />
|
|
23
|
+
<Skeleton className="h-4 w-40" />
|
|
24
|
+
<Skeleton className="h-5 w-16" />
|
|
25
|
+
<Skeleton className="h-4 w-24" />
|
|
26
|
+
</div>
|
|
27
|
+
))}
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function AdminMigrationsLoading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="space-y-6 p-6">
|
|
6
|
+
<div className="space-y-2">
|
|
7
|
+
<Skeleton className="h-8 w-36" />
|
|
8
|
+
<Skeleton className="h-4 w-72" />
|
|
9
|
+
</div>
|
|
10
|
+
<div className="rounded-md border">
|
|
11
|
+
{Array.from({ length: 6 }, (_, i) => `sk-row-${i}`).map((k) => (
|
|
12
|
+
<div key={k} className="flex items-center gap-4 border-b px-4 py-3 last:border-b-0">
|
|
13
|
+
<Skeleton className="h-4 w-48" />
|
|
14
|
+
<Skeleton className="h-5 w-20" />
|
|
15
|
+
<Skeleton className="h-4 w-32" />
|
|
16
|
+
<Skeleton className="h-4 w-16" />
|
|
17
|
+
</div>
|
|
18
|
+
))}
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function AdminOnboardingLoading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="space-y-6 p-6">
|
|
6
|
+
<div className="space-y-2">
|
|
7
|
+
<Skeleton className="h-8 w-40" />
|
|
8
|
+
<Skeleton className="h-4 w-64" />
|
|
9
|
+
</div>
|
|
10
|
+
<div className="grid grid-cols-4 gap-3">
|
|
11
|
+
{Array.from({ length: 4 }, (_, i) => `sk-stat-${i}`).map((k) => (
|
|
12
|
+
<Skeleton key={k} className="h-20 rounded-lg" />
|
|
13
|
+
))}
|
|
14
|
+
</div>
|
|
15
|
+
<Skeleton className="h-48 rounded-lg" />
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function AdminPromotionEditLoading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="space-y-6 p-6">
|
|
6
|
+
<Skeleton className="h-8 w-48" />
|
|
7
|
+
<div className="max-w-2xl space-y-4">
|
|
8
|
+
<Skeleton className="h-10 w-full" />
|
|
9
|
+
<Skeleton className="h-10 w-full" />
|
|
10
|
+
<Skeleton className="h-10 w-2/3" />
|
|
11
|
+
<Skeleton className="h-24 w-full" />
|
|
12
|
+
<Skeleton className="h-10 w-32" />
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useParams } from "next/navigation";
|
|
4
|
+
import { useCallback, useEffect, useState } from "react";
|
|
5
|
+
import { PromotionForm } from "@/components/admin/promotions/promotion-form";
|
|
6
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
7
|
+
import type { Promotion } from "@/lib/promotions-types";
|
|
8
|
+
import { trpcVanilla } from "@/lib/trpc";
|
|
9
|
+
|
|
10
|
+
const client = trpcVanilla;
|
|
11
|
+
|
|
12
|
+
export default function EditPromotionPage() {
|
|
13
|
+
const { id } = useParams<{ id: string }>();
|
|
14
|
+
const [promo, setPromo] = useState<Promotion | null>(null);
|
|
15
|
+
const [loading, setLoading] = useState(true);
|
|
16
|
+
|
|
17
|
+
const load = useCallback(async () => {
|
|
18
|
+
setLoading(true);
|
|
19
|
+
try {
|
|
20
|
+
const result = await client.promotions.get.query({ id });
|
|
21
|
+
setPromo(result);
|
|
22
|
+
} catch {
|
|
23
|
+
// keep null
|
|
24
|
+
} finally {
|
|
25
|
+
setLoading(false);
|
|
26
|
+
}
|
|
27
|
+
}, [id]);
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
load();
|
|
31
|
+
}, [load]);
|
|
32
|
+
|
|
33
|
+
if (loading) {
|
|
34
|
+
return (
|
|
35
|
+
<div className="p-6 space-y-4">
|
|
36
|
+
<Skeleton className="h-8 w-48" />
|
|
37
|
+
<Skeleton className="h-64 w-full max-w-2xl" />
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!promo) {
|
|
43
|
+
return (
|
|
44
|
+
<div className="p-6">
|
|
45
|
+
<p className="text-sm text-muted-foreground">Promotion not found.</p>
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div className="p-6 space-y-6">
|
|
52
|
+
<h1 className="text-2xl font-bold tracking-tight">Edit: {promo.name}</h1>
|
|
53
|
+
<PromotionForm initialData={promo} />
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function AdminPromotionDetailLoading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="space-y-6 p-6">
|
|
6
|
+
<Skeleton className="h-8 w-48" />
|
|
7
|
+
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
8
|
+
{Array.from({ length: 4 }, (_, i) => `stat-sk-${i}`).map((skId) => (
|
|
9
|
+
<Skeleton key={skId} className="h-24" />
|
|
10
|
+
))}
|
|
11
|
+
</div>
|
|
12
|
+
<Skeleton className="h-48" />
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
15
|
+
}
|