From 9a4815e1658f741c15661d0d2af30c1be4d260ea Mon Sep 17 00:00:00 2001 From: Thomas Jespersen Date: Sun, 26 Jan 2025 21:00:18 +0100 Subject: [PATCH 1/5] Change the change-locale endpoint in LocalSwitcher to use the new users/me endpoint --- .../infrastructure/translations/LocaleSwitcher.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/shared-webapp/infrastructure/translations/LocaleSwitcher.tsx b/application/shared-webapp/infrastructure/translations/LocaleSwitcher.tsx index f9c010893..405b1b9d4 100644 --- a/application/shared-webapp/infrastructure/translations/LocaleSwitcher.tsx +++ b/application/shared-webapp/infrastructure/translations/LocaleSwitcher.tsx @@ -29,7 +29,7 @@ export function LocaleSwitcher() { const newLocale = [...selection][0] as Locale; if (newLocale != null) { if (userInfo?.isAuthenticated) { - await fetch("/api/account-management/users/change-locale", { + await fetch("/api/account-management/users/me/change-locale", { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ locale: newLocale }) From 88e4dde05cce83a2c049b45a643f1acc7f9cbd4b Mon Sep 17 00:00:00 2001 From: Thomas Jespersen Date: Sun, 26 Jan 2025 22:19:33 +0100 Subject: [PATCH 2/5] Use state to force I18nProvider to rerender when changing language --- .../infrastructure/translations/Translation.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/application/shared-webapp/infrastructure/translations/Translation.tsx b/application/shared-webapp/infrastructure/translations/Translation.tsx index 07cf122de..5634dd034 100644 --- a/application/shared-webapp/infrastructure/translations/Translation.tsx +++ b/application/shared-webapp/infrastructure/translations/Translation.tsx @@ -1,4 +1,4 @@ -import { useMemo } from "react"; +import { useMemo, useState } from "react"; import { I18nProvider } from "@lingui/react"; import { i18n, type Messages } from "@lingui/core"; import localeMap from "./i18n.config.json"; @@ -118,19 +118,25 @@ type TranslationProviderProps = { }; function TranslationProvider({ children, translation }: Readonly) { + const [currentLocale, setCurrentLocale] = useState(i18n.locale); + const value: TranslationContext = useMemo( () => ({ setLocale: async (locale: string) => { await translation.dynamicActivate(locale); + setCurrentLocale(locale); // Update state to force re-render }, locales: translation.locales, getLocaleInfo: translation.getLocaleInfo }), [translation] ); + return ( - {children} + + {children} + ); } From 00ed2fa56b21a270dfe49efc09d534951a90367b Mon Sep 17 00:00:00 2001 From: Thomas Jespersen Date: Sun, 26 Jan 2025 22:53:30 +0100 Subject: [PATCH 3/5] Ensure that language can be changed using the keyboard --- .../translations/LocaleSwitcher.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/application/shared-webapp/infrastructure/translations/LocaleSwitcher.tsx b/application/shared-webapp/infrastructure/translations/LocaleSwitcher.tsx index 405b1b9d4..3d38c9e79 100644 --- a/application/shared-webapp/infrastructure/translations/LocaleSwitcher.tsx +++ b/application/shared-webapp/infrastructure/translations/LocaleSwitcher.tsx @@ -1,4 +1,4 @@ -import { LanguagesIcon } from "lucide-react"; +import { LanguagesIcon, CheckIcon } from "lucide-react"; import { type Locale, translationContext } from "./TranslationContext"; import { use, useContext, useMemo, useState } from "react"; import { useLingui } from "@lingui/react"; @@ -26,8 +26,10 @@ export function LocaleSwitcher() { ); const handleLocaleChange = async (selection: Selection) => { + setIsOpen(false); + const newLocale = [...selection][0] as Locale; - if (newLocale != null) { + if (newLocale != null && newLocale !== currentLocale) { if (userInfo?.isAuthenticated) { await fetch("/api/account-management/users/me/change-locale", { method: "PUT", @@ -43,8 +45,6 @@ export function LocaleSwitcher() { await setLocale(newLocale); localStorage.setItem(preferredLocaleKey, newLocale); } - - setIsOpen(false); } }; @@ -58,15 +58,18 @@ export function LocaleSwitcher() { {items.map((item) => ( - {item.label} +
+ {item.label} + {item.id === currentLocale && } +
))}
From 7c4ceadaa37334a9b9e266cffcbb50c9c02b6b46 Mon Sep 17 00:00:00 2001 From: Thomas Jespersen Date: Sun, 26 Jan 2025 23:20:04 +0100 Subject: [PATCH 4/5] Enhance LocaleSwitcher with keyboard navigation and consistent menu styling --- .../translations/LocaleSwitcher.tsx | 67 ++++++++----------- 1 file changed, 27 insertions(+), 40 deletions(-) diff --git a/application/shared-webapp/infrastructure/translations/LocaleSwitcher.tsx b/application/shared-webapp/infrastructure/translations/LocaleSwitcher.tsx index 3d38c9e79..9d8b4185f 100644 --- a/application/shared-webapp/infrastructure/translations/LocaleSwitcher.tsx +++ b/application/shared-webapp/infrastructure/translations/LocaleSwitcher.tsx @@ -1,17 +1,14 @@ import { LanguagesIcon, CheckIcon } from "lucide-react"; import { type Locale, translationContext } from "./TranslationContext"; -import { use, useContext, useMemo, useState } from "react"; +import { use, useContext, useMemo } from "react"; import { useLingui } from "@lingui/react"; import { Button } from "@repo/ui/components/Button"; -import { ListBox, ListBoxItem } from "@repo/ui/components/ListBox"; -import { Popover } from "@repo/ui/components/Popover"; -import { DialogTrigger } from "@repo/ui/components/Dialog"; -import type { Selection } from "react-aria-components"; +import { Menu, MenuItem, MenuTrigger } from "@repo/ui/components/Menu"; import { AuthenticationContext } from "@repo/infrastructure/auth/AuthenticationProvider"; import { preferredLocaleKey } from "./constants"; +import type { Key } from "@react-types/shared"; export function LocaleSwitcher() { - const [isOpen, setIsOpen] = useState(false); const { setLocale, getLocaleInfo, locales } = use(translationContext); const { i18n } = useLingui(); const { userInfo } = useContext(AuthenticationContext); @@ -25,25 +22,24 @@ export function LocaleSwitcher() { [locales, getLocaleInfo] ); - const handleLocaleChange = async (selection: Selection) => { - setIsOpen(false); - - const newLocale = [...selection][0] as Locale; - if (newLocale != null && newLocale !== currentLocale) { + const handleLocaleChange = (key: Key) => { + const locale = key.toString() as Locale; + if (locale !== currentLocale) { if (userInfo?.isAuthenticated) { - await fetch("/api/account-management/users/me/change-locale", { + void fetch("/api/account-management/users/me/change-locale", { method: "PUT", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ locale: newLocale }) + body: JSON.stringify({ locale }) }) .then(async (_) => { - await setLocale(newLocale); - localStorage.setItem(preferredLocaleKey, newLocale); + await setLocale(locale); + localStorage.setItem(preferredLocaleKey, locale); }) .catch((error) => console.error("Failed to update locale:", error)); } else { - await setLocale(newLocale); - localStorage.setItem(preferredLocaleKey, newLocale); + void setLocale(locale).then(() => { + localStorage.setItem(preferredLocaleKey, locale); + }); } } }; @@ -51,29 +47,20 @@ export function LocaleSwitcher() { const currentLocale = i18n.locale as Locale; return ( - - - - - {items.map((item) => ( - -
- {item.label} - {item.id === currentLocale && } -
-
- ))} -
-
-
+ + {items.map((item) => ( + +
+ {item.label} + {item.id === currentLocale && } +
+
+ ))} +
+ ); } From 13b2403216029fb18a5b9e477d0331725390b85f Mon Sep 17 00:00:00 2001 From: Thomas Jespersen Date: Sun, 26 Jan 2025 23:52:35 +0100 Subject: [PATCH 5/5] Add spacing between top menu buttons to prevent border cropping --- .../WebApp/shared/components/topMenu/index.tsx | 2 +- .../back-office/WebApp/shared/components/topMenu/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/application/account-management/WebApp/shared/components/topMenu/index.tsx b/application/account-management/WebApp/shared/components/topMenu/index.tsx index 40861915b..98b0e57bd 100644 --- a/application/account-management/WebApp/shared/components/topMenu/index.tsx +++ b/application/account-management/WebApp/shared/components/topMenu/index.tsx @@ -22,7 +22,7 @@ export function TopMenu({ children }: Readonly) { {children}
- +