Files
simstudioai--sim/apps/sim/components/emails/invitations/batch-invitation-email.tsx
T
wehub-resource-sync d25d482dc2
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:20:55 +08:00

109 lines
3.2 KiB
TypeScript

import { Link, Text } from '@react-email/components'
import { baseStyles } from '@/components/emails/_styles'
import { EmailLayout } from '@/components/emails/components'
import { getBrandConfig } from '@/ee/whitelabeling'
interface WorkspaceInvitation {
workspaceId: string
workspaceName: string
permission: 'admin' | 'write' | 'read'
}
interface BatchInvitationEmailProps {
inviterName: string
organizationName: string
organizationRole: 'admin' | 'member'
workspaceInvitations: WorkspaceInvitation[]
acceptUrl: string
}
const getPermissionLabel = (permission: string) => {
switch (permission) {
case 'admin':
return 'Admin (full access)'
case 'write':
return 'Editor (can edit workflows)'
case 'read':
return 'Viewer (read-only access)'
default:
return permission
}
}
const getRoleLabel = (role: string) => {
switch (role) {
case 'admin':
return 'Admin'
case 'member':
return 'Member'
default:
return role
}
}
const EMPTY_INVITATIONS: WorkspaceInvitation[] = []
export function BatchInvitationEmail({
inviterName = 'Someone',
organizationName = 'the team',
organizationRole = 'member',
workspaceInvitations = EMPTY_INVITATIONS,
acceptUrl,
}: BatchInvitationEmailProps) {
const brand = getBrandConfig()
const hasWorkspaces = workspaceInvitations.length > 0
return (
<EmailLayout
preview={`You've been invited to join ${organizationName}${hasWorkspaces ? ` and ${workspaceInvitations.length} workspace(s)` : ''}`}
showUnsubscribe={false}
>
<Text style={baseStyles.paragraph}>Hello,</Text>
<Text style={baseStyles.paragraph}>
<strong>{inviterName}</strong> has invited you to join <strong>{organizationName}</strong>{' '}
on {brand.name}.
</Text>
{/* Team Role Information */}
<Text style={baseStyles.paragraph}>
<strong>Team Role:</strong> {getRoleLabel(organizationRole)}
</Text>
<Text style={baseStyles.paragraph}>
{organizationRole === 'admin'
? "As a Team Admin, you'll be able to manage team members, billing, and workspace access."
: "As a Team Member, you'll have access to shared team billing and can be invited to workspaces."}
</Text>
{/* Workspace Invitations */}
{hasWorkspaces && (
<>
<Text style={baseStyles.paragraph}>
<strong>
Workspace Access ({workspaceInvitations.length} workspace
{workspaceInvitations.length !== 1 ? 's' : ''}):
</strong>
</Text>
{workspaceInvitations.map((ws) => (
<Text key={ws.workspaceId} style={{ ...baseStyles.paragraph, marginLeft: '20px' }}>
<strong>{ws.workspaceName}</strong> - {getPermissionLabel(ws.permission)}
</Text>
))}
</>
)}
<Link href={acceptUrl} style={{ textDecoration: 'none' }}>
<Text style={baseStyles.button}>Accept Invitation</Text>
</Link>
{/* Divider */}
<div style={baseStyles.divider} />
<Text style={{ ...baseStyles.footerText, textAlign: 'left' }}>
Invitation expires in 7 days. If unexpected, you can ignore this email.
</Text>
</EmailLayout>
)
}
export default BatchInvitationEmail