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:
@@ -1,4 +1,5 @@
|
||||
import { getTagsForHobbies } from "@/shared/hobbyConfig";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { usePopularItems } from "../../hooks/useOnboarding";
|
||||
import { SelectableItemCard } from "./SelectableItemCard";
|
||||
|
||||
@@ -17,6 +18,7 @@ export function OnboardingItemBrowser({
|
||||
onContinue,
|
||||
onSkip,
|
||||
}: OnboardingItemBrowserProps) {
|
||||
const { t } = useTranslation("onboarding");
|
||||
const tags = getTagsForHobbies(selectedHobbies);
|
||||
const { data: items, isLoading } = usePopularItems(tags);
|
||||
|
||||
@@ -48,11 +50,12 @@ export function OnboardingItemBrowser({
|
||||
<div className="flex flex-col items-center min-h-screen px-8 py-16">
|
||||
<div className="max-w-5xl w-full text-center">
|
||||
<h1 className="text-3xl font-bold text-gray-900 mb-2">
|
||||
Popular gear for{" "}
|
||||
{selectedHobbies.length === 1 ? selectedHobbies[0] : "your hobbies"}
|
||||
{selectedHobbies.length === 1
|
||||
? t("items.title", { hobby: selectedHobbies[0] })
|
||||
: t("items.titleMultiple")}
|
||||
</h1>
|
||||
<p className="text-base text-gray-500 mb-8">
|
||||
Tap items you already own. We'll add them to your collection.
|
||||
{t("items.subtitle")}
|
||||
</p>
|
||||
|
||||
{isLoading && (
|
||||
@@ -64,11 +67,10 @@ export function OnboardingItemBrowser({
|
||||
{!isLoading && !hasItems && (
|
||||
<div className="py-12 text-center">
|
||||
<h2 className="text-lg font-semibold text-gray-900 mb-2">
|
||||
No gear cataloged yet
|
||||
{t("items.noCatalog")}
|
||||
</h2>
|
||||
<p className="text-base text-gray-500 mb-8">
|
||||
We're still building our catalog for this hobby. You can skip this
|
||||
step and add gear manually later.
|
||||
{t("items.noCatalogDescription")}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
@@ -105,8 +107,7 @@ export function OnboardingItemBrowser({
|
||||
onClick={onContinue}
|
||||
className="px-8 py-3 bg-gray-700 hover:bg-gray-800 text-white font-medium rounded-lg transition-colors"
|
||||
>
|
||||
Review {selectedItemIds.size}{" "}
|
||||
{selectedItemIds.size === 1 ? "item" : "items"}
|
||||
{t("items.reviewCount", { count: selectedItemIds.size })}
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
@@ -114,7 +115,7 @@ export function OnboardingItemBrowser({
|
||||
onClick={onSkip}
|
||||
className="text-sm text-gray-400 hover:text-gray-600 transition-colors"
|
||||
>
|
||||
Skip this step
|
||||
{t("common:actions.skipStep")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user