feat: Localize Sleep, Diaper, Activity, and Settings pages
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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user