Add backend with analytics, notifications, and enhanced features
Some checks failed
Backend CI/CD Pipeline / Lint and Test Backend (push) Has been cancelled
CI/CD Pipeline / Lint and Test (push) Has been cancelled
Backend CI/CD Pipeline / E2E Tests Backend (push) Has been cancelled
Backend CI/CD Pipeline / Build Backend Application (push) Has been cancelled
Backend CI/CD Pipeline / Performance Testing (push) Has been cancelled
CI/CD Pipeline / E2E Tests (push) Has been cancelled
CI/CD Pipeline / Build Application (push) Has been cancelled

Backend:
- Complete NestJS backend implementation with comprehensive features
- Analytics: Weekly/monthly reports with PDF/CSV export
- Smart notifications: Persistent notifications with milestones and anomaly detection
- AI safety: Medical disclaimer triggers and prompt injection protection
- COPPA/GDPR compliance: Full audit logging system

Frontend:
- Updated settings page and analytics components
- API integration improvements

Docs:
- Added implementation gaps tracking
- Azure OpenAI integration documentation
- Testing and post-launch summaries

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
andupetcu
2025-10-01 15:22:50 +03:00
parent 999bc39467
commit a91a7b009a
22 changed files with 5048 additions and 10 deletions

View File

@@ -3,7 +3,7 @@
import { Box, Typography, Card, CardContent, TextField, Button, Divider, Switch, FormControlLabel, Alert, CircularProgress, Snackbar } from '@mui/material';
import { Save, Logout } from '@mui/icons-material';
import { useAuth } from '@/lib/auth/AuthContext';
import { useState } from 'react';
import { useState, useEffect } from 'react';
import { AppShell } from '@/components/layouts/AppShell/AppShell';
import { ProtectedRoute } from '@/components/common/ProtectedRoute';
import { usersApi } from '@/lib/api/users';
@@ -22,6 +22,24 @@ export default function SettingsPage() {
const [successMessage, setSuccessMessage] = useState<string | null>(null);
const [nameError, setNameError] = useState<string | null>(null);
// Load preferences from user object when it changes
useEffect(() => {
if (user?.preferences) {
setSettings({
notifications: user.preferences.notifications ?? true,
emailUpdates: user.preferences.emailUpdates ?? false,
darkMode: user.preferences.darkMode ?? false,
});
}
}, [user?.preferences]);
// Sync name state when user data changes
useEffect(() => {
if (user?.name) {
setName(user.name);
}
}, [user]);
const handleSave = async () => {
// Validate name
if (!name || name.trim() === '') {
@@ -34,12 +52,20 @@ export default function SettingsPage() {
setNameError(null);
try {
await usersApi.updateProfile({ name: name.trim() });
const response = await usersApi.updateProfile({
name: name.trim(),
preferences: settings
});
console.log('✅ Profile updated successfully:', response);
// Refresh user to get latest data from server
await refreshUser();
setSuccessMessage('Profile updated successfully!');
} catch (err: any) {
console.error('Failed to update profile:', err);
setError(err.response?.data?.message || 'Failed to update profile. Please try again.');
console.error('Failed to update profile:', err);
console.error('Error response:', err.response);
setError(err.response?.data?.message || err.message || 'Failed to update profile. Please try again.');
} finally {
setIsLoading(false);
}
@@ -129,15 +155,13 @@ export default function SettingsPage() {
<Typography variant="h6" fontWeight="600" gutterBottom>
Notifications
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
Settings are stored locally (backend integration coming soon)
</Typography>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1, mt: 2 }}>
<FormControlLabel
control={
<Switch
checked={settings.notifications}
onChange={(e) => setSettings({ ...settings, notifications: e.target.checked })}
disabled={isLoading}
/>
}
label="Push Notifications"
@@ -147,11 +171,21 @@ export default function SettingsPage() {
<Switch
checked={settings.emailUpdates}
onChange={(e) => setSettings({ ...settings, emailUpdates: e.target.checked })}
disabled={isLoading}
/>
}
label="Email Updates"
/>
</Box>
<Button
variant="contained"
startIcon={isLoading ? <CircularProgress size={20} color="inherit" /> : <Save />}
onClick={handleSave}
disabled={isLoading}
sx={{ mt: 2, alignSelf: 'flex-start' }}
>
{isLoading ? 'Saving...' : 'Save Preferences'}
</Button>
</CardContent>
</Card>
</motion.div>