feat: Localize Sleep, Diaper, Activity, and Settings pages
Some checks failed
CI/CD Pipeline / Lint and Test (push) Has been cancelled
CI/CD Pipeline / E2E Tests (push) Has been cancelled
CI/CD Pipeline / Build Application (push) Has been cancelled

Added comprehensive localization to tracking and settings pages:

**Translation Keys Added:**
- Sleep: locations, status, duration formatting, success/delete messages
- Diaper: conditions, rash severity and alert, success/delete messages
- Activity: activity types, form labels, placeholders
- Settings: profile, preferences, notifications, appearance, account actions
- Common: shared labels (selectChild, noChildrenAdded, etc.)

**Pages Localized:**
1. Sleep tracking page (/app/track/sleep/page.tsx)
   - All form labels and dropdowns
   - Location options (crib, bed, stroller, carrier, other)
   - Sleep status (completed/ongoing)
   - Duration display with interpolation
   - Success and delete messages

2. Diaper tracking page (/app/track/diaper/page.tsx)
   - Diaper types (wet, dirty, both, dry)
   - Conditions (normal, soft, hard, watery, mucus, blood)
   - Rash detection with severity levels
   - Alert message for diaper rash
   - Recent diapers display with translated labels

3. Activity tracking page (/app/track/activity/page.tsx)
   - Activity types (play, walk, music, reading, tummy time, outdoor, other)
   - Duration and description fields
   - Form placeholders
   - Recent activities display

4. Settings page (/app/settings/page.tsx)
   - Profile information section
   - Preferences, notifications, appearance sections
   - Account actions (logout)
   - Save/saving button states
   - Success message

All pages now support multi-language translation and are ready for
Spanish, French, Portuguese, and Chinese translations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-03 13:18:01 +00:00
parent b1429afcbe
commit 8bac3bad4b
7 changed files with 230 additions and 115 deletions

View File

@@ -18,8 +18,10 @@ import { MeasurementUnitSelector } from '@/components/settings/MeasurementUnitSe
import { TimeZoneSelector } from '@/components/settings/TimeZoneSelector';
import { TimeFormatSelector } from '@/components/settings/TimeFormatSelector';
import { motion } from 'framer-motion';
import { useTranslation } from '@/hooks/useTranslation';
export default function SettingsPage() {
const { t } = useTranslation('settings');
const { user, logout, refreshUser } = useAuth();
const [name, setName] = useState(user?.name || '');
const [timezone, setTimezone] = useState(user?.timezone || 'UTC');
@@ -61,7 +63,7 @@ export default function SettingsPage() {
const handleSaveAll = async () => {
// Validate name
if (!name || name.trim() === '') {
setNameError('Name cannot be empty');
setNameError(t('profile.nameRequired'));
return;
}
@@ -83,7 +85,7 @@ export default function SettingsPage() {
// Refresh user to get latest data from server
await refreshUser();
setSuccessMessage('Settings saved successfully!');
setSuccessMessage(t('saved'));
} catch (err: any) {
console.error('❌ Failed to save settings:', err);
console.error('Error response:', err.response);
@@ -102,10 +104,10 @@ export default function SettingsPage() {
<AppShell>
<Box sx={{ maxWidth: 'md', mx: 'auto' }}>
<Typography variant="h4" component="h1" fontWeight="600" gutterBottom>
Settings
{t('title')}
</Typography>
<Typography variant="body1" color="text.secondary" sx={{ mb: 4 }}>
Manage your account settings and preferences
{t('profile.title')}
</Typography>
{/* Error Alert */}
@@ -130,11 +132,11 @@ export default function SettingsPage() {
<Card sx={{ mb: 3 }}>
<CardContent>
<Typography variant="h6" component="h2" fontWeight="600" gutterBottom>
Profile Information
{t('profile.title')}
</Typography>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, mt: 2 }}>
<TextField
label="Name"
label={t('profile.name')}
value={name}
onChange={(e) => {
setName(e.target.value);
@@ -146,11 +148,11 @@ export default function SettingsPage() {
disabled={isLoading}
/>
<TextField
label="Email"
label={t('profile.email')}
value={user?.email || ''}
fullWidth
disabled
helperText="Email cannot be changed"
helperText={t('profile.emailNotEditable')}
/>
</Box>
</CardContent>
@@ -166,7 +168,7 @@ export default function SettingsPage() {
<Card sx={{ mb: 3 }}>
<CardContent>
<Typography variant="h6" component="h2" fontWeight="600" gutterBottom>
Preferences
{t('preferences.title')}
</Typography>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3, mt: 2 }}>
<LanguageSelector />
@@ -193,7 +195,7 @@ export default function SettingsPage() {
<Card sx={{ mb: 3 }}>
<CardContent>
<Typography variant="h6" component="h2" fontWeight="600" gutterBottom>
Notifications
{t('notifications.title')}
</Typography>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1, mt: 2 }}>
<FormControlLabel
@@ -204,7 +206,7 @@ export default function SettingsPage() {
disabled={isLoading}
/>
}
label="Push Notifications"
label={t('notifications.push')}
/>
<FormControlLabel
control={
@@ -214,7 +216,7 @@ export default function SettingsPage() {
disabled={isLoading}
/>
}
label="Email Updates"
label={t('notifications.email')}
/>
</Box>
</CardContent>
@@ -230,7 +232,7 @@ export default function SettingsPage() {
<Card sx={{ mb: 3 }}>
<CardContent>
<Typography variant="h6" component="h2" fontWeight="600" gutterBottom>
Appearance
{t('appearance.title')}
</Typography>
<Box sx={{ mt: 2 }}>
<FormControlLabel
@@ -240,7 +242,7 @@ export default function SettingsPage() {
onChange={(e) => setSettings({ ...settings, darkMode: e.target.checked })}
/>
}
label="Dark Mode (Coming Soon)"
label={t('appearance.darkMode')}
disabled
/>
</Box>
@@ -329,7 +331,7 @@ export default function SettingsPage() {
disabled={isLoading}
sx={{ minWidth: 200 }}
>
{isLoading ? 'Saving...' : 'Save Preferences'}
{isLoading ? t('saving') : t('save')}
</Button>
</Box>
</motion.div>
@@ -343,7 +345,7 @@ export default function SettingsPage() {
<Card>
<CardContent>
<Typography variant="h6" component="h2" fontWeight="600" gutterBottom>
Account Actions
{t('accountActions.title')}
</Typography>
<Divider sx={{ my: 2 }} />
<Button
@@ -353,7 +355,7 @@ export default function SettingsPage() {
onClick={handleLogout}
fullWidth
>
Logout
{t('accountActions.logout')}
</Button>
</CardContent>
</Card>