## Description Currently users can sign and complete draft documents, which will result in a completed document in an invalid state. ## Changes Made - Prevent recipients from inserting or uninserting fields for draft documents - Prevent recipients from completing draft documents - Remove ability to copy signing tokens unless document is pending <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Enhanced document status visibility and control across various components in the application. Users can now see and interact with document statuses more dynamically in views like `DocumentPageView`, `DocumentEditPageView`, and `DocumentsDataTable`. - Improved document signing process with updated status checks, ensuring actions like signing, completing, and removing fields are only available under appropriate document statuses. - **Bug Fixes** - Adjusted document status validation logic in server-side operations to prevent actions on incorrectly stated documents, enhancing the overall security and functionality of document processing. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
69 lines
2.2 KiB
TypeScript
69 lines
2.2 KiB
TypeScript
'use client';
|
|
|
|
import React from 'react';
|
|
|
|
import { useCopyToClipboard } from '@documenso/lib/client-only/hooks/use-copy-to-clipboard';
|
|
import { getRecipientType } from '@documenso/lib/client-only/recipient-type';
|
|
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
|
import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient-roles';
|
|
import { recipientAbbreviation } from '@documenso/lib/utils/recipient-formatter';
|
|
import type { Recipient } from '@documenso/prisma/client';
|
|
import { DocumentStatus } from '@documenso/prisma/client';
|
|
import { cn } from '@documenso/ui/lib/utils';
|
|
import { useToast } from '@documenso/ui/primitives/use-toast';
|
|
|
|
import { StackAvatar } from './stack-avatar';
|
|
|
|
export type AvatarWithRecipientProps = {
|
|
recipient: Recipient;
|
|
documentStatus: DocumentStatus;
|
|
};
|
|
|
|
export function AvatarWithRecipient({ recipient, documentStatus }: AvatarWithRecipientProps) {
|
|
const [, copy] = useCopyToClipboard();
|
|
const { toast } = useToast();
|
|
|
|
const signingToken = documentStatus === DocumentStatus.PENDING ? recipient.token : null;
|
|
|
|
const onRecipientClick = () => {
|
|
if (!signingToken) {
|
|
return;
|
|
}
|
|
|
|
void copy(`${NEXT_PUBLIC_WEBAPP_URL()}/sign/${signingToken}`).then(() => {
|
|
toast({
|
|
title: 'Copied to clipboard',
|
|
description: 'The signing link has been copied to your clipboard.',
|
|
});
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div
|
|
className={cn('my-1 flex items-center gap-2', {
|
|
'cursor-pointer hover:underline': signingToken,
|
|
})}
|
|
role={signingToken ? 'button' : undefined}
|
|
title={signingToken ? 'Click to copy signing link for sending to recipient' : undefined}
|
|
onClick={onRecipientClick}
|
|
>
|
|
<StackAvatar
|
|
first={true}
|
|
key={recipient.id}
|
|
type={getRecipientType(recipient)}
|
|
fallbackText={recipientAbbreviation(recipient)}
|
|
/>
|
|
|
|
<div
|
|
className="text-muted-foreground text-sm"
|
|
title={signingToken ? 'Click to copy signing link for sending to recipient' : undefined}
|
|
>
|
|
<p>{recipient.email}</p>
|
|
<p className="text-muted-foreground/70 text-xs">
|
|
{RECIPIENT_ROLES_DESCRIPTION[recipient.role].roleName}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|