feat: add page title translations (#2629)

This commit is contained in:
David Nguyen
2026-03-19 15:44:53 +11:00
committed by GitHub
parent 4f8132be61
commit e87aa29823
53 changed files with 761 additions and 121 deletions
@@ -1,5 +1,6 @@
import { useEffect, useMemo, useState } from 'react';
import { msg } from '@lingui/core/macro';
import { Trans } from '@lingui/react/macro';
import { EnvelopeType } from '@prisma/client';
import { FolderType, OrganisationType } from '@prisma/client';
@@ -38,7 +39,7 @@ import { useCurrentTeam } from '~/providers/team';
import { appMetaTags } from '~/utils/meta';
export function meta() {
return appMetaTags('Documents');
return appMetaTags(msg`Documents`);
}
const ZSearchParamsSchema = ZFindDocumentsInternalRequestSchema.pick({
@@ -1,5 +1,6 @@
import { useState } from 'react';
import { msg } from '@lingui/core/macro';
import { Trans, useLingui } from '@lingui/react/macro';
import { FolderIcon, HomeIcon, Loader2, SearchIcon } from 'lucide-react';
import { Link, useSearchParams } from 'react-router';
@@ -19,7 +20,7 @@ import { useCurrentTeam } from '~/providers/team';
import { appMetaTags } from '~/utils/meta';
export function meta() {
return appMetaTags('Documents');
return appMetaTags(msg`Documents`);
}
export default function DocumentsFoldersPage() {
@@ -24,7 +24,7 @@ import { appMetaTags } from '~/utils/meta';
import type { Route } from './+types/settings._layout';
export function meta() {
return appMetaTags('Team Settings');
return appMetaTags(msg`Team Settings`);
}
export async function loader({ request, params }: Route.LoaderArgs) {
@@ -1,3 +1,4 @@
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react/macro';
import { Loader } from 'lucide-react';
@@ -14,7 +15,7 @@ import { useCurrentTeam } from '~/providers/team';
import { appMetaTags } from '~/utils/meta';
export function meta() {
return appMetaTags('Branding Preferences');
return appMetaTags(msg`Branding Preferences`);
}
export default function TeamsSettingsPage() {
@@ -69,7 +70,7 @@ export default function TeamsSettingsPage() {
if (isLoadingTeam || !teamWithSettings) {
return (
<div className="flex items-center justify-center rounded-lg py-32">
<Loader className="text-muted-foreground h-6 w-6 animate-spin" />
<Loader className="h-6 w-6 animate-spin text-muted-foreground" />
</div>
);
}
@@ -1,3 +1,4 @@
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react/macro';
import { Loader } from 'lucide-react';
import { useLoaderData } from 'react-router';
@@ -16,7 +17,7 @@ import { useCurrentTeam } from '~/providers/team';
import { appMetaTags } from '~/utils/meta';
export function meta() {
return appMetaTags('Document Preferences');
return appMetaTags(msg`Document Preferences`);
}
export const loader = () => {
@@ -1,3 +1,4 @@
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react/macro';
import { trpc } from '@documenso/trpc/react';
@@ -13,7 +14,7 @@ import { useCurrentTeam } from '~/providers/team';
import { appMetaTags } from '~/utils/meta';
export function meta() {
return appMetaTags('Settings');
return appMetaTags(msg`Settings`);
}
export default function TeamEmailSettingsGeneral() {
@@ -1,5 +1,6 @@
import { useEffect, useMemo, useState } from 'react';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react/macro';
import { Trans } from '@lingui/react/macro';
import { type TemplateDirectLink, TemplateType } from '@prisma/client';
@@ -31,7 +32,7 @@ type DirectTemplate = FindTemplateRow & {
};
export function meta() {
return appMetaTags('Public Profile');
return appMetaTags(msg`Public Profile`);
}
// Todo: This can be optimized.
@@ -1,3 +1,4 @@
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { TeamMemberRole } from '@prisma/client';
@@ -15,7 +16,7 @@ import { useOptionalCurrentTeam } from '~/providers/team';
import { appMetaTags } from '~/utils/meta';
export function meta() {
return appMetaTags('API Tokens');
return appMetaTags(msg`API Tokens`);
}
export default function ApiTokensPage() {
@@ -70,7 +71,7 @@ export default function ApiTokensPage() {
{tokens && tokens.length === 0 && (
<div className="mb-4">
<p className="text-muted-foreground mt-2 text-sm italic">
<p className="mt-2 text-sm italic text-muted-foreground">
<Trans>Your tokens will be shown here once you create them.</Trans>
</p>
</div>
@@ -79,24 +80,24 @@ export default function ApiTokensPage() {
{tokens && tokens.length > 0 && (
<div className="mt-4 flex max-w-xl flex-col gap-y-4">
{tokens.map((token) => (
<div key={token.id} className="border-border rounded-lg border p-4">
<div key={token.id} className="rounded-lg border border-border p-4">
<div className="flex items-center justify-between gap-x-4">
<div>
<h5 className="text-base">{token.name}</h5>
<p className="text-muted-foreground mt-2 text-xs">
<p className="mt-2 text-xs text-muted-foreground">
<Trans>
Created on {i18n.date(token.createdAt, DateTime.DATETIME_FULL)}
</Trans>
</p>
{token.expires ? (
<p className="text-muted-foreground mt-1 text-xs">
<p className="mt-1 text-xs text-muted-foreground">
<Trans>
Expires on {i18n.date(token.expires, DateTime.DATETIME_FULL)}
</Trans>
</p>
) : (
<p className="text-muted-foreground mt-1 text-xs">
<p className="mt-1 text-xs text-muted-foreground">
<Trans>Token doesn't have an expiration date</Trans>
</p>
)}
@@ -55,7 +55,7 @@ const WebhookSearchParamsSchema = ZUrlSearchParamsSchema.extend({
});
export function meta() {
return appMetaTags('Webhooks');
return appMetaTags(msg`Webhooks`);
}
export default function WebhookPage({ params }: Route.ComponentProps) {
@@ -151,10 +151,10 @@ export default function WebhookPage({ params }: Route.ComponentProps) {
accessorKey: 'event',
cell: ({ row }) => (
<div>
<p className="text-foreground text-sm font-semibold">
<p className="text-sm font-semibold text-foreground">
{toFriendlyWebhookEventName(row.original.event)}
</p>
<p className="text-muted-foreground text-xs">{row.original.id}</p>
<p className="text-xs text-muted-foreground">{row.original.id}</p>
</div>
),
},
@@ -276,17 +276,17 @@ export default function WebhookPage({ params }: Route.ComponentProps) {
<Tabs value={parsedSearchParams.status || ''} className="flex-shrink-0">
<TabsList>
<TabsTrigger className="hover:text-foreground min-w-[60px]" value="" asChild>
<TabsTrigger className="min-w-[60px] hover:text-foreground" value="" asChild>
<Link to={getTabHref('')}>
<Trans>All</Trans>
</Link>
</TabsTrigger>
<TabsTrigger className="hover:text-foreground min-w-[60px]" value="SUCCESS" asChild>
<TabsTrigger className="min-w-[60px] hover:text-foreground" value="SUCCESS" asChild>
<Link to={getTabHref(WebhookCallStatus.SUCCESS)}>
<Trans>Success</Trans>
</Link>
</TabsTrigger>
<TabsTrigger className="hover:text-foreground min-w-[60px]" value="FAILED" asChild>
<TabsTrigger className="min-w-[60px] hover:text-foreground" value="FAILED" asChild>
<Link to={getTabHref(WebhookCallStatus.FAILED)}>
<Trans>Failed</Trans>
</Link>
@@ -375,7 +375,7 @@ const WebhookEventCombobox = () => {
return (
<MultiSelectCombobox
emptySelectionPlaceholder={
<p className="text-muted-foreground font-normal">
<p className="font-normal text-muted-foreground">
<Trans>
<span className="text-muted-foreground/70">Events:</span> All
</Trans>
@@ -4,25 +4,13 @@ import { msg } from '@lingui/core/macro';
import { Plural, useLingui } from '@lingui/react/macro';
import { Trans } from '@lingui/react/macro';
import type { Webhook } from '@prisma/client';
import {
CheckCircle2Icon,
EditIcon,
Loader,
MoreHorizontalIcon,
ScrollTextIcon,
Trash2Icon,
XCircleIcon,
} from 'lucide-react';
import { DateTime } from 'luxon';
import { EditIcon, Loader, MoreHorizontalIcon, ScrollTextIcon, Trash2Icon } from 'lucide-react';
import { Link } from 'react-router';
import { toFriendlyWebhookEventName } from '@documenso/lib/universal/webhook/to-friendly-webhook-event-name';
import { trpc } from '@documenso/trpc/react';
import { cn } from '@documenso/ui/lib/utils';
import { Badge } from '@documenso/ui/primitives/badge';
import { Button } from '@documenso/ui/primitives/button';
import { DataTable, type DataTableColumnDef } from '@documenso/ui/primitives/data-table';
import { DataTablePagination } from '@documenso/ui/primitives/data-table-pagination';
import {
DropdownMenu,
DropdownMenuContent,
@@ -41,7 +29,7 @@ import { useCurrentTeam } from '~/providers/team';
import { appMetaTags } from '~/utils/meta';
export function meta() {
return appMetaTags('Webhooks');
return appMetaTags(msg`Webhooks`);
}
export default function WebhookPage() {
@@ -64,9 +52,9 @@ export default function WebhookPage() {
header: t`Webhook`,
cell: ({ row }) => (
<Link to={`/t/${team.url}/settings/webhooks/${row.original.id}`}>
<p className="text-muted-foreground text-xs">{row.original.id}</p>
<p className="text-xs text-muted-foreground">{row.original.id}</p>
<p
className="text-foreground max-w-sm truncate text-xs font-semibold"
className="max-w-sm truncate text-xs font-semibold text-foreground"
title={row.original.webhookUrl}
>
{row.original.webhookUrl}
@@ -130,7 +118,7 @@ export default function WebhookPage() {
enable: isError,
}}
emptyState={
<div className="text-muted-foreground/60 flex h-60 flex-col items-center justify-center gap-y-4">
<div className="flex h-60 flex-col items-center justify-center gap-y-4 text-muted-foreground/60">
<p>
<Trans>
You have no webhooks yet. Your webhooks will be shown here once you create them.
@@ -172,7 +160,7 @@ const WebhookTableActionDropdown = ({ webhook }: { webhook: Webhook }) => {
return (
<DropdownMenu>
<DropdownMenuTrigger data-testid="webhook-table-action-btn">
<MoreHorizontalIcon className="text-muted-foreground h-5 w-5" />
<MoreHorizontalIcon className="h-5 w-5 text-muted-foreground" />
</DropdownMenuTrigger>
<DropdownMenuContent align="end" forceMount>
@@ -1,5 +1,6 @@
import { useMemo, useState } from 'react';
import { msg } from '@lingui/core/macro';
import { Trans } from '@lingui/react/macro';
import { EnvelopeType, OrganisationType } from '@prisma/client';
import { Bird } from 'lucide-react';
@@ -30,7 +31,7 @@ const TEMPLATE_VIEWS = ['team', 'organisation'] as const;
type TemplateView = (typeof TEMPLATE_VIEWS)[number];
export function meta() {
return appMetaTags('Templates');
return appMetaTags(msg`Templates`);
}
export default function TemplatesPage() {
@@ -1,5 +1,6 @@
import { useState } from 'react';
import { msg } from '@lingui/core/macro';
import { Trans, useLingui } from '@lingui/react/macro';
import { FolderIcon, HomeIcon, Loader2, SearchIcon } from 'lucide-react';
import { Link, useSearchParams } from 'react-router';
@@ -19,7 +20,7 @@ import { useCurrentTeam } from '~/providers/team';
import { appMetaTags } from '~/utils/meta';
export function meta() {
return appMetaTags('Templates');
return appMetaTags(msg`Templates`);
}
export default function TemplatesFoldersPage() {