diff --git a/messages/en-US.json b/messages/en-US.json index 1c9468dc..3eb137e9 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -10,7 +10,7 @@ "setupCreateSite": "Create Site", "setupCreateResources": "Create Resources", "setupOrgName": "Organization Name", - "setupDisplayName": "This is the display name for your organization.", + "orgDisplayName": "This is the display name of your organization.", "setupOrgId": "Organization ID", "setupIdentifierMessage": "This is the unique identifier for your organization. This is separate from the display name.", "setupErrorIdentifier": "Organization ID is already taken. Please choose a different one.", @@ -150,5 +150,46 @@ "proxy": "Proxy", "rules": "Rules", "resourceSettingDescription": "Configure the settings on your resource", - "resourceSetting": "{resourceName} Settings" + "resourceSetting": "{resourceName} Settings", + "alwaysAllow": "Always Allow", + "alwaysDeny": "Always Deny", + "orgSettingsDescription": "Configure your organization's general settings", + "orgGeneralSettings": "Organization Settings", + "orgGeneralSettingsDescription": "Manage your organization details and configuration", + "orgGeneralSave": "Save General Settings", + "orgDangerZone": "Danger Zone", + "orgDangerZoneDescription": "Once you delete this org, there is no going back. Please be certain.", + "orgDelete": "Delete Organization", + "orgDeleteConfirm": "Confirm Delete Organization", + "orgMessageRemove": "This action is irreversible and will delete all associated data.", + "orgMessageConfirm": "To confirm, please type the name of the organization below.", + "orgQuestionRemove": "Are you sure you want to remove the organization {selectedOrg}?", + "orgUpdated": "Organization updated", + "orgUpdatedDescription": "The organization has been updated.", + "orgErrorUpdate": "Failed to update organization", + "orgErrorUpdateMessage": "An error occurred while updating the organization.", + "orgErrorFetch": "Failed to fetch organizations", + "orgErrorFetchMessage": "An error occurred while listing your organizations", + "orgErrorDelete": "Failed to delete organization", + "orgErrorDeleteMessage": "An error occurred while deleting the organization.", + "orgDeleted": "Organization deleted", + "orgDeletedMessage": "The organization and its data has been deleted.", + "accessUsersManage": "Manage Users", + "accessUsersDescription": "Invite users and add them to roles to manage access to your organization", + "accessUsersSearch": "Search users...", + "accessUserCreate": "Create User", + "accessUserRemove": "Remove User", + "username": "Username", + "identityProvider": "Identity Provider", + "role": "Role", + "accessRoleNameRequired": "Name is required", + "accessRolesManage": "Manage Roles", + "accessRolesDescription": "Configure roles to manage access to your organization", + "accessRolesSearch": "Search roles...", + "accessRolesAdd": "Add Role", + "accessRoleDelete": "Delete Role", + "description": "Description", + "inviteTitle": "Open Invitations", + "inviteDescription": "Manage your invitations to other users", + "inviteSearch": "Search invitations..." } \ No newline at end of file diff --git a/src/app/[orgId]/settings/access/invitations/InvitationsDataTable.tsx b/src/app/[orgId]/settings/access/invitations/InvitationsDataTable.tsx index e2154b2d..ecce6913 100644 --- a/src/app/[orgId]/settings/access/invitations/InvitationsDataTable.tsx +++ b/src/app/[orgId]/settings/access/invitations/InvitationsDataTable.tsx @@ -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 { columns: ColumnDef[]; @@ -14,12 +15,15 @@ export function InvitationsDataTable({ columns, data }: DataTableProps) { + + const t = useTranslations(); + return ( ); diff --git a/src/app/[orgId]/settings/access/invitations/page.tsx b/src/app/[orgId]/settings/access/invitations/page.tsx index 9c8b5e11..e7899282 100644 --- a/src/app/[orgId]/settings/access/invitations/page.tsx +++ b/src/app/[orgId]/settings/access/invitations/page.tsx @@ -9,6 +9,7 @@ import UserProvider from "@app/providers/UserProvider"; import { verifySession } from "@app/lib/auth/verifySession"; import AccessPageHeaderAndNav from "../AccessPageHeaderAndNav"; import SettingsSectionTitle from "@app/components/SettingsSectionTitle"; +import { getTranslations } from 'next-intl/server'; type InvitationsPageProps = { params: Promise<{ orgId: string }>; @@ -71,11 +72,13 @@ export default async function InvitationsPage(props: InvitationsPageProps) { }; }); + const t = await getTranslations(); + return ( <> diff --git a/src/app/[orgId]/settings/access/roles/RolesDataTable.tsx b/src/app/[orgId]/settings/access/roles/RolesDataTable.tsx index 93ddd1cc..ab381813 100644 --- a/src/app/[orgId]/settings/access/roles/RolesDataTable.tsx +++ b/src/app/[orgId]/settings/access/roles/RolesDataTable.tsx @@ -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 { columns: ColumnDef[]; @@ -16,15 +17,18 @@ export function RolesDataTable({ data, createRole }: DataTableProps) { + + const t = useTranslations(); + return ( ); } diff --git a/src/app/[orgId]/settings/access/roles/RolesTable.tsx b/src/app/[orgId]/settings/access/roles/RolesTable.tsx index 7ebcfbce..8a3f3647 100644 --- a/src/app/[orgId]/settings/access/roles/RolesTable.tsx +++ b/src/app/[orgId]/settings/access/roles/RolesTable.tsx @@ -19,6 +19,7 @@ import CreateRoleForm from "./CreateRoleForm"; import DeleteRoleForm from "./DeleteRoleForm"; import { createApiClient } from "@app/lib/api"; import { useEnvContext } from "@app/hooks/useEnvContext"; +import { useTranslations } from 'next-intl'; export type RoleRow = Role; @@ -38,6 +39,8 @@ export default function UsersTable({ roles: r }: RolesTableProps) { const { org } = useOrgContext(); + const t = useTranslations(); + const columns: ColumnDef[] = [ { id: "actions", @@ -58,7 +61,7 @@ export default function UsersTable({ roles: r }: RolesTableProps) { className="h-8 w-8 p-0" > - Open menu + {t('openMenu')} @@ -71,7 +74,7 @@ export default function UsersTable({ roles: r }: RolesTableProps) { }} > - Delete Role + {t('accessRoleDelete')} @@ -92,7 +95,7 @@ export default function UsersTable({ roles: r }: RolesTableProps) { column.toggleSorting(column.getIsSorted() === "asc") } > - Name + {t('name')} ); @@ -100,7 +103,7 @@ export default function UsersTable({ roles: r }: RolesTableProps) { }, { accessorKey: "description", - header: "Description" + header: t('description') } ]; diff --git a/src/app/[orgId]/settings/access/roles/page.tsx b/src/app/[orgId]/settings/access/roles/page.tsx index 16fefd7d..fed52c26 100644 --- a/src/app/[orgId]/settings/access/roles/page.tsx +++ b/src/app/[orgId]/settings/access/roles/page.tsx @@ -9,6 +9,7 @@ import RolesTable, { RoleRow } from "./RolesTable"; import { SidebarSettings } from "@app/components/SidebarSettings"; import AccessPageHeaderAndNav from "../AccessPageHeaderAndNav"; import SettingsSectionTitle from "@app/components/SettingsSectionTitle"; +import { getTranslations } from 'next-intl/server'; type RolesPageProps = { params: Promise<{ orgId: string }>; @@ -62,12 +63,13 @@ export default async function RolesPage(props: RolesPageProps) { } const roleRows: RoleRow[] = roles; + const t = await getTranslations(); return ( <> diff --git a/src/app/[orgId]/settings/access/users/UsersDataTable.tsx b/src/app/[orgId]/settings/access/users/UsersDataTable.tsx index 643d8641..93998a45 100644 --- a/src/app/[orgId]/settings/access/users/UsersDataTable.tsx +++ b/src/app/[orgId]/settings/access/users/UsersDataTable.tsx @@ -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 { columns: ColumnDef[]; @@ -16,15 +17,18 @@ export function UsersDataTable({ data, inviteUser }: DataTableProps) { + + const t = useTranslations(); + return ( ); } diff --git a/src/app/[orgId]/settings/access/users/UsersTable.tsx b/src/app/[orgId]/settings/access/users/UsersTable.tsx index 8036cc84..eebf6d22 100644 --- a/src/app/[orgId]/settings/access/users/UsersTable.tsx +++ b/src/app/[orgId]/settings/access/users/UsersTable.tsx @@ -20,6 +20,7 @@ import { formatAxiosError } from "@app/lib/api"; import { createApiClient } from "@app/lib/api"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { useUserContext } from "@app/hooks/useUserContext"; +import { useTranslations } from 'next-intl'; export type UserRow = { id: string; @@ -47,6 +48,7 @@ export default function UsersTable({ users: u }: UsersTableProps) { const api = createApiClient(useEnvContext()); const { user, updateUser } = useUserContext(); const { org } = useOrgContext(); + const t = useTranslations(); const columns: ColumnDef[] = [ { @@ -68,7 +70,7 @@ export default function UsersTable({ users: u }: UsersTableProps) { className="h-8 w-8 p-0" > - Open menu + {t('openMenu')} @@ -79,7 +81,7 @@ export default function UsersTable({ users: u }: UsersTableProps) { className="block w-full" > - Manage User + {t('accessUsersManage')} {`${userRow.username}-${userRow.idpId}` !== @@ -95,7 +97,7 @@ export default function UsersTable({ users: u }: UsersTableProps) { }} > - Remove User + {t('accessUserRemove')} )} @@ -118,7 +120,7 @@ export default function UsersTable({ users: u }: UsersTableProps) { column.toggleSorting(column.getIsSorted() === "asc") } > - Username + {t('username')} ); @@ -134,7 +136,7 @@ export default function UsersTable({ users: u }: UsersTableProps) { column.toggleSorting(column.getIsSorted() === "asc") } > - Identity Provider + {t('identityProvider')} ); @@ -150,7 +152,7 @@ export default function UsersTable({ users: u }: UsersTableProps) { column.toggleSorting(column.getIsSorted() === "asc") } > - Role + {t('role')} ); diff --git a/src/app/[orgId]/settings/access/users/page.tsx b/src/app/[orgId]/settings/access/users/page.tsx index f82cfdb0..11a2570d 100644 --- a/src/app/[orgId]/settings/access/users/page.tsx +++ b/src/app/[orgId]/settings/access/users/page.tsx @@ -10,6 +10,7 @@ import UserProvider from "@app/providers/UserProvider"; import { verifySession } from "@app/lib/auth/verifySession"; import AccessPageHeaderAndNav from "../AccessPageHeaderAndNav"; import SettingsSectionTitle from "@app/components/SettingsSectionTitle"; +import { getTranslations } from 'next-intl/server'; type UsersPageProps = { params: Promise<{ orgId: string }>; @@ -83,11 +84,13 @@ export default async function UsersPage(props: UsersPageProps) { }; }); + const t = await getTranslations(); + return ( <> diff --git a/src/app/[orgId]/settings/general/layout.tsx b/src/app/[orgId]/settings/general/layout.tsx index a2d9cc0a..3fae9ce4 100644 --- a/src/app/[orgId]/settings/general/layout.tsx +++ b/src/app/[orgId]/settings/general/layout.tsx @@ -10,6 +10,7 @@ import { GetOrgUserResponse } from "@server/routers/user"; import { AxiosResponse } from "axios"; import { redirect } from "next/navigation"; import { cache } from "react"; +import { getTranslations } from 'next-intl/server'; type GeneralSettingsProps = { children: React.ReactNode; @@ -57,9 +58,11 @@ export default async function GeneralSettingsPage({ redirect(`/${orgId}`); } + const t = await getTranslations(); + const navItems = [ { - title: "General", + title: t('general'), href: `/{orgId}/settings/general`, }, ]; @@ -69,8 +72,8 @@ export default async function GeneralSettingsPage({ diff --git a/src/app/[orgId]/settings/general/page.tsx b/src/app/[orgId]/settings/general/page.tsx index 9819be59..14a2885c 100644 --- a/src/app/[orgId]/settings/general/page.tsx +++ b/src/app/[orgId]/settings/general/page.tsx @@ -44,6 +44,7 @@ import { SettingsSectionFooter } from "@app/components/Settings"; import { useUserContext } from "@app/hooks/useUserContext"; +import { useTranslations } from 'next-intl'; const GeneralFormSchema = z.object({ name: z.string() @@ -79,8 +80,8 @@ export default function GeneralPage() { ); toast({ - title: "Organization deleted", - description: "The organization and its data has been deleted." + title: t('orgDeleted'), + description: t('orgDeletedMessage') }); if (res.status === 200) { @@ -90,11 +91,8 @@ export default function GeneralPage() { console.error(err); toast({ variant: "destructive", - title: "Failed to delete org", - description: formatAxiosError( - err, - "An error occurred while deleting the org." - ) + title: t('orgErrorDelete'), + description: formatAxiosError(err,t('orgErrorDeleteMessage')) }); } finally { setLoadingDelete(false); @@ -121,11 +119,8 @@ export default function GeneralPage() { console.error(err); toast({ variant: "destructive", - title: "Failed to fetch orgs", - description: formatAxiosError( - err, - "An error occurred while listing your orgs" - ) + title: t('orgErrorFetch'), + description: formatAxiosError(err,t('orgErrorFetchMessage')) }); } } @@ -138,8 +133,8 @@ export default function GeneralPage() { }) .then(() => { toast({ - title: "Organization updated", - description: "The organization has been updated." + title: t('orgUpdated'), + description: t('orgUpdatedDescription') }); router.refresh(); @@ -147,11 +142,8 @@ export default function GeneralPage() { .catch((e) => { toast({ variant: "destructive", - title: "Failed to update org", - description: formatAxiosError( - e, - "An error occurred while updating the org." - ) + title: t('orgErrorUpdate'), + description: formatAxiosError(e,t('orgErrorUpdateMessage')) }); }) .finally(() => { @@ -159,6 +151,8 @@ export default function GeneralPage() { }); } + const t = useTranslations(); + return (

- Are you sure you want to delete the organization{" "} - {org?.org.name}? + {t('orgQuestionRemove', {selectedOrg: org?.org.name})}

- This action is irreversible and will delete all - associated data. + {t('orgMessageRemove')}

- To confirm, type the name of the organization below. + {t('orgMessageConfirm')}

} - buttonText="Confirm Delete Organization" + buttonText={t('orgDeleteConfirm')} onConfirm={deleteOrg} string={org?.org.name || ""} - title="Delete Organization" + title={t('orgDelete')} /> - Organization Settings + {t('orgGeneralSettings')} - Manage your organization details and configuration + {t('orgGeneralSettingsDescription')} @@ -210,14 +202,13 @@ export default function GeneralPage() { name="name" render={({ field }) => ( - Name + {t('name')} - This is the display name of the - organization. + {t('orgDisplayName')} )} @@ -234,17 +225,16 @@ export default function GeneralPage() { loading={loadingSave} disabled={loadingSave} > - Save General Settings + {t('orgGeneralSave')} - Danger Zone + {t('orgDangerZone')} - Once you delete this org, there is no going back. Please - be certain. + {t('orgDangerZoneDescription')} @@ -256,7 +246,7 @@ export default function GeneralPage() { loading={loadingDelete} disabled={loadingDelete} > - Delete Organization Data + {t('orgDelete')} diff --git a/src/app/[orgId]/settings/resources/[resourceId]/rules/page.tsx b/src/app/[orgId]/settings/resources/[resourceId]/rules/page.tsx index 2a9fa00f..139b9926 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/rules/page.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/rules/page.tsx @@ -1,4 +1,5 @@ "use client"; + import { useEffect, useState, use } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input";