- Added new localization keys for project management, settings, and onboarding views.
- Updated labels and placeholders in project modal, password change modal, and backup/restore modal for better clarity.
- Improved user feedback messages for password mismatch and backup creation failures.
- Enhanced the timer details view with localized strings for active work, sessions, and distribution.
- Refined the due date picker modal with localized quick date and time options.
- Updated photo task modal and scan panel to include localized text for better accessibility.
- Ensured consistent use of translation function for all user-facing strings.
- Updated NativeCancelSubscriptionModal to use translation keys for titles and messages.
- Enhanced CircleSetupView with translation for notifications and UI text.
- Refactored ThingsView to implement translation for notifications, titles, and descriptions.
- Added translation support in AdvancedOptionsSection for labels and descriptions.
- Implemented i18n in RepeatPickerField for various UI elements and labels.
- Integrated translation functionality using react-i18next in Settings.jsx
- Replaced hardcoded strings with translation keys for better localization support
- Updated AddTaskModal.jsx to include translations for task-related strings
- Enhanced user experience by providing localized messages for various actions and notifications
Part of #145.
Twenty-three files across the task list zone: the list and card views,
sorting and grouping, multi-select and its toolbar and help sheet,
archived tasks, the assignee card, the chore action menu, the
nudge/NFC/photo modals, the rich text editor, the scan panel, the
notification templates and the keyboard-shortcut toasts.
Extends the existing `chores` namespace, so `src/i18n/config.js` is
untouched.
English only — no translations, no behaviour change. Every t() value is
checked against this branch's base: the string must appear
character-for-character in the code it replaces (247 call sites).
Two values are matched loosely and worth naming: archived.closeMultiSelect
in both the archived view and the toolbar. The base builds that tooltip as
`${size === 0 ? 'Close' : 'Clear'} multi-select (Esc)`, so only one branch
of the ternary exists contiguously in the source. Both keys hold exactly
what each branch renders; the tooltip is kept whole so a translator can
reorder it.
Rebased on current `develop` again after #215 and #216 landed — the
dictionary conflict was theirs, not the code's. No code file in this PR
was touched upstream in the meantime.
Part of #145.
Sixteen files that were left out of my earlier PRs because my branch also
carried unrelated changes in them. Those are stripped here: each file is
your current `develop` version with the string extraction applied on top,
nothing else.
Covered: the chore action hook and its toasts, activities and smart-insight
cards, the chore toolbar, chore history and its card, saved filters, the
timer details view, project and label modals, the notification picker,
the pending badge, the sync status indicator, the SSE settings and hook,
and the profile avatar menu.
All namespaces already exist, so `src/i18n/config.js` is untouched.
Keys added: 83 `chores`, 31 `common`, 10 `timer`, 9 `history`, 6 `labels`,
5 `projects`, 2 `filters`, 1 `settings`.
English only — no translations, no behaviour change. Every t() value is
checked to appear character-for-character in the code it replaces, or to
match the value already in your dictionary for the same key: 221 call
sites, no mismatches.
Five files from the same batch are deliberately left out. They build
translated labels in module-level constant tables, where the hook cannot
be called — `FilterBar`, `RepeatSection`, `RepeatPickerField`,
`FilterBuilderContent` and `AdvancedOptionsSection`. Those need the key
to travel as data and be resolved inside the component, which is a design
change rather than an extraction, so it deserves its own PR.
Part of #145.
Two files you localized yourself, each with a handful of strings that the
pass didn't reach:
- `ChoreView` — the offline-sync notices ("You're offline — completion
will sync when back online" and its skip/start/pause/restore siblings)
and the error toasts they fall back to. 12 keys added to `en/chores.json`.
- `MFASettings` — the "Generate New Codes" button. 1 key added to
`en/settings.json`.
Both extend namespaces that already exist, so `src/i18n/config.js` is
untouched and this cannot conflict with my other open PRs.
English only — no translations, no behaviour change. Every t() value is
checked to appear character-for-character in the code it replaces, or to
match the value already in your dictionary for the same key (126 call
sites total across both files).
Part of #145.
Fourteen files across seven feature areas that had no namespace yet: the
things create/edit modals and their history, the chore history detail and
edit modals, the activity feed, the points view and its redemption modal,
the project view with its selector and icon picker, the label view, the
advanced filter builder and the timer edit modal.
Seven new namespaces registered in `src/i18n/config.js` in one change
rather than one per PR, so the `ns:` array is touched once and my other
extraction PRs cannot conflict with this one. Namespaces stay
feature-scoped as described in #145; if you'd rather fold any of these
into `common` or `chores`, say which and I'll rework it.
Dictionaries: `history` 57 keys, `points` 50, `timer` 25, `projects` 16,
`things` 14, `filters` 13, `labels` 5.
English only — no translations, no behaviour change. Every t() value is
checked against this branch's base: the string must appear
character-for-character in the code it replaces (226 call sites).
Three values in `UserPoints` are matched loosely and worth naming. The
base builds the leaderboard heading and subtitle around a ternary —
`{mode === 'points' ? 'Points' : 'Tasks'} Leaderboard` and `Rankings based
on {…} during the selected time period` — so neither full sentence exists
contiguously in the source. Each key holds exactly what one branch
renders. The sentences are kept whole rather than split around the
ternary, since a sentence assembled from fragments cannot be reordered by
a translator.
- Add all missing translation keys to ChoreView component
- Replace hardcoded strings with i18n translation calls
- Complete Spanish (es) translations for ChoreView and Settings
- Complete Arabic (ar) translations for ChoreView and Settings
- Update ProfileSettings component with full translation support
- Add translations for notifications, confirmations, and UI labels
- Add navigation translations (All Tasks, Archived, Things, etc.)
- Translate NavBar menu items and logout button
- Add comprehensive SettingsOverview translations
- Translate upgrade card and all settings sections
- Add ChoreView translations structure
- Improve RTL CSS support for better card alignment
- Fix flex, list, and container alignment for RTL languages
Navigation drawer now shows translated menu items in user's language.
Settings overview page fully translated.
RTL languages (Arabic, Hebrew) now have proper alignment for sidepanel cards.
- Add multi-language support with i18next and react-i18next
- Implement user-selectable date format preferences (5 formats)
- Add time format preferences (12-hour/24-hour)
- Implement RTL (right-to-left) support for Arabic, Hebrew, Persian, Urdu
- Add first day of week preference
- Create LocalizationContext for managing i18n settings
- Add LocalizationSettings component to Settings page
- Include sample translations: English, Spanish, Arabic
- Configure 10 languages: en, es, fr, de, ar, he, zh, ja, pt, ru
- Add translation management documentation and Crowdin config
- Create date formatting utilities that respect user preferences
- Add RTL CSS styles for proper layout mirroring
- Update Settings and ThemeToggle components to use translations
- Add comprehensive documentation (implementation guide, quick reference, translation guide)
All user preferences are persisted to localStorage and apply throughout the app.