From b2e916378d33ebdf1d928e804471d3419c1e3b51 Mon Sep 17 00:00:00 2001 From: Ephraim Atta-Duncan Date: Mon, 25 Sep 2023 11:15:31 +0000 Subject: [PATCH 1/4] feat: add dropdown to tweet or copy signing link --- .../sign/[token]/complete/share-button.tsx | 68 +++++++++++++++---- package-lock.json | 11 ++- 2 files changed, 65 insertions(+), 14 deletions(-) diff --git a/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx b/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx index c13b8a7ab..b7ecde242 100644 --- a/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx +++ b/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx @@ -2,10 +2,16 @@ import { HTMLAttributes } from 'react'; -import { Share } from 'lucide-react'; +import { Copy, Share, Twitter } from 'lucide-react'; import { trpc } from '@documenso/trpc/react'; import { Button } from '@documenso/ui/primitives/button'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from '@documenso/ui/primitives/dropdown-menu'; import { useToast } from '@documenso/ui/primitives/use-toast'; import { useCopyToClipboard } from '~/hooks/use-copy-to-clipboard'; @@ -15,6 +21,12 @@ export type ShareButtonProps = HTMLAttributes & { documentId: number; }; +const generateTwitterIntent = (text: string, shareUrl: string) => { + return `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}%0A${encodeURIComponent( + shareUrl, + )}`; +}; + export const ShareButton = ({ token, documentId }: ShareButtonProps) => { const { toast } = useToast(); const [, copyToClipboard] = useCopyToClipboard(); @@ -22,7 +34,7 @@ export const ShareButton = ({ token, documentId }: ShareButtonProps) => { const { mutateAsync: createOrGetShareLink, isLoading } = trpc.shareLink.createOrGetShareLink.useMutation(); - const onShareClick = async () => { + const onCopyClick = async () => { const { slug } = await createOrGetShareLink({ token: token, documentId, @@ -36,16 +48,48 @@ export const ShareButton = ({ token, documentId }: ShareButtonProps) => { }); }; + const onTweetClick = async () => { + const { slug } = await createOrGetShareLink({ + token: token, + documentId, + }); + + window.open( + generateTwitterIntent( + 'I just signed a document with @documenso. Check it out!', + `${window.location.origin}/share/${slug}`, + ), + '_blank', + ); + }; + return ( - + + + + + + +
+ + Copy Link +
+
+ +
+ + Tweet +
+
+
+
); }; diff --git a/package-lock.json b/package-lock.json index 451b7c2ec..5cf8c38f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19809,6 +19809,7 @@ "@aws-sdk/signature-v4-crt": "^3.410.0", "@documenso/email": "*", "@documenso/prisma": "*", + "@documenso/signing": "*", "@next-auth/prisma-adapter": "1.0.7", "@pdf-lib/fontkit": "^1.1.1", "@scure/base": "^1.1.3", @@ -19862,17 +19863,23 @@ "packages/signing": { "name": "@documenso/signing", "version": "1.0.0", - "license": "MIT", + "license": "AGPLv3", "dependencies": { "@documenso/tsconfig": "*", "node-forge": "^1.3.1", "node-signpdf": "^2.0.0", - "pdf-lib": "^1.17.1" + "pdf-lib": "^1.17.1", + "ts-pattern": "^5.0.5" }, "devDependencies": { "@types/node-forge": "^1.3.4" } }, + "packages/signing/node_modules/ts-pattern": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.0.5.tgz", + "integrity": "sha512-tL0w8U/pgaacOmkb9fRlYzWEUDCfVjjv9dD4wHTgZ61MjhuMt46VNWTG747NqW6vRzoWIKABVhFSOJ82FvXrfA==" + }, "packages/tailwind-config": { "name": "@documenso/tailwind-config", "version": "0.0.0", From 78498793fa565a16924ae24c02d1d15a65ff13d9 Mon Sep 17 00:00:00 2001 From: Ephraim Atta-Duncan Date: Mon, 25 Sep 2023 11:21:39 +0000 Subject: [PATCH 2/4] chore: refactor function --- .../app/(signing)/sign/[token]/complete/share-button.tsx | 7 +------ packages/lib/universal/generate-twitter-intent.ts | 5 +++++ 2 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 packages/lib/universal/generate-twitter-intent.ts diff --git a/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx b/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx index b7ecde242..a589c65dd 100644 --- a/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx +++ b/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx @@ -4,6 +4,7 @@ import { HTMLAttributes } from 'react'; import { Copy, Share, Twitter } from 'lucide-react'; +import { generateTwitterIntent } from '@documenso/lib/universal/generate-twitter-intent'; import { trpc } from '@documenso/trpc/react'; import { Button } from '@documenso/ui/primitives/button'; import { @@ -21,12 +22,6 @@ export type ShareButtonProps = HTMLAttributes & { documentId: number; }; -const generateTwitterIntent = (text: string, shareUrl: string) => { - return `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}%0A${encodeURIComponent( - shareUrl, - )}`; -}; - export const ShareButton = ({ token, documentId }: ShareButtonProps) => { const { toast } = useToast(); const [, copyToClipboard] = useCopyToClipboard(); diff --git a/packages/lib/universal/generate-twitter-intent.ts b/packages/lib/universal/generate-twitter-intent.ts new file mode 100644 index 000000000..6ef95dd06 --- /dev/null +++ b/packages/lib/universal/generate-twitter-intent.ts @@ -0,0 +1,5 @@ +export const generateTwitterIntent = (text: string, shareUrl: string) => { + return `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}%0A${encodeURIComponent( + shareUrl, + )}`; +}; From e4b6d42672baae8019016a53dd615c77cff928d3 Mon Sep 17 00:00:00 2001 From: Mythie Date: Tue, 26 Sep 2023 15:56:11 +1000 Subject: [PATCH 3/4] fix: styling updates --- .../sign/[token]/complete/share-button.tsx | 120 +++++++++++++----- .../lib/universal/generate-twitter-intent.ts | 6 +- 2 files changed, 91 insertions(+), 35 deletions(-) diff --git a/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx b/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx index a589c65dd..bd69de316 100644 --- a/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx +++ b/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx @@ -1,6 +1,6 @@ 'use client'; -import { HTMLAttributes } from 'react'; +import { HTMLAttributes, useState } from 'react'; import { Copy, Share, Twitter } from 'lucide-react'; @@ -8,11 +8,13 @@ import { generateTwitterIntent } from '@documenso/lib/universal/generate-twitter import { trpc } from '@documenso/trpc/react'; import { Button } from '@documenso/ui/primitives/button'; import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from '@documenso/ui/primitives/dropdown-menu'; + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '@documenso/ui/primitives/dialog'; import { useToast } from '@documenso/ui/primitives/use-toast'; import { useCopyToClipboard } from '~/hooks/use-copy-to-clipboard'; @@ -26,14 +28,36 @@ export const ShareButton = ({ token, documentId }: ShareButtonProps) => { const { toast } = useToast(); const [, copyToClipboard] = useCopyToClipboard(); - const { mutateAsync: createOrGetShareLink, isLoading } = - trpc.shareLink.createOrGetShareLink.useMutation(); + const [isOpen, setIsOpen] = useState(false); + + const { + mutateAsync: createOrGetShareLink, + data: shareLink, + isLoading, + } = trpc.shareLink.createOrGetShareLink.useMutation(); + + const onOpenChange = (nextOpen: boolean) => { + if (nextOpen) { + void createOrGetShareLink({ + token, + documentId, + }); + } + + setIsOpen(nextOpen); + }; const onCopyClick = async () => { - const { slug } = await createOrGetShareLink({ - token: token, - documentId, - }); + let { slug = '' } = shareLink || {}; + + if (!slug) { + const result = await createOrGetShareLink({ + token, + documentId, + }); + + slug = result.slug; + } await copyToClipboard(`${window.location.origin}/share/${slug}`).catch(() => null); @@ -41,26 +65,36 @@ export const ShareButton = ({ token, documentId }: ShareButtonProps) => { title: 'Copied to clipboard', description: 'The sharing link has been copied to your clipboard.', }); + + setIsOpen(false); }; const onTweetClick = async () => { - const { slug } = await createOrGetShareLink({ - token: token, - documentId, - }); + let { slug = '' } = shareLink || {}; + + if (!slug) { + const result = await createOrGetShareLink({ + token, + documentId, + }); + + slug = result.slug; + } window.open( generateTwitterIntent( - 'I just signed a document with @documenso. Check it out!', + `I just ${token ? 'signed' : 'sent'} a document with @documenso. Check it out!`, `${window.location.origin}/share/${slug}`, ), '_blank', ); + + setIsOpen(false); }; return ( - - + + - - - -
- - Copy Link + + + + + Share + + Share your signing experience! + + +
+
+ I just signed a document with{' '} + @documenso + . Check it out! + + + {window.location.origin}/share/{shareLink?.slug || '...'} +
- - -
- + + + +
+
+ Or +
- - - + + +
+ + ); }; diff --git a/packages/lib/universal/generate-twitter-intent.ts b/packages/lib/universal/generate-twitter-intent.ts index 6ef95dd06..29774fb32 100644 --- a/packages/lib/universal/generate-twitter-intent.ts +++ b/packages/lib/universal/generate-twitter-intent.ts @@ -1,5 +1,5 @@ export const generateTwitterIntent = (text: string, shareUrl: string) => { - return `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}%0A${encodeURIComponent( - shareUrl, - )}`; + return `https://twitter.com/intent/tweet?text=${encodeURIComponent( + text, + )}%0A%0A${encodeURIComponent(shareUrl)}`; }; From 584d5bd8ead962e78d4374ee0f80e3d0520d20ae Mon Sep 17 00:00:00 2001 From: Mythie Date: Tue, 26 Sep 2023 15:58:43 +1000 Subject: [PATCH 4/4] fix: update share preview --- .../src/app/(signing)/sign/[token]/complete/share-button.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx b/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx index bd69de316..f4476ade8 100644 --- a/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx +++ b/apps/web/src/app/(signing)/sign/[token]/complete/share-button.tsx @@ -115,7 +115,7 @@ export const ShareButton = ({ token, documentId }: ShareButtonProps) => {
- I just signed a document with{' '} + I just {token ? 'signed' : 'sent'} a document with{' '} @documenso . Check it out!