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

@@ -254,7 +254,7 @@ export default function DiaperTrackPage() {
notes: notes || undefined,
});
setSuccessMessage('Diaper change logged successfully!');
setSuccessMessage(t('diaper.success'));
// Reset form
resetForm();
@@ -289,7 +289,7 @@ export default function DiaperTrackPage() {
try {
setLoading(true);
await trackingApi.deleteActivity(activityToDelete);
setSuccessMessage('Diaper change deleted successfully');
setSuccessMessage(t('diaper.deleted'));
setDeleteDialogOpen(false);
setActivityToDelete(null);
await loadRecentDiapers();
@@ -333,8 +333,8 @@ export default function DiaperTrackPage() {
const getDiaperDetails = (activity: Activity) => {
const data = activity.data as DiaperData;
const typeLabel = data.diaperType.charAt(0).toUpperCase() + data.diaperType.slice(1);
const conditionsLabel = data.conditions?.join(', ') || '';
const typeLabel = t(`diaper.types.${data.diaperType}`);
const conditionsLabel = data.conditions?.map(c => t(`diaper.conditions.${c}`)).join(', ') || '';
let details = typeLabel;
if (conditionsLabel) {
@@ -342,7 +342,7 @@ export default function DiaperTrackPage() {
}
if (data.hasRash) {
details += ` - Rash (${data.rashSeverity})`;
details += ` - ${t('diaper.rash.title')} (${t(`diaper.rash.severities.${data.rashSeverity}`)})`;
}
return details;
@@ -390,17 +390,17 @@ export default function DiaperTrackPage() {
<CardContent sx={{ textAlign: 'center', py: 8 }}>
<ChildCare sx={{ fontSize: 64, color: 'text.secondary', mb: 2 }} />
<Typography variant="h6" color="text.secondary" gutterBottom>
No Children Added
{t('common.noChildrenAdded')}
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
You need to add a child before you can track diaper changes
{t('common.noChildrenMessage')}
</Typography>
<Button
variant="contained"
startIcon={<Add />}
onClick={() => router.push('/children')}
>
Add Child
{t('common.addChild')}
</Button>
</CardContent>
</Card>
@@ -437,11 +437,11 @@ export default function DiaperTrackPage() {
{children.length > 1 && (
<Paper sx={{ p: 2, mb: 3 }}>
<FormControl fullWidth>
<InputLabel>Select Child</InputLabel>
<InputLabel>{t('common.selectChild')}</InputLabel>
<Select
value={selectedChild}
onChange={(e) => setSelectedChild(e.target.value)}
label="Select Child"
label={t('common.selectChild')}
>
{children.map((child) => (
<MenuItem key={child.id} value={child.id}>
@@ -474,7 +474,7 @@ export default function DiaperTrackPage() {
InputLabelProps={{ shrink: true }}
/>
<Button variant="outlined" onClick={setTimeNow} sx={{ minWidth: 100 }}>
Now
{t('diaper.now')}
</Button>
</Box>
</Box>
@@ -524,13 +524,13 @@ export default function DiaperTrackPage() {
{/* Condition Selector */}
<Box sx={{ mb: 3 }}>
<Typography variant="subtitle1" fontWeight="600" sx={{ mb: 1 }}>
Condition (select all that apply)
{t('diaper.conditions.title')}
</Typography>
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1 }}>
{availableConditions.map((condition) => (
<Chip
key={condition}
label={condition.charAt(0).toUpperCase() + condition.slice(1)}
label={t(`diaper.conditions.${condition}`)}
onClick={() => handleConditionToggle(condition)}
color={conditions.includes(condition) ? 'primary' : 'default'}
variant={conditions.includes(condition) ? 'filled' : 'outlined'}
@@ -542,14 +542,14 @@ export default function DiaperTrackPage() {
{/* Rash Indicator */}
<FormControl fullWidth sx={{ mb: 3 }}>
<InputLabel>Diaper Rash?</InputLabel>
<InputLabel>{t('diaper.rash.title')}</InputLabel>
<Select
value={hasRash ? 'yes' : 'no'}
onChange={(e) => setHasRash(e.target.value === 'yes')}
label="Diaper Rash?"
label={t('diaper.rash.title')}
>
<MenuItem value="no">No</MenuItem>
<MenuItem value="yes">Yes</MenuItem>
<MenuItem value="no">{t('diaper.rash.no')}</MenuItem>
<MenuItem value="yes">{t('diaper.rash.yes')}</MenuItem>
</Select>
</FormControl>
@@ -558,19 +558,19 @@ export default function DiaperTrackPage() {
<Box sx={{ mb: 3 }}>
<Alert severity="warning" sx={{ mb: 2 }}>
<Typography variant="body2" sx={{ mb: 1 }}>
Diaper rash detected. Consider applying diaper rash cream and consulting your pediatrician if it persists.
{t('diaper.rash.alert')}
</Typography>
</Alert>
<FormControl fullWidth>
<InputLabel>Rash Severity</InputLabel>
<InputLabel>{t('diaper.rash.severity')}</InputLabel>
<Select
value={rashSeverity}
onChange={(e) => setRashSeverity(e.target.value as 'mild' | 'moderate' | 'severe')}
label="Rash Severity"
label={t('diaper.rash.severity')}
>
<MenuItem value="mild">Mild</MenuItem>
<MenuItem value="moderate">Moderate</MenuItem>
<MenuItem value="severe">Severe</MenuItem>
<MenuItem value="mild">{t('diaper.rash.severities.mild')}</MenuItem>
<MenuItem value="moderate">{t('diaper.rash.severities.moderate')}</MenuItem>
<MenuItem value="severe">{t('diaper.rash.severities.severe')}</MenuItem>
</Select>
</FormControl>
</Box>
@@ -606,7 +606,7 @@ export default function DiaperTrackPage() {
<Paper sx={{ p: 3 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
<Typography variant="h6" fontWeight="600">
{t('diaper.title')}
{t('diaper.recentDiapers')}
</Typography>
<IconButton onClick={loadRecentDiapers} disabled={diapersLoading}>
<Refresh />
@@ -646,10 +646,10 @@ export default function DiaperTrackPage() {
<Box sx={{ flex: 1 }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.5, flexWrap: 'wrap' }}>
<Typography variant="body1" fontWeight="600">
Diaper Change
{t('diaper.title')}
</Typography>
<Chip
label={data.diaperType.charAt(0).toUpperCase() + data.diaperType.slice(1)}
label={t(`diaper.types.${data.diaperType}`)}
size="small"
sx={{
bgcolor: getDiaperTypeColor(data.diaperType),
@@ -659,7 +659,7 @@ export default function DiaperTrackPage() {
{data.hasRash && (
<Chip
icon={<Warning sx={{ fontSize: 16 }} />}
label={`Rash: ${data.rashSeverity}`}
label={`${t('diaper.rash.title')}: ${t(`diaper.rash.severities.${data.rashSeverity}`)}`}
size="small"
color={getRashSeverityColor(data.rashSeverity || 'mild') as any}
/>
@@ -714,10 +714,10 @@ export default function DiaperTrackPage() {
</DialogContent>
<DialogActions>
<Button onClick={() => setDeleteDialogOpen(false)} disabled={loading}>
Cancel
{t('common.cancel')}
</Button>
<Button onClick={handleDeleteConfirm} color="error" disabled={loading}>
{loading ? t('deleteEntry') : t('deleteEntry')}
{loading ? t('common.delete') : t('common.delete')}
</Button>
</DialogActions>
</Dialog>