feat: copy signing link from avatar stack (#658)

This commit is contained in:
Ephraim Atta-Duncan
2023-11-17 05:12:47 +00:00
committed by GitHub
parent 06714a2aeb
commit 8adc44802f
4 changed files with 57 additions and 33 deletions

View File

@ -6,8 +6,8 @@ import { Loader } from 'lucide-react';
import { useSession } from 'next-auth/react'; import { useSession } from 'next-auth/react';
import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params'; import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params';
import { FindResultSet } from '@documenso/lib/types/find-result-set'; import type { FindResultSet } from '@documenso/lib/types/find-result-set';
import { Document, Recipient, User } from '@documenso/prisma/client'; import type { Document, Recipient, User } from '@documenso/prisma/client';
import { DataTable } from '@documenso/ui/primitives/data-table'; import { DataTable } from '@documenso/ui/primitives/data-table';
import { DataTablePagination } from '@documenso/ui/primitives/data-table-pagination'; import { DataTablePagination } from '@documenso/ui/primitives/data-table-pagination';

View File

@ -0,0 +1,46 @@
'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 { recipientAbbreviation } from '@documenso/lib/utils/recipient-formatter';
import type { Recipient } from '@documenso/prisma/client';
import { useToast } from '@documenso/ui/primitives/use-toast';
import { StackAvatar } from './stack-avatar';
export type AvatarWithRecipientProps = {
recipient: Recipient;
};
export function AvatarWithRecipient({ recipient }: AvatarWithRecipientProps) {
const [, copy] = useCopyToClipboard();
const { toast } = useToast();
const onRecipientClick = () => {
void copy(`${process.env.NEXT_PUBLIC_WEBAPP_URL}/sign/${recipient.token}`).then(() => {
toast({
title: 'Copied to clipboard',
description: 'The signing link has been copied to your clipboard.',
});
});
};
return (
<div className="my-1 flex cursor-pointer items-center gap-2" onClick={onRecipientClick}>
<StackAvatar
first={true}
key={recipient.id}
type={getRecipientType(recipient)}
fallbackText={recipientAbbreviation(recipient)}
/>
<span
className="text-muted-foreground text-sm hover:underline"
title="Click to copy signing link for sending to recipient"
>
{recipient.email}
</span>
</div>
);
}

View File

@ -1,6 +1,6 @@
import { getRecipientType } from '@documenso/lib/client-only/recipient-type'; import { getRecipientType } from '@documenso/lib/client-only/recipient-type';
import { recipientAbbreviation } from '@documenso/lib/utils/recipient-formatter'; import { recipientAbbreviation } from '@documenso/lib/utils/recipient-formatter';
import { Recipient } from '@documenso/prisma/client'; import type { Recipient } from '@documenso/prisma/client';
import { import {
Tooltip, Tooltip,
TooltipContent, TooltipContent,
@ -8,6 +8,7 @@ import {
TooltipTrigger, TooltipTrigger,
} from '@documenso/ui/primitives/tooltip'; } from '@documenso/ui/primitives/tooltip';
import { AvatarWithRecipient } from './avatar-with-recipient';
import { StackAvatar } from './stack-avatar'; import { StackAvatar } from './stack-avatar';
import { StackAvatars } from './stack-avatars'; import { StackAvatars } from './stack-avatars';
@ -85,15 +86,7 @@ export const StackAvatarsWithTooltip = ({
<div> <div>
<h1 className="text-base font-medium">Opened</h1> <h1 className="text-base font-medium">Opened</h1>
{openedRecipients.map((recipient: Recipient) => ( {openedRecipients.map((recipient: Recipient) => (
<div key={recipient.id} className="my-1 flex items-center gap-2"> <AvatarWithRecipient key={recipient.id} recipient={recipient} />
<StackAvatar
first={true}
key={recipient.id}
type={getRecipientType(recipient)}
fallbackText={recipientAbbreviation(recipient)}
/>
<span className="text-muted-foreground text-sm">{recipient.email}</span>
</div>
))} ))}
</div> </div>
)} )}
@ -102,15 +95,7 @@ export const StackAvatarsWithTooltip = ({
<div> <div>
<h1 className="text-base font-medium">Uncompleted</h1> <h1 className="text-base font-medium">Uncompleted</h1>
{uncompletedRecipients.map((recipient: Recipient) => ( {uncompletedRecipients.map((recipient: Recipient) => (
<div key={recipient.id} className="my-1 flex items-center gap-2"> <AvatarWithRecipient key={recipient.id} recipient={recipient} />
<StackAvatar
first={true}
key={recipient.id}
type={getRecipientType(recipient)}
fallbackText={recipientAbbreviation(recipient)}
/>
<span className="text-muted-foreground text-sm">{recipient.email}</span>
</div>
))} ))}
</div> </div>
)} )}

View File

@ -2,10 +2,11 @@ import { DateTime } from 'luxon';
import { P, match } from 'ts-pattern'; import { P, match } from 'ts-pattern';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import { Document, Prisma, SigningStatus } from '@documenso/prisma/client'; import type { Document, Prisma } from '@documenso/prisma/client';
import { SigningStatus } from '@documenso/prisma/client';
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status'; import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
import { FindResultSet } from '../../types/find-result-set'; import type { FindResultSet } from '../../types/find-result-set';
export interface FindDocumentsOptions { export interface FindDocumentsOptions {
userId: number; userId: number;
@ -160,19 +161,11 @@ export const findDocuments = async ({
}), }),
]); ]);
const maskedData = data.map((doc) => ({
...doc,
Recipient: doc.Recipient.map((recipient) => ({
...recipient,
token: recipient.email === user.email ? recipient.token : '',
})),
}));
return { return {
data: maskedData, data,
count, count,
currentPage: Math.max(page, 1), currentPage: Math.max(page, 1),
perPage, perPage,
totalPages: Math.ceil(count / perPage), totalPages: Math.ceil(count / perPage),
} satisfies FindResultSet<typeof maskedData>; } satisfies FindResultSet<typeof data>;
}; };