@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,25 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function PricingLoading() {
|
|
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 gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
|
11
|
+
{Array.from({ length: 3 }, (_, n) => `sk-${n}`).map((skId) => (
|
|
12
|
+
<div key={skId} className="rounded-sm border p-6 space-y-4">
|
|
13
|
+
<Skeleton className="h-5 w-24" />
|
|
14
|
+
<Skeleton className="h-10 w-20" />
|
|
15
|
+
<Skeleton className="h-4 w-32" />
|
|
16
|
+
{Array.from({ length: 4 }, (_, n) => `feat-${n}`).map((featId) => (
|
|
17
|
+
<Skeleton key={featId} className="h-3 w-full" />
|
|
18
|
+
))}
|
|
19
|
+
<Skeleton className="h-10 w-full" />
|
|
20
|
+
</div>
|
|
21
|
+
))}
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { PricingPage } from "@/components/pricing/pricing-page";
|
|
3
|
+
import { SITE_URL } from "@/lib/api-config";
|
|
4
|
+
import { getBrandConfig } from "@/lib/brand-config";
|
|
5
|
+
|
|
6
|
+
const brand = getBrandConfig();
|
|
7
|
+
|
|
8
|
+
export const metadata: Metadata = {
|
|
9
|
+
title: `Pricing — ${brand.brandName} pays for itself`,
|
|
10
|
+
description: `Every day, ${brand.brandName} distributes credits back to active users. The bigger the community grows, the more you receive. Early users get the most.`,
|
|
11
|
+
openGraph: {
|
|
12
|
+
title: `Pricing — ${brand.brandName} pays for itself`,
|
|
13
|
+
description: `Every day, ${brand.brandName} distributes credits back to active users. The bigger the community grows, the more you receive.`,
|
|
14
|
+
url: `${SITE_URL}/pricing`,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default async function Page() {
|
|
19
|
+
return <PricingPage />;
|
|
20
|
+
}
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import Link from "next/link";
|
|
3
|
+
import { LandingNav } from "@/components/landing/landing-nav";
|
|
4
|
+
import { getBrandConfig } from "@/lib/brand-config";
|
|
5
|
+
|
|
6
|
+
const brand = getBrandConfig();
|
|
7
|
+
|
|
8
|
+
export const metadata: Metadata = {
|
|
9
|
+
title: `Privacy Policy — ${brand.productName}`,
|
|
10
|
+
description: `Privacy Policy for ${brand.productName}`,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default function PrivacyPage() {
|
|
14
|
+
return (
|
|
15
|
+
<>
|
|
16
|
+
<LandingNav />
|
|
17
|
+
<div className="mx-auto max-w-2xl px-6 py-16">
|
|
18
|
+
<h1 className="text-2xl font-bold tracking-tight">Privacy Policy</h1>
|
|
19
|
+
<p className="mt-2 text-sm text-muted-foreground">Last updated: February 2026</p>
|
|
20
|
+
|
|
21
|
+
<nav className="mt-6 rounded-sm border border-border bg-card p-4">
|
|
22
|
+
<p className="mb-3 text-xs font-medium uppercase tracking-[0.15em] text-muted-foreground">
|
|
23
|
+
Contents
|
|
24
|
+
</p>
|
|
25
|
+
<ol className="list-none space-y-1.5 text-sm text-muted-foreground">
|
|
26
|
+
<li>
|
|
27
|
+
<a href="#section-1" className="underline underline-offset-4 hover:text-foreground">
|
|
28
|
+
1. Identity and Contact Details
|
|
29
|
+
</a>
|
|
30
|
+
</li>
|
|
31
|
+
<li>
|
|
32
|
+
<a href="#section-2" className="underline underline-offset-4 hover:text-foreground">
|
|
33
|
+
2. What We Collect and Why
|
|
34
|
+
</a>
|
|
35
|
+
</li>
|
|
36
|
+
<li>
|
|
37
|
+
<a href="#section-3" className="underline underline-offset-4 hover:text-foreground">
|
|
38
|
+
3. When We Access or Share Your Information
|
|
39
|
+
</a>
|
|
40
|
+
</li>
|
|
41
|
+
<li>
|
|
42
|
+
<a href="#section-4" className="underline underline-offset-4 hover:text-foreground">
|
|
43
|
+
4. Your Rights Under GDPR
|
|
44
|
+
</a>
|
|
45
|
+
</li>
|
|
46
|
+
<li>
|
|
47
|
+
<a href="#section-5" className="underline underline-offset-4 hover:text-foreground">
|
|
48
|
+
5. Your Rights Under CCPA
|
|
49
|
+
</a>
|
|
50
|
+
</li>
|
|
51
|
+
<li>
|
|
52
|
+
<a href="#section-6" className="underline underline-offset-4 hover:text-foreground">
|
|
53
|
+
6. Data Retention
|
|
54
|
+
</a>
|
|
55
|
+
</li>
|
|
56
|
+
<li>
|
|
57
|
+
<a href="#section-7" className="underline underline-offset-4 hover:text-foreground">
|
|
58
|
+
7. Cookies and Tracking
|
|
59
|
+
</a>
|
|
60
|
+
</li>
|
|
61
|
+
<li>
|
|
62
|
+
<a href="#section-8" className="underline underline-offset-4 hover:text-foreground">
|
|
63
|
+
8. Security
|
|
64
|
+
</a>
|
|
65
|
+
</li>
|
|
66
|
+
<li>
|
|
67
|
+
<a href="#section-9" className="underline underline-offset-4 hover:text-foreground">
|
|
68
|
+
9. International Data Transfers
|
|
69
|
+
</a>
|
|
70
|
+
</li>
|
|
71
|
+
<li>
|
|
72
|
+
<a href="#section-10" className="underline underline-offset-4 hover:text-foreground">
|
|
73
|
+
10. Data Breach Notification
|
|
74
|
+
</a>
|
|
75
|
+
</li>
|
|
76
|
+
<li>
|
|
77
|
+
<a href="#section-11" className="underline underline-offset-4 hover:text-foreground">
|
|
78
|
+
11. Children's Privacy
|
|
79
|
+
</a>
|
|
80
|
+
</li>
|
|
81
|
+
<li>
|
|
82
|
+
<a href="#section-12" className="underline underline-offset-4 hover:text-foreground">
|
|
83
|
+
12. Changes to This Policy
|
|
84
|
+
</a>
|
|
85
|
+
</li>
|
|
86
|
+
<li>
|
|
87
|
+
<a href="#section-13" className="underline underline-offset-4 hover:text-foreground">
|
|
88
|
+
13. Contact
|
|
89
|
+
</a>
|
|
90
|
+
</li>
|
|
91
|
+
</ol>
|
|
92
|
+
</nav>
|
|
93
|
+
|
|
94
|
+
<div className="mt-8 space-y-8 text-sm leading-relaxed text-muted-foreground">
|
|
95
|
+
<section id="section-1" className="scroll-mt-16">
|
|
96
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">
|
|
97
|
+
1. Identity and Contact Details
|
|
98
|
+
</h2>
|
|
99
|
+
<p>
|
|
100
|
+
{brand.companyLegalName} (“{brand.brandName},” “we,”
|
|
101
|
+
“us,” or “our”) is the data controller responsible for your
|
|
102
|
+
personal data. We operate the {brand.productName} platform available at {brand.domain}
|
|
103
|
+
.
|
|
104
|
+
</p>
|
|
105
|
+
<p className="mt-2">
|
|
106
|
+
If you have questions about how we handle your data, or if you wish to exercise any of
|
|
107
|
+
your rights described below, contact us at{" "}
|
|
108
|
+
<a
|
|
109
|
+
href={`mailto:${brand.emails.privacy}`}
|
|
110
|
+
className="text-foreground underline underline-offset-4"
|
|
111
|
+
>
|
|
112
|
+
{brand.emails.privacy}
|
|
113
|
+
</a>
|
|
114
|
+
.
|
|
115
|
+
</p>
|
|
116
|
+
</section>
|
|
117
|
+
|
|
118
|
+
<section id="section-2" className="scroll-mt-16">
|
|
119
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">
|
|
120
|
+
2. What We Collect and Why
|
|
121
|
+
</h2>
|
|
122
|
+
<p>
|
|
123
|
+
We only collect information that is necessary to provide and improve{" "}
|
|
124
|
+
{brand.productName}
|
|
125
|
+
services. We do not collect data for advertising or sell your information to third
|
|
126
|
+
parties.
|
|
127
|
+
</p>
|
|
128
|
+
|
|
129
|
+
<h3 className="mb-1 mt-4 text-sm font-semibold text-foreground">Account information</h3>
|
|
130
|
+
<p>
|
|
131
|
+
Your name and email address, collected when you create an account. We use this to
|
|
132
|
+
identify you, communicate with you about your account, and send transactional emails
|
|
133
|
+
such as password resets and billing notifications. Legal basis: performance of our
|
|
134
|
+
contract with you.
|
|
135
|
+
</p>
|
|
136
|
+
|
|
137
|
+
<h3 className="mb-1 mt-4 text-sm font-semibold text-foreground">Billing information</h3>
|
|
138
|
+
<p>
|
|
139
|
+
Payment card details are processed directly by Stripe and are never stored on{" "}
|
|
140
|
+
{brand.brandName}
|
|
141
|
+
servers. We receive only a tokenized reference, your billing email, and transaction
|
|
142
|
+
history from Stripe. Legal basis: performance of our contract with you.
|
|
143
|
+
</p>
|
|
144
|
+
|
|
145
|
+
<h3 className="mb-1 mt-4 text-sm font-semibold text-foreground">API keys</h3>
|
|
146
|
+
<p>
|
|
147
|
+
You provide your own API keys for third-party AI providers (the “bring your own
|
|
148
|
+
key” model). These keys are encrypted at rest and used only to make requests to
|
|
149
|
+
your chosen providers on your behalf. We do not log or store the content of AI
|
|
150
|
+
interactions. Legal basis: performance of our contract with you.
|
|
151
|
+
</p>
|
|
152
|
+
|
|
153
|
+
<h3 className="mb-1 mt-4 text-sm font-semibold text-foreground">Bot configuration</h3>
|
|
154
|
+
<p>
|
|
155
|
+
Plugin selections, channel configurations, provider settings, and other choices you
|
|
156
|
+
make while setting up and operating your bots. This data is necessary to deliver the
|
|
157
|
+
service as you have configured it. Legal basis: performance of our contract with you.
|
|
158
|
+
</p>
|
|
159
|
+
|
|
160
|
+
<h3 className="mb-1 mt-4 text-sm font-semibold text-foreground">Usage data</h3>
|
|
161
|
+
<p>
|
|
162
|
+
API call counts, feature usage metrics, and hosted capability credit consumption. We
|
|
163
|
+
use this data for billing, capacity planning, and service improvement. Legal basis:
|
|
164
|
+
legitimate interest in maintaining and improving our service.
|
|
165
|
+
</p>
|
|
166
|
+
|
|
167
|
+
<h3 className="mb-1 mt-4 text-sm font-semibold text-foreground">Technical data</h3>
|
|
168
|
+
<p>
|
|
169
|
+
IP address, browser type, and operating system collected via web server logs. We use
|
|
170
|
+
this for security monitoring, abuse prevention, and debugging. Server logs are
|
|
171
|
+
retained for 90 days. Legal basis: legitimate interest in securing our service.
|
|
172
|
+
</p>
|
|
173
|
+
</section>
|
|
174
|
+
|
|
175
|
+
<section id="section-3" className="scroll-mt-16">
|
|
176
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">
|
|
177
|
+
3. When We Access or Share Your Information
|
|
178
|
+
</h2>
|
|
179
|
+
<p>
|
|
180
|
+
We do not sell your personal data. We do not use third-party tracking or advertising
|
|
181
|
+
cookies. We share data with the following categories of sub-processors only as needed
|
|
182
|
+
to provide the service:
|
|
183
|
+
</p>
|
|
184
|
+
<ul className="ml-4 mt-2 list-disc space-y-1">
|
|
185
|
+
<li>
|
|
186
|
+
<span className="text-foreground">Stripe</span> — payment processing. Stripe
|
|
187
|
+
receives your billing information to process subscription payments. Stripe's
|
|
188
|
+
privacy policy governs their handling of your payment data.
|
|
189
|
+
</li>
|
|
190
|
+
<li>
|
|
191
|
+
<span className="text-foreground">AI providers</span> (user-selected,
|
|
192
|
+
bring-your-own-key model) — request fulfillment. Your prompts and inputs are
|
|
193
|
+
sent to the AI provider you have configured. We do not choose or control which
|
|
194
|
+
provider you use.
|
|
195
|
+
</li>
|
|
196
|
+
<li>
|
|
197
|
+
<span className="text-foreground">Hosting provider</span> — infrastructure.
|
|
198
|
+
Our servers and Docker fleet are hosted by third-party infrastructure providers who
|
|
199
|
+
may process data on our behalf under strict data processing agreements.
|
|
200
|
+
</li>
|
|
201
|
+
<li>
|
|
202
|
+
<span className="text-foreground">Email service</span> — transactional emails.
|
|
203
|
+
We use a third-party email service to send password resets, billing notifications,
|
|
204
|
+
and other operational messages.
|
|
205
|
+
</li>
|
|
206
|
+
</ul>
|
|
207
|
+
<p className="mt-2">
|
|
208
|
+
We may also disclose information if required by law, to enforce our Terms of Service,
|
|
209
|
+
or to protect the rights, property, or safety of {brand.companyLegalName}, our users,
|
|
210
|
+
or the public.
|
|
211
|
+
</p>
|
|
212
|
+
</section>
|
|
213
|
+
|
|
214
|
+
<section id="section-4" className="scroll-mt-16">
|
|
215
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">
|
|
216
|
+
4. Your Rights Under GDPR
|
|
217
|
+
</h2>
|
|
218
|
+
<p>
|
|
219
|
+
If you are located in the European Union or European Economic Area, you have the
|
|
220
|
+
following rights under the General Data Protection Regulation:
|
|
221
|
+
</p>
|
|
222
|
+
<ul className="ml-4 mt-2 list-disc space-y-1">
|
|
223
|
+
<li>Right of access (Art. 15) — request a copy of your personal data</li>
|
|
224
|
+
<li>
|
|
225
|
+
Right to rectification (Art. 16) — correct inaccurate or incomplete data
|
|
226
|
+
</li>
|
|
227
|
+
<li>
|
|
228
|
+
Right to erasure (Art. 17) — request deletion of your personal data
|
|
229
|
+
(“right to be forgotten”)
|
|
230
|
+
</li>
|
|
231
|
+
<li>
|
|
232
|
+
Right to restrict processing (Art. 18) — limit how we use your data in certain
|
|
233
|
+
circumstances
|
|
234
|
+
</li>
|
|
235
|
+
<li>
|
|
236
|
+
Right to data portability (Art. 20) — receive your data in a structured,
|
|
237
|
+
commonly used, machine-readable format
|
|
238
|
+
</li>
|
|
239
|
+
<li>
|
|
240
|
+
Right to object (Art. 21) — object to processing based on legitimate interest
|
|
241
|
+
</li>
|
|
242
|
+
<li>Right to lodge a complaint with a supervisory authority in your member state</li>
|
|
243
|
+
</ul>
|
|
244
|
+
<p className="mt-2">
|
|
245
|
+
To exercise any of these rights, email{" "}
|
|
246
|
+
<a
|
|
247
|
+
href={`mailto:${brand.emails.privacy}`}
|
|
248
|
+
className="text-foreground underline underline-offset-4"
|
|
249
|
+
>
|
|
250
|
+
{brand.emails.privacy}
|
|
251
|
+
</a>
|
|
252
|
+
. We will respond within 30 days.
|
|
253
|
+
</p>
|
|
254
|
+
</section>
|
|
255
|
+
|
|
256
|
+
<section id="section-5" className="scroll-mt-16">
|
|
257
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">
|
|
258
|
+
5. Your Rights Under CCPA
|
|
259
|
+
</h2>
|
|
260
|
+
<p>
|
|
261
|
+
If you are a California resident, the California Consumer Privacy Act provides you
|
|
262
|
+
with the following rights:
|
|
263
|
+
</p>
|
|
264
|
+
<ul className="ml-4 mt-2 list-disc space-y-1">
|
|
265
|
+
<li>Right to know what personal information is collected, used, shared, or sold</li>
|
|
266
|
+
<li>Right to delete personal information held by us</li>
|
|
267
|
+
<li>
|
|
268
|
+
Right to opt-out of the sale of personal information (note: we do not sell personal
|
|
269
|
+
information)
|
|
270
|
+
</li>
|
|
271
|
+
<li>Right to non-discrimination for exercising your privacy rights</li>
|
|
272
|
+
</ul>
|
|
273
|
+
<p className="mt-2">
|
|
274
|
+
To exercise these rights, email{" "}
|
|
275
|
+
<a
|
|
276
|
+
href={`mailto:${brand.emails.privacy}`}
|
|
277
|
+
className="text-foreground underline underline-offset-4"
|
|
278
|
+
>
|
|
279
|
+
{brand.emails.privacy}
|
|
280
|
+
</a>
|
|
281
|
+
.
|
|
282
|
+
</p>
|
|
283
|
+
</section>
|
|
284
|
+
|
|
285
|
+
<section id="section-6" className="scroll-mt-16">
|
|
286
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">6. Data Retention</h2>
|
|
287
|
+
<p>
|
|
288
|
+
We retain your account data for as long as your account is active. If you request
|
|
289
|
+
deletion of your account, we will delete your personal data within 30 days. Some
|
|
290
|
+
information may be retained longer where required by law:
|
|
291
|
+
</p>
|
|
292
|
+
<ul className="ml-4 mt-2 list-disc space-y-1">
|
|
293
|
+
<li>
|
|
294
|
+
Billing and transaction records are retained for up to 7 years as required by tax
|
|
295
|
+
and financial regulations
|
|
296
|
+
</li>
|
|
297
|
+
<li>Server logs are retained for 90 days</li>
|
|
298
|
+
<li>Backups containing your data are purged within 60 days of account deletion</li>
|
|
299
|
+
</ul>
|
|
300
|
+
</section>
|
|
301
|
+
|
|
302
|
+
<section id="section-7" className="scroll-mt-16">
|
|
303
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">
|
|
304
|
+
7. Cookies and Tracking
|
|
305
|
+
</h2>
|
|
306
|
+
<p>
|
|
307
|
+
We use essential cookies only. These cookies are required for authentication and
|
|
308
|
+
session management (powered by better-auth) and cannot be disabled without breaking
|
|
309
|
+
the service. We do not use marketing cookies, analytics cookies, or third-party
|
|
310
|
+
tracking pixels. There is no cookie banner because there is nothing optional to
|
|
311
|
+
consent to.
|
|
312
|
+
</p>
|
|
313
|
+
</section>
|
|
314
|
+
|
|
315
|
+
<section id="section-8" className="scroll-mt-16">
|
|
316
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">8. Security</h2>
|
|
317
|
+
<p>
|
|
318
|
+
We take reasonable measures to protect your personal data. API keys are encrypted at
|
|
319
|
+
rest. All data in transit is protected via HTTPS. Access to production systems is
|
|
320
|
+
restricted to authorized personnel. We conduct regular security reviews of our
|
|
321
|
+
infrastructure and codebase. However, no method of transmission or storage is 100%
|
|
322
|
+
secure, and we cannot guarantee absolute security.
|
|
323
|
+
</p>
|
|
324
|
+
</section>
|
|
325
|
+
|
|
326
|
+
<section id="section-9" className="scroll-mt-16">
|
|
327
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">
|
|
328
|
+
9. International Data Transfers
|
|
329
|
+
</h2>
|
|
330
|
+
<p>
|
|
331
|
+
Your data may be processed in the United States or other countries where our
|
|
332
|
+
infrastructure providers operate. If you are located in the EU/EEA, transfers of your
|
|
333
|
+
personal data outside the EU/EEA are governed by Standard Contractual Clauses or
|
|
334
|
+
equivalent safeguards as required by GDPR.
|
|
335
|
+
</p>
|
|
336
|
+
</section>
|
|
337
|
+
|
|
338
|
+
<section id="section-10" className="scroll-mt-16">
|
|
339
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">
|
|
340
|
+
10. Data Breach Notification
|
|
341
|
+
</h2>
|
|
342
|
+
<p>
|
|
343
|
+
In the event of a data breach that is likely to result in a risk to your rights and
|
|
344
|
+
freedoms, we will notify affected users without undue delay. Where required by GDPR,
|
|
345
|
+
we will also notify the relevant supervisory authority within 72 hours of becoming
|
|
346
|
+
aware of the breach.
|
|
347
|
+
</p>
|
|
348
|
+
</section>
|
|
349
|
+
|
|
350
|
+
<section id="section-11" className="scroll-mt-16">
|
|
351
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">
|
|
352
|
+
11. Children's Privacy
|
|
353
|
+
</h2>
|
|
354
|
+
<p>
|
|
355
|
+
{brand.productName} is not intended for use by children under the age of 13. We do not
|
|
356
|
+
knowingly collect personal data from children under 13. If you believe a child under
|
|
357
|
+
13 has provided us with personal data, please contact us at{" "}
|
|
358
|
+
<a
|
|
359
|
+
href={`mailto:${brand.emails.privacy}`}
|
|
360
|
+
className="text-foreground underline underline-offset-4"
|
|
361
|
+
>
|
|
362
|
+
{brand.emails.privacy}
|
|
363
|
+
</a>{" "}
|
|
364
|
+
and we will delete the data promptly.
|
|
365
|
+
</p>
|
|
366
|
+
</section>
|
|
367
|
+
|
|
368
|
+
<section id="section-12" className="scroll-mt-16">
|
|
369
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">
|
|
370
|
+
12. Changes to This Policy
|
|
371
|
+
</h2>
|
|
372
|
+
<p>
|
|
373
|
+
We may update this Privacy Policy from time to time. If we make material changes, we
|
|
374
|
+
will notify you by email or through a prominent notice on the service before the
|
|
375
|
+
changes take effect. Your continued use of {brand.productName} after the changes take
|
|
376
|
+
effect constitutes acceptance of the updated policy.
|
|
377
|
+
</p>
|
|
378
|
+
</section>
|
|
379
|
+
|
|
380
|
+
<section id="section-13" className="scroll-mt-16">
|
|
381
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">13. Contact</h2>
|
|
382
|
+
<p>
|
|
383
|
+
Questions about this privacy policy? Email us at{" "}
|
|
384
|
+
<a
|
|
385
|
+
href={`mailto:${brand.emails.privacy}`}
|
|
386
|
+
className="text-foreground underline underline-offset-4"
|
|
387
|
+
>
|
|
388
|
+
{brand.emails.privacy}
|
|
389
|
+
</a>
|
|
390
|
+
.
|
|
391
|
+
</p>
|
|
392
|
+
</section>
|
|
393
|
+
</div>
|
|
394
|
+
|
|
395
|
+
<div className="mt-12 flex flex-wrap gap-4 text-sm text-muted-foreground">
|
|
396
|
+
<Link href="/terms" className="underline underline-offset-4 hover:text-foreground">
|
|
397
|
+
Terms of Service
|
|
398
|
+
</Link>
|
|
399
|
+
<Link href="/" className="underline underline-offset-4 hover:text-foreground">
|
|
400
|
+
Home
|
|
401
|
+
</Link>
|
|
402
|
+
</div>
|
|
403
|
+
</div>
|
|
404
|
+
</>
|
|
405
|
+
);
|
|
406
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { MetadataRoute } from "next";
|
|
2
|
+
import { SITE_URL } from "@/lib/api-config";
|
|
3
|
+
|
|
4
|
+
export default function sitemap(): MetadataRoute.Sitemap {
|
|
5
|
+
return [
|
|
6
|
+
{ url: SITE_URL, lastModified: new Date() },
|
|
7
|
+
{ url: `${SITE_URL}/pricing`, lastModified: new Date() },
|
|
8
|
+
{ url: `${SITE_URL}/terms`, lastModified: new Date() },
|
|
9
|
+
{ url: `${SITE_URL}/privacy`, lastModified: new Date() },
|
|
10
|
+
];
|
|
11
|
+
}
|
|
@@ -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:status");
|
|
10
|
+
|
|
11
|
+
export default function StatusError({
|
|
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("Status error", error);
|
|
23
|
+
}, [error]);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className="flex min-h-screen 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">Status Error</CardTitle>
|
|
32
|
+
</div>
|
|
33
|
+
</CardHeader>
|
|
34
|
+
<CardContent className="space-y-4">
|
|
35
|
+
<p className="text-muted-foreground">
|
|
36
|
+
Something went wrong loading system status. 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="/">
|
|
64
|
+
<HomeIcon />
|
|
65
|
+
Home
|
|
66
|
+
</a>
|
|
67
|
+
</Button>
|
|
68
|
+
</CardFooter>
|
|
69
|
+
</Card>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
2
|
+
|
|
3
|
+
export default function StatusLoading() {
|
|
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="rounded-sm border p-6 space-y-4">
|
|
11
|
+
<Skeleton className="h-5 w-32" />
|
|
12
|
+
{Array.from({ length: 5 }, (_, n) => `sk-${n}`).map((skId) => (
|
|
13
|
+
<div key={skId} className="flex items-center justify-between py-2">
|
|
14
|
+
<Skeleton className="h-4 w-32" />
|
|
15
|
+
<Skeleton className="h-4 w-20" />
|
|
16
|
+
</div>
|
|
17
|
+
))}
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { StatusPage } from "@/components/status/status-page";
|
|
3
|
+
import { SITE_URL } from "@/lib/api-config";
|
|
4
|
+
import { getBrandConfig } from "@/lib/brand-config";
|
|
5
|
+
|
|
6
|
+
const brand = getBrandConfig();
|
|
7
|
+
|
|
8
|
+
export const metadata: Metadata = {
|
|
9
|
+
title: `Platform Status — ${brand.brandName}`,
|
|
10
|
+
description: `Real-time health and uptime status for the ${brand.brandName} platform.`,
|
|
11
|
+
openGraph: {
|
|
12
|
+
title: `Platform Status — ${brand.brandName}`,
|
|
13
|
+
description: `Real-time health and uptime status for the ${brand.brandName} platform.`,
|
|
14
|
+
url: `${SITE_URL}/status`,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default function Page() {
|
|
19
|
+
return <StatusPage />;
|
|
20
|
+
}
|