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,3 +1,4 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { LucideIcon } from "../../lib/iconData";
|
||||
|
||||
interface ReviewItem {
|
||||
@@ -23,6 +24,7 @@ export function OnboardingReview({
|
||||
onSkip,
|
||||
isSubmitting,
|
||||
}: OnboardingReviewProps) {
|
||||
const { t } = useTranslation("onboarding");
|
||||
// Group by category
|
||||
const grouped = new Map<string, ReviewItem[]>();
|
||||
for (const item of items) {
|
||||
@@ -35,12 +37,12 @@ export function OnboardingReview({
|
||||
<div className="flex flex-col items-center justify-center min-h-screen px-8">
|
||||
<div className="max-w-2xl w-full text-center">
|
||||
<h1 className="text-3xl font-bold text-gray-900 mb-2">
|
||||
Your starting collection
|
||||
{t("review.title")}
|
||||
</h1>
|
||||
<p className="text-base text-gray-500 mb-8">
|
||||
{items.length > 0
|
||||
? `${items.length} ${items.length === 1 ? "item" : "items"} ready to add`
|
||||
: "No items selected — you can always add gear later from the catalog."}
|
||||
? t("review.itemsReady", { count: items.length })
|
||||
: t("review.noItemsSelected")}
|
||||
</p>
|
||||
|
||||
{items.length > 0 && (
|
||||
@@ -101,7 +103,7 @@ export function OnboardingReview({
|
||||
disabled={isSubmitting}
|
||||
className="px-8 py-3 bg-gray-700 hover:bg-gray-800 disabled:opacity-50 text-white font-medium rounded-lg transition-colors"
|
||||
>
|
||||
{isSubmitting ? "Adding..." : "Add to my collection"}
|
||||
{isSubmitting ? t("review.adding") : t("review.addToCollection")}
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
@@ -109,7 +111,7 @@ export function OnboardingReview({
|
||||
onClick={onSkip}
|
||||
className="px-8 py-3 bg-gray-700 hover:bg-gray-800 text-white font-medium rounded-lg transition-colors"
|
||||
>
|
||||
Continue
|
||||
{t("common:actions.continue")}
|
||||
</button>
|
||||
)}
|
||||
{items.length > 0 && (
|
||||
@@ -118,7 +120,7 @@ export function OnboardingReview({
|
||||
onClick={onSkip}
|
||||
className="text-sm text-gray-400 hover:text-gray-600 transition-colors"
|
||||
>
|
||||
Skip this step
|
||||
{t("common:actions.skipStep")}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user