add i18n to frontend

This commit is contained in:
Eduard Gert
2026-05-15 16:22:14 +02:00
parent cccb0e9230
commit 5bdccfe8f4
44 changed files with 1953 additions and 932 deletions
@@ -1,6 +1,8 @@
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { Dialogs, Events } from "@wailsio/runtime";
import { Connection, WindowManager } from "@bindings/services";
import i18next from "@/lib/i18n";
import { ToggleSwitch } from "@/components/ToggleSwitch.tsx";
import { useStatus } from "@/hooks/useStatus";
import { useProfile } from "@/modules/profile/ProfileContext.tsx";
@@ -14,11 +16,11 @@ enum ConnectionState {
Disconnecting = "disconnecting",
}
const STATUS_LABEL: Record<ConnectionState, string> = {
[ConnectionState.Disconnected]: "Disconnected",
[ConnectionState.Connecting]: "Connecting...",
[ConnectionState.Connected]: "Connected",
[ConnectionState.Disconnecting]: "Disconnecting...",
const STATUS_KEY: Record<ConnectionState, string> = {
[ConnectionState.Disconnected]: "connect.status.disconnected",
[ConnectionState.Connecting]: "connect.status.connecting",
[ConnectionState.Connected]: "connect.status.connected",
[ConnectionState.Disconnecting]: "connect.status.disconnecting",
};
const EVENT_BROWSER_LOGIN_CANCEL = "browser-login:cancel";
@@ -90,7 +92,7 @@ async function startLogin(): Promise<void> {
WindowManager.CloseBrowserLogin().catch(console.error);
if (cancelled) return;
await Dialogs.Error({
Title: "Login Failed",
Title: i18next.t("connect.error.loginTitle"),
Message: errorMessage(e),
});
} finally {
@@ -100,6 +102,7 @@ async function startLogin(): Promise<void> {
}
export const ConnectionStatusSwitch = () => {
const { t } = useTranslation();
const { status, refresh } = useStatus();
const { activeProfile, username } = useProfile();
@@ -141,7 +144,7 @@ export const ConnectionStatusSwitch = () => {
});
} catch (e) {
await Dialogs.Error({
Title: "Connect Failed",
Title: t("connect.error.connectTitle"),
Message: errorMessage(e),
});
} finally {
@@ -156,7 +159,7 @@ export const ConnectionStatusSwitch = () => {
await Connection.Down();
} catch (e) {
await Dialogs.Error({
Title: "Disconnect Failed",
Title: t("connect.error.disconnectTitle"),
Message: errorMessage(e),
});
} finally {
@@ -215,10 +218,10 @@ export const ConnectionStatusSwitch = () => {
}
>
{unreachable
? "Daemon unavailable"
? t("connect.status.daemonUnavailable")
: needsLogin
? "Login required"
: STATUS_LABEL[connState]}
? t("connect.status.loginRequired")
: t(STATUS_KEY[connState])}
</h1>
<p
className={cn(
@@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import { CardNavItem } from "@/components/CardNavItem.tsx";
import { Layers3Icon, MonitorSmartphoneIcon } from "lucide-react";
import deFlag from "@/assets/flags/1x1/de.svg";
@@ -8,32 +9,33 @@ type Props = {
};
export const Navigation = ({ peersActive = false, onPeersClick }: Props) => {
const { t } = useTranslation();
return (
<nav className={"w-full flex flex-col gap-1 mt-auto"}>
<CardNavItem
icon={MonitorSmartphoneIcon}
title={"Peers"}
description={"17 of 25 Online"}
title={t("nav.peers.title")}
description={t("nav.peers.description", { online: 17, total: 25 })}
active={peersActive}
onClick={onPeersClick}
/>
<CardNavItem
icon={Layers3Icon}
title={"Resources"}
description={"13 of 16 Active"}
title={t("nav.resources.title")}
description={t("nav.resources.description", { active: 13, total: 16 })}
iconSize={14}
/>
<CardNavItem
iconNode={
<img
src={deFlag}
alt={"Germany"}
alt={t("nav.exitNode.flagAlt", { country: "Germany" })}
className={
"h-6 w-6 rounded-full border-[3px] border-nb-gray-850 shrink-0"
}
/>
}
title={"Exit Node Berlin"}
title={t("nav.exitNode.title", { location: "Berlin" })}
description={"100.92.14.37"}
/>
</nav>