diff --git a/apps/web/src/components/(dashboard)/avatar/stack-avatar.tsx b/apps/web/src/components/(dashboard)/avatar/stack-avatar.tsx
index abf6d6074..7d19d9027 100644
--- a/apps/web/src/components/(dashboard)/avatar/stack-avatar.tsx
+++ b/apps/web/src/components/(dashboard)/avatar/stack-avatar.tsx
@@ -43,6 +43,10 @@ export const StackAvatar = ({ first, zIndex, fallbackText = '', type }: StackAva
case RecipientStatusType.REJECTED:
classes = 'bg-red-200 text-red-800';
break;
+ case RecipientStatusType.EXPIRED:
+ classes = 'bg-gray-200 text-gray-700';
+ break;
+
default:
break;
}
diff --git a/apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx b/apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx
index bccee558e..71b40bc4e 100644
--- a/apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx
+++ b/apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx
@@ -50,6 +50,10 @@ export const StackAvatarsWithTooltip = ({
(recipient) => getRecipientType(recipient) === RecipientStatusType.REJECTED,
);
+ const expiredRecipients = recipients.filter(
+ (recipient) => getRecipientType(recipient) === RecipientStatusType.EXPIRED,
+ );
+
const sortedRecipients = useMemo(() => {
const otherRecipients = recipients.filter(
(recipient) => getRecipientType(recipient) !== RecipientStatusType.REJECTED,
@@ -119,6 +123,30 @@ export const StackAvatarsWithTooltip = ({
)}
+ {expiredRecipients.length > 0 && (
+
+
+ Expired
+
+ {expiredRecipients.map((recipient: Recipient) => (
+
+
+
+
{recipient.email}
+
+ {_(RECIPIENT_ROLES_DESCRIPTION[recipient.role].roleName)}
+
+
+
+ ))}
+
+ )}
+
{waitingRecipients.length > 0 && (
diff --git a/packages/lib/client-only/recipient-type.ts b/packages/lib/client-only/recipient-type.ts
index 627765dff..661a14009 100644
--- a/packages/lib/client-only/recipient-type.ts
+++ b/packages/lib/client-only/recipient-type.ts
@@ -7,6 +7,7 @@ export enum RecipientStatusType {
WAITING = 'waiting',
UNSIGNED = 'unsigned',
REJECTED = 'rejected',
+ EXPIRED = 'expired',
}
export const getRecipientType = (recipient: Recipient) => {
@@ -36,6 +37,10 @@ export const getRecipientType = (recipient: Recipient) => {
return RecipientStatusType.WAITING;
}
+ if (recipient.signingStatus === SigningStatus.EXPIRED) {
+ return RecipientStatusType.EXPIRED;
+ }
+
return RecipientStatusType.UNSIGNED;
};
@@ -54,5 +59,9 @@ export const getExtraRecipientsType = (extraRecipients: Recipient[]) => {
return RecipientStatusType.WAITING;
}
+ if (types.includes(RecipientStatusType.EXPIRED)) {
+ return RecipientStatusType.EXPIRED;
+ }
+
return RecipientStatusType.COMPLETED;
};
diff --git a/packages/lib/server-only/document/complete-document-with-token.ts b/packages/lib/server-only/document/complete-document-with-token.ts
index 342ec5d56..81655b965 100644
--- a/packages/lib/server-only/document/complete-document-with-token.ts
+++ b/packages/lib/server-only/document/complete-document-with-token.ts
@@ -8,8 +8,8 @@ import {
RecipientRole,
SendStatus,
SigningStatus,
+ WebhookTriggerEvents,
} from '@documenso/prisma/client';
-import { WebhookTriggerEvents } from '@documenso/prisma/client';
import { jobs } from '../../jobs/client';
import type { TRecipientActionAuth } from '../../types/document-auth';