@nextsparkjs/core 0.1.0-beta.84 → 0.1.0-beta.85
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/dist/styles/classes.json +1 -1
- package/dist/templates/app/(auth)/forgot-password/page.tsx +216 -0
- package/dist/templates/app/(auth)/layout.tsx +51 -0
- package/dist/templates/app/(auth)/login/page.tsx +21 -0
- package/dist/templates/app/(auth)/reset-password/page.tsx +212 -0
- package/dist/templates/app/(auth)/signup/page.tsx +21 -0
- package/dist/templates/app/(auth)/verify-email/page.tsx +190 -0
- package/dist/templates/app/(public)/[...slug]/page.tsx +378 -0
- package/dist/templates/app/(public)/docs/[section]/[page]/page.tsx +90 -0
- package/dist/templates/app/(public)/docs/layout.tsx +25 -0
- package/dist/templates/app/(public)/docs/page.tsx +81 -0
- package/dist/templates/app/(public)/layout.tsx +41 -0
- package/dist/templates/app/(public)/page.tsx +19 -0
- package/dist/templates/app/403/page.tsx +89 -0
- package/dist/templates/app/api/auth/[...all]/route.ts +78 -0
- package/dist/templates/app/api/cron/billing/lifecycle/route.ts +98 -0
- package/dist/templates/app/api/csp-report/route.ts +175 -0
- package/dist/templates/app/api/devtools/config/entities/route.ts +108 -0
- package/dist/templates/app/api/devtools/config/theme/route.ts +66 -0
- package/dist/templates/app/api/devtools/tests/[...path]/route.ts +130 -0
- package/dist/templates/app/api/devtools/tests/route.ts +134 -0
- package/dist/templates/app/api/health/route.ts +29 -0
- package/dist/templates/app/api/internal/user-metadata/route.ts +36 -0
- package/dist/templates/app/api/superadmin/subscriptions/route.ts +310 -0
- package/dist/templates/app/api/superadmin/teams/[teamId]/route.ts +286 -0
- package/dist/templates/app/api/superadmin/teams/route.ts +188 -0
- package/dist/templates/app/api/superadmin/users/[userId]/route.ts +540 -0
- package/dist/templates/app/api/superadmin/users/route.ts +323 -0
- package/dist/templates/app/api/user/delete-account/route.ts +55 -0
- package/dist/templates/app/api/user/plan-flags/route.ts +283 -0
- package/dist/templates/app/api/user/profile/route.ts +133 -0
- package/dist/templates/app/api/v1/[entity]/[id]/child/[childType]/[childId]/route.ts +210 -0
- package/dist/templates/app/api/v1/[entity]/[id]/child/[childType]/route.ts +331 -0
- package/dist/templates/app/api/v1/[entity]/[id]/route.ts +35 -0
- package/dist/templates/app/api/v1/[entity]/docs.md +369 -0
- package/dist/templates/app/api/v1/[entity]/presets.ts +194 -0
- package/dist/templates/app/api/v1/[entity]/route.ts +31 -0
- package/dist/templates/app/api/v1/api-keys/[id]/route.ts +303 -0
- package/dist/templates/app/api/v1/api-keys/docs.md +101 -0
- package/dist/templates/app/api/v1/api-keys/presets.ts +31 -0
- package/dist/templates/app/api/v1/api-keys/route.ts +250 -0
- package/dist/templates/app/api/v1/auth/docs.md +184 -0
- package/dist/templates/app/api/v1/auth/presets.ts +44 -0
- package/dist/templates/app/api/v1/auth/signup-with-invite/route.ts +227 -0
- package/dist/templates/app/api/v1/billing/cancel/route.ts +206 -0
- package/dist/templates/app/api/v1/billing/change-plan/route.ts +97 -0
- package/dist/templates/app/api/v1/billing/check-action/route.ts +81 -0
- package/dist/templates/app/api/v1/billing/checkout/route.ts +124 -0
- package/dist/templates/app/api/v1/billing/docs.md +209 -0
- package/dist/templates/app/api/v1/billing/plans/route.ts +85 -0
- package/dist/templates/app/api/v1/billing/portal/route.ts +90 -0
- package/dist/templates/app/api/v1/billing/presets.ts +121 -0
- package/dist/templates/app/api/v1/billing/webhooks/stripe/route.ts +428 -0
- package/dist/templates/app/api/v1/blocks/[slug]/route.ts +29 -0
- package/dist/templates/app/api/v1/blocks/docs.md +173 -0
- package/dist/templates/app/api/v1/blocks/presets.ts +121 -0
- package/dist/templates/app/api/v1/blocks/route.ts +45 -0
- package/dist/templates/app/api/v1/blocks/validate/route.ts +45 -0
- package/dist/templates/app/api/v1/cron/docs.md +116 -0
- package/dist/templates/app/api/v1/cron/presets.ts +26 -0
- package/dist/templates/app/api/v1/cron/process/route.ts +108 -0
- package/dist/templates/app/api/v1/devtools/blocks/route.ts +82 -0
- package/dist/templates/app/api/v1/devtools/docs/route.ts +150 -0
- package/dist/templates/app/api/v1/devtools/docs.md +204 -0
- package/dist/templates/app/api/v1/devtools/features/route.ts +61 -0
- package/dist/templates/app/api/v1/devtools/flows/route.ts +61 -0
- package/dist/templates/app/api/v1/devtools/presets.ts +113 -0
- package/dist/templates/app/api/v1/devtools/scheduled-actions/route.ts +120 -0
- package/dist/templates/app/api/v1/devtools/testing/route.ts +82 -0
- package/dist/templates/app/api/v1/media/docs.md +117 -0
- package/dist/templates/app/api/v1/media/presets.ts +24 -0
- package/dist/templates/app/api/v1/media/upload/route.ts +150 -0
- package/dist/templates/app/api/v1/patterns/[id]/usages/route.ts +116 -0
- package/dist/templates/app/api/v1/plugin/[...path]/route.ts +373 -0
- package/dist/templates/app/api/v1/plugin/docs.md +79 -0
- package/dist/templates/app/api/v1/plugin/presets.ts +21 -0
- package/dist/templates/app/api/v1/plugin/route.ts +96 -0
- package/dist/templates/app/api/v1/post-categories/[id]/route.ts +255 -0
- package/dist/templates/app/api/v1/post-categories/docs.md +134 -0
- package/dist/templates/app/api/v1/post-categories/presets.ts +78 -0
- package/dist/templates/app/api/v1/post-categories/route.ts +119 -0
- package/dist/templates/app/api/v1/team-invitations/[token]/accept/route.ts +179 -0
- package/dist/templates/app/api/v1/team-invitations/[token]/decline/route.ts +120 -0
- package/dist/templates/app/api/v1/team-invitations/[token]/route.ts +89 -0
- package/dist/templates/app/api/v1/team-invitations/docs.md +88 -0
- package/dist/templates/app/api/v1/team-invitations/presets.ts +43 -0
- package/dist/templates/app/api/v1/team-invitations/route.ts +114 -0
- package/dist/templates/app/api/v1/teams/[teamId]/invitations/route.ts +171 -0
- package/dist/templates/app/api/v1/teams/[teamId]/invoices/[invoiceNumber]/route.ts +105 -0
- package/dist/templates/app/api/v1/teams/[teamId]/invoices/route.ts +125 -0
- package/dist/templates/app/api/v1/teams/[teamId]/members/[memberId]/route.ts +263 -0
- package/dist/templates/app/api/v1/teams/[teamId]/members/route.ts +358 -0
- package/dist/templates/app/api/v1/teams/[teamId]/route.ts +322 -0
- package/dist/templates/app/api/v1/teams/[teamId]/subscription/route.ts +50 -0
- package/dist/templates/app/api/v1/teams/[teamId]/usage/[limitSlug]/route.ts +91 -0
- package/dist/templates/app/api/v1/teams/docs.md +320 -0
- package/dist/templates/app/api/v1/teams/presets.ts +178 -0
- package/dist/templates/app/api/v1/teams/route.ts +293 -0
- package/dist/templates/app/api/v1/teams/switch/route.ts +88 -0
- package/dist/templates/app/api/v1/theme/[...path]/route.ts +361 -0
- package/dist/templates/app/api/v1/theme/docs.md +74 -0
- package/dist/templates/app/api/v1/theme/presets.ts +21 -0
- package/dist/templates/app/api/v1/theme/route.ts +96 -0
- package/dist/templates/app/api/v1/users/[id]/meta/[key]/route.ts +363 -0
- package/dist/templates/app/api/v1/users/[id]/route.ts +302 -0
- package/dist/templates/app/api/v1/users/docs.md +93 -0
- package/dist/templates/app/api/v1/users/presets.ts +59 -0
- package/dist/templates/app/api/v1/users/route.ts +197 -0
- package/dist/templates/app/dashboard/(main)/[entity]/[id]/edit/page.tsx +117 -0
- package/dist/templates/app/dashboard/(main)/[entity]/[id]/page.tsx +103 -0
- package/dist/templates/app/dashboard/(main)/[entity]/create/page.tsx +95 -0
- package/dist/templates/app/dashboard/(main)/[entity]/error.tsx +51 -0
- package/dist/templates/app/dashboard/(main)/[entity]/layout.tsx +113 -0
- package/dist/templates/app/dashboard/(main)/[entity]/loading.tsx +61 -0
- package/dist/templates/app/dashboard/(main)/[entity]/page.tsx +90 -0
- package/dist/templates/app/dashboard/(main)/layout.tsx +98 -0
- package/dist/templates/app/dashboard/(main)/loading.tsx +5 -0
- package/dist/templates/app/dashboard/(main)/page.tsx +201 -0
- package/dist/templates/app/dashboard/(main)/patterns/[id]/edit/page.tsx +114 -0
- package/dist/templates/app/dashboard/(main)/patterns/[id]/page.tsx +20 -0
- package/dist/templates/app/dashboard/(main)/patterns/[id]/reports/page.tsx +171 -0
- package/dist/templates/app/dashboard/(main)/patterns/create/page.tsx +86 -0
- package/dist/templates/app/dashboard/(main)/patterns/page.tsx +444 -0
- package/dist/templates/app/dashboard/features/analytics/page.tsx +35 -0
- package/dist/templates/app/dashboard/features/automation/page.tsx +35 -0
- package/dist/templates/app/dashboard/features/layout.tsx +13 -0
- package/dist/templates/app/dashboard/features/loading.tsx +5 -0
- package/dist/templates/app/dashboard/features/webhooks/page.tsx +35 -0
- package/dist/templates/app/dashboard/layout.tsx +86 -0
- package/dist/templates/app/dashboard/permission-denied/page.tsx +29 -0
- package/dist/templates/app/dashboard/settings/api-keys/loading.tsx +5 -0
- package/dist/templates/app/dashboard/settings/api-keys/page.tsx +513 -0
- package/dist/templates/app/dashboard/settings/billing/loading.tsx +5 -0
- package/dist/templates/app/dashboard/settings/billing/page.tsx +284 -0
- package/dist/templates/app/dashboard/settings/invoices/[invoiceNumber]/page.tsx +222 -0
- package/dist/templates/app/dashboard/settings/invoices/loading.tsx +5 -0
- package/dist/templates/app/dashboard/settings/invoices/page.tsx +82 -0
- package/dist/templates/app/dashboard/settings/layout.tsx +151 -0
- package/dist/templates/app/dashboard/settings/loading.tsx +5 -0
- package/dist/templates/app/dashboard/settings/notifications/loading.tsx +5 -0
- package/dist/templates/app/dashboard/settings/notifications/page.tsx +462 -0
- package/dist/templates/app/dashboard/settings/page.tsx +92 -0
- package/dist/templates/app/dashboard/settings/password/loading.tsx +5 -0
- package/dist/templates/app/dashboard/settings/password/page.tsx +306 -0
- package/dist/templates/app/dashboard/settings/plans/loading.tsx +5 -0
- package/dist/templates/app/dashboard/settings/plans/page.tsx +40 -0
- package/dist/templates/app/dashboard/settings/profile/loading.tsx +5 -0
- package/dist/templates/app/dashboard/settings/profile/page.tsx +686 -0
- package/dist/templates/app/dashboard/settings/security/loading.tsx +5 -0
- package/dist/templates/app/dashboard/settings/security/page.tsx +505 -0
- package/dist/templates/app/dashboard/settings/teams/loading.tsx +5 -0
- package/dist/templates/app/dashboard/settings/teams/page.tsx +272 -0
- package/dist/templates/app/dashboard/settings/teams/permissions/page.tsx +92 -0
- package/dist/templates/app/devtools/blocks/[slug]/page.tsx +39 -0
- package/dist/templates/app/devtools/blocks/page.tsx +31 -0
- package/dist/templates/app/devtools/config/page.tsx +31 -0
- package/dist/templates/app/devtools/features/page.tsx +31 -0
- package/dist/templates/app/devtools/flows/page.tsx +31 -0
- package/dist/templates/app/devtools/layout.tsx +58 -0
- package/dist/templates/app/devtools/page.tsx +121 -0
- package/dist/templates/app/devtools/scheduled-actions/page.tsx +157 -0
- package/dist/templates/app/devtools/style/page.tsx +330 -0
- package/dist/templates/app/devtools/tags/page.tsx +31 -0
- package/dist/templates/app/devtools/tests/[[...path]]/page.tsx +47 -0
- package/dist/templates/app/favicon.ico +0 -0
- package/dist/templates/app/globals.css +12 -0
- package/dist/templates/app/layout.tsx +96 -0
- package/dist/templates/app/public/page.tsx +30 -0
- package/dist/templates/app/superadmin/docs/[section]/[page]/page.tsx +92 -0
- package/dist/templates/app/superadmin/docs/page.tsx +75 -0
- package/dist/templates/app/superadmin/layout.tsx +67 -0
- package/dist/templates/app/superadmin/page.tsx +149 -0
- package/dist/templates/app/superadmin/subscriptions/page.tsx +655 -0
- package/dist/templates/app/superadmin/team-roles/page.tsx +493 -0
- package/dist/templates/app/superadmin/teams/[teamId]/page.tsx +687 -0
- package/dist/templates/app/superadmin/teams/page.tsx +302 -0
- package/dist/templates/app/superadmin/users/[userId]/page.tsx +548 -0
- package/dist/templates/app/superadmin/users/page.tsx +528 -0
- package/package.json +2 -2
- package/templates/app/(auth)/forgot-password/page.tsx +216 -0
- package/templates/app/(auth)/layout.tsx +51 -0
- package/templates/app/(auth)/login/page.tsx +21 -0
- package/templates/app/(auth)/reset-password/page.tsx +212 -0
- package/templates/app/(auth)/signup/page.tsx +21 -0
- package/templates/app/(auth)/verify-email/page.tsx +190 -0
- package/templates/app/(public)/[...slug]/page.tsx +378 -0
- package/templates/app/(public)/docs/[section]/[page]/page.tsx +90 -0
- package/templates/app/(public)/docs/layout.tsx +25 -0
- package/templates/app/(public)/docs/page.tsx +81 -0
- package/templates/app/(public)/layout.tsx +41 -0
- package/templates/app/(public)/page.tsx +19 -0
- package/templates/app/403/page.tsx +89 -0
- package/templates/app/api/auth/[...all]/route.ts +78 -0
- package/templates/app/api/cron/billing/lifecycle/route.ts +98 -0
- package/templates/app/api/csp-report/route.ts +175 -0
- package/templates/app/api/devtools/config/entities/route.ts +108 -0
- package/templates/app/api/devtools/config/theme/route.ts +66 -0
- package/templates/app/api/devtools/tests/[...path]/route.ts +130 -0
- package/templates/app/api/devtools/tests/route.ts +134 -0
- package/templates/app/api/health/route.ts +29 -0
- package/templates/app/api/internal/user-metadata/route.ts +36 -0
- package/templates/app/api/superadmin/subscriptions/route.ts +310 -0
- package/templates/app/api/superadmin/teams/[teamId]/route.ts +286 -0
- package/templates/app/api/superadmin/teams/route.ts +188 -0
- package/templates/app/api/superadmin/users/[userId]/route.ts +540 -0
- package/templates/app/api/superadmin/users/route.ts +323 -0
- package/templates/app/api/user/delete-account/route.ts +55 -0
- package/templates/app/api/user/plan-flags/route.ts +283 -0
- package/templates/app/api/user/profile/route.ts +133 -0
- package/templates/app/api/v1/[entity]/[id]/child/[childType]/[childId]/route.ts +210 -0
- package/templates/app/api/v1/[entity]/[id]/child/[childType]/route.ts +331 -0
- package/templates/app/api/v1/[entity]/[id]/route.ts +35 -0
- package/templates/app/api/v1/[entity]/docs.md +369 -0
- package/templates/app/api/v1/[entity]/presets.ts +194 -0
- package/templates/app/api/v1/[entity]/route.ts +31 -0
- package/templates/app/api/v1/api-keys/[id]/route.ts +303 -0
- package/templates/app/api/v1/api-keys/docs.md +101 -0
- package/templates/app/api/v1/api-keys/presets.ts +31 -0
- package/templates/app/api/v1/api-keys/route.ts +250 -0
- package/templates/app/api/v1/auth/docs.md +184 -0
- package/templates/app/api/v1/auth/presets.ts +44 -0
- package/templates/app/api/v1/auth/signup-with-invite/route.ts +227 -0
- package/templates/app/api/v1/billing/cancel/route.ts +206 -0
- package/templates/app/api/v1/billing/change-plan/route.ts +97 -0
- package/templates/app/api/v1/billing/check-action/route.ts +81 -0
- package/templates/app/api/v1/billing/checkout/route.ts +124 -0
- package/templates/app/api/v1/billing/docs.md +209 -0
- package/templates/app/api/v1/billing/plans/route.ts +85 -0
- package/templates/app/api/v1/billing/portal/route.ts +90 -0
- package/templates/app/api/v1/billing/presets.ts +121 -0
- package/templates/app/api/v1/billing/webhooks/stripe/route.ts +428 -0
- package/templates/app/api/v1/blocks/[slug]/route.ts +29 -0
- package/templates/app/api/v1/blocks/docs.md +173 -0
- package/templates/app/api/v1/blocks/presets.ts +121 -0
- package/templates/app/api/v1/blocks/route.ts +45 -0
- package/templates/app/api/v1/blocks/validate/route.ts +45 -0
- package/templates/app/api/v1/cron/docs.md +116 -0
- package/templates/app/api/v1/cron/presets.ts +26 -0
- package/templates/app/api/v1/cron/process/route.ts +108 -0
- package/templates/app/api/v1/devtools/blocks/route.ts +82 -0
- package/templates/app/api/v1/devtools/docs/route.ts +150 -0
- package/templates/app/api/v1/devtools/docs.md +204 -0
- package/templates/app/api/v1/devtools/features/route.ts +61 -0
- package/templates/app/api/v1/devtools/flows/route.ts +61 -0
- package/templates/app/api/v1/devtools/presets.ts +113 -0
- package/templates/app/api/v1/devtools/scheduled-actions/route.ts +120 -0
- package/templates/app/api/v1/devtools/testing/route.ts +82 -0
- package/templates/app/api/v1/media/docs.md +117 -0
- package/templates/app/api/v1/media/presets.ts +24 -0
- package/templates/app/api/v1/media/upload/route.ts +150 -0
- package/templates/app/api/v1/patterns/[id]/usages/route.ts +116 -0
- package/templates/app/api/v1/plugin/[...path]/route.ts +373 -0
- package/templates/app/api/v1/plugin/docs.md +79 -0
- package/templates/app/api/v1/plugin/presets.ts +21 -0
- package/templates/app/api/v1/plugin/route.ts +96 -0
- package/templates/app/api/v1/post-categories/[id]/route.ts +255 -0
- package/templates/app/api/v1/post-categories/docs.md +134 -0
- package/templates/app/api/v1/post-categories/presets.ts +78 -0
- package/templates/app/api/v1/post-categories/route.ts +119 -0
- package/templates/app/api/v1/team-invitations/[token]/accept/route.ts +179 -0
- package/templates/app/api/v1/team-invitations/[token]/decline/route.ts +120 -0
- package/templates/app/api/v1/team-invitations/[token]/route.ts +89 -0
- package/templates/app/api/v1/team-invitations/docs.md +88 -0
- package/templates/app/api/v1/team-invitations/presets.ts +43 -0
- package/templates/app/api/v1/team-invitations/route.ts +114 -0
- package/templates/app/api/v1/teams/[teamId]/invitations/route.ts +171 -0
- package/templates/app/api/v1/teams/[teamId]/invoices/[invoiceNumber]/route.ts +105 -0
- package/templates/app/api/v1/teams/[teamId]/invoices/route.ts +125 -0
- package/templates/app/api/v1/teams/[teamId]/members/[memberId]/route.ts +263 -0
- package/templates/app/api/v1/teams/[teamId]/members/route.ts +358 -0
- package/templates/app/api/v1/teams/[teamId]/route.ts +322 -0
- package/templates/app/api/v1/teams/[teamId]/subscription/route.ts +50 -0
- package/templates/app/api/v1/teams/[teamId]/usage/[limitSlug]/route.ts +91 -0
- package/templates/app/api/v1/teams/docs.md +320 -0
- package/templates/app/api/v1/teams/presets.ts +178 -0
- package/templates/app/api/v1/teams/route.ts +293 -0
- package/templates/app/api/v1/teams/switch/route.ts +88 -0
- package/templates/app/api/v1/theme/[...path]/route.ts +361 -0
- package/templates/app/api/v1/theme/docs.md +74 -0
- package/templates/app/api/v1/theme/presets.ts +21 -0
- package/templates/app/api/v1/theme/route.ts +96 -0
- package/templates/app/api/v1/users/[id]/meta/[key]/route.ts +363 -0
- package/templates/app/api/v1/users/[id]/route.ts +302 -0
- package/templates/app/api/v1/users/docs.md +93 -0
- package/templates/app/api/v1/users/presets.ts +59 -0
- package/templates/app/api/v1/users/route.ts +197 -0
- package/templates/app/dashboard/(main)/[entity]/[id]/edit/page.tsx +117 -0
- package/templates/app/dashboard/(main)/[entity]/[id]/page.tsx +103 -0
- package/templates/app/dashboard/(main)/[entity]/create/page.tsx +95 -0
- package/templates/app/dashboard/(main)/[entity]/error.tsx +51 -0
- package/templates/app/dashboard/(main)/[entity]/layout.tsx +113 -0
- package/templates/app/dashboard/(main)/[entity]/loading.tsx +61 -0
- package/templates/app/dashboard/(main)/[entity]/page.tsx +90 -0
- package/templates/app/dashboard/(main)/layout.tsx +98 -0
- package/templates/app/dashboard/(main)/loading.tsx +5 -0
- package/templates/app/dashboard/(main)/page.tsx +201 -0
- package/templates/app/dashboard/(main)/patterns/[id]/edit/page.tsx +114 -0
- package/templates/app/dashboard/(main)/patterns/[id]/page.tsx +20 -0
- package/templates/app/dashboard/(main)/patterns/[id]/reports/page.tsx +171 -0
- package/templates/app/dashboard/(main)/patterns/create/page.tsx +86 -0
- package/templates/app/dashboard/(main)/patterns/page.tsx +444 -0
- package/templates/app/dashboard/features/analytics/page.tsx +35 -0
- package/templates/app/dashboard/features/automation/page.tsx +35 -0
- package/templates/app/dashboard/features/layout.tsx +13 -0
- package/templates/app/dashboard/features/loading.tsx +5 -0
- package/templates/app/dashboard/features/webhooks/page.tsx +35 -0
- package/templates/app/dashboard/layout.tsx +86 -0
- package/templates/app/dashboard/permission-denied/page.tsx +29 -0
- package/templates/app/dashboard/settings/api-keys/loading.tsx +5 -0
- package/templates/app/dashboard/settings/api-keys/page.tsx +513 -0
- package/templates/app/dashboard/settings/billing/loading.tsx +5 -0
- package/templates/app/dashboard/settings/billing/page.tsx +284 -0
- package/templates/app/dashboard/settings/invoices/[invoiceNumber]/page.tsx +222 -0
- package/templates/app/dashboard/settings/invoices/loading.tsx +5 -0
- package/templates/app/dashboard/settings/invoices/page.tsx +82 -0
- package/templates/app/dashboard/settings/layout.tsx +151 -0
- package/templates/app/dashboard/settings/loading.tsx +5 -0
- package/templates/app/dashboard/settings/notifications/loading.tsx +5 -0
- package/templates/app/dashboard/settings/notifications/page.tsx +462 -0
- package/templates/app/dashboard/settings/page.tsx +92 -0
- package/templates/app/dashboard/settings/password/loading.tsx +5 -0
- package/templates/app/dashboard/settings/password/page.tsx +306 -0
- package/templates/app/dashboard/settings/plans/loading.tsx +5 -0
- package/templates/app/dashboard/settings/plans/page.tsx +40 -0
- package/templates/app/dashboard/settings/profile/loading.tsx +5 -0
- package/templates/app/dashboard/settings/profile/page.tsx +686 -0
- package/templates/app/dashboard/settings/security/loading.tsx +5 -0
- package/templates/app/dashboard/settings/security/page.tsx +505 -0
- package/templates/app/dashboard/settings/teams/loading.tsx +5 -0
- package/templates/app/dashboard/settings/teams/page.tsx +272 -0
- package/templates/app/dashboard/settings/teams/permissions/page.tsx +92 -0
- package/templates/app/devtools/blocks/[slug]/page.tsx +39 -0
- package/templates/app/devtools/blocks/page.tsx +31 -0
- package/templates/app/devtools/config/page.tsx +31 -0
- package/templates/app/devtools/features/page.tsx +31 -0
- package/templates/app/devtools/flows/page.tsx +31 -0
- package/templates/app/devtools/layout.tsx +58 -0
- package/templates/app/devtools/page.tsx +121 -0
- package/templates/app/devtools/scheduled-actions/page.tsx +157 -0
- package/templates/app/devtools/style/page.tsx +330 -0
- package/templates/app/devtools/tags/page.tsx +31 -0
- package/templates/app/devtools/tests/[[...path]]/page.tsx +47 -0
- package/templates/app/favicon.ico +0 -0
- package/templates/app/globals.css +12 -0
- package/templates/app/layout.tsx +96 -0
- package/templates/app/public/page.tsx +30 -0
- package/templates/app/superadmin/docs/[section]/[page]/page.tsx +92 -0
- package/templates/app/superadmin/docs/page.tsx +75 -0
- package/templates/app/superadmin/layout.tsx +67 -0
- package/templates/app/superadmin/page.tsx +149 -0
- package/templates/app/superadmin/subscriptions/page.tsx +655 -0
- package/templates/app/superadmin/team-roles/page.tsx +493 -0
- package/templates/app/superadmin/teams/[teamId]/page.tsx +687 -0
- package/templates/app/superadmin/teams/page.tsx +302 -0
- package/templates/app/superadmin/users/[userId]/page.tsx +548 -0
- package/templates/app/superadmin/users/page.tsx +528 -0
|
@@ -0,0 +1,687 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useQuery } from "@tanstack/react-query";
|
|
4
|
+
import { useParams } from "next/navigation";
|
|
5
|
+
import { format } from "date-fns";
|
|
6
|
+
import {
|
|
7
|
+
Card,
|
|
8
|
+
CardContent,
|
|
9
|
+
CardDescription,
|
|
10
|
+
CardHeader,
|
|
11
|
+
CardTitle,
|
|
12
|
+
} from "@nextsparkjs/core/components/ui/card";
|
|
13
|
+
import { Button } from "@nextsparkjs/core/components/ui/button";
|
|
14
|
+
import { Badge } from "@nextsparkjs/core/components/ui/badge";
|
|
15
|
+
import { Avatar, AvatarFallback } from "@nextsparkjs/core/components/ui/avatar";
|
|
16
|
+
import {
|
|
17
|
+
Table,
|
|
18
|
+
TableBody,
|
|
19
|
+
TableCell,
|
|
20
|
+
TableHead,
|
|
21
|
+
TableHeader,
|
|
22
|
+
TableRow,
|
|
23
|
+
} from "@nextsparkjs/core/components/ui/table";
|
|
24
|
+
import {
|
|
25
|
+
ArrowLeft,
|
|
26
|
+
Users,
|
|
27
|
+
User,
|
|
28
|
+
Calendar,
|
|
29
|
+
Loader2,
|
|
30
|
+
AlertTriangle,
|
|
31
|
+
RefreshCw,
|
|
32
|
+
Crown,
|
|
33
|
+
Shield,
|
|
34
|
+
Eye,
|
|
35
|
+
CreditCard,
|
|
36
|
+
CheckCircle,
|
|
37
|
+
Clock,
|
|
38
|
+
XCircle,
|
|
39
|
+
AlertCircle,
|
|
40
|
+
Receipt,
|
|
41
|
+
ExternalLink,
|
|
42
|
+
TrendingUp,
|
|
43
|
+
} from "lucide-react";
|
|
44
|
+
import Link from "next/link";
|
|
45
|
+
import { getTemplateOrDefaultClient } from "@nextsparkjs/registries/template-registry.client";
|
|
46
|
+
|
|
47
|
+
interface TeamOwner {
|
|
48
|
+
id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
email: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
interface TeamMember {
|
|
54
|
+
id: string;
|
|
55
|
+
userId: string;
|
|
56
|
+
name: string;
|
|
57
|
+
email: string;
|
|
58
|
+
role: "owner" | "admin" | "member" | "viewer";
|
|
59
|
+
joinedAt: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
interface Team {
|
|
63
|
+
id: string;
|
|
64
|
+
name: string;
|
|
65
|
+
owner: TeamOwner;
|
|
66
|
+
memberCount: number;
|
|
67
|
+
createdAt: string;
|
|
68
|
+
updatedAt: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface SubscriptionPlan {
|
|
72
|
+
id: string;
|
|
73
|
+
slug: string;
|
|
74
|
+
name: string;
|
|
75
|
+
type: string;
|
|
76
|
+
priceMonthly: number | null;
|
|
77
|
+
priceFormatted: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
interface Subscription {
|
|
81
|
+
id: string;
|
|
82
|
+
plan: SubscriptionPlan;
|
|
83
|
+
status: string;
|
|
84
|
+
currentPeriodStart: string;
|
|
85
|
+
currentPeriodEnd: string;
|
|
86
|
+
trialEndsAt: string | null;
|
|
87
|
+
canceledAt: string | null;
|
|
88
|
+
cancelAtPeriodEnd: boolean;
|
|
89
|
+
externalSubscriptionId: string | null;
|
|
90
|
+
externalCustomerId: string | null;
|
|
91
|
+
createdAt: string;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
interface BillingEvent {
|
|
95
|
+
id: string;
|
|
96
|
+
type: string;
|
|
97
|
+
status: string;
|
|
98
|
+
amount: number;
|
|
99
|
+
amountFormatted: string;
|
|
100
|
+
currency: string;
|
|
101
|
+
invoiceUrl: string | null;
|
|
102
|
+
receiptUrl: string | null;
|
|
103
|
+
createdAt: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
interface UsageData {
|
|
107
|
+
[key: string]: {
|
|
108
|
+
current: number;
|
|
109
|
+
periodKey: string;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
interface TeamDetailData {
|
|
114
|
+
team: Team;
|
|
115
|
+
members: TeamMember[];
|
|
116
|
+
subscription: Subscription | null;
|
|
117
|
+
billingHistory: BillingEvent[];
|
|
118
|
+
usage: UsageData;
|
|
119
|
+
metadata: {
|
|
120
|
+
requestedBy: string;
|
|
121
|
+
requestedAt: string;
|
|
122
|
+
source: string;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const roleIcons = {
|
|
127
|
+
owner: Crown,
|
|
128
|
+
admin: Shield,
|
|
129
|
+
member: User,
|
|
130
|
+
viewer: Eye,
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const roleColors = {
|
|
134
|
+
owner: "destructive",
|
|
135
|
+
admin: "default",
|
|
136
|
+
member: "secondary",
|
|
137
|
+
viewer: "outline",
|
|
138
|
+
} as const;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Team Detail Page
|
|
142
|
+
*
|
|
143
|
+
* Displays detailed information about a specific team for superadmins (read-only).
|
|
144
|
+
*/
|
|
145
|
+
function TeamDetailPage() {
|
|
146
|
+
const params = useParams();
|
|
147
|
+
const teamId = params.teamId as string;
|
|
148
|
+
|
|
149
|
+
// Fetch team data from API
|
|
150
|
+
const { data: teamData, isLoading, error, refetch } = useQuery<TeamDetailData>({
|
|
151
|
+
queryKey: ["superadmin-team", teamId],
|
|
152
|
+
queryFn: async () => {
|
|
153
|
+
const response = await fetch(`/api/superadmin/teams/${teamId}`);
|
|
154
|
+
if (!response.ok) {
|
|
155
|
+
if (response.status === 404) {
|
|
156
|
+
throw new Error("Team not found");
|
|
157
|
+
}
|
|
158
|
+
throw new Error("Failed to fetch team data");
|
|
159
|
+
}
|
|
160
|
+
return response.json();
|
|
161
|
+
},
|
|
162
|
+
retry: 2,
|
|
163
|
+
staleTime: 30000,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Get team initials for avatar
|
|
167
|
+
const getTeamInitials = (name: string) => {
|
|
168
|
+
const words = name.split(" ");
|
|
169
|
+
if (words.length >= 2) {
|
|
170
|
+
return `${words[0][0]}${words[1][0]}`.toUpperCase();
|
|
171
|
+
}
|
|
172
|
+
return name.slice(0, 2).toUpperCase();
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// Loading state
|
|
176
|
+
if (isLoading) {
|
|
177
|
+
return (
|
|
178
|
+
<div className="space-y-6">
|
|
179
|
+
<div className="flex items-center gap-4">
|
|
180
|
+
<Button variant="outline" size="sm" asChild>
|
|
181
|
+
<Link href="/superadmin/teams" className="flex items-center gap-2">
|
|
182
|
+
<ArrowLeft className="h-4 w-4" />
|
|
183
|
+
Back to Teams
|
|
184
|
+
</Link>
|
|
185
|
+
</Button>
|
|
186
|
+
<div>
|
|
187
|
+
<h1 className="text-3xl font-bold tracking-tight">Team Details</h1>
|
|
188
|
+
<p className="text-muted-foreground">Loading team data...</p>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<div className="flex items-center justify-center py-12">
|
|
193
|
+
<Loader2 className="h-8 w-8 animate-spin" />
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Error state
|
|
200
|
+
if (error) {
|
|
201
|
+
return (
|
|
202
|
+
<div className="space-y-6">
|
|
203
|
+
<div className="flex items-center gap-4">
|
|
204
|
+
<Button variant="outline" size="sm" asChild>
|
|
205
|
+
<Link href="/superadmin/teams" className="flex items-center gap-2">
|
|
206
|
+
<ArrowLeft className="h-4 w-4" />
|
|
207
|
+
Back to Teams
|
|
208
|
+
</Link>
|
|
209
|
+
</Button>
|
|
210
|
+
<div>
|
|
211
|
+
<h1 className="text-3xl font-bold tracking-tight">Team Details</h1>
|
|
212
|
+
<p className="text-muted-foreground">Error loading data</p>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
<Card>
|
|
217
|
+
<CardHeader>
|
|
218
|
+
<CardTitle className="flex items-center gap-2">
|
|
219
|
+
<AlertTriangle className="h-5 w-5 text-destructive" />
|
|
220
|
+
Error Loading Team
|
|
221
|
+
</CardTitle>
|
|
222
|
+
<CardDescription>
|
|
223
|
+
{error instanceof Error ? error.message : "Failed to load team data"}
|
|
224
|
+
</CardDescription>
|
|
225
|
+
</CardHeader>
|
|
226
|
+
<CardContent>
|
|
227
|
+
<Button
|
|
228
|
+
onClick={() => refetch()}
|
|
229
|
+
variant="outline"
|
|
230
|
+
className="flex items-center gap-2"
|
|
231
|
+
>
|
|
232
|
+
<RefreshCw className="h-4 w-4" />
|
|
233
|
+
Retry
|
|
234
|
+
</Button>
|
|
235
|
+
</CardContent>
|
|
236
|
+
</Card>
|
|
237
|
+
</div>
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const team = teamData?.team;
|
|
242
|
+
const members = teamData?.members || [];
|
|
243
|
+
|
|
244
|
+
return (
|
|
245
|
+
<div className="space-y-6">
|
|
246
|
+
{/* Header */}
|
|
247
|
+
<div className="flex items-center gap-4">
|
|
248
|
+
<Button variant="outline" size="sm" asChild>
|
|
249
|
+
<Link href="/superadmin/teams" className="flex items-center gap-2">
|
|
250
|
+
<ArrowLeft className="h-4 w-4" />
|
|
251
|
+
Back to Teams
|
|
252
|
+
</Link>
|
|
253
|
+
</Button>
|
|
254
|
+
<div className="flex-1">
|
|
255
|
+
<h1 className="text-3xl font-bold tracking-tight">Team Details</h1>
|
|
256
|
+
<p className="text-muted-foreground">
|
|
257
|
+
View team information and members (read-only)
|
|
258
|
+
</p>
|
|
259
|
+
</div>
|
|
260
|
+
<Button
|
|
261
|
+
onClick={() => refetch()}
|
|
262
|
+
variant="outline"
|
|
263
|
+
size="sm"
|
|
264
|
+
className="flex items-center gap-2"
|
|
265
|
+
>
|
|
266
|
+
<RefreshCw className="h-4 w-4" />
|
|
267
|
+
Refresh
|
|
268
|
+
</Button>
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
{/* Team Info Card */}
|
|
272
|
+
<Card>
|
|
273
|
+
<CardHeader>
|
|
274
|
+
<div className="flex items-start gap-4">
|
|
275
|
+
<Avatar className="h-16 w-16">
|
|
276
|
+
<AvatarFallback className="bg-primary/10 text-primary text-xl">
|
|
277
|
+
{team?.name ? getTeamInitials(team.name) : "??"}
|
|
278
|
+
</AvatarFallback>
|
|
279
|
+
</Avatar>
|
|
280
|
+
<div className="flex-1">
|
|
281
|
+
<div className="flex items-center gap-3">
|
|
282
|
+
<CardTitle className="text-2xl">{team?.name}</CardTitle>
|
|
283
|
+
</div>
|
|
284
|
+
<CardDescription className="mt-1">
|
|
285
|
+
ID: {team?.id}
|
|
286
|
+
</CardDescription>
|
|
287
|
+
</div>
|
|
288
|
+
</div>
|
|
289
|
+
</CardHeader>
|
|
290
|
+
<CardContent>
|
|
291
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
292
|
+
{/* Owner */}
|
|
293
|
+
<div>
|
|
294
|
+
<h4 className="text-sm font-medium text-muted-foreground mb-2">
|
|
295
|
+
Owner
|
|
296
|
+
</h4>
|
|
297
|
+
<div className="flex items-center gap-2">
|
|
298
|
+
<Avatar className="h-8 w-8">
|
|
299
|
+
<AvatarFallback className="text-xs">
|
|
300
|
+
{team?.owner.name?.[0]?.toUpperCase() || "?"}
|
|
301
|
+
</AvatarFallback>
|
|
302
|
+
</Avatar>
|
|
303
|
+
<div>
|
|
304
|
+
<div className="font-medium">{team?.owner.name}</div>
|
|
305
|
+
<div className="text-sm text-muted-foreground">
|
|
306
|
+
{team?.owner.email}
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
</div>
|
|
310
|
+
</div>
|
|
311
|
+
|
|
312
|
+
{/* Members */}
|
|
313
|
+
<div>
|
|
314
|
+
<h4 className="text-sm font-medium text-muted-foreground mb-2">
|
|
315
|
+
Members
|
|
316
|
+
</h4>
|
|
317
|
+
<div className="flex items-center gap-2">
|
|
318
|
+
<Users className="h-5 w-5 text-muted-foreground" />
|
|
319
|
+
<span className="text-xl font-bold">{team?.memberCount || 0}</span>
|
|
320
|
+
<span className="text-muted-foreground">
|
|
321
|
+
{team?.memberCount === 1 ? "member" : "members"}
|
|
322
|
+
</span>
|
|
323
|
+
</div>
|
|
324
|
+
</div>
|
|
325
|
+
|
|
326
|
+
{/* Created */}
|
|
327
|
+
<div>
|
|
328
|
+
<h4 className="text-sm font-medium text-muted-foreground mb-2">
|
|
329
|
+
Created
|
|
330
|
+
</h4>
|
|
331
|
+
<div className="flex items-center gap-2 text-muted-foreground">
|
|
332
|
+
<Calendar className="h-5 w-5" />
|
|
333
|
+
<span>
|
|
334
|
+
{team?.createdAt
|
|
335
|
+
? format(new Date(team.createdAt), "MMMM dd, yyyy")
|
|
336
|
+
: "Unknown"}
|
|
337
|
+
</span>
|
|
338
|
+
</div>
|
|
339
|
+
</div>
|
|
340
|
+
</div>
|
|
341
|
+
</CardContent>
|
|
342
|
+
</Card>
|
|
343
|
+
|
|
344
|
+
{/* Members Table */}
|
|
345
|
+
<Card>
|
|
346
|
+
<CardHeader>
|
|
347
|
+
<CardTitle className="flex items-center gap-2">
|
|
348
|
+
<Users className="h-5 w-5" />
|
|
349
|
+
Team Members ({members.length})
|
|
350
|
+
</CardTitle>
|
|
351
|
+
<CardDescription>
|
|
352
|
+
All members of this team and their roles.
|
|
353
|
+
</CardDescription>
|
|
354
|
+
</CardHeader>
|
|
355
|
+
<CardContent>
|
|
356
|
+
{members.length === 0 ? (
|
|
357
|
+
<div className="text-center py-8">
|
|
358
|
+
<Users className="mx-auto h-12 w-12 text-muted-foreground" />
|
|
359
|
+
<h3 className="mt-4 text-lg font-medium">No members</h3>
|
|
360
|
+
<p className="mt-2 text-sm text-muted-foreground">
|
|
361
|
+
This team has no members yet.
|
|
362
|
+
</p>
|
|
363
|
+
</div>
|
|
364
|
+
) : (
|
|
365
|
+
<div className="rounded-md border">
|
|
366
|
+
<Table>
|
|
367
|
+
<TableHeader>
|
|
368
|
+
<TableRow>
|
|
369
|
+
<TableHead>Member</TableHead>
|
|
370
|
+
<TableHead>Email</TableHead>
|
|
371
|
+
<TableHead>Role</TableHead>
|
|
372
|
+
<TableHead>Joined</TableHead>
|
|
373
|
+
</TableRow>
|
|
374
|
+
</TableHeader>
|
|
375
|
+
<TableBody>
|
|
376
|
+
{members.map((member) => {
|
|
377
|
+
const RoleIcon = roleIcons[member.role] || User;
|
|
378
|
+
return (
|
|
379
|
+
<TableRow key={member.id}>
|
|
380
|
+
<TableCell>
|
|
381
|
+
<div className="flex items-center gap-3">
|
|
382
|
+
<Avatar className="h-8 w-8">
|
|
383
|
+
<AvatarFallback className="text-xs">
|
|
384
|
+
{member.name?.[0]?.toUpperCase() || "?"}
|
|
385
|
+
</AvatarFallback>
|
|
386
|
+
</Avatar>
|
|
387
|
+
<div className="font-medium">{member.name}</div>
|
|
388
|
+
</div>
|
|
389
|
+
</TableCell>
|
|
390
|
+
<TableCell>
|
|
391
|
+
<span className="font-mono text-sm">{member.email}</span>
|
|
392
|
+
</TableCell>
|
|
393
|
+
<TableCell>
|
|
394
|
+
<Badge variant={roleColors[member.role]} className="gap-1">
|
|
395
|
+
<RoleIcon className="h-3 w-3" />
|
|
396
|
+
{member.role.charAt(0).toUpperCase() + member.role.slice(1)}
|
|
397
|
+
</Badge>
|
|
398
|
+
</TableCell>
|
|
399
|
+
<TableCell>
|
|
400
|
+
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
|
401
|
+
<Calendar className="h-4 w-4" />
|
|
402
|
+
{member.joinedAt
|
|
403
|
+
? format(new Date(member.joinedAt), "MMM dd, yyyy")
|
|
404
|
+
: "Unknown"}
|
|
405
|
+
</div>
|
|
406
|
+
</TableCell>
|
|
407
|
+
</TableRow>
|
|
408
|
+
);
|
|
409
|
+
})}
|
|
410
|
+
</TableBody>
|
|
411
|
+
</Table>
|
|
412
|
+
</div>
|
|
413
|
+
)}
|
|
414
|
+
</CardContent>
|
|
415
|
+
</Card>
|
|
416
|
+
|
|
417
|
+
{/* Subscription Section */}
|
|
418
|
+
{teamData?.subscription ? (
|
|
419
|
+
<Card>
|
|
420
|
+
<CardHeader>
|
|
421
|
+
<CardTitle className="flex items-center gap-2">
|
|
422
|
+
<CreditCard className="h-5 w-5" />
|
|
423
|
+
Subscription
|
|
424
|
+
</CardTitle>
|
|
425
|
+
<CardDescription>
|
|
426
|
+
Current subscription status and billing information.
|
|
427
|
+
</CardDescription>
|
|
428
|
+
</CardHeader>
|
|
429
|
+
<CardContent>
|
|
430
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
431
|
+
{/* Plan */}
|
|
432
|
+
<div>
|
|
433
|
+
<h4 className="text-sm font-medium text-muted-foreground mb-2">
|
|
434
|
+
Current Plan
|
|
435
|
+
</h4>
|
|
436
|
+
<div className="flex items-center gap-2">
|
|
437
|
+
<Badge variant={teamData.subscription.plan.type === 'paid' ? 'default' : 'secondary'}>
|
|
438
|
+
{teamData.subscription.plan.name}
|
|
439
|
+
</Badge>
|
|
440
|
+
<span className="text-sm text-muted-foreground">
|
|
441
|
+
{teamData.subscription.plan.priceFormatted}
|
|
442
|
+
</span>
|
|
443
|
+
</div>
|
|
444
|
+
</div>
|
|
445
|
+
|
|
446
|
+
{/* Status */}
|
|
447
|
+
<div>
|
|
448
|
+
<h4 className="text-sm font-medium text-muted-foreground mb-2">
|
|
449
|
+
Status
|
|
450
|
+
</h4>
|
|
451
|
+
<Badge
|
|
452
|
+
variant={
|
|
453
|
+
teamData.subscription.status === 'active' ? 'default' :
|
|
454
|
+
teamData.subscription.status === 'trialing' ? 'secondary' :
|
|
455
|
+
teamData.subscription.status === 'past_due' ? 'destructive' :
|
|
456
|
+
'outline'
|
|
457
|
+
}
|
|
458
|
+
className="gap-1"
|
|
459
|
+
>
|
|
460
|
+
{teamData.subscription.status === 'active' && <CheckCircle className="h-3 w-3" />}
|
|
461
|
+
{teamData.subscription.status === 'trialing' && <Clock className="h-3 w-3" />}
|
|
462
|
+
{teamData.subscription.status === 'past_due' && <AlertCircle className="h-3 w-3" />}
|
|
463
|
+
{teamData.subscription.status === 'canceled' && <XCircle className="h-3 w-3" />}
|
|
464
|
+
{teamData.subscription.status.charAt(0).toUpperCase() + teamData.subscription.status.slice(1).replace('_', ' ')}
|
|
465
|
+
</Badge>
|
|
466
|
+
{teamData.subscription.cancelAtPeriodEnd && (
|
|
467
|
+
<p className="text-xs text-destructive mt-1">Cancels at period end</p>
|
|
468
|
+
)}
|
|
469
|
+
</div>
|
|
470
|
+
|
|
471
|
+
{/* Current Period */}
|
|
472
|
+
<div>
|
|
473
|
+
<h4 className="text-sm font-medium text-muted-foreground mb-2">
|
|
474
|
+
Current Period
|
|
475
|
+
</h4>
|
|
476
|
+
<div className="text-sm">
|
|
477
|
+
<div className="flex items-center gap-1">
|
|
478
|
+
<Calendar className="h-3 w-3 text-muted-foreground" />
|
|
479
|
+
{format(new Date(teamData.subscription.currentPeriodStart), "MMM dd")} - {format(new Date(teamData.subscription.currentPeriodEnd), "MMM dd, yyyy")}
|
|
480
|
+
</div>
|
|
481
|
+
</div>
|
|
482
|
+
</div>
|
|
483
|
+
|
|
484
|
+
{/* Trial / External Links */}
|
|
485
|
+
<div>
|
|
486
|
+
{teamData.subscription.trialEndsAt && (
|
|
487
|
+
<>
|
|
488
|
+
<h4 className="text-sm font-medium text-muted-foreground mb-2">
|
|
489
|
+
Trial Ends
|
|
490
|
+
</h4>
|
|
491
|
+
<div className="flex items-center gap-2 text-sm">
|
|
492
|
+
<Clock className="h-4 w-4 text-muted-foreground" />
|
|
493
|
+
{format(new Date(teamData.subscription.trialEndsAt), "MMM dd, yyyy")}
|
|
494
|
+
</div>
|
|
495
|
+
</>
|
|
496
|
+
)}
|
|
497
|
+
{teamData.subscription.externalSubscriptionId && (
|
|
498
|
+
<>
|
|
499
|
+
<h4 className="text-sm font-medium text-muted-foreground mb-2">
|
|
500
|
+
Stripe
|
|
501
|
+
</h4>
|
|
502
|
+
<a
|
|
503
|
+
href={`https://dashboard.stripe.com/subscriptions/${teamData.subscription.externalSubscriptionId}`}
|
|
504
|
+
target="_blank"
|
|
505
|
+
rel="noopener noreferrer"
|
|
506
|
+
className="inline-flex items-center gap-1 text-sm text-primary hover:underline"
|
|
507
|
+
>
|
|
508
|
+
View in Stripe
|
|
509
|
+
<ExternalLink className="h-3 w-3" />
|
|
510
|
+
</a>
|
|
511
|
+
</>
|
|
512
|
+
)}
|
|
513
|
+
</div>
|
|
514
|
+
</div>
|
|
515
|
+
|
|
516
|
+
{/* Subscription Metadata */}
|
|
517
|
+
<div className="mt-4 pt-4 border-t text-xs text-muted-foreground">
|
|
518
|
+
<span>Subscription ID: {teamData.subscription.id}</span>
|
|
519
|
+
{teamData.subscription.externalCustomerId && (
|
|
520
|
+
<span className="ml-4">Customer ID: {teamData.subscription.externalCustomerId}</span>
|
|
521
|
+
)}
|
|
522
|
+
</div>
|
|
523
|
+
</CardContent>
|
|
524
|
+
</Card>
|
|
525
|
+
) : (
|
|
526
|
+
<Card>
|
|
527
|
+
<CardHeader>
|
|
528
|
+
<CardTitle className="flex items-center gap-2">
|
|
529
|
+
<CreditCard className="h-5 w-5" />
|
|
530
|
+
Subscription
|
|
531
|
+
</CardTitle>
|
|
532
|
+
</CardHeader>
|
|
533
|
+
<CardContent>
|
|
534
|
+
<div className="text-center py-8">
|
|
535
|
+
<CreditCard className="mx-auto h-12 w-12 text-muted-foreground" />
|
|
536
|
+
<h3 className="mt-4 text-lg font-medium">No Subscription</h3>
|
|
537
|
+
<p className="mt-2 text-sm text-muted-foreground">
|
|
538
|
+
This team does not have an active subscription.
|
|
539
|
+
</p>
|
|
540
|
+
</div>
|
|
541
|
+
</CardContent>
|
|
542
|
+
</Card>
|
|
543
|
+
)}
|
|
544
|
+
|
|
545
|
+
{/* Billing History */}
|
|
546
|
+
{teamData?.billingHistory && teamData.billingHistory.length > 0 && (
|
|
547
|
+
<Card>
|
|
548
|
+
<CardHeader>
|
|
549
|
+
<CardTitle className="flex items-center gap-2">
|
|
550
|
+
<Receipt className="h-5 w-5" />
|
|
551
|
+
Billing History
|
|
552
|
+
</CardTitle>
|
|
553
|
+
<CardDescription>
|
|
554
|
+
Recent payment events and invoices.
|
|
555
|
+
</CardDescription>
|
|
556
|
+
</CardHeader>
|
|
557
|
+
<CardContent>
|
|
558
|
+
<div className="rounded-md border">
|
|
559
|
+
<Table>
|
|
560
|
+
<TableHeader>
|
|
561
|
+
<TableRow>
|
|
562
|
+
<TableHead>Date</TableHead>
|
|
563
|
+
<TableHead>Type</TableHead>
|
|
564
|
+
<TableHead>Status</TableHead>
|
|
565
|
+
<TableHead className="text-right">Amount</TableHead>
|
|
566
|
+
<TableHead>Actions</TableHead>
|
|
567
|
+
</TableRow>
|
|
568
|
+
</TableHeader>
|
|
569
|
+
<TableBody>
|
|
570
|
+
{teamData.billingHistory.map((event) => (
|
|
571
|
+
<TableRow key={event.id}>
|
|
572
|
+
<TableCell>
|
|
573
|
+
<div className="flex items-center gap-2 text-sm">
|
|
574
|
+
<Calendar className="h-4 w-4 text-muted-foreground" />
|
|
575
|
+
{format(new Date(event.createdAt), "MMM dd, yyyy")}
|
|
576
|
+
</div>
|
|
577
|
+
</TableCell>
|
|
578
|
+
<TableCell>
|
|
579
|
+
<span className="capitalize">{event.type.replace('_', ' ')}</span>
|
|
580
|
+
</TableCell>
|
|
581
|
+
<TableCell>
|
|
582
|
+
<Badge
|
|
583
|
+
variant={
|
|
584
|
+
event.status === 'succeeded' ? 'default' :
|
|
585
|
+
event.status === 'pending' ? 'secondary' :
|
|
586
|
+
event.status === 'failed' ? 'destructive' :
|
|
587
|
+
'outline'
|
|
588
|
+
}
|
|
589
|
+
className="gap-1"
|
|
590
|
+
>
|
|
591
|
+
{event.status === 'succeeded' && <CheckCircle className="h-3 w-3" />}
|
|
592
|
+
{event.status === 'pending' && <Clock className="h-3 w-3" />}
|
|
593
|
+
{event.status === 'failed' && <XCircle className="h-3 w-3" />}
|
|
594
|
+
{event.status.charAt(0).toUpperCase() + event.status.slice(1)}
|
|
595
|
+
</Badge>
|
|
596
|
+
</TableCell>
|
|
597
|
+
<TableCell className="text-right font-mono">
|
|
598
|
+
{event.amountFormatted}
|
|
599
|
+
</TableCell>
|
|
600
|
+
<TableCell>
|
|
601
|
+
<div className="flex items-center gap-2">
|
|
602
|
+
{event.invoiceUrl && (
|
|
603
|
+
<a
|
|
604
|
+
href={event.invoiceUrl}
|
|
605
|
+
target="_blank"
|
|
606
|
+
rel="noopener noreferrer"
|
|
607
|
+
className="text-primary hover:underline text-sm"
|
|
608
|
+
>
|
|
609
|
+
Invoice
|
|
610
|
+
</a>
|
|
611
|
+
)}
|
|
612
|
+
{event.receiptUrl && (
|
|
613
|
+
<a
|
|
614
|
+
href={event.receiptUrl}
|
|
615
|
+
target="_blank"
|
|
616
|
+
rel="noopener noreferrer"
|
|
617
|
+
className="text-primary hover:underline text-sm"
|
|
618
|
+
>
|
|
619
|
+
Receipt
|
|
620
|
+
</a>
|
|
621
|
+
)}
|
|
622
|
+
</div>
|
|
623
|
+
</TableCell>
|
|
624
|
+
</TableRow>
|
|
625
|
+
))}
|
|
626
|
+
</TableBody>
|
|
627
|
+
</Table>
|
|
628
|
+
</div>
|
|
629
|
+
</CardContent>
|
|
630
|
+
</Card>
|
|
631
|
+
)}
|
|
632
|
+
|
|
633
|
+
{/* Usage Summary */}
|
|
634
|
+
{teamData?.usage && Object.keys(teamData.usage).length > 0 && (
|
|
635
|
+
<Card>
|
|
636
|
+
<CardHeader>
|
|
637
|
+
<CardTitle className="flex items-center gap-2">
|
|
638
|
+
<TrendingUp className="h-5 w-5" />
|
|
639
|
+
Current Usage
|
|
640
|
+
</CardTitle>
|
|
641
|
+
<CardDescription>
|
|
642
|
+
Resource usage for the current billing period.
|
|
643
|
+
</CardDescription>
|
|
644
|
+
</CardHeader>
|
|
645
|
+
<CardContent>
|
|
646
|
+
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
|
|
647
|
+
{Object.entries(teamData.usage).map(([limitSlug, usage]) => (
|
|
648
|
+
<div key={limitSlug} className="p-4 bg-muted/50 rounded-lg">
|
|
649
|
+
<div className="text-sm font-medium text-muted-foreground capitalize">
|
|
650
|
+
{limitSlug.replace(/_/g, ' ')}
|
|
651
|
+
</div>
|
|
652
|
+
<div className="text-2xl font-bold mt-1">
|
|
653
|
+
{usage.current.toLocaleString()}
|
|
654
|
+
</div>
|
|
655
|
+
<div className="text-xs text-muted-foreground mt-1">
|
|
656
|
+
Period: {usage.periodKey}
|
|
657
|
+
</div>
|
|
658
|
+
</div>
|
|
659
|
+
))}
|
|
660
|
+
</div>
|
|
661
|
+
</CardContent>
|
|
662
|
+
</Card>
|
|
663
|
+
)}
|
|
664
|
+
|
|
665
|
+
{/* Metadata Footer */}
|
|
666
|
+
{teamData?.metadata && (
|
|
667
|
+
<Card className="bg-muted/30">
|
|
668
|
+
<CardContent className="pt-4">
|
|
669
|
+
<div className="text-xs text-muted-foreground space-y-1">
|
|
670
|
+
<p>
|
|
671
|
+
Last updated:{" "}
|
|
672
|
+
{new Date(teamData.metadata.requestedAt).toLocaleString()}
|
|
673
|
+
</p>
|
|
674
|
+
<p>Requested by: {teamData.metadata.requestedBy}</p>
|
|
675
|
+
<p>Source: {teamData.metadata.source}</p>
|
|
676
|
+
</div>
|
|
677
|
+
</CardContent>
|
|
678
|
+
</Card>
|
|
679
|
+
)}
|
|
680
|
+
</div>
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
export default getTemplateOrDefaultClient(
|
|
685
|
+
"app/superadmin/teams/[teamId]/page.tsx",
|
|
686
|
+
TeamDetailPage
|
|
687
|
+
);
|