feat: signature rejection (#1472)

## Description

Adds support for rejecting a given document informing the document
owner.

Flows for resolving a rejection don't currently exist so it's up to the
document owner to reach out to the recipient and work out a way to move
forward via a new document or offline agreement.

## Related Issue


## Changes Made

- Added new rejection properties to the recipient schema
- Added API endpoints to support rejection
- Added email templates for notifying the document owner and recipient
- Added a dialog on the signing page to start the rejection flow.

## Testing Performed

- Manually tested the flow end to end
- Automated tests are planned
This commit is contained in:
Lucas Smith
2024-11-14 21:37:42 +11:00
committed by GitHub
parent f2439abbc9
commit 5398026b80
44 changed files with 1595 additions and 226 deletions

View File

@ -0,0 +1,70 @@
import { msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { Body, Container, Head, Html, Img, Preview, Section } from '../components';
import { useBranding } from '../providers/branding';
import { TemplateDocumentRejectionConfirmed } from '../template-components/template-document-rejection-confirmed';
import { TemplateFooter } from '../template-components/template-footer';
export type DocumentRejectionConfirmedEmailProps = {
recipientName: string;
documentName: string;
documentOwnerName: string;
reason: string;
assetBaseUrl?: string;
};
export function DocumentRejectionConfirmedEmail({
recipientName,
documentName,
documentOwnerName,
reason,
assetBaseUrl = 'http://localhost:3002',
}: DocumentRejectionConfirmedEmailProps) {
const { _ } = useLingui();
const branding = useBranding();
const previewText = _(msg`You have rejected the document '${documentName}'`);
const getAssetUrl = (path: string) => {
return new URL(path, assetBaseUrl).toString();
};
return (
<Html>
<Head />
<Preview>{previewText}</Preview>
<Body className="mx-auto my-auto bg-white font-sans">
<Section>
<Container className="mx-auto mb-2 mt-8 max-w-xl rounded-lg border border-solid border-slate-200 p-4 backdrop-blur-sm">
<Section>
{branding.brandingEnabled && branding.brandingLogo ? (
<Img src={branding.brandingLogo} alt="Branding Logo" className="mb-4 h-6" />
) : (
<Img
src={getAssetUrl('/static/logo.png')}
alt="Documenso Logo"
className="mb-4 h-6"
/>
)}
<TemplateDocumentRejectionConfirmed
recipientName={recipientName}
documentName={documentName}
documentOwnerName={documentOwnerName}
reason={reason}
/>
</Section>
</Container>
<Container className="mx-auto max-w-xl">
<TemplateFooter />
</Container>
</Section>
</Body>
</Html>
);
}
export default DocumentRejectionConfirmedEmail;