feat(server): new email template (#9528)

use `yarn af server dev:mail` to preview all mail template
fix CLOUD-93
This commit is contained in:
darkskygit
2025-01-22 02:55:24 +00:00
parent 2db9cc3922
commit 83ed215f4a
54 changed files with 4794 additions and 892 deletions
@@ -0,0 +1,30 @@
export { default as Invitation, type InvitationProps } from './invitation';
export {
default as InvitationAccepted,
type InvitationAcceptedProps,
} from './invitation-accepted';
export { default as MemberLeave, type MemberLeaveProps } from './member-leave';
export {
default as MemberRemoved,
type MemberRemovedProps,
} from './member-removed';
export {
default as OwnershipReceived,
type OwnershipReceivedProps,
} from './ownership-received';
export {
default as OwnershipTransferred,
type OwnershipTransferredProps,
} from './ownership-transferred';
export {
default as LinkInvitationApproved,
type LinkInvitationApprovedProps,
} from './review-approved';
export {
default as LinkInvitationReviewDeclined,
type LinkInvitationReviewDeclinedProps,
} from './review-declined';
export {
default as LinkInvitationReviewRequest,
type LinkInvitationReviewRequestProps,
} from './review-request';
@@ -0,0 +1,35 @@
import { TEST_USER, TEST_WORKSPACE } from '../common';
import {
Content,
P,
Template,
Title,
User,
type UserProps,
Workspace,
type WorkspaceProps,
} from '../components';
export type InvitationAcceptedProps = {
user: UserProps;
workspace: WorkspaceProps;
};
export default function InvitationAccepted(props: InvitationAcceptedProps) {
const { user, workspace } = props;
return (
<Template>
<Title>{user.email} accepted your invitation</Title>
<Content>
<P>
<User {...user} /> has joined <Workspace {...workspace} />
</P>
</Content>
</Template>
);
}
InvitationAccepted.PreviewProps = {
user: TEST_USER,
workspace: TEST_WORKSPACE,
};
@@ -0,0 +1,41 @@
import { TEST_USER, TEST_WORKSPACE } from '../common';
import {
Button,
Content,
P,
Template,
Title,
User,
type UserProps,
Workspace,
type WorkspaceProps,
} from '../components';
export type InvitationProps = {
user: UserProps;
workspace: WorkspaceProps;
url: string;
};
export default function Invitation(props: InvitationProps) {
const { user, workspace, url } = props;
return (
<Template>
<Title>You are invited!</Title>
<Content>
<P>
<User {...user} /> invited you to join <Workspace {...workspace} />
</P>
<P>Click button to join this workspace</P>
<Button href={url}>Accept & Join</Button>
</Content>
</Template>
);
}
Invitation.PreviewProps = {
user: TEST_USER,
workspace: TEST_WORKSPACE,
url: 'https://app.affine.pro',
};
@@ -0,0 +1,38 @@
import { TEST_USER, TEST_WORKSPACE } from '../common';
import {
Content,
Name,
P,
Template,
Title,
type UserProps,
Workspace,
type WorkspaceProps,
} from '../components';
export type MemberLeaveProps = {
user: UserProps;
workspace: WorkspaceProps;
};
export default function MemberLeave(props: MemberLeaveProps) {
const { user, workspace } = props;
return (
<Template>
<Title>
Member left <Workspace {...workspace} size={24} />
</Title>
<Content>
<P>
<Name>{user.email}</Name> has left workspace{' '}
<Workspace {...workspace} />
</P>
</Content>
</Template>
);
}
MemberLeave.PreviewProps = {
user: TEST_USER,
workspace: TEST_WORKSPACE,
};
@@ -0,0 +1,32 @@
import { TEST_WORKSPACE } from '../common';
import {
Content,
P,
Template,
Title,
Workspace,
type WorkspaceProps,
} from '../components';
export type MemberRemovedProps = {
workspace: WorkspaceProps;
};
export default function MemberRemoved(props: MemberRemovedProps) {
const { workspace } = props;
return (
<Template>
<Title>Workspace access removed</Title>
<Content>
<P>
You have been removed from <Workspace {...workspace} />. You no longer
have access to this workspace.
</P>
</Content>
</Template>
);
}
MemberRemoved.PreviewProps = {
workspace: TEST_WORKSPACE,
};
@@ -0,0 +1,34 @@
import { TEST_WORKSPACE } from '../common';
import {
Content,
P,
Template,
Title,
Workspace,
type WorkspaceProps,
} from '../components';
export type OwnershipReceivedProps = {
workspace: WorkspaceProps;
};
export default function OwnershipReceived(props: OwnershipReceivedProps) {
const { workspace } = props;
return (
<Template>
<Title>Welcome, new workspace owner!</Title>
<Content>
<P>
You have been assigned as the owner of
<Workspace {...workspace} />. As a workspace owner, you have full
control over this workspace.
</P>
</Content>
</Template>
);
}
OwnershipReceived.PreviewProps = {
workspace: TEST_WORKSPACE,
};
@@ -0,0 +1,32 @@
import { TEST_WORKSPACE } from '../common';
import {
Content,
P,
Template,
Title,
Workspace,
type WorkspaceProps,
} from '../components';
export type OwnershipTransferredProps = {
workspace: WorkspaceProps;
};
export default function OwnershipTransferred(props: OwnershipTransferredProps) {
const { workspace } = props;
return (
<Template>
<Title>Ownership transferred</Title>
<Content>
<P>
You have transferred ownership of <Workspace {...workspace} />. You
are now a collaborator in this workspace.
</P>
</Content>
</Template>
);
}
OwnershipTransferred.PreviewProps = {
workspace: TEST_WORKSPACE,
};
@@ -0,0 +1,39 @@
import { TEST_WORKSPACE } from '../common';
import {
Button,
Content,
P,
Template,
Title,
Workspace,
type WorkspaceProps,
} from '../components';
export type LinkInvitationApprovedProps = {
workspace: WorkspaceProps;
url: string;
};
export default function LinkInvitationApproved(
props: LinkInvitationApprovedProps
) {
const { workspace, url } = props;
return (
<Template>
<Title>Welcome to the workspace!</Title>
<Content>
<P>
Your request to join <Workspace {...workspace} /> has been accepted.
You can now access the team workspace and collaborate with other
members.
</P>
</Content>
<Button href={url}>Open Workspace</Button>
</Template>
);
}
LinkInvitationApproved.PreviewProps = {
workspace: TEST_WORKSPACE,
url: 'https://app.affine.pro',
};
@@ -0,0 +1,34 @@
import { TEST_WORKSPACE } from '../common';
import {
Content,
P,
Template,
Title,
Workspace,
type WorkspaceProps,
} from '../components';
export type LinkInvitationReviewDeclinedProps = {
workspace: WorkspaceProps;
};
export default function LinkInvitationReviewDeclined(
props: LinkInvitationReviewDeclinedProps
) {
const { workspace } = props;
return (
<Template>
<Title>Request declined</Title>
<Content>
<P>
Your request to join <Workspace {...workspace} /> has been declined by
the workspace admin.
</P>
</Content>
</Template>
);
}
LinkInvitationReviewDeclined.PreviewProps = {
workspace: TEST_WORKSPACE,
};
@@ -0,0 +1,45 @@
import { TEST_USER, TEST_WORKSPACE } from '../common';
import {
Button,
Content,
P,
Template,
Title,
User,
type UserProps,
Workspace,
type WorkspaceProps,
} from '../components';
export type LinkInvitationReviewRequestProps = {
workspace: WorkspaceProps;
user: UserProps;
url: string;
};
export default function LinkInvitationReviewRequest(
props: LinkInvitationReviewRequestProps
) {
const { workspace, user, url } = props;
return (
<Template>
<Title>
Request to join <Workspace {...workspace} size={24} />
</Title>
<Content>
<P>
<User {...user} /> has requested to join <Workspace {...workspace} />.
<br />
As a workspace owner/admin, you can approve or decline this request.
</P>
<Button href={url}>Review request</Button>
</Content>
</Template>
);
}
LinkInvitationReviewRequest.PreviewProps = {
workspace: TEST_WORKSPACE,
user: TEST_USER,
url: 'https://app.affine.pro',
};