Skip to content

Commit 9dcaf6c

Browse files
authored
Add new languages (#716)
* some translation updates * Add a note about the weblate * Add the newly supported languages * get stuff working * address feedback
1 parent 070ea74 commit 9dcaf6c

File tree

10 files changed

+495
-459
lines changed

10 files changed

+495
-459
lines changed

client/public/locales/de/translation.json

Lines changed: 415 additions & 415 deletions
Large diffs are not rendered by default.

client/public/locales/en-us/translation.json

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"10_months": "10 Months",
33
"11_months": "11 Months",
4-
"12_months": "12 months",
4+
"12_months": "12 Months",
55
"1_month": "1 Month",
66
"2_months": "2 Months",
7-
"3_months": "3 months",
7+
"3_months": "3 Months",
88
"4_months": "4 Months",
99
"5_months": "5 Months",
10-
"6_months": "6 months",
10+
"6_months": "6 Months",
1111
"7_months": "7 Months",
1212
"8_months": "8 Months",
1313
"9_months": "9 Months",
@@ -120,6 +120,7 @@
120120
"date_is_required": "Date is required.",
121121
"date_range": "Date Range",
122122
"days_since_deleted": "{{days}} days since deleted",
123+
"de": "German",
123124
"decimal_separator": "Decimal Separator",
124125
"decimal_separator_required_message": "Decimal separator is required.",
125126
"delete": "Delete",
@@ -321,6 +322,7 @@
321322
"please_select_valid_csv_file_message": "Please select a valid CSV file.",
322323
"preferred_currency": "Preferred Currency",
323324
"preferred_language": "Preferred Language",
325+
"preferred_language_description": "Translations may be incorrect or incomplete. If you notice any issues, please consider contributing a fix on <0>Weblate</0>.",
324326
"purchase_date": "Purchase Date",
325327
"purchase_price": "Purchase Price",
326328
"purchased_on_for": "Purchased on {{date}} for {{price}}.",
@@ -437,5 +439,6 @@
437439
"view_and_restore_deleted_assets": "View and restore deleted assets.",
438440
"view_and_restore_deleted_transactions": "View and restore deleted transactions.",
439441
"welcome_to": "Welcome to",
440-
"widget_no_items_configured_message": "No items are configured for this widget."
442+
"widget_no_items_configured_message": "No items are configured for this widget.",
443+
"zh_hans": "Chinese (Simplified)"
441444
}
Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
{
2-
"10_months": "10 Mois",
3-
"11_months": "11 Mois",
4-
"12_months": "12 Mois",
5-
"1_month": "1 Mois",
6-
"2_months": "2 Mois",
7-
"4_months": "4 mois",
8-
"5_months": "5 mois",
9-
"6_months": "6 mois",
10-
"7_months": "7 mois",
11-
"3_months": "3 mois",
12-
"8_months": "8 mois",
13-
"9_months": "9 mois",
14-
"account": "Compte",
15-
"a_simple_app_for_managing_monthly_budgets": "Une application simple pour gérer vos budgets mensuels.",
16-
"account_column_is_required_message": "La colonne « Compte » est obligatoire.",
17-
"account_created_email_verification_message": "Compte créé. Vérifiez votre boîte mail pour trouver le message de vérification.",
18-
"account_created_successfully_message": "Compte créé avec succès.",
19-
"account_details": "Détails du compte",
20-
"account_is_required": "Un compte est nécessaire.",
21-
"account_mapping": "Cartographie des comptes",
22-
"account_name": "Nom du compte",
23-
"account_trends": "Tendances du compte",
24-
"account_type": "Type de compte",
25-
"accounts": "Comptes",
26-
"accounts_settings": "Paramètres des comptes",
27-
"add_balance": "Ajouter un solde",
28-
"add_category": "Ajouter une catégorie"
2+
"10_months": "10 Mois",
3+
"11_months": "11 Mois",
4+
"12_months": "12 Mois",
5+
"1_month": "1 Mois",
6+
"2_months": "2 Mois",
7+
"3_months": "3 Mois",
8+
"4_months": "4 Mois",
9+
"5_months": "5 Mois",
10+
"6_months": "6 Mois",
11+
"7_months": "7 Mois",
12+
"8_months": "8 Mois",
13+
"9_months": "9 Mois",
14+
"a_simple_app_for_managing_monthly_budgets": "Une application simple pour gérer vos budgets mensuels.",
15+
"account": "Compte",
16+
"account_column_is_required_message": "La colonne « Compte » est obligatoire.",
17+
"account_created_email_verification_message": "Compte créé. Vérifiez votre boîte mail pour trouver le message de vérification.",
18+
"account_created_successfully_message": "Compte créé avec succès.",
19+
"account_details": "Détails du compte",
20+
"account_is_required": "Un compte est nécessaire.",
21+
"account_mapping": "Cartographie des comptes",
22+
"account_name": "Nom du compte",
23+
"account_trends": "Tendances du compte",
24+
"account_type": "Type de compte",
25+
"accounts": "Comptes",
26+
"accounts_settings": "Paramètres des comptes",
27+
"add_balance": "Ajouter un solde",
28+
"add_category": "Ajouter une catégorie"
2929
}
File renamed without changes.

client/src/app/Authorized/PageContent/Settings/UserSettings/UserSettings.tsx

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { notifications } from "@mantine/notifications";
44
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
55
import { AxiosResponse } from "axios";
66
import React from "react";
7+
import { Trans, useTranslation } from "react-i18next";
78
import { useAuth } from "~/providers/AuthProvider/AuthProvider";
89
import { translateAxiosError } from "~/helpers/requests";
910
import {
@@ -15,7 +16,7 @@ import {
1516
import Card from "~/components/core/Card/Card";
1617
import PrimaryText from "~/components/core/Text/PrimaryText/PrimaryText";
1718
import Select from "~/components/core/Select/Select/Select";
18-
import { useTranslation } from "react-i18next";
19+
import DimmedText from "~/components/core/Text/DimmedText/DimmedText";
1920

2021
const UserSettings = (): React.ReactNode => {
2122
const currencyField = useField({
@@ -108,7 +109,28 @@ const UserSettings = (): React.ReactNode => {
108109
/>
109110
<Select
110111
label={
111-
<PrimaryText size="sm">{t("preferred_language")}</PrimaryText>
112+
<Stack gap="0">
113+
<PrimaryText size="sm">
114+
{t("preferred_language")}
115+
</PrimaryText>
116+
<DimmedText size="xs">
117+
<Trans
118+
i18nKey="preferred_language_description"
119+
components={[
120+
<a
121+
key="link"
122+
href="https://hosted.weblate.org/engage/budget-board/"
123+
target="_blank"
124+
rel="noopener noreferrer"
125+
style={{
126+
color: "inherit",
127+
textDecoration: "underline",
128+
}}
129+
/>,
130+
]}
131+
/>
132+
</DimmedText>
133+
</Stack>
112134
}
113135
placeholder={t("select_your_preferred_language")}
114136
data={Languages.map((lang: LanguageItem) => ({

client/src/models/userSettings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,6 @@ export class LanguageItem {
3434
export const Languages: LanguageItem[] = [
3535
{ value: "default", label: "system_default" },
3636
{ value: "en-us", label: "en_us" },
37+
{ value: "de", label: "de" },
38+
{ value: "zh-hans", label: "zh_hans" },
3739
];

server/BudgetBoard.Database/Models/UserSettings.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,14 @@ public static class SupportedLanguages
2323
{
2424
public const string SystemDefault = "default";
2525
public const string EnglishUnitedStates = "en-us";
26-
public static List<string> AllLanguages { get; } = [SystemDefault, EnglishUnitedStates];
26+
public const string German = "de";
27+
public const string ChineseSimplified = "zh-hans";
28+
29+
public static List<string> SupportedCultureNames { get; } =
30+
[EnglishUnitedStates, German, ChineseSimplified];
31+
32+
public static List<string> AllUserLanguageOptions { get; } =
33+
[SystemDefault, .. SupportedCultureNames];
2734
}
2835

2936
public class UserSettings

server/BudgetBoard.Service/UserSettingsService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public async Task UpdateUserSettingsAsync(Guid userGuid, IUserSettingsUpdateRequ
6464

6565
if (!string.IsNullOrEmpty(request.Language))
6666
{
67-
var isValidLanguage = SupportedLanguages.AllLanguages.Contains(
67+
var isValidLanguage = SupportedLanguages.AllUserLanguageOptions.Contains(
6868
request.Language.ToLower()
6969
);
7070
if (!isValidLanguage)

server/BudgetBoard.WebAPI/Program.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -299,25 +299,26 @@
299299
// Activate the CORS policy
300300
app.UseCors(MyAllowSpecificOrigins);
301301

302-
// Add localization support
303-
var supportedCultures = new[] { "en-US" };
302+
// Enable authentication and authorization after CORS Middleware
303+
// processing (UseCors) in case the Authorization Middleware tries
304+
// to initiate a challenge before the CORS Middleware has a chance
305+
// to set the appropriate headers.
306+
app.UseAuthentication();
307+
app.UseAuthorization();
308+
309+
// Add localization support after authentication so user identity is available
310+
var supportedCultures = SupportedLanguages.SupportedCultureNames.ToArray();
304311
var localizationOptions = new RequestLocalizationOptions()
305312
.SetDefaultCulture(supportedCultures[0])
306313
.AddSupportedCultures(supportedCultures)
307314
.AddSupportedUICultures(supportedCultures);
308315

309316
// Insert custom user language provider at the beginning of the list
317+
// Falls back to browser locale if user hasn't configured a language
310318
localizationOptions.RequestCultureProviders.Insert(0, new UserLanguageCultureProvider());
311319

312320
app.UseRequestLocalization(localizationOptions);
313321

314-
// Enable authentication and authorization after CORS Middleware
315-
// processing (UseCors) in case the Authorization Middleware tries
316-
// to initiate a challenge before the CORS Middleware has a chance
317-
// to set the appropriate headers.
318-
app.UseAuthentication();
319-
app.UseAuthorization();
320-
321322
app.MapControllers();
322323

323324
// Automatically apply any Db changes

server/BudgetBoard.WebAPI/Utils/UserLanguageCultureProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ HttpContext httpContext
6363
// If there's any error reading the database, fall through to the next provider
6464
}
6565

66+
// User has no language preference or set to "default", fall back to browser locale
6667
return null;
6768
}
6869
}

0 commit comments

Comments
 (0)