Files
maternal-app/maternal-web/lib/api/users.ts
Andrei 40dbb2287a
Some checks failed
ParentFlow CI/CD Pipeline / Backend Tests (push) Has been cancelled
ParentFlow CI/CD Pipeline / Frontend Tests (push) Has been cancelled
ParentFlow CI/CD Pipeline / Security Scanning (push) Has been cancelled
ParentFlow CI/CD Pipeline / Build Docker Images (map[context:maternal-app/maternal-app-backend dockerfile:Dockerfile.production name:backend]) (push) Has been cancelled
ParentFlow CI/CD Pipeline / Build Docker Images (map[context:maternal-web dockerfile:Dockerfile.production name:frontend]) (push) Has been cancelled
ParentFlow CI/CD Pipeline / Deploy to Development (push) Has been cancelled
ParentFlow CI/CD Pipeline / Deploy to Production (push) Has been cancelled
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
feat: Implement comprehensive onboarding improvements with role-based family invites
This commit adds a complete onboarding improvements system including progress
tracking, streamlined UI, and role-based family invitation system.

## Backend Changes

### Database Migrations
- Add onboarding tracking fields to users table (onboarding_completed, onboarding_step, onboarding_data)
- Add role-based invite codes to families table (parent/caregiver/viewer codes with expiration)
- Add indexes for fast invite code lookups

### User Preferences Module
- Add UserPreferencesController with onboarding endpoints
- Add UserPreferencesService with progress tracking methods
- Add UpdateOnboardingProgressDto for validation
- Endpoints: GET/PUT /api/v1/preferences/onboarding, POST /api/v1/preferences/onboarding/complete

### Families Module - Role-Based Invites
- Add generateRoleInviteCode() - Generate role-specific codes with expiration
- Add getRoleInviteCodes() - Retrieve all active codes for a family
- Add joinFamilyWithRoleCode() - Join family with automatic role assignment
- Add revokeRoleInviteCode() - Revoke specific role invite codes
- Add sendEmailInvite() - Generate code and send email invitation
- Endpoints: POST/GET/DELETE /api/v1/families/:id/invite-codes, POST /api/v1/families/join-with-role, POST /api/v1/families/:id/email-invite

### Email Service
- Add sendFamilyInviteEmail() - Send role-based invitation emails
- Beautiful HTML templates with role badges (👨‍👩‍👧 parent, 🤝 caregiver, 👁️ viewer)
- Role-specific permission descriptions
- Graceful fallback if email sending fails

### Auth Service
- Fix duplicate family creation bug in joinFamily()
- Ensure users only join family once during onboarding

## Frontend Changes

### Onboarding Page
- Reduce steps from 5 to 4 (combined language + measurements)
- Replace card-based selection with dropdown selectors
- Add automatic progress saving after each step
- Add progress restoration on page mount
- Extract FamilySetupStep into reusable component

### Family Page
- Add RoleInvitesSection component with accordion UI
- Generate/view/copy/regenerate/revoke controls for each role
- Send email invites directly from UI
- Display expiration dates (e.g., "Expires in 5 days")
- Info tooltips explaining role permissions
- Only visible to users with parent role

### API Client
- Add role-based invite methods to families API
- Add onboarding progress methods to users API
- TypeScript interfaces for all new data structures

## Features

 Streamlined 4-step onboarding with dropdown selectors
 Automatic progress save/restore across sessions
 Role-based family invites (parent/caregiver/viewer)
 Beautiful email invitations with role descriptions
 Automatic role assignment when joining with invite codes
 Granular permission control per role
 Email fallback if sending fails
 All changes tested and production-ready

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-09 15:25:16 +00:00

73 lines
1.8 KiB
TypeScript

import apiClient from './client';
export interface UserPreferences {
notifications?: boolean;
emailUpdates?: boolean;
darkMode?: boolean;
}
export interface UpdateProfileData {
name?: string;
photoUrl?: string;
timezone?: string;
preferences?: UserPreferences;
}
export interface UserProfile {
id: string;
email: string;
name: string;
photoUrl?: string;
role: string;
locale: string;
emailVerified: boolean;
preferences?: UserPreferences;
families?: string[];
onboardingCompleted?: boolean;
onboardingStep?: number;
onboardingData?: OnboardingData;
}
export interface OnboardingData {
selectedLanguage?: string;
selectedMeasurement?: 'metric' | 'imperial';
familyChoice?: 'create' | 'join';
childData?: {
name?: string;
birthDate?: string;
gender?: string;
};
}
export interface OnboardingStatus {
completed: boolean;
step: number;
data: OnboardingData;
}
export const usersApi = {
// Update user profile
updateProfile: async (data: UpdateProfileData): Promise<UserProfile> => {
const response = await apiClient.patch('/api/v1/auth/profile', data);
return response.data.data;
},
// Get onboarding status
getOnboardingStatus: async (): Promise<OnboardingStatus> => {
const response = await apiClient.get('/api/v1/preferences/onboarding');
return response.data.data;
},
// Update onboarding progress
updateOnboardingProgress: async (data: { step: number; data?: OnboardingData }): Promise<UserProfile> => {
const response = await apiClient.put('/api/v1/preferences/onboarding/progress', data);
return response.data.data.user;
},
// Mark onboarding as complete
completeOnboarding: async (): Promise<UserProfile> => {
const response = await apiClient.post('/api/v1/preferences/onboarding/complete');
return response.data.data.user;
},
};