SaaSApp
Multi-tenant product application with workspace management and billing
SaaSApp
The SaaSApp specialization provides a complete multi-tenant SaaS application interface with workspace management, team collaboration, billing and subscriptions, and third-party integrations. It's designed for B2B or B2C products that need tenant isolation and subscription management.
Overview
SaaSApp extends the base App with SaaS-specific features:
- Multi-Tenancy - Workspace/organization isolation
- Workspace Switcher - Switch between organizations
- Team Management - Invite members and assign roles
- Billing & Subscriptions - Manage plans and payment
- Integrations - Connect third-party services
Type Signature
interface SaaSAppProps extends AppProps {
/** SaaS application configuration */
config?: {
/** Enable multi-tenancy */
multiTenant?: boolean // default: true
/** Show workspace switcher */
showWorkspaceSwitcher?: boolean // default: true
/** Show billing section */
showBilling?: boolean // default: true
/** Show team management */
showTeam?: boolean // default: true
/** Show integrations */
showIntegrations?: boolean // default: true
/** Pricing tiers */
pricingTiers?: string[] // e.g., ["free", "pro", "enterprise"]
/** Feature flags */
features?: Record<string, boolean>
}
}Naming Convention
All SaaSApp components follow the pattern: SaaS${Component} = ${Component} + SaaS-specific props.
// Base component + SaaS props = SaaS component
SaaSDashboard = Dashboard + { showUsageMetrics, showTeamActivity }
SaaSTeam = Team + { showInvites, enableSSO }
SaaSBilling = Billing + { showUsage, showInvoices }
SaaSIntegrations = Integrations + { showMarketplace, enableOAuth }
SaaSSettings = Settings + { showWorkspace, showBilling }Quick Start
import type { AppComponents } from 'mdxui'
import { SaaSApp } from '@mdxui/cockpit'
export const components: AppComponents = {
App: SaaSApp,
Shell,
Sidebar,
Header,
Dashboard: SaaSDashboard,
Settings: SaaSSettings,
}In your MDX:
<SaaSApp
name="Acme Platform"
config={{
multiTenant: true,
showWorkspaceSwitcher: true,
showBilling: true,
showTeam: true,
showIntegrations: true,
pricingTiers: ['free', 'pro', 'enterprise']
}}
>
<Shell>
<SaaSDashboard />
</Shell>
</SaaSApp>App Structure
SaaSApp
├── SaaSDashboard - Product dashboard with usage metrics
├── [ProductViews] - Core product functionality (app-specific)
├── SaaSTeam - Team member management and invites
├── SaaSBilling - Subscription and payment management
├── SaaSIntegrations - Third-party integrations
└── SaaSSettings - Workspace and account settingsDefault Views
SaaSDashboard
Main product dashboard showing usage and team activity.
interface SaaSDashboardProps extends DashboardProps {
/** Show usage metrics */
showUsageMetrics?: boolean // default: true
/** Show team activity */
showTeamActivity?: boolean // default: true
/** Show billing summary */
showBillingSummary?: boolean // default: true
/** Show plan limits */
showPlanLimits?: boolean // default: true
}Layout:
DashboardView (single)
├── MetricsPanel - Plan usage, team size, activity
├── ChartPanel - Usage trends over time
├── ActivityPanel - Recent team activity
└── StatsPanel - Quick stats and limitsUsage:
<SaaSDashboard
showUsageMetrics={true}
showTeamActivity={true}
showBillingSummary={true}
showPlanLimits={true}
/>SaaSTeam
Team member management with roles and permissions.
interface SaaSTeamProps {
/** Show pending invites */
showInvites?: boolean // default: true
/** Enable SSO configuration */
enableSSO?: boolean // default: false
/** Show role management */
showRoles?: boolean // default: true
/** Available roles */
roles?: Array<{
name: string
permissions: string[]
}>
}Layout:
TeamView (column)
├── ToolbarPanel - Invite button, filters
├── TablePanel - Team members
│ ├── Avatar + Name
│ ├── Email
│ ├── Role
│ ├── Last active
│ └── Actions (edit, remove)
├── InvitesPanel - Pending invitations
│ ├── Email
│ ├── Role
│ ├── Sent date
│ └── Actions (resend, cancel)
└── DetailPanel - Member details
├── Profile info
├── Role editor
├── Activity log
└── Danger zone (remove)Usage:
<SaaSTeam
showInvites={true}
enableSSO={false}
showRoles={true}
roles={[
{ name: 'owner', permissions: ['*'] },
{ name: 'admin', permissions: ['read', 'write', 'invite'] },
{ name: 'member', permissions: ['read', 'write'] },
{ name: 'viewer', permissions: ['read'] }
]}
/>SaaSBilling
Subscription and payment management.
interface SaaSBillingProps {
/** Show usage-based billing */
showUsage?: boolean // default: true
/** Show invoice history */
showInvoices?: boolean // default: true
/** Show payment methods */
showPaymentMethods?: boolean // default: true
/** Enable plan changes */
enablePlanChanges?: boolean // default: true
/** Pricing tiers */
pricingTiers?: Array<{
name: string
price: number
interval: 'month' | 'year'
features: string[]
}>
}Layout:
BillingView (single)
├── MetricsPanel - Current plan, next billing date, total
├── PlanPanel - Current plan details and upgrade options
│ ├── Plan name
│ ├── Price
│ ├── Features
│ └── Change plan button
├── UsagePanel - Usage-based metrics
│ ├── Resource usage
│ ├── Limits
│ └── Overage charges
├── InvoicesPanel - Invoice history
│ ├── Date
│ ├── Amount
│ ├── Status
│ └── Download
└── PaymentMethodsPanel - Saved payment methods
├── Card info
├── Default badge
└── Actions (edit, delete, set default)Usage:
<SaaSBilling
showUsage={true}
showInvoices={true}
showPaymentMethods={true}
enablePlanChanges={true}
pricingTiers={[
{
name: 'Free',
price: 0,
interval: 'month',
features: ['Up to 3 users', '100 items', 'Basic support']
},
{
name: 'Pro',
price: 29,
interval: 'month',
features: ['Unlimited users', '10,000 items', 'Priority support', 'Advanced analytics']
},
{
name: 'Enterprise',
price: 299,
interval: 'month',
features: ['Unlimited everything', 'SLA', 'Dedicated support', 'Custom integrations']
}
]}
/>SaaSIntegrations
Third-party integration management.
interface SaaSIntegrationsProps {
/** Show integration marketplace */
showMarketplace?: boolean // default: true
/** Enable OAuth flows */
enableOAuth?: boolean // default: true
/** Show connected integrations */
showConnected?: boolean // default: true
/** Available integrations */
integrations?: Array<{
id: string
name: string
description: string
icon: string
category: string
oauthUrl?: string
}>
}Layout:
IntegrationsView (column)
├── TabsPanel - Connected, Available, Categories
├── CardsPanel - Integration cards
│ ├── Icon + Name
│ ├── Description
│ ├── Category badge
│ └── Connect/Configure button
└── DetailPanel - Integration details
├── Overview
├── Configuration form
├── Test connection
└── Disconnect buttonUsage:
<SaaSIntegrations
showMarketplace={true}
enableOAuth={true}
showConnected={true}
integrations={[
{
id: 'slack',
name: 'Slack',
description: 'Send notifications to Slack channels',
icon: 'slack-icon.svg',
category: 'Communication',
oauthUrl: 'https://slack.com/oauth/authorize'
},
{
id: 'stripe',
name: 'Stripe',
description: 'Accept payments with Stripe',
icon: 'stripe-icon.svg',
category: 'Payment'
}
]}
/>SaaSSettings
Workspace and account settings.
interface SaaSSettingsProps extends SettingsProps {
/** Show workspace settings */
showWorkspace?: boolean // default: true
/** Show billing settings */
showBilling?: boolean // default: true
/** Show danger zone */
showDangerZone?: boolean // default: true
}Layout:
SettingsView (single)
├── TabsPanel - General, Workspace, Billing, Security, Danger
├── GeneralPanel - Profile settings
├── WorkspacePanel - Workspace name, logo, domain
├── BillingPanel - Billing contact, tax ID
├── SecurityPanel - Password, 2FA, sessions
└── DangerPanel - Transfer ownership, delete workspaceUsage:
<SaaSSettings
showWorkspace={true}
showBilling={true}
showDangerZone={true}
/>Configuration
Multi-Tenancy
<SaaSApp
config={{
multiTenant: true,
showWorkspaceSwitcher: true
}}
>
{/* Workspace isolation enabled */}
</SaaSApp>Workspace Switcher
// Enable workspace switcher in header
<SaaSApp
config={{
showWorkspaceSwitcher: true
}}
>
<Shell>
{/* Workspace dropdown appears in header */}
</Shell>
</SaaSApp>Pricing Tiers
<SaaSApp
config={{
pricingTiers: ['free', 'pro', 'enterprise']
}}
>
<SaaSBilling
pricingTiers={[
{
name: 'Free',
price: 0,
interval: 'month',
features: ['Basic features']
},
{
name: 'Pro',
price: 29,
interval: 'month',
features: ['All features']
}
]}
/>
</SaaSApp>Feature Flags
<SaaSApp
config={{
features: {
analytics: true,
apiAccess: false,
customBranding: true,
sso: false
}
}}
>
{/* Features controlled by flags */}
</SaaSApp>Auto-Wiring
SaaSApp components automatically wire to Payload collections:
| Component | Collection | Purpose |
|---|---|---|
SaaSTeam | teamMembers | Team member management |
SaaS Billing | subscriptions | Subscription management |
SaaSBilling | invoices | Invoice history |
SaaSIntegrations | integrations | Integration connections |
Collection Schemas
workspaces Collection:
{
name: string
slug: string
logo?: string
domain?: string
plan: 'free' | 'pro' | 'enterprise'
features: Record<string, boolean>
ownerId: User
createdAt: Date
}teamMembers Collection:
{
workspaceId: string
userId: User
role: 'owner' | 'admin' | 'member' | 'viewer'
invitedBy: User
joinedAt: Date
}subscriptions Collection:
{
workspaceId: string
plan: string
interval: 'month' | 'year'
price: number
status: 'active' | 'canceled' | 'past_due'
currentPeriodEnd: Date
customerId: string // Stripe customer ID
}invoices Collection:
{
workspaceId: string
subscriptionId: string
amount: number
status: 'paid' | 'open' | 'void'
dueDate: Date
paidAt?: Date
invoiceUrl: string
}integrations Collection:
{
workspaceId: string
integrationId: string
config: Record<string, any>
accessToken?: string
refreshToken?: string
expiresAt?: Date
enabled: boolean
}Navigation
Default navigation structure:
const navigation = [
{ path: '/', label: 'Dashboard', icon: 'LayoutDashboard' },
// Product-specific views here
{ path: '/team', label: 'Team', icon: 'Users' },
{ path: '/billing', label: 'Billing', icon: 'CreditCard' },
{ path: '/integrations', label: 'Integrations', icon: 'Puzzle' },
{ path: '/settings', label: 'Settings', icon: 'Settings' },
]Best Practices
Multi-Tenancy
- Workspace isolation - Always scope queries by workspace
- Role-based access - Enforce permissions per workspace
- Resource limits - Respect plan limits per workspace
- Tenant migration - Support workspace transfers
<SaaSApp
config={{
multiTenant: true,
showWorkspaceSwitcher: true
}}
/>Team Management
- Invite flows - Email invitations with expiry
- Role hierarchy - Owner > Admin > Member > Viewer
- SSO support - Enable for enterprise plans
- Activity logs - Track member actions
<SaaSTeam
showInvites={true}
enableSSO={true}
roles={[
{ name: 'owner', permissions: ['*'] },
{ name: 'admin', permissions: ['read', 'write', 'invite'] },
{ name: 'member', permissions: ['read', 'write'] }
]}
/>Billing
- Transparent pricing - Show all charges clearly
- Usage tracking - Monitor plan limits
- Payment failures - Handle gracefully with retries
- Downgrade protection - Preserve data on plan changes
<SaaSBilling
showUsage={true}
showInvoices={true}
enablePlanChanges={true}
/>Integrations
- OAuth security - Use secure token storage
- Token refresh - Auto-refresh expired tokens
- Error handling - Graceful degradation
- Testing tools - Provide test connections
<SaaSIntegrations
enableOAuth={true}
showMarketplace={true}
/>Related Components
- App - Base App component
- Dashboard - Dashboard view
- Settings - Settings view
- Features - Feature management
Examples
Minimal SaaS App
<SaaSApp name="My Product">
<Shell>
<SaaSDashboard />
</Shell>
</SaaSApp>Full-Featured SaaS App
<SaaSApp
name="Acme Platform"
config={{
multiTenant: true,
showWorkspaceSwitcher: true,
showBilling: true,
showTeam: true,
showIntegrations: true,
pricingTiers: ['free', 'pro', 'enterprise'],
features: {
analytics: true,
apiAccess: true,
customBranding: true,
sso: true
}
}}
>
<Shell>
<Routes>
<Route path="/" element={
<SaaSDashboard
showUsageMetrics={true}
showTeamActivity={true}
showBillingSummary={true}
/>
} />
<Route path="/team" element={
<SaaSTeam
showInvites={true}
enableSSO={true}
showRoles={true}
/>
} />
<Route path="/billing" element={
<SaaSBilling
showUsage={true}
showInvoices={true}
showPaymentMethods={true}
enablePlanChanges={true}
/>
} />
<Route path="/integrations" element={
<SaaSIntegrations
showMarketplace={true}
enableOAuth={true}
/>
} />
<Route path="/settings" element={
<SaaSSettings
showWorkspace={true}
showBilling={true}
showDangerZone={true}
/>
} />
</Routes>
</Shell>
</SaaSApp>