feat(compliance): Implement COPPA/GDPR compliance UI
Frontend Compliance Features: - Created compliance API client (data export, account deletion, deletion status) - Added DataExport component with download functionality - Added AccountDeletion component with 30-day grace period UI - Updated Settings page with Privacy & Compliance sections COPPA Age Verification: - Added date of birth field to registration - Age calculation with COPPA compliance (under 13 blocked) - Parental email and consent for users 13-17 - Dynamic form validation based on age Privacy & Terms: - Separate checkboxes for Terms of Service and Privacy Policy - Required acceptance for registration - Links to policy pages Completes GDPR Right to Data Portability and Right to Erasure. Completes COPPA parental consent requirements.
This commit is contained in:
99
maternal-web/lib/api/compliance.ts
Normal file
99
maternal-web/lib/api/compliance.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import { apiClient } from './client';
|
||||
|
||||
export interface UserDataExport {
|
||||
user: {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
dateOfBirth?: string;
|
||||
createdAt: string;
|
||||
};
|
||||
families: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
role: string;
|
||||
}>;
|
||||
children: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
dateOfBirth: string;
|
||||
gender: string;
|
||||
}>;
|
||||
activities: Array<{
|
||||
id: string;
|
||||
type: string;
|
||||
timestamp: string;
|
||||
data: any;
|
||||
}>;
|
||||
aiConversations: Array<{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
messages: Array<{
|
||||
role: string;
|
||||
content: string;
|
||||
timestamp: string;
|
||||
}>;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface DeletionRequest {
|
||||
id: string;
|
||||
requestedAt: string;
|
||||
scheduledDeletionAt: string;
|
||||
status: 'pending' | 'cancelled' | 'completed';
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export const complianceApi = {
|
||||
/**
|
||||
* Export all user data (GDPR Right to Data Portability)
|
||||
*/
|
||||
exportUserData: async (): Promise<UserDataExport> => {
|
||||
const response = await apiClient.get<{ data: UserDataExport }>('/compliance/data-export');
|
||||
return response.data.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Download user data as JSON file
|
||||
*/
|
||||
downloadUserData: async (): Promise<void> => {
|
||||
const data = await complianceApi.exportUserData();
|
||||
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = `maternal-app-data-export-${new Date().toISOString().split('T')[0]}.json`;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
window.URL.revokeObjectURL(url);
|
||||
},
|
||||
|
||||
/**
|
||||
* Request account deletion with 30-day grace period (GDPR Right to Erasure)
|
||||
*/
|
||||
requestAccountDeletion: async (reason?: string): Promise<DeletionRequest> => {
|
||||
const response = await apiClient.post<{ data: DeletionRequest }>('/compliance/request-deletion', {
|
||||
reason,
|
||||
});
|
||||
return response.data.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Cancel pending account deletion request
|
||||
*/
|
||||
cancelAccountDeletion: async (cancellationReason?: string): Promise<DeletionRequest> => {
|
||||
const response = await apiClient.post<{ data: DeletionRequest }>('/compliance/cancel-deletion', {
|
||||
cancellationReason,
|
||||
});
|
||||
return response.data.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get pending deletion request status
|
||||
*/
|
||||
getDeletionStatus: async (): Promise<DeletionRequest | null> => {
|
||||
const response = await apiClient.get<{ data: DeletionRequest | null }>('/compliance/deletion-status');
|
||||
return response.data.data;
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user