feat(i18n): extract strings from navigation, dialogs, onboarding, settings, and login

- Add useTranslation() to TopNav, BottomTabBar, FabMenu, UserMenu
- Internationalize ConfirmDialog, AuthPromptModal, ExternalLinkDialog
- Extract all onboarding flow strings (Welcome, HobbyPicker, ItemBrowser, Review, Done)
- Internationalize settings page (weight unit, currency, API keys, import/export)
- Internationalize login page and root error boundary
- All dialogs in __root.tsx use t() for UI chrome

Phase 34, Plan 02 (core navigation and global UI)
This commit is contained in:
2026-04-13 18:19:29 +02:00
parent 8c0fb31df2
commit 672b17fd13
15 changed files with 123 additions and 98 deletions

View File

@@ -1,7 +1,9 @@
import { useTranslation } from "react-i18next";
import { useDeleteItem, useItems } from "../hooks/useItems";
import { useUIStore } from "../stores/uiStore";
export function ConfirmDialog() {
const { t } = useTranslation();
const confirmDeleteItemId = useUIStore((s) => s.confirmDeleteItemId);
const closeConfirmDelete = useUIStore((s) => s.closeConfirmDelete);
const deleteItem = useDeleteItem();
@@ -30,12 +32,10 @@ export function ConfirmDialog() {
/>
<div className="relative bg-white rounded-xl shadow-lg p-6 max-w-sm mx-4 w-full">
<h3 className="text-lg font-semibold text-gray-900 mb-2">
Delete Item
{t("confirm.deleteItem")}
</h3>
<p className="text-sm text-gray-600 mb-6">
Are you sure you want to delete{" "}
<span className="font-medium">{itemName}</span>? This action cannot be
undone.
{t("confirm.deleteItemMessage", { name: itemName })}
</p>
<div className="flex justify-end gap-3">
<button
@@ -43,7 +43,7 @@ export function ConfirmDialog() {
onClick={closeConfirmDelete}
className="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors"
>
Cancel
{t("actions.cancel")}
</button>
<button
type="button"
@@ -51,7 +51,7 @@ export function ConfirmDialog() {
disabled={deleteItem.isPending}
className="px-4 py-2 text-sm font-medium text-white bg-red-600 hover:bg-red-700 disabled:opacity-50 rounded-lg transition-colors"
>
{deleteItem.isPending ? "Deleting..." : "Delete"}
{deleteItem.isPending ? t("actions.deleting") : t("actions.delete")}
</button>
</div>
</div>