fix: Add missing COPPA fields to registration payload
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 dateOfBirth, parentalEmail, and coppaConsentGiven to RegisterData interface
- Updated register function to include all required COPPA compliance fields in API payload
- Added debug logging to see registration payload
- Fixed 400 error during registration due to missing required dateOfBirth field

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-03 15:23:02 +00:00
parent d81010ef91
commit 952efa6d37
3 changed files with 59 additions and 23 deletions

View File

@@ -55,9 +55,9 @@ export default function TrackPage() {
{t('selectActivity')}
</Typography>
<Grid container spacing={3}>
<Grid container spacing={3} sx={{ justifyContent: 'flex-start' }}>
{trackingOptions.map((option) => (
<Grid item xs={12} sm={6} md={3} key={option.title}>
<Grid item xs={6} sm={4} md={2.4} key={option.title}>
<Card
sx={{
height: '180px', // Fixed height for consistency
@@ -78,12 +78,32 @@ export default function TrackPage() {
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
py: 4,
}}
>
<CardContent sx={{ textAlign: 'center' }}>
<CardContent sx={{
textAlign: 'center',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '100%',
p: 2,
'&:last-child': { pb: 2 }
}}>
{option.icon}
<Typography variant="h6" fontWeight="600" sx={{ mt: 2 }}>
<Typography
variant="h6"
fontWeight="600"
sx={{
mt: 2,
wordWrap: 'break-word',
wordBreak: 'break-word',
hyphens: 'auto',
textAlign: 'center',
width: '100%',
}}
>
{option.title}
</Typography>
</CardContent>

View File

@@ -363,8 +363,8 @@ export const InsightsDashboard: React.FC = () => {
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.3, delay: 0 }}
>
<Card sx={{ bgcolor: COLORS.feeding, color: 'white', height: '160px', minHeight: '160px' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
<Card sx={{ bgcolor: COLORS.feeding, color: 'white', height: '160px', minHeight: '160px', width: '100%' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'center', p: 2, '&:last-child': { pb: 2 } }}>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>
<Restaurant sx={{ fontSize: 32, mr: 1 }} />
<Typography variant="h6" fontWeight="600">
@@ -388,8 +388,8 @@ export const InsightsDashboard: React.FC = () => {
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.3, delay: 0.1 }}
>
<Card sx={{ bgcolor: COLORS.sleep, color: 'white', height: '160px', minHeight: '160px' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
<Card sx={{ bgcolor: COLORS.sleep, color: 'white', height: '160px', minHeight: '160px', width: '100%' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'center', p: 2, '&:last-child': { pb: 2 } }}>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>
<Hotel sx={{ fontSize: 32, mr: 1 }} />
<Typography variant="h6" fontWeight="600">
@@ -413,8 +413,8 @@ export const InsightsDashboard: React.FC = () => {
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.3, delay: 0.2 }}
>
<Card sx={{ bgcolor: COLORS.diaper, color: 'white', height: '160px', minHeight: '160px' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
<Card sx={{ bgcolor: COLORS.diaper, color: 'white', height: '160px', minHeight: '160px', width: '100%' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'center', p: 2, '&:last-child': { pb: 2 } }}>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>
<BabyChangingStation sx={{ fontSize: 32, mr: 1 }} />
<Typography variant="h6" fontWeight="600">
@@ -438,8 +438,8 @@ export const InsightsDashboard: React.FC = () => {
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.3, delay: 0.3 }}
>
<Card sx={{ bgcolor: COLORS.milestone, color: 'white', height: '160px', minHeight: '160px' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
<Card sx={{ bgcolor: COLORS.milestone, color: 'white', height: '160px', minHeight: '160px', width: '100%' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'center', p: 2, '&:last-child': { pb: 2 } }}>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>
<TrendingUp sx={{ fontSize: 32, mr: 1 }} />
<Typography variant="h6" fontWeight="600">
@@ -461,8 +461,8 @@ export const InsightsDashboard: React.FC = () => {
{/* Charts */}
<Grid container spacing={3} sx={{ mb: 3 }}>
<Grid item xs={12} md={6}>
<Card sx={{ height: '350px', minHeight: '350px' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
<Card sx={{ height: '350px', minHeight: '350px', width: '100%' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column', p: 2, '&:last-child': { pb: 2 } }}>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
<Restaurant sx={{ mr: 1, color: COLORS.feeding }} />
<Typography variant="h6" fontWeight="600">
@@ -483,8 +483,8 @@ export const InsightsDashboard: React.FC = () => {
</Grid>
<Grid item xs={12} md={6}>
<Card sx={{ height: '350px', minHeight: '350px' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
<Card sx={{ height: '350px', minHeight: '350px', width: '100%' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column', p: 2, '&:last-child': { pb: 2 } }}>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
<Hotel sx={{ mr: 1, color: COLORS.sleep }} />
<Typography variant="h6" fontWeight="600">
@@ -513,8 +513,8 @@ export const InsightsDashboard: React.FC = () => {
{diaperData.length > 0 && (
<Grid item xs={12} md={6}>
<Card>
<CardContent>
<Card sx={{ height: '350px', minHeight: '350px', width: '100%' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column', p: 2, '&:last-child': { pb: 2 } }}>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
<BabyChangingStation sx={{ mr: 1, color: COLORS.diaper }} />
<Typography variant="h6" fontWeight="600">
@@ -546,8 +546,8 @@ export const InsightsDashboard: React.FC = () => {
)}
<Grid item xs={12} md={diaperData.length > 0 ? 6 : 12}>
<Card sx={{ height: '350px', minHeight: '350px' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
<Card sx={{ height: '350px', minHeight: '350px', width: '100%' }}>
<CardContent sx={{ height: '100%', display: 'flex', flexDirection: 'column', p: 2, '&:last-child': { pb: 2 } }}>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
<Assessment sx={{ mr: 1, color: 'primary.main' }} />
<Typography variant="h6" fontWeight="600">

View File

@@ -28,6 +28,9 @@ export interface RegisterData {
password: string;
name: string;
role?: string;
dateOfBirth: string; // COPPA compliance - required
parentalEmail?: string; // For users 13-17
coppaConsentGiven?: boolean; // For users 13-17
}
interface AuthContextType {
@@ -144,13 +147,26 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
// Auto-detect timezone from user's device
const detectedTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const response = await apiClient.post('/api/v1/auth/register', {
const payload: any = {
email: data.email,
password: data.password,
name: data.name,
timezone: detectedTimezone || 'UTC',
dateOfBirth: data.dateOfBirth,
deviceInfo,
});
};
// Add optional COPPA fields if provided
if (data.parentalEmail) {
payload.parentalEmail = data.parentalEmail;
}
if (data.coppaConsentGiven !== undefined) {
payload.coppaConsentGiven = data.coppaConsentGiven;
}
console.log('[Auth] Registration payload:', JSON.stringify(payload, null, 2));
const response = await apiClient.post('/api/v1/auth/register', payload);
// Backend returns { success, data: { user, family, tokens } }
const { data: responseData } = response.data;