feat: web i18n (#1286)
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
import type { HTMLAttributes } from 'react';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Download } from 'lucide-react';
|
||||
|
||||
import { downloadPDF } from '@documenso/lib/client-only/download-pdf';
|
||||
@@ -24,9 +26,11 @@ export const DocumentDownloadButton = ({
|
||||
disabled,
|
||||
...props
|
||||
}: DownloadButtonProps) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const { _ } = useLingui();
|
||||
const { toast } = useToast();
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const onDownloadClick = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
@@ -43,8 +47,8 @@ export const DocumentDownloadButton = ({
|
||||
setIsLoading(false);
|
||||
|
||||
toast({
|
||||
title: 'Something went wrong',
|
||||
description: 'An error occurred while downloading your document.',
|
||||
title: _('Something went wrong'),
|
||||
description: _('An error occurred while downloading your document.'),
|
||||
variant: 'destructive',
|
||||
});
|
||||
}
|
||||
@@ -61,7 +65,7 @@ export const DocumentDownloadButton = ({
|
||||
{...props}
|
||||
>
|
||||
{!isLoading && <Download className="mr-2 h-5 w-5" />}
|
||||
Download
|
||||
<Trans>Download</Trans>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
import React, { forwardRef } from 'react';
|
||||
|
||||
import { Trans, msg } from '@lingui/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import type { SelectProps } from '@radix-ui/react-select';
|
||||
import { InfoIcon } from 'lucide-react';
|
||||
|
||||
@@ -17,24 +19,33 @@ import {
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@documenso/ui/primitives/tooltip';
|
||||
|
||||
export const DocumentGlobalAuthAccessSelect = forwardRef<HTMLButtonElement, SelectProps>(
|
||||
(props, ref) => (
|
||||
<Select {...props}>
|
||||
<SelectTrigger ref={ref} className="bg-background text-muted-foreground">
|
||||
<SelectValue data-testid="documentAccessSelectValue" placeholder="No restrictions" />
|
||||
</SelectTrigger>
|
||||
(props, ref) => {
|
||||
const { _ } = useLingui();
|
||||
|
||||
<SelectContent position="popper">
|
||||
{Object.values(DocumentAccessAuth).map((authType) => (
|
||||
<SelectItem key={authType} value={authType}>
|
||||
{DOCUMENT_AUTH_TYPES[authType].value}
|
||||
return (
|
||||
<Select {...props}>
|
||||
<SelectTrigger ref={ref} className="bg-background text-muted-foreground">
|
||||
<SelectValue
|
||||
data-testid="documentAccessSelectValue"
|
||||
placeholder={_(msg`No restrictions`)}
|
||||
/>
|
||||
</SelectTrigger>
|
||||
|
||||
<SelectContent position="popper">
|
||||
{Object.values(DocumentAccessAuth).map((authType) => (
|
||||
<SelectItem key={authType} value={authType}>
|
||||
{DOCUMENT_AUTH_TYPES[authType].value}
|
||||
</SelectItem>
|
||||
))}
|
||||
|
||||
{/* Note: -1 is remapped in the Zod schema to the required value. */}
|
||||
<SelectItem value={'-1'}>
|
||||
<Trans>No restrictions</Trans>
|
||||
</SelectItem>
|
||||
))}
|
||||
|
||||
{/* Note: -1 is remapped in the Zod schema to the required value. */}
|
||||
<SelectItem value={'-1'}>No restrictions</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
),
|
||||
</SelectContent>
|
||||
</Select>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
DocumentGlobalAuthAccessSelect.displayName = 'DocumentGlobalAuthAccessSelect';
|
||||
@@ -47,18 +58,26 @@ export const DocumentGlobalAuthAccessTooltip = () => (
|
||||
|
||||
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
|
||||
<h2>
|
||||
<strong>Document access</strong>
|
||||
<strong>
|
||||
<Trans>Document access</Trans>
|
||||
</strong>
|
||||
</h2>
|
||||
|
||||
<p>The authentication required for recipients to view the document.</p>
|
||||
<p>
|
||||
<Trans>The authentication required for recipients to view the document.</Trans>
|
||||
</p>
|
||||
|
||||
<ul className="ml-3.5 list-outside list-disc space-y-0.5 py-2">
|
||||
<li>
|
||||
<strong>Require account</strong> - The recipient must be signed in to view the document
|
||||
<Trans>
|
||||
<strong>Require account</strong> - The recipient must be signed in to view the document
|
||||
</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<strong>No restrictions</strong> - The document can be accessed directly by the URL sent
|
||||
to the recipient
|
||||
<Trans>
|
||||
<strong>No restrictions</strong> - The document can be accessed directly by the URL sent
|
||||
to the recipient
|
||||
</Trans>
|
||||
</li>
|
||||
</ul>
|
||||
</TooltipContent>
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
import React, { forwardRef } from 'react';
|
||||
|
||||
import { Trans, msg } from '@lingui/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import type { SelectProps } from '@radix-ui/react-select';
|
||||
import { InfoIcon } from 'lucide-react';
|
||||
|
||||
@@ -17,26 +19,36 @@ import {
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@documenso/ui/primitives/tooltip';
|
||||
|
||||
export const DocumentGlobalAuthActionSelect = forwardRef<HTMLButtonElement, SelectProps>(
|
||||
(props, ref) => (
|
||||
<Select {...props}>
|
||||
<SelectTrigger className="bg-background text-muted-foreground">
|
||||
<SelectValue ref={ref} data-testid="documentActionSelectValue" placeholder="No restrictions" />
|
||||
</SelectTrigger>
|
||||
(props, ref) => {
|
||||
const { _ } = useLingui();
|
||||
|
||||
<SelectContent position="popper">
|
||||
{Object.values(DocumentActionAuth)
|
||||
.filter((auth) => auth !== DocumentAuth.ACCOUNT)
|
||||
.map((authType) => (
|
||||
<SelectItem key={authType} value={authType}>
|
||||
{DOCUMENT_AUTH_TYPES[authType].value}
|
||||
</SelectItem>
|
||||
))}
|
||||
return (
|
||||
<Select {...props}>
|
||||
<SelectTrigger className="bg-background text-muted-foreground">
|
||||
<SelectValue
|
||||
ref={ref}
|
||||
data-testid="documentActionSelectValue"
|
||||
placeholder={_(msg`No restrictions`)}
|
||||
/>
|
||||
</SelectTrigger>
|
||||
|
||||
{/* Note: -1 is remapped in the Zod schema to the required value. */}
|
||||
<SelectItem value={'-1'}>No restrictions</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
),
|
||||
<SelectContent position="popper">
|
||||
{Object.values(DocumentActionAuth)
|
||||
.filter((auth) => auth !== DocumentAuth.ACCOUNT)
|
||||
.map((authType) => (
|
||||
<SelectItem key={authType} value={authType}>
|
||||
{DOCUMENT_AUTH_TYPES[authType].value}
|
||||
</SelectItem>
|
||||
))}
|
||||
|
||||
{/* Note: -1 is remapped in the Zod schema to the required value. */}
|
||||
<SelectItem value={'-1'}>
|
||||
<Trans>No restrictions</Trans>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
DocumentGlobalAuthActionSelect.displayName = 'DocumentGlobalAuthActionSelect';
|
||||
@@ -48,13 +60,19 @@ export const DocumentGlobalAuthActionTooltip = () => (
|
||||
</TooltipTrigger>
|
||||
|
||||
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
|
||||
<h2>Global recipient action authentication</h2>
|
||||
|
||||
<p>The authentication required for recipients to sign the signature field.</p>
|
||||
<h2>
|
||||
<Trans>Global recipient action authentication</Trans>
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
This can be overriden by setting the authentication requirements directly on each recipient
|
||||
in the next step.
|
||||
<Trans>The authentication required for recipients to sign the signature field.</Trans>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<Trans>
|
||||
This can be overriden by setting the authentication requirements directly on each
|
||||
recipient in the next step.
|
||||
</Trans>
|
||||
</p>
|
||||
|
||||
<ul className="ml-3.5 list-outside list-disc space-y-0.5 py-2">
|
||||
@@ -62,15 +80,21 @@ export const DocumentGlobalAuthActionTooltip = () => (
|
||||
<strong>Require account</strong> - The recipient must be signed in
|
||||
</li> */}
|
||||
<li>
|
||||
<strong>Require passkey</strong> - The recipient must have an account and passkey
|
||||
configured via their settings
|
||||
<Trans>
|
||||
<strong>Require passkey</strong> - The recipient must have an account and passkey
|
||||
configured via their settings
|
||||
</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Require 2FA</strong> - The recipient must have an account and 2FA enabled via
|
||||
their settings
|
||||
<Trans>
|
||||
<strong>Require 2FA</strong> - The recipient must have an account and 2FA enabled via
|
||||
their settings
|
||||
</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<strong>No restrictions</strong> - No authentication required
|
||||
<Trans>
|
||||
<strong>No restrictions</strong> - No authentication required
|
||||
</Trans>
|
||||
</li>
|
||||
</ul>
|
||||
</TooltipContent>
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { Trans } from '@lingui/macro';
|
||||
|
||||
export const DocumentSendEmailMessageHelper = () => {
|
||||
return (
|
||||
<div>
|
||||
<p className="text-muted-foreground text-sm">
|
||||
You can use the following variables in your message:
|
||||
<Trans>You can use the following variables in your message:</Trans>
|
||||
</p>
|
||||
|
||||
<ul className="mt-2 flex list-inside list-disc flex-col gap-y-2 text-sm">
|
||||
@@ -14,19 +16,19 @@ export const DocumentSendEmailMessageHelper = () => {
|
||||
<code className="text-muted-foreground bg-muted-foreground/20 rounded p-1 text-sm">
|
||||
{'{signer.name}'}
|
||||
</code>{' '}
|
||||
- The signer's name
|
||||
- <Trans>The signer's name</Trans>
|
||||
</li>
|
||||
<li className="text-muted-foreground">
|
||||
<code className="text-muted-foreground bg-muted-foreground/20 rounded p-1 text-sm">
|
||||
{'{signer.email}'}
|
||||
</code>{' '}
|
||||
- The signer's email
|
||||
- <Trans>The signer's email</Trans>
|
||||
</li>
|
||||
<li className="text-muted-foreground">
|
||||
<code className="text-muted-foreground bg-muted-foreground/20 rounded p-1 text-sm">
|
||||
{'{document.name}'}
|
||||
</code>{' '}
|
||||
- The document's name
|
||||
- <Trans>The document's name</Trans>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -3,15 +3,13 @@
|
||||
import type { HTMLAttributes } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { Trans, msg } from '@lingui/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Copy, Sparkles } from 'lucide-react';
|
||||
import { FaXTwitter } from 'react-icons/fa6';
|
||||
|
||||
import { useCopyShareLink } from '@documenso/lib/client-only/hooks/use-copy-share-link';
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import {
|
||||
TOAST_DOCUMENT_SHARE_ERROR,
|
||||
TOAST_DOCUMENT_SHARE_SUCCESS,
|
||||
} from '@documenso/lib/constants/toast';
|
||||
import { generateTwitterIntent } from '@documenso/lib/universal/generate-twitter-intent';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
|
||||
@@ -39,11 +37,22 @@ export const DocumentShareButton = ({
|
||||
className,
|
||||
trigger,
|
||||
}: DocumentShareButtonProps) => {
|
||||
const { _ } = useLingui();
|
||||
const { toast } = useToast();
|
||||
|
||||
const { copyShareLink, createAndCopyShareLink, isCopyingShareLink } = useCopyShareLink({
|
||||
onSuccess: () => toast(TOAST_DOCUMENT_SHARE_SUCCESS),
|
||||
onError: () => toast(TOAST_DOCUMENT_SHARE_ERROR),
|
||||
onSuccess: () =>
|
||||
toast({
|
||||
title: _(msg`Copied to clipboard`),
|
||||
description: _(msg`The sharing link has been copied to your clipboard.`),
|
||||
}),
|
||||
onError: () =>
|
||||
toast({
|
||||
title: _(msg`Something went wrong`),
|
||||
description: _(msg`The sharing link could not be created at this time. Please try again.`),
|
||||
variant: 'destructive',
|
||||
duration: 5000,
|
||||
}),
|
||||
});
|
||||
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
@@ -123,7 +132,7 @@ export const DocumentShareButton = ({
|
||||
loading={isLoading}
|
||||
>
|
||||
{!isLoading && <Sparkles className="mr-2 h-5 w-5" />}
|
||||
Share Signature Card
|
||||
<Trans>Share Signature Card</Trans>
|
||||
</Button>
|
||||
)}
|
||||
</DialogTrigger>
|
||||
|
||||
Reference in New Issue
Block a user