add new emails in suspended workspace cleaning job (#9834)

From: Felix from Twenty <noreply@yourdomain.com>
Subject: Action needed to prevent workspace deletion
<img width="400" alt="Screenshot 2025-01-24 at 16 31 35"
src="https://github.com/user-attachments/assets/8350a499-6815-4b00-a4fb-615b2a3b60e0"
/>


From: Felix from Twenty <noreply@yourdomain.com>
Subject: Your workspace has been deleted
<img width="456" alt="Screenshot 2025-01-24 at 16 33 15"
src="https://github.com/user-attachments/assets/7e392e7c-519c-4b38-ae8c-ab3c9dd72c24"
/>



closes [284](https://github.com/twentyhq/core-team-issues/issues/284) &
[285](https://github.com/twentyhq/core-team-issues/issues/285) - [parent
issue](https://github.com/twentyhq/core-team-issues/issues/179)

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
This commit is contained in:
Etienne
2025-01-24 18:37:06 +01:00
committed by GitHub
parent 07dec36976
commit aacbf11435
13 changed files with 186 additions and 494 deletions

View File

@ -1,48 +0,0 @@
import { BaseEmail } from 'src/components/BaseEmail';
import { CallToAction } from 'src/components/CallToAction';
import { HighlightedText } from 'src/components/HighlightedText';
import { MainText } from 'src/components/MainText';
import { Title } from 'src/components/Title';
type CleanInactiveWorkspaceEmailProps = {
daysLeft: number;
userName: string;
workspaceDisplayName: string;
};
export const CleanInactiveWorkspaceEmail = ({
daysLeft,
userName,
workspaceDisplayName,
}: CleanInactiveWorkspaceEmailProps) => {
const dayOrDays = daysLeft > 1 ? 'days' : 'day';
const remainingDays = daysLeft > 1 ? `${daysLeft} ` : '';
const helloString = userName?.length > 1 ? `Hello ${userName}` : 'Hello';
return (
<BaseEmail>
<Title value="Inactive Workspace 😴" />
<HighlightedText value={`${daysLeft} ${dayOrDays} left`} />
<MainText>
{helloString},
<br />
<br />
It appears that there has been a period of inactivity on your{' '}
<b>{workspaceDisplayName}</b> workspace.
<br />
<br />
Please note that the account is due for deactivation soon, and all
associated data within this workspace will be deleted.
<br />
<br />
No need for concern, though! Simply create or edit a record within the
next {remainingDays}
{dayOrDays} to retain access.
</MainText>
<CallToAction href="https://app.twenty.com" value="Connect to Twenty" />
</BaseEmail>
);
};
export default CleanInactiveWorkspaceEmail;

View File

@ -0,0 +1,41 @@
import { BaseEmail } from 'src/components/BaseEmail';
import { CallToAction } from 'src/components/CallToAction';
import { MainText } from 'src/components/MainText';
import { Title } from 'src/components/Title';
type CleanSuspendedWorkspaceEmailProps = {
inactiveDaysBeforeDelete: number;
userName: string;
workspaceDisplayName: string | undefined;
};
export const CleanSuspendedWorkspaceEmail = ({
inactiveDaysBeforeDelete,
userName,
workspaceDisplayName,
}: CleanSuspendedWorkspaceEmailProps) => {
const helloString = userName?.length > 1 ? `Hello ${userName}` : 'Hello';
return (
<BaseEmail width={333}>
<Title value="Deleted Workspace 🥺" />
<MainText>
{helloString},
<br />
<br />
Your workspace <b>{workspaceDisplayName}</b> has been deleted as your
subscription expired {inactiveDaysBeforeDelete} days ago.
<br />
<br />
All data in this workspace has been permanently deleted.
<br />
<br />
If you wish to use Twenty again, you can create a new workspace.
</MainText>
<CallToAction
href="https://app.twenty.com/"
value="Create a new workspace"
/>
</BaseEmail>
);
};

View File

@ -1,40 +0,0 @@
import { Column, Row, Section } from '@react-email/components';
import { BaseEmail } from 'src/components/BaseEmail';
import { MainText } from 'src/components/MainText';
import { Title } from 'src/components/Title';
type DeleteInactiveWorkspaceEmailData = {
daysSinceInactive: number;
workspaceId: string;
};
export const DeleteInactiveWorkspaceEmail = (
workspacesToDelete: DeleteInactiveWorkspaceEmailData[],
) => {
const minDaysSinceInactive = Math.min(
...workspacesToDelete.map(
(workspaceToDelete) => workspaceToDelete.daysSinceInactive,
),
);
return (
<BaseEmail width={350}>
<Title value="Dead Workspaces 😵 that should be deleted" />
<MainText>
List of <b>workspaceIds</b> inactive since at least{' '}
<b>{minDaysSinceInactive} days</b>:
<Section>
{workspacesToDelete.map((workspaceToDelete) => {
return (
<Row key={workspaceToDelete.workspaceId}>
<Column>{workspaceToDelete.workspaceId}</Column>
</Row>
);
})}
</Section>
</MainText>
</BaseEmail>
);
};
export default DeleteInactiveWorkspaceEmail;

View File

@ -0,0 +1,49 @@
import { BaseEmail } from 'src/components/BaseEmail';
import { CallToAction } from 'src/components/CallToAction';
import { MainText } from 'src/components/MainText';
import { Title } from 'src/components/Title';
type WarnSuspendedWorkspaceEmailProps = {
daysSinceInactive: number;
inactiveDaysBeforeDelete: number;
userName: string;
workspaceDisplayName: string | undefined;
};
export const WarnSuspendedWorkspaceEmail = ({
daysSinceInactive,
inactiveDaysBeforeDelete,
userName,
workspaceDisplayName,
}: WarnSuspendedWorkspaceEmailProps) => {
const daysLeft = inactiveDaysBeforeDelete - daysSinceInactive;
const dayOrDays = daysLeft > 1 ? 'days' : 'day';
const remainingDays = daysLeft > 0 ? `${daysLeft} ` : '';
const helloString = userName?.length > 1 ? `Hello ${userName}` : 'Hello';
return (
<BaseEmail width={333}>
<Title value="Suspended Workspace 😴" />
<MainText>
{helloString},
<br />
<br />
It appears that your workspace <b>{workspaceDisplayName}</b> has been
suspended for {daysSinceInactive} days.
<br />
<br />
The workspace will be deactivated in {remainingDays} {dayOrDays}, and
all its data will be deleted.
<br />
<br />
If you wish to continue using Twenty, please update your subscription
within the next {remainingDays} {dayOrDays}.
</MainText>
<CallToAction
href="https://app.twenty.com/settings/billing"
value="Update your subscription"
/>
</BaseEmail>
);
};

View File

@ -1,6 +1,6 @@
export * from './emails/clean-inactive-workspaces.email';
export * from './emails/delete-inactive-workspaces.email';
export * from './emails/clean-suspended-workspace.email';
export * from './emails/password-reset-link.email';
export * from './emails/password-update-notify.email';
export * from './emails/send-email-verification-link.email';
export * from './emails/send-invite-link.email';
export * from './emails/warn-suspended-workspace.email';