From 0b796440f1672d7c4e48572f849bcf0b983456f3 Mon Sep 17 00:00:00 2001 From: SkateSpots Date: Fri, 2 Oct 2026 10:11:06 +0700 Subject: [PATCH] =?UTF-8?q?feat(i18n):=20Spanish=20batch=202=20=E2=80=94?= =?UTF-8?q?=20nav/chrome,=20events/shops/tours,=20crews/DMs,=20settings/au?= =?UTF-8?q?th,=20wallet/stash/newsletter/stats?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ~3,470 new keys (5,770 total, EN=ES), ~115 more files wired. - nav + chromeUi: header, More menu, burger menu, footer, map toolbar widgets (sort/trust/weather), spot-type label helper. - placesUi: events, shops, tours, food. socialUi: crews, DMs, notifications, collectives, crew chat/coordinator. settingsUi: settings, auth/signup, onboarding, profile edit, legal. walletUi: wallet/Cashu, stash, mints, app shop, newsletter, community stats, leaderboards, profile. - Fixed 738 usages where an agent dropped the socialUi. prefix (caught by check:i18n). --- AGENTS.md | 25 +- src/components/AddToCalendar.tsx | 8 +- src/components/AddToCollectionDialog.tsx | 52 +- src/components/AdminReviewCard.tsx | 8 +- src/components/AmberApprovalHint.tsx | 15 +- src/components/AttendeeList.tsx | 19 +- src/components/BetaDisclaimerDialog.tsx | 25 +- src/components/CollectiveJoinRequestCard.tsx | 30 +- src/components/CollectiveMembers.tsx | 34 +- src/components/ConfirmMembershipCard.tsx | 27 +- src/components/CoordinatorSettingsCard.tsx | 112 +- src/components/CrewAgentPanel.tsx | 49 +- src/components/CrewBadge.tsx | 14 +- src/components/CrewChat.tsx | 62 +- src/components/CrewForm.tsx | 291 +- src/components/CrewInviteCard.tsx | 24 +- src/components/CrewInviteDialog.tsx | 58 +- src/components/CrewLinkField.tsx | 13 +- src/components/CrewLookingFor.tsx | 6 +- src/components/CrewNip05Badge.tsx | 6 +- src/components/CrewRequestToJoin.tsx | 22 +- src/components/CrewTreasuryCard.tsx | 22 +- src/components/DestinationSearch.tsx | 19 +- src/components/EditProfileForm.tsx | 159 +- src/components/ErrorState.tsx | 15 +- src/components/EventCard.tsx | 25 +- src/components/EventCountdown.tsx | 20 +- src/components/EventSponsors.tsx | 4 +- src/components/EventUpdates.tsx | 42 +- src/components/EventsCalendar.tsx | 63 +- src/components/FeaturedEventUpgrade.tsx | 35 +- src/components/FollowListManager.tsx | 38 +- src/components/GrantProCard.tsx | 28 +- src/components/JoinRequestCard.tsx | 45 +- src/components/Layout.tsx | 103 +- src/components/MemberVisibilityControl.tsx | 16 +- src/components/MyDataTab.tsx | 118 +- src/components/NewMessageDialog.tsx | 34 +- src/components/NewsletterBackfillPanel.tsx | 22 +- src/components/NewsletterComposer.tsx | 35 +- src/components/NewsletterIssueView.tsx | 8 +- src/components/NewsletterOverlay.tsx | 17 +- src/components/NewsletterSubscribeButton.tsx | 24 +- src/components/Nip05Required.tsx | 20 +- src/components/NotificationBell.tsx | 69 +- src/components/NotificationSettingsCard.tsx | 62 +- src/components/RegionBackfillCard.tsx | 40 +- src/components/RelatrSettings.tsx | 72 +- src/components/RelayListManager.tsx | 73 +- src/components/RequestToJoinCollective.tsx | 27 +- src/components/RsvpButtons.tsx | 38 +- src/components/SecuritySettings.tsx | 130 +- src/components/ShareProfileDialog.tsx | 14 +- src/components/ShopBountyCard.tsx | 28 +- src/components/SkateNip05Input.tsx | 14 +- src/components/SortDropdown.tsx | 28 +- src/components/SpotMap.tsx | 7 +- src/components/TourCard.tsx | 63 +- src/components/TrustBadge.tsx | 16 +- src/components/TrustFilter.tsx | 34 +- src/components/UserStatusIndicator.tsx | 6 +- src/components/VouchCard.tsx | 35 +- src/components/WalletModal.tsx | 84 +- src/components/WeatherToggle.tsx | 6 +- src/components/ZapBadgesCard.tsx | 30 +- src/components/ZapButton.tsx | 6 +- src/components/ZapCrewDialog.tsx | 50 +- src/components/ZapDialog.tsx | 107 +- src/components/auth/AccountSwitcher.tsx | 10 +- src/components/auth/AmberCallbackHandler.tsx | 54 +- src/components/auth/LoginArea.tsx | 10 +- src/components/auth/LoginDialog.tsx | 131 +- src/components/auth/MnemonicSignupDialog.tsx | 106 +- src/components/auth/SignupDialog.tsx | 177 +- src/components/auth/SignupMethodDialog.tsx | 42 +- src/components/crew/CrewCoordinatorCard.tsx | 48 +- src/components/crew/CrewHero.tsx | 8 +- src/components/crew/CrewLeadership.tsx | 17 +- src/components/crew/CrewSponsorBanner.tsx | 6 +- src/components/crew/CrewSponsorPicker.tsx | 14 +- src/components/crew/CrewVideoSection.tsx | 18 +- src/components/onboarding/RelayEducation.tsx | 80 +- src/components/wallet/CashuWalletCard.tsx | 181 +- src/components/wallet/EscrowKeyCard.tsx | 19 +- .../wallet/LightningPrivacyTips.tsx | 65 +- src/components/wallet/MintPrivacyManager.tsx | 104 +- src/components/wallet/NwcWalletCard.tsx | 46 +- src/components/wallet/QRScannerModal.tsx | 20 +- .../wallet/RecoveryPhraseDialog.tsx | 23 +- .../wallet/WalletComparisonGuide.tsx | 55 +- src/hooks/useNavPreferences.ts | 14 +- src/i18n/en.ts | 3720 +++++++++++++++- src/i18n/es.ts | 3722 ++++++++++++++++- src/lib/spotTypeLabel.ts | 31 + src/pages/AboutPage.tsx | 109 +- src/pages/AdminReviewPage.tsx | 84 +- src/pages/AppShopPage.tsx | 113 +- src/pages/BountyLeaderboardPage.tsx | 83 +- src/pages/CollectionDetailPage.tsx | 50 +- src/pages/CommunityStatsPage.tsx | 179 +- src/pages/ContactsPage.tsx | 53 +- src/pages/ConversationPage.tsx | 80 +- src/pages/CreateCrewPage.tsx | 16 +- src/pages/CreateEventPage.tsx | 132 +- src/pages/CreateShopPage.tsx | 106 +- src/pages/CreateTourPage.tsx | 467 ++- src/pages/CrewDetailPage.tsx | 78 +- src/pages/CrewsPage.tsx | 86 +- src/pages/DirectMessagesPage.tsx | 68 +- src/pages/EditCrewPage.tsx | 16 +- src/pages/EditEventPage.tsx | 132 +- src/pages/EditShopPage.tsx | 112 +- src/pages/EditTourPage.tsx | 10 +- src/pages/EventDetailPage.tsx | 73 +- src/pages/EventsPage.tsx | 146 +- src/pages/FAQPage.tsx | 93 +- src/pages/FoodPage.tsx | 50 +- src/pages/GlossaryPage.tsx | 31 +- src/pages/GroupConversationPage.tsx | 30 +- src/pages/Index.tsx | 26 +- src/pages/LicensePage.tsx | 28 +- src/pages/MapPage.tsx | 5 +- src/pages/MintsPage.tsx | 107 +- src/pages/NIP19Page.tsx | 84 +- src/pages/NewsletterPage.tsx | 101 +- src/pages/NotFound.tsx | 10 +- src/pages/OnboardingPage.tsx | 219 +- src/pages/PrivacyPage.tsx | 139 +- src/pages/SettingsPage.tsx | 218 +- src/pages/ShopDetailPage.tsx | 68 +- src/pages/SignersPage.tsx | 105 +- src/pages/StashPage.tsx | 122 +- src/pages/SupportersPage.tsx | 71 +- src/pages/TourDetailPage.tsx | 84 +- src/pages/WalletPage.tsx | 42 +- src/pages/ZapLeaderboardPage.tsx | 31 +- 136 files changed, 11615 insertions(+), 3814 deletions(-) create mode 100644 src/lib/spotTypeLabel.ts diff --git a/AGENTS.md b/AGENTS.md index 51dc0ff..7d3cfcc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1642,14 +1642,23 @@ similar are internal endpoints/hook names, not credits — leave them.) chain) fails the build if any literal `t('…')` key is missing from `en` OR `es`, or if `en`/`es` drift. Dynamic template keys (`t(\`ns.${x}\`)`) are NOT checked — keep those few in sync by hand. -- **Coverage (2026-10-01, batch 1 done):** ~1,680 new keys (2,297 total) and ~65 - files wired — **Map (`mapUi`)**, **spots (`spotUi`)** incl. detail/create/edit/ - chat, **Marketplace/trades/offers/escrow/shipping (`marketUi`)**, and **Lab/ - `/become/*`/coaches/skaters (`labUi`)**. **Still to do (batch 2+):** Settings, - auth (LoginArea/dialogs), Onboarding, Events, Shops, Tours, Crews, DMs/group, - Stash, Newsletter, Community Stats, legal (About/FAQ/Privacy/License/Glossary), - Wallet/Mints, App Shop, Food, Bounties/leaderboards, Admin review. Untranslated - text falls back to English, so partial coverage degrades gracefully. +- **Coverage (2026-10-02, batches 1–2 done):** **~5,770 keys** (EN=ES) and ~180 + files wired. Namespaces: batch 1 — `mapUi`, `spotUi`, `marketUi`, `labUi`; + batch 2 — `nav` (header/More/burger labels) + `chromeUi` (footer, toolbar + widgets, spot-type labels), `placesUi` (events/shops/tours/food), `socialUi` + (crews/DMs/notifications/collectives), `settingsUi` (settings/auth/signup/ + onboarding/profile/legal), `walletUi` (wallet/Cashu, stash, mints, app shop, + newsletter, community stats, leaderboards, profile page). +- **Still to translate (batch 3):** `RouteDialog`/`StopDepartures`/`TripItineraryCard` + (routing UI), the Sasquatch panel/dialogs (`SasquatchGuide`, `SasquatchProDialog`, + `SasquatchActionCard`, `SasquatchAiStatusCard`), `AddToCollectionDialog` edge + copy, `SplashScreen`/`LazyMount`, and **shared data-module labels** that live + outside components (`SPOT_TYPE_LABELS`/`SPOT_CATEGORIES` in `src/lib/types.ts`, + `src/lib/skateTags.ts`, `src/lib/spotStatus.ts`, `src/lib/sortOptions.ts`). + **Dates & relative times** are still English (no localized date layer yet). +- ⚠️ A batch-2 agent dropped the `socialUi.` namespace prefix in ~36 files — the + `check:i18n` guard caught all 738 usages. **Always run `node scripts/check-i18n.mjs` + (it's in `npm test`) after wiring a file.** - ⚠️ **When wiring a file, keep `en.ts`/`es.ts` key-for-key in sync** and run `node scripts/check-i18n.mjs` before committing. diff --git a/src/components/AddToCalendar.tsx b/src/components/AddToCalendar.tsx index fc52a6f..1eaf391 100644 --- a/src/components/AddToCalendar.tsx +++ b/src/components/AddToCalendar.tsx @@ -12,6 +12,7 @@ import { type CalendarEventInput, } from '@/lib/calendar'; import { cn } from '@/lib/utils'; +import { useTranslation } from '@/contexts/language'; interface AddToCalendarProps { event: CalendarEventInput; @@ -25,6 +26,7 @@ interface AddToCalendarProps { * Offers a native .ics download (Apple/Outlook) and a Google Calendar link. */ export function AddToCalendar({ event, color = '#06b6d4', className }: AddToCalendarProps) { + const { t } = useTranslation(); return ( @@ -35,7 +37,7 @@ export function AddToCalendar({ event, color = '#06b6d4', className }: AddToCale style={{ borderColor: `${color}55`, color }} > - Add to Calendar + {t('placesUi.addToCalendar.add')} @@ -44,7 +46,7 @@ export function AddToCalendar({ event, color = '#06b6d4', className }: AddToCale className="cursor-pointer" > - Apple / Outlook (.ics) + {t('placesUi.addToCalendar.appleOutlook')} - Google Calendar + {t('placesUi.addToCalendar.google')} diff --git a/src/components/AddToCollectionDialog.tsx b/src/components/AddToCollectionDialog.tsx index 4570b9d..aec4644 100644 --- a/src/components/AddToCollectionDialog.tsx +++ b/src/components/AddToCollectionDialog.tsx @@ -12,6 +12,7 @@ import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; import { Skeleton } from '@/components/ui/skeleton'; import { useToast } from '@/hooks/useToast'; +import { useTranslation } from '@/contexts/language'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import { useMySpotCollections, @@ -29,6 +30,7 @@ interface AddToCollectionDialogProps { } export function AddToCollectionDialog({ open, onOpenChange, spot }: AddToCollectionDialogProps) { + const { t } = useTranslation(); const { user } = useCurrentUser(); const { data: collections, isLoading } = useMySpotCollections(); const { createCollection, isPending: isCreating } = useCreateSpotCollection(); @@ -45,8 +47,8 @@ export function AddToCollectionDialog({ open, onOpenChange, spot }: AddToCollect const handleAddToCollection = async (collection: SpotCollection) => { if (collection.spotRefs.includes(spotRef)) { toast({ - title: 'Already saved', - description: `"${spot.title}" is already in "${collection.title}"`, + title: t('walletUi.addToCollection.alreadySaved'), + description: t('walletUi.addToCollection.alreadySavedDesc', { spot: spot.title, collection: collection.title }), }); return; } @@ -59,14 +61,14 @@ export function AddToCollectionDialog({ open, onOpenChange, spot }: AddToCollect spotIdentifier: spot.identifier, }); toast({ - title: 'Spot saved!', - description: `Added "${spot.title}" to "${collection.title}"`, + title: t('walletUi.addToCollection.saved'), + description: t('walletUi.addToCollection.savedDesc', { spot: spot.title, collection: collection.title }), }); onOpenChange(false); } catch (error) { toast({ - title: 'Failed to save', - description: error instanceof Error ? error.message : 'Something went wrong', + title: t('walletUi.addToCollection.saveFailed'), + description: error instanceof Error ? error.message : t('walletUi.addToCollection.somethingWrong'), variant: 'destructive', }); } finally { @@ -85,8 +87,8 @@ export function AddToCollectionDialog({ open, onOpenChange, spot }: AddToCollect spotRefs: [spotRef], // Add the current spot to the new collection }); toast({ - title: 'Collection created!', - description: `"${spot.title}" added to your new collection "${newTitle}"`, + title: t('walletUi.addToCollection.created'), + description: t('walletUi.addToCollection.createdDesc', { spot: spot.title, collection: newTitle }), }); setNewTitle(''); setNewDescription(''); @@ -94,8 +96,8 @@ export function AddToCollectionDialog({ open, onOpenChange, spot }: AddToCollect onOpenChange(false); } catch (error) { toast({ - title: 'Failed to create collection', - description: error instanceof Error ? error.message : 'Something went wrong', + title: t('walletUi.addToCollection.createFailed'), + description: error instanceof Error ? error.message : t('walletUi.addToCollection.somethingWrong'), variant: 'destructive', }); } @@ -108,11 +110,11 @@ export function AddToCollectionDialog({ open, onOpenChange, spot }: AddToCollect - Save to Collection + {t('walletUi.addToCollection.title')}
-

Please log in to save spots to collections

+

{t('walletUi.addToCollection.loginRequired')}

@@ -125,10 +127,10 @@ export function AddToCollectionDialog({ open, onOpenChange, spot }: AddToCollect - Save to Collection + {t('walletUi.addToCollection.title')} - Save "{spot.title}" to one of your collections + {t('walletUi.addToCollection.desc', { spot: spot.title })} @@ -179,8 +181,8 @@ export function AddToCollectionDialog({ open, onOpenChange, spot }: AddToCollect

- {collection.spotRefs.length} spot{collection.spotRefs.length !== 1 ? 's' : ''} - {isInCollection && ' · Already saved'} + {t('walletUi.addToCollection.spotCount', { count: collection.spotRefs.length })} + {isInCollection && ` · ${t('walletUi.addToCollection.alreadySavedTag')}`}

@@ -190,8 +192,8 @@ export function AddToCollectionDialog({ open, onOpenChange, spot }: AddToCollect ) : !showNewForm ? (
-

You don't have any collections yet

-

Create your first one below!

+

{t('walletUi.addToCollection.noCollections')}

+

{t('walletUi.addToCollection.createFirst')}

) : null} @@ -199,7 +201,7 @@ export function AddToCollectionDialog({ open, onOpenChange, spot }: AddToCollect {showNewForm ? (
- +
- +