add admin/user i18n

This commit is contained in:
Lokowitz 2025-05-06 06:49:47 +00:00
parent e38941adf1
commit 4dd9f4736d
4 changed files with 40 additions and 28 deletions

View file

@ -285,5 +285,17 @@
"apiKeysDeleteConfirm": "Confirm Delete API Key",
"apiKeysDelete": "Delete API Key",
"apiKeysManage": "Manage API Keys",
"apiKeysDescription": "API keys are used to authenticate with the integration API"
"apiKeysDescription": "API keys are used to authenticate with the integration API",
"userTitle": "Manage All Users",
"userDescription": "View and manage all users in the system",
"userAbount": "About User Management",
"userAbountDescription": "This table displays all root user objects in the system. Each user may belong to multiple organizations. Removing a user from an organization does not delete their root user object - they will remain in the system. To completely remove a user from the system, you must delete their root user object using the delete action in this table.",
"userServer": "Server Users",
"userSearch": "Search server users...",
"userErrorDelete": "Error deleting user",
"userDeleteConfirm": "Confirm Delete User",
"userDeleteServer": "Delete User from Server",
"userMessageRemove": "The user will be removed from all organizations and be completely removed from the server.",
"userMessageConfirm": "To confirm, please type the name of the user below.",
"userQuestionRemove": "Are you sure you want to permanently delete {selectedUser} from the server?"
}

View file

@ -4,6 +4,7 @@ import {
ColumnDef,
} from "@tanstack/react-table";
import { DataTable } from "@app/components/ui/data-table";
import { useTranslations } from 'next-intl';
interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[];
@ -14,12 +15,15 @@ export function UsersDataTable<TData, TValue>({
columns,
data
}: DataTableProps<TData, TValue>) {
const t = useTranslations();
return (
<DataTable
columns={columns}
data={data}
title="Server Users"
searchPlaceholder="Search server users..."
title={t('userServer')}
searchPlaceholder={t('userSearch')}
searchColumn="email"
/>
);

View file

@ -11,6 +11,7 @@ import { toast } from "@app/hooks/useToast";
import { formatAxiosError } from "@app/lib/api";
import { createApiClient } from "@app/lib/api";
import { useEnvContext } from "@app/hooks/useEnvContext";
import { useTranslations } from 'next-intl';
export type GlobalUserRow = {
id: string;
@ -29,6 +30,7 @@ type Props = {
export default function UsersTable({ users }: Props) {
const router = useRouter();
const t = useTranslations();
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [selected, setSelected] = useState<GlobalUserRow | null>(null);
@ -42,8 +44,8 @@ export default function UsersTable({ users }: Props) {
console.error("Error deleting user", e);
toast({
variant: "destructive",
title: "Error deleting user",
description: formatAxiosError(e, "Error deleting user")
title: t('userErrorDelete'),
description: formatAxiosError(e, t('userErrorDelete'))
});
})
.then(() => {
@ -82,7 +84,7 @@ export default function UsersTable({ users }: Props) {
column.toggleSorting(column.getIsSorted() === "asc")
}
>
Username
{t('username')}
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
@ -98,7 +100,7 @@ export default function UsersTable({ users }: Props) {
column.toggleSorting(column.getIsSorted() === "asc")
}
>
Email
{t('email')}
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
@ -114,7 +116,7 @@ export default function UsersTable({ users }: Props) {
column.toggleSorting(column.getIsSorted() === "asc")
}
>
Name
{t('name')}
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
@ -130,7 +132,7 @@ export default function UsersTable({ users }: Props) {
column.toggleSorting(column.getIsSorted() === "asc")
}
>
Identity Provider
{t('identityProvider')}
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
@ -151,7 +153,7 @@ export default function UsersTable({ users }: Props) {
setIsDeleteModalOpen(true);
}}
>
Delete
{t('delete')}
</Button>
</div>
</>
@ -172,35 +174,26 @@ export default function UsersTable({ users }: Props) {
dialog={
<div className="space-y-4">
<p>
Are you sure you want to permanently delete{" "}
<b className="break-all">
{selected?.email ||
selected?.name ||
selected?.username}
</b>{" "}
from the server?
{t('userQuestionRemove', {selectedUser: selected?.email || selected?.name || selected?.username})}
</p>
<p>
<b>
The user will be removed from all
organizations and be completely removed from
the server.
{t('userMessageRemove')}
</b>
</p>
<p>
To confirm, please type the name of the user
below.
{t('userMessageConfirm')}
</p>
</div>
}
buttonText="Confirm Delete User"
buttonText={t('userDeleteConfirm')}
onConfirm={async () => deleteUser(selected!.id)}
string={
selected.email || selected.name || selected.username
}
title="Delete User from Server"
title={t('userDeleteServer')}
/>
)}

View file

@ -6,6 +6,7 @@ import { AdminListUsersResponse } from "@server/routers/user/adminListUsers";
import UsersTable, { GlobalUserRow } from "./AdminUsersTable";
import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert";
import { InfoIcon } from "lucide-react";
import { getTranslations } from 'next-intl/server';
type PageProps = {
params: Promise<{ orgId: string }>;
@ -39,17 +40,19 @@ export default async function UsersPage(props: PageProps) {
};
});
const t = await getTranslations();
return (
<>
<SettingsSectionTitle
title="Manage All Users"
description="View and manage all users in the system"
title={t('userTitle')}
description={t('userDescription')}
/>
<Alert variant="neutral" className="mb-6">
<InfoIcon className="h-4 w-4" />
<AlertTitle className="font-semibold">About User Management</AlertTitle>
<AlertTitle className="font-semibold">{t('userAbount')}</AlertTitle>
<AlertDescription>
This table displays all root user objects in the system. Each user may belong to multiple organizations. Removing a user from an organization does not delete their root user object - they will remain in the system. To completely remove a user from the system, you must delete their root user object using the delete action in this table.
{t('userAbountDescription')}
</AlertDescription>
</Alert>
<UsersTable users={userRows} />