diff --git a/messages/de-DE.json b/messages/de-DE.json index c94c7786..013c790f 100644 --- a/messages/de-DE.json +++ b/messages/de-DE.json @@ -385,7 +385,7 @@ "userErrorOrgRemoveDescription": "Beim Entfernen des Benutzers ist ein Fehler aufgetreten.", "userOrgRemoved": "Benutzer entfernt", "userOrgRemovedDescription": "Der Benutzer {email} wurde aus der Organisation entfernt.", - "userQuestionOrgRemove": "Sind Sie sicher, dass Sie {email} aus der Organisation entfernen möchten?", + "userQuestionOrgRemove": "Sind Sie sicher, dass Sie {email} aus der Organisation entfernen möchten?", "userMessageOrgRemove": "Nach dem Entfernen hat dieser Benutzer keinen Zugriff mehr auf die Organisation. Sie können ihn später jederzeit wieder einladen, aber er muss die Einladung erneut annehmen.", "userMessageOrgConfirm": "Geben Sie zur Bestätigung den Namen des Benutzers unten ein.", "userRemoveOrgConfirm": "Entfernen des Benutzers bestätigen", @@ -684,7 +684,7 @@ "accessRoleErrorRemove": "Fehler beim Entfernen der Rolle", "accessRoleErrorRemoveDescription": "Beim Entfernen der Rolle ist ein Fehler aufgetreten.", "accessRoleName": "Rollenname", - "accessRoleQuestionRemove": "Sie sind dabei, die Rolle {name} zu löschen. Diese Aktion kann nicht rückgängig gemacht werden.", + "accessRoleQuestionRemove": "Sie sind dabei, die Rolle {name} zu löschen. Diese Aktion kann nicht rückgängig gemacht werden.", "accessRoleRemove": "Rolle entfernen", "accessRoleRemoveDescription": "Eine Rolle aus der Organisation entfernen", "accessRoleRemoveSubmit": "Rolle entfernen", @@ -709,7 +709,7 @@ "idpManageDescription": "Identitätsanbieter im System anzeigen und verwalten", "idpDeletedDescription": "Identitätsanbieter erfolgreich gelöscht", "idpOidc": "OAuth2/OIDC", - "idpQuestionRemove": "Sind Sie sicher, dass Sie den Identitätsanbieter {name} dauerhaft löschen möchten?", + "idpQuestionRemove": "Sind Sie sicher, dass Sie den Identitätsanbieter {name} dauerhaft löschen möchten?", "idpMessageRemove": "Dies wird den Identitätsanbieter und alle zugehörigen Konfigurationen entfernen. Benutzer, die sich über diesen Anbieter authentifizieren, können sich nicht mehr anmelden.", "idpMessageConfirm": "Bitte geben Sie zur Bestätigung den Namen des Identitätsanbieters unten ein.", "idpConfirmDelete": "Löschen des Identitätsanbieters bestätigen", diff --git a/messages/en-US.json b/messages/en-US.json index 112a39db..ab3ba6bb 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -27,6 +27,7 @@ "createAnAccount": "Create an Account", "inviteNotAccepted": "Invite Not Accepted", "authCreateAccount": "Create an account to get started", + "authNoAccount": "Don't have an account?", "email": "Email", "password": "Password", "confirmPassword": "Confirm Password", @@ -314,6 +315,9 @@ "licenseKeyDeletedDescription": "The license key has been deleted.", "licenseErrorKeyActivate": "Failed to activate license key", "licenseErrorKeyActivateDescription": "An error occurred while activating the license key.", + "licenseAbout": "About Licensing", + "communityEdition": "Community Edition", + "licenseAboutDescription": "This is for business and enterprise users who are using Pangolin in a commercial environment. If you are using Pangolin for personal use, you can ignore this section.", "licenseKeyActivated": "License key activated", "licenseKeyActivatedDescription": "The license key has been successfully activated.", "licenseErrorKeyRecheck": "Failed to recheck license keys", @@ -350,6 +354,7 @@ "total": "Total", "licenseContinuePayment": "Continue to Payment", "pricingPage": "pricing page", + "pricingPortal": "See Purchase Portal", "licensePricingPage": "For the most up-to-date pricing and discounts, please visit the ", "invite": "Invitations", "inviteRegenerate": "Regenerate Invitation", @@ -385,7 +390,7 @@ "userErrorOrgRemoveDescription": "An error occurred while removing the user.", "userOrgRemoved": "User removed", "userOrgRemovedDescription": "The user {email} has been removed from the organization.", - "userQuestionOrgRemove": "Are you sure you want to remove {email} from the organization?", + "userQuestionOrgRemove": "Are you sure you want to remove {email} from the organization?", "userMessageOrgRemove": "Once removed, this user will no longer have access to the organization. You can always re-invite them later, but they will need to accept the invitation again.", "userMessageOrgConfirm": "To confirm, please type the name of the of the user below.", "userRemoveOrgConfirm": "Confirm Remove User", @@ -626,6 +631,7 @@ "resourceErrorWhitelistSave": "Failed to save whitelist", "resourceErrorWhitelistSaveDescription": "An error occurred while saving the whitelist", "resourcePasswordSubmit": "Enable Password Protection", + "resourcePasswordProtection": "Password Protection {status}", "resourcePasswordRemove": "Resource password removed", "resourcePasswordRemoveDescription": "The resource password has been removed successfully", "resourcePasswordSetup": "Resource password set", @@ -707,7 +713,7 @@ "idpManageDescription": "View and manage identity providers in the system", "idpDeletedDescription": "Identity provider deleted successfully", "idpOidc": "OAuth2/OIDC", - "idpQuestionRemove": "Are you sure you want to permanently delete the identity provider {name}?", + "idpQuestionRemove": "Are you sure you want to permanently delete the identity provider {name}?", "idpMessageRemove": "This will remove the identity provider and all associated configurations. Users who authenticate through this provider will no longer be able to log in.", "idpMessageConfirm": "To confirm, please type the name of the identity provider below.", "idpConfirmDelete": "Confirm Delete Identity Provider", @@ -792,6 +798,7 @@ "orgMappingPathOptional": "Organization Mapping Path (Optional)", "orgPolicyUpdate": "Update Policy", "orgPolicyAdd": "Add Policy", + "orgPolicyConfig": "Configure access for an organization", "idpUpdatedDescription": "Identity provider updated successfully", "redirectUrl": "Redirect URL", "redirectUrlAbout": "About Redirect URL", diff --git a/messages/fr-FR.json b/messages/fr-FR.json index fe5faedc..5d964622 100644 --- a/messages/fr-FR.json +++ b/messages/fr-FR.json @@ -385,7 +385,7 @@ "userErrorOrgRemoveDescription": "Une erreur s'est produite lors de la suppression de l'utilisateur.", "userOrgRemoved": "Utilisateur supprimé", "userOrgRemovedDescription": "L'utilisateur {email} a été retiré de l'organisation.", - "userQuestionOrgRemove": "Êtes-vous sûr de vouloir retirer {email} de l'organisation ?", + "userQuestionOrgRemove": "Êtes-vous sûr de vouloir retirer {email} de l'organisation ?", "userMessageOrgRemove": "Une fois retiré, cet utilisateur n'aura plus accès à l'organisation. Vous pouvez toujours le réinviter plus tard, mais il devra accepter l'invitation à nouveau.", "userMessageOrgConfirm": "Pour confirmer, veuillez saisir le nom de l'utilisateur ci-dessous.", "userRemoveOrgConfirm": "Confirmer la suppression de l'utilisateur", @@ -684,7 +684,7 @@ "accessRoleErrorRemove": "Échec de la suppression du rôle", "accessRoleErrorRemoveDescription": "Une erreur s'est produite lors de la suppression du rôle.", "accessRoleName": "Nom du rôle", - "accessRoleQuestionRemove": "Vous êtes sur le point de supprimer le rôle {name}. Cette action est irréversible.", + "accessRoleQuestionRemove": "Vous êtes sur le point de supprimer le rôle {name}. Cette action est irréversible.", "accessRoleRemove": "Supprimer le rôle", "accessRoleRemoveDescription": "Retirer un rôle de l'organisation", "accessRoleRemoveSubmit": "Supprimer le rôle", @@ -709,7 +709,7 @@ "idpManageDescription": "Voir et gérer les fournisseurs d'identité dans le système", "idpDeletedDescription": "Fournisseur d'identité supprimé avec succès", "idpOidc": "OAuth2/OIDC", - "idpQuestionRemove": "Êtes-vous sûr de vouloir supprimer définitivement le fournisseur d'identité {name} ?", + "idpQuestionRemove": "Êtes-vous sûr de vouloir supprimer définitivement le fournisseur d'identité {name}?", "idpMessageRemove": "Cela supprimera le fournisseur d'identité et toutes les configurations associées. Les utilisateurs qui s'authentifient via ce fournisseur ne pourront plus se connecter.", "idpMessageConfirm": "Pour confirmer, veuillez saisir le nom du fournisseur d'identité ci-dessous.", "idpConfirmDelete": "Confirmer la suppression du fournisseur d'identité", diff --git a/messages/it-IT.json b/messages/it-IT.json index c72f08bc..e42735cf 100644 --- a/messages/it-IT.json +++ b/messages/it-IT.json @@ -385,7 +385,7 @@ "userErrorOrgRemoveDescription": "Si è verificato un errore durante la rimozione dell'utente.", "userOrgRemoved": "Utente rimosso", "userOrgRemovedDescription": "L'utente {email} è stato rimosso dall'organizzazione.", - "userQuestionOrgRemove": "Sei sicuro di voler rimuovere {email} dall'organizzazione?", + "userQuestionOrgRemove": "Sei sicuro di voler rimuovere {email} dall'organizzazione?", "userMessageOrgRemove": "Una volta rimosso, questo utente non avrà più accesso all'organizzazione. Puoi sempre reinvitarlo in seguito, ma dovrà accettare nuovamente l'invito.", "userMessageOrgConfirm": "Per confermare, digita il nome dell'utente qui sotto.", "userRemoveOrgConfirm": "Conferma Rimozione Utente", @@ -684,7 +684,7 @@ "accessRoleErrorRemove": "Impossibile rimuovere il ruolo", "accessRoleErrorRemoveDescription": "Si è verificato un errore durante la rimozione del ruolo.", "accessRoleName": "Nome Del Ruolo", - "accessRoleQuestionRemove": "Stai per eliminare il ruolo {name}. Non puoi annullare questa azione.", + "accessRoleQuestionRemove": "Stai per eliminare il ruolo {name}. Non puoi annullare questa azione.", "accessRoleRemove": "Rimuovi Ruolo", "accessRoleRemoveDescription": "Rimuovi un ruolo dall'organizzazione", "accessRoleRemoveSubmit": "Rimuovi Ruolo", @@ -709,7 +709,7 @@ "idpManageDescription": "Visualizza e gestisci i provider di identità nel sistema", "idpDeletedDescription": "Provider di identità eliminato con successo", "idpOidc": "OAuth2/OIDC", - "idpQuestionRemove": "Sei sicuro di voler eliminare definitivamente il provider di identità {name}?", + "idpQuestionRemove": "Sei sicuro di voler eliminare definitivamente il provider di identità {name}?", "idpMessageRemove": "Questo rimuoverà il provider di identità e tutte le configurazioni associate. Gli utenti che si autenticano tramite questo provider non potranno più accedere.", "idpMessageConfirm": "Per confermare, digita il nome del provider di identità qui sotto.", "idpConfirmDelete": "Conferma Eliminazione Provider di Identità", diff --git a/messages/pl-PL.json b/messages/pl-PL.json index d11a743b..acc1f3d8 100644 --- a/messages/pl-PL.json +++ b/messages/pl-PL.json @@ -385,7 +385,7 @@ "userErrorOrgRemoveDescription": "Wystąpił błąd podczas usuwania użytkownika.", "userOrgRemoved": "Użytkownik usunięty", "userOrgRemovedDescription": "Użytkownik {email} został usunięty z organizacji.", - "userQuestionOrgRemove": "Czy na pewno chcesz usunąć {email} z organizacji?", + "userQuestionOrgRemove": "Czy na pewno chcesz usunąć {email} z organizacji?", "userMessageOrgRemove": "Po usunięciu ten użytkownik nie będzie miał już dostępu do organizacji. Zawsze możesz ponownie go zaprosić później, ale będzie musiał ponownie zaakceptować zaproszenie.", "userMessageOrgConfirm": "Aby potwierdzić, wpisz nazwę użytkownika poniżej.", "userRemoveOrgConfirm": "Potwierdź usunięcie użytkownika", @@ -684,7 +684,7 @@ "accessRoleErrorRemove": "Nie udało się usunąć roli", "accessRoleErrorRemoveDescription": "Wystąpił błąd podczas usuwania roli.", "accessRoleName": "Nazwa roli", - "accessRoleQuestionRemove": "Zamierzasz usunąć rolę {name}. Tej akcji nie można cofnąć.", + "accessRoleQuestionRemove": "Zamierzasz usunąć rolę {name}. Tej akcji nie można cofnąć.", "accessRoleRemove": "Usuń rolę", "accessRoleRemoveDescription": "Usuń rolę z organizacji", "accessRoleRemoveSubmit": "Usuń rolę", @@ -709,7 +709,7 @@ "idpManageDescription": "Wyświetl i zarządzaj dostawcami tożsamości w systemie", "idpDeletedDescription": "Dostawca tożsamości został pomyślnie usunięty", "idpOidc": "OAuth2/OIDC", - "idpQuestionRemove": "Czy na pewno chcesz trwale usunąć dostawcę tożsamości {name}?", + "idpQuestionRemove": "Czy na pewno chcesz trwale usunąć dostawcę tożsamości {name}?", "idpMessageRemove": "Spowoduje to usunięcie dostawcy tożsamości i wszystkich powiązanych konfiguracji. Użytkownicy uwierzytelniający się przez tego dostawcę nie będą mogli się już zalogować.", "idpMessageConfirm": "Aby potwierdzić, wpisz nazwę dostawcy tożsamości poniżej.", "idpConfirmDelete": "Potwierdź usunięcie dostawcy tożsamości", diff --git a/messages/pt-PT.json b/messages/pt-PT.json index 75b0d8ef..9b02e1b8 100644 --- a/messages/pt-PT.json +++ b/messages/pt-PT.json @@ -385,7 +385,7 @@ "userErrorOrgRemoveDescription": "Ocorreu um erro ao remover o usuário.", "userOrgRemoved": "Usuário removido", "userOrgRemovedDescription": "O usuário {email} foi removido da organização.", - "userQuestionOrgRemove": "Tem certeza que deseja remover {email} da organização?", + "userQuestionOrgRemove": "Tem certeza que deseja remover {email} da organização?", "userMessageOrgRemove": "Uma vez removido, este usuário não terá mais acesso à organização. Você sempre pode reconvidá-lo depois, mas eles precisarão aceitar o convite novamente.", "userMessageOrgConfirm": "Para confirmar, digite o nome do usuário abaixo.", "userRemoveOrgConfirm": "Confirmar Remoção do Usuário", @@ -684,7 +684,7 @@ "accessRoleErrorRemove": "Falha ao remover função", "accessRoleErrorRemoveDescription": "Ocorreu um erro ao remover a função.", "accessRoleName": "Nome da Função", - "accessRoleQuestionRemove": "Você está prestes a excluir a função {name}. Você não pode desfazer esta ação.", + "accessRoleQuestionRemove": "Você está prestes a excluir a função {name}. Você não pode desfazer esta ação.", "accessRoleRemove": "Remover Função", "accessRoleRemoveDescription": "Remover uma função da organização", "accessRoleRemoveSubmit": "Remover Função", @@ -709,7 +709,7 @@ "idpManageDescription": "Visualizar e gerir provedores de identidade no sistema", "idpDeletedDescription": "Provedor de identidade eliminado com sucesso", "idpOidc": "OAuth2/OIDC", - "idpQuestionRemove": "Tem certeza que deseja eliminar permanentemente o provedor de identidade {name}?", + "idpQuestionRemove": "Tem certeza que deseja eliminar permanentemente o provedor de identidade {name}?", "idpMessageRemove": "Isto irá remover o provedor de identidade e todas as configurações associadas. Os utilizadores que se autenticam através deste provedor não poderão mais fazer login.", "idpMessageConfirm": "Para confirmar, por favor digite o nome do provedor de identidade abaixo.", "idpConfirmDelete": "Confirmar Eliminação do Provedor de Identidade", diff --git a/messages/tr-TR.json b/messages/tr-TR.json index 3209478c..73b10add 100644 --- a/messages/tr-TR.json +++ b/messages/tr-TR.json @@ -385,7 +385,7 @@ "userErrorOrgRemoveDescription": "An error occurred while removing the user.", "userOrgRemoved": "User removed", "userOrgRemovedDescription": "The user {email} has been removed from the organization.", - "userQuestionOrgRemove": "Are you sure you want to remove {email} from the organization?", + "userQuestionOrgRemove": "Are you sure you want to remove {email} from the organization?", "userMessageOrgRemove": "Once removed, this user will no longer have access to the organization. You can always re-invite them later, but they will need to accept the invitation again.", "userMessageOrgConfirm": "To confirm, please type the name of the of the user below.", "userRemoveOrgConfirm": "Confirm Remove User", @@ -709,7 +709,7 @@ "idpManageDescription": "View and manage identity providers in the system", "idpDeletedDescription": "Identity provider deleted successfully", "idpOidc": "OAuth2/OIDC", - "idpQuestionRemove": "Are you sure you want to permanently delete the identity provider {name}?", + "idpQuestionRemove": "Are you sure you want to permanently delete the identity provider {name}?", "idpMessageRemove": "This will remove the identity provider and all associated configurations. Users who authenticate through this provider will no longer be able to log in.", "idpMessageConfirm": "To confirm, please type the name of the identity provider below.", "idpConfirmDelete": "Confirm Delete Identity Provider", diff --git a/src/app/[orgId]/settings/access/AccessPageHeaderAndNav.tsx b/src/app/[orgId]/settings/access/AccessPageHeaderAndNav.tsx index 2dcdb679..47690dc6 100644 --- a/src/app/[orgId]/settings/access/AccessPageHeaderAndNav.tsx +++ b/src/app/[orgId]/settings/access/AccessPageHeaderAndNav.tsx @@ -14,6 +14,7 @@ export default function AccessPageHeaderAndNav({ hasInvitations }: AccessPageHeaderAndNavProps) { const t = useTranslations(); + const navItems = [ { title: t('users'), diff --git a/src/app/[orgId]/settings/access/invitations/RegenerateInvitationForm.tsx b/src/app/[orgId]/settings/access/invitations/RegenerateInvitationForm.tsx index f151da9d..59c1b1b4 100644 --- a/src/app/[orgId]/settings/access/invitations/RegenerateInvitationForm.tsx +++ b/src/app/[orgId]/settings/access/invitations/RegenerateInvitationForm.tsx @@ -123,7 +123,7 @@ export default function RegenerateInvitationForm({ onRegenerate({ id: invitation.id, email: invitation.email, - expiresAt: res.data.data.expiresAt ?? "", + expiresAt: res.data.data.expiresAt, role: invitation.role, roleId: invitation.roleId }); diff --git a/src/app/[orgId]/settings/access/invitations/page.tsx b/src/app/[orgId]/settings/access/invitations/page.tsx index 044b0be6..665b9a43 100644 --- a/src/app/[orgId]/settings/access/invitations/page.tsx +++ b/src/app/[orgId]/settings/access/invitations/page.tsx @@ -19,6 +19,7 @@ export const dynamic = "force-dynamic"; export default async function InvitationsPage(props: InvitationsPageProps) { const params = await props.params; + const t = await getTranslations(); const getUser = cache(verifySession); const user = await getUser(); @@ -72,8 +73,6 @@ export default async function InvitationsPage(props: InvitationsPageProps) { }; }); - const t = await getTranslations(); - return ( <> @@ -244,7 +244,7 @@ export default function UsersTable({ users: u }: UsersTableProps) { dialog={

- {t('userQuestionOrgRemove', {email: selectedUser?.email || selectedUser?.name || selectedUser?.username || ''})} + {t('userQuestionOrgRemove', {email: selectedUser?.email || selectedUser?.name || selectedUser?.username})}

diff --git a/src/app/[orgId]/settings/api-keys/create/page.tsx b/src/app/[orgId]/settings/api-keys/create/page.tsx index dcf2c027..809784e4 100644 --- a/src/app/[orgId]/settings/api-keys/create/page.tsx +++ b/src/app/[orgId]/settings/api-keys/create/page.tsx @@ -92,7 +92,8 @@ export default function Page() { const api = createApiClient({ env }); const { orgId } = useParams(); const router = useRouter(); - + const t = useTranslations(); + const [loadingPage, setLoadingPage] = useState(true); const [createLoading, setCreateLoading] = useState(false); const [apiKey, setApiKey] = useState(null); @@ -114,8 +115,6 @@ export default function Page() { } }); - const t = useTranslations(); - async function onSubmit(data: CreateFormValues) { setCreateLoading(true); diff --git a/src/app/[orgId]/settings/general/page.tsx b/src/app/[orgId]/settings/general/page.tsx index 967cc21a..463c9463 100644 --- a/src/app/[orgId]/settings/general/page.tsx +++ b/src/app/[orgId]/settings/general/page.tsx @@ -60,6 +60,7 @@ export default function GeneralPage() { const { org } = useOrgContext(); const api = createApiClient(useEnvContext()); const { user } = useUserContext(); + const t = useTranslations(); const [loadingDelete, setLoadingDelete] = useState(false); const [loadingSave, setLoadingSave] = useState(false); @@ -151,8 +152,6 @@ export default function GeneralPage() { }); } - const t = useTranslations(); - return ( void; } -const t = useTranslations(); - export default function CustomDomainInput({ domainOptions, selectedDomainId, - placeholder = t('subdomain'), + placeholder = "Subdomain", value: defaultValue, onChange }: CustomDomainInputProps) { diff --git a/src/app/[orgId]/settings/resources/[resourceId]/authentication/SetResourcePasswordForm.tsx b/src/app/[orgId]/settings/resources/[resourceId]/authentication/SetResourcePasswordForm.tsx index a324b755..3158c9e4 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/authentication/SetResourcePasswordForm.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/authentication/SetResourcePasswordForm.tsx @@ -57,6 +57,7 @@ export default function SetResourcePasswordForm({ onSetPassword }: SetPasswordFormProps) { const api = createApiClient(useEnvContext()); + const t = useTranslations(); const [loading, setLoading] = useState(false); @@ -65,8 +66,6 @@ export default function SetResourcePasswordForm({ defaultValues }); - const t = useTranslations(); - useEffect(() => { if (!open) { return; diff --git a/src/app/[orgId]/settings/resources/[resourceId]/authentication/page.tsx b/src/app/[orgId]/settings/resources/[resourceId]/authentication/page.tsx index f8dcb615..6182c04a 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/authentication/page.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/authentication/page.tsx @@ -83,6 +83,7 @@ export default function ResourceAuthenticationPage() { const api = createApiClient({ env }); const router = useRouter(); + const t = useTranslations(); const [pageLoading, setPageLoading] = useState(true); @@ -130,8 +131,6 @@ export default function ResourceAuthenticationPage() { defaultValues: { emails: [] } }); - const t = useTranslations(); - useEffect(() => { const fetchData = async () => { try { @@ -565,8 +564,7 @@ export default function ResourceAuthenticationPage() { > - Password Protection{" "} - {authInfo.password ? t('enabled') : t('disabled')} + {t('resourcePasswordProtection', {status: authInfo.password? t('enabled') : t('disabled')})}

diff --git a/src/app/admin/license/page.tsx b/src/app/admin/license/page.tsx index 2b72bfd8..67d2912e 100644 --- a/src/app/admin/license/page.tsx +++ b/src/app/admin/license/page.tsx @@ -130,10 +130,10 @@ export default function LicensePage() { } } catch (e) { toast({ - title: "Failed to load license keys", + title: t('licenseErrorKeyLoad'), description: formatAxiosError( e, - "An error occurred loading license keys." + t('licenseErrorKeyLoadDescription') ) }); } @@ -149,16 +149,16 @@ export default function LicensePage() { } await loadLicenseKeys(); toast({ - title: "License key deleted", - description: "The license key has been deleted." + title: t('licenseKeyDeleted'), + description: t('licenseKeyDeletedDescription') }); setIsDeleteModalOpen(false); } catch (e) { toast({ - title: "Failed to delete license key", + title: t('licenseErrorKeyDelete'), description: formatAxiosError( e, - "An error occurred deleting license key." + t('licenseErrorKeyDeleteDescription') ) }); } finally { @@ -175,15 +175,15 @@ export default function LicensePage() { } await loadLicenseKeys(); toast({ - title: "License keys rechecked", - description: "All license keys have been rechecked" + title: t('licenseErrorKeyRechecked'), + description: t('licenseErrorKeyRecheckedDescription') }); } catch (e) { toast({ - title: "Failed to recheck license keys", + title: t('licenseErrorKeyRecheck'), description: formatAxiosError( e, - "An error occurred rechecking license keys." + t('licenseErrorKeyRecheckDescription') ) }); } finally { @@ -202,8 +202,8 @@ export default function LicensePage() { } toast({ - title: "License key activated", - description: "The license key has been successfully activated." + title: t('licenseKeyActivated'), + description: t('licenseKeyActivatedDescription') }); setIsCreateModalOpen(false); @@ -212,10 +212,10 @@ export default function LicensePage() { } catch (e) { toast({ variant: "destructive", - title: "Failed to activate license key", + title: t('licenseErrorKeyActivate'), description: formatAxiosError( e, - "An error occurred while activating the license key." + t('licenseErrorKeyActivateDescription') ) }); } finally { @@ -360,12 +360,10 @@ export default function LicensePage() { - About Licensing + {t('licenseAbout')} - This is for business and enterprise users who are using - Pangolin in a commercial environment. If you are using - Pangolin for personal use, you can ignore this section. + {t('licenseAboutDescription')} @@ -397,12 +395,12 @@ export default function LicensePage() {
{supporterStatus?.visible ? (
- Community Edition + {t('communityEdition')}
) : (
- Community Edition + {t('communityEdition')}
)}
diff --git a/src/app/auth/idp/[idpId]/oidc/callback/page.tsx b/src/app/auth/idp/[idpId]/oidc/callback/page.tsx index 36fabbc4..2bbea496 100644 --- a/src/app/auth/idp/[idpId]/oidc/callback/page.tsx +++ b/src/app/auth/idp/[idpId]/oidc/callback/page.tsx @@ -3,7 +3,7 @@ import ValidateOidcToken from "./ValidateOidcToken"; import { idp } from "@server/db/schemas"; import db from "@server/db"; import { eq } from "drizzle-orm"; -import { useTranslations } from "next-intl"; +import { getTranslations } from 'next-intl/server'; export default async function Page(props: { params: Promise<{ orgId: string; idpId: string }>; @@ -14,6 +14,7 @@ export default async function Page(props: { }) { const params = await props.params; const searchParams = await props.searchParams; + const t = await getTranslations(); const allCookies = await cookies(); const stateCookie = allCookies.get("p_oidc_state")?.value; @@ -24,8 +25,6 @@ export default async function Page(props: { .from(idp) .where(eq(idp.idpId, parseInt(params.idpId!))); - const t = useTranslations(); - if (!idpRes) { return
{t('idpErrorNotFound')}
; } diff --git a/src/app/auth/layout.tsx b/src/app/auth/layout.tsx index 0079ebe5..3017030b 100644 --- a/src/app/auth/layout.tsx +++ b/src/app/auth/layout.tsx @@ -73,7 +73,7 @@ export default async function AuthLayout({ children }: AuthLayoutProps) { aria-label="GitHub" className="flex items-center space-x-2 whitespace-nowrap" > - Community Edition + {t('communityEdition')} - Don't have an account?{" "} + {t('authNoAccount')}{" "} { - setError(formatAxiosError(e, "An error occurred")); - console.error("Failed to request reset:", e); + setError(formatAxiosError(e, t('errorOccurred'))); + console.error(t('passwordErrorRequestReset'), e); setIsSubmitting(false); }); @@ -168,8 +168,8 @@ export default function ResetPasswordForm({ } as ResetPasswordBody ) .catch((e) => { - setError(formatAxiosError(e, "An error occurred")); - console.error("Failed to reset password:", e); + setError(formatAxiosError(e, t('errorOccurred'))); + console.error(t('passwordErrorReset'), e); setIsSubmitting(false); }); @@ -185,7 +185,7 @@ export default function ResetPasswordForm({ return; } - setSuccessMessage("Password reset successfully! Back to log in..."); + setSuccessMessage(t('passwordResetSuccess')); setTimeout(() => { if (redirect) { diff --git a/src/app/auth/reset-password/page.tsx b/src/app/auth/reset-password/page.tsx index 3423bbb5..f948c34b 100644 --- a/src/app/auth/reset-password/page.tsx +++ b/src/app/auth/reset-password/page.tsx @@ -4,7 +4,7 @@ import { cache } from "react"; import ResetPasswordForm from "./ResetPasswordForm"; import Link from "next/link"; import { cleanRedirect } from "@app/lib/cleanRedirect"; -import { useTranslations } from "next-intl"; +import { getTranslations } from 'next-intl/server'; export const dynamic = "force-dynamic"; @@ -18,6 +18,7 @@ export default async function Page(props: { const searchParams = await props.searchParams; const getUser = cache(verifySession); const user = await getUser(); + const t = await getTranslations(); if (user) { redirect("/"); @@ -28,8 +29,6 @@ export default async function Page(props: { redirectUrl = cleanRedirect(searchParams.redirect); } - const t = useTranslations(); - return ( <> { let colLength = 0; @@ -171,8 +172,6 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) { return fullUrl.toString(); } - const t = useTranslations(); - const onWhitelistSubmit = (values: any) => { setLoadingLogin(true); api.post>( diff --git a/src/app/auth/resource/[resourceId]/ResourceNotFound.tsx b/src/app/auth/resource/[resourceId]/ResourceNotFound.tsx index 5a2e863e..11c7b817 100644 --- a/src/app/auth/resource/[resourceId]/ResourceNotFound.tsx +++ b/src/app/auth/resource/[resourceId]/ResourceNotFound.tsx @@ -10,6 +10,7 @@ import Link from "next/link"; import { useTranslations } from "next-intl"; export default async function ResourceNotFound() { + const t = useTranslations(); return ( diff --git a/src/app/auth/signup/SignupForm.tsx b/src/app/auth/signup/SignupForm.tsx index ec321f38..d3639a0e 100644 --- a/src/app/auth/signup/SignupForm.tsx +++ b/src/app/auth/signup/SignupForm.tsx @@ -87,7 +87,7 @@ export default function SignupForm({ .catch((e) => { console.error(e); setError( - formatAxiosError(e, "An error occurred while signing up") + formatAxiosError(e, t('signupError')) ); }); diff --git a/src/app/auth/signup/page.tsx b/src/app/auth/signup/page.tsx index 315b314a..242bf10b 100644 --- a/src/app/auth/signup/page.tsx +++ b/src/app/auth/signup/page.tsx @@ -6,7 +6,7 @@ import { Mail } from "lucide-react"; import Link from "next/link"; import { redirect } from "next/navigation"; import { cache } from "react"; -import { useTranslations } from "next-intl"; +import { getTranslations } from 'next-intl/server'; export const dynamic = "force-dynamic"; @@ -16,13 +16,12 @@ export default async function Page(props: { const searchParams = await props.searchParams; const getUser = cache(verifySession); const user = await getUser(); + const t = await getTranslations(); const env = pullEnv(); const isInvite = searchParams?.redirect?.includes("/invite"); - const t = useTranslations(); - if (env.flags.disableSignupWithoutInvite && !isInvite) { redirect("/"); } diff --git a/src/app/auth/verify-email/VerifyEmailForm.tsx b/src/app/auth/verify-email/VerifyEmailForm.tsx index 235fc70c..05257c1d 100644 --- a/src/app/auth/verify-email/VerifyEmailForm.tsx +++ b/src/app/auth/verify-email/VerifyEmailForm.tsx @@ -56,6 +56,7 @@ export default function VerifyEmailForm({ redirect, }: VerifyEmailFormProps) { const router = useRouter(); + const t = useTranslations(); const [error, setError] = useState(null); const [successMessage, setSuccessMessage] = useState(null); @@ -72,8 +73,6 @@ export default function VerifyEmailForm({ }, }); - const t = useTranslations(); - async function onSubmit(data: z.infer) { setIsSubmitting(true); @@ -82,15 +81,15 @@ export default function VerifyEmailForm({ code: data.pin, }) .catch((e) => { - setError(formatAxiosError(e, "An error occurred")); - console.error("Failed to verify email:", e); + setError(formatAxiosError(e, t('errorOccurred'))); + console.error(t('emailErrorVerify'), e); setIsSubmitting(false); }); if (res && res.data?.data?.valid) { setError(null); setSuccessMessage( - "Email successfully verified! Redirecting you..." + t('emailVerified') ); setTimeout(() => { if (redirect) { @@ -108,16 +107,16 @@ export default function VerifyEmailForm({ setIsResending(true); const res = await api.post("/auth/verify-email/request").catch((e) => { - setError(formatAxiosError(e, "An error occurred")); - console.error("Failed to resend verification code:", e); + setError(formatAxiosError(e, t('errorOccurred'))); + console.error(t('verificationCodeErrorResend'), e); }); if (res) { setError(null); toast({ variant: "default", - title: "Verification code resent", - description: "We've resent a verification code to your email address. Please check your inbox.", + title: t('verificationCodeResend'), + description: t('verificationCodeResendDescription'), }); } diff --git a/src/app/components/SupporterMessage.tsx b/src/app/components/SupporterMessage.tsx index d9869f7b..2f415e14 100644 --- a/src/app/components/SupporterMessage.tsx +++ b/src/app/components/SupporterMessage.tsx @@ -6,6 +6,7 @@ import { Star } from "lucide-react"; import { useTranslations } from 'next-intl'; export default function SupporterMessage({ tier }: { tier: string }) { + const t = useTranslations(); return ( diff --git a/src/app/invite/page.tsx b/src/app/invite/page.tsx index 5ba30dd8..bf423a75 100644 --- a/src/app/invite/page.tsx +++ b/src/app/invite/page.tsx @@ -6,9 +6,7 @@ import { AxiosResponse } from "axios"; import { redirect } from "next/navigation"; import InviteStatusCard from "./InviteStatusCard"; import { formatAxiosError } from "@app/lib/api"; -import { useTranslations } from "next-intl"; - -; +import { getTranslations } from 'next-intl/server'; export default async function InvitePage(props: { searchParams: Promise<{ [key: string]: string | string[] | undefined }>; @@ -22,8 +20,7 @@ export default async function InvitePage(props: { } const user = await verifySession(); - - const t = useTranslations(); + const t = await getTranslations(); const parts = tokenParam.split("-"); if (parts.length !== 2) { diff --git a/src/app/navigation.tsx b/src/app/navigation.tsx index 7ee9ec75..8ea3c080 100644 --- a/src/app/navigation.tsx +++ b/src/app/navigation.tsx @@ -10,7 +10,6 @@ import { KeyRound, TicketCheck } from "lucide-react"; -import { useTranslations } from "next-intl"; export const orgLangingNavItems: SidebarNavItem[] = [ { diff --git a/src/app/setup/layout.tsx b/src/app/setup/layout.tsx index 6b1b80e3..e254037d 100644 --- a/src/app/setup/layout.tsx +++ b/src/app/setup/layout.tsx @@ -11,7 +11,6 @@ import { ListUserOrgsResponse } from "@server/routers/org"; import { internal } from "@app/lib/api"; import { AxiosResponse } from "axios"; import { authCookieHeader } from "@app/lib/api/cookies"; -import { useTranslations } from "next-intl"; export const metadata: Metadata = { title: `Setup - Pangolin`, diff --git a/src/app/setup/page.tsx b/src/app/setup/page.tsx index a6e63f58..293dc24a 100644 --- a/src/app/setup/page.tsx +++ b/src/app/setup/page.tsx @@ -45,6 +45,7 @@ const orgSchema = z.object({ export default function StepperForm() { const [currentStep, setCurrentStep] = useState("org"); const [orgIdTaken, setOrgIdTaken] = useState(false); + const t = useTranslations(); const [loading, setLoading] = useState(false); const [isChecked, setIsChecked] = useState(false); @@ -106,15 +107,13 @@ export default function StepperForm() { } catch (e) { console.error(e); setError( - formatAxiosError(e, "An error occurred while creating org") + formatAxiosError(e, t('orgErrorCreate')) ); } setLoading(false); } - const t = useTranslations(); - return ( <>