feat: Implement AI response feedback UI and complete high-priority features
Frontend Features: - Add MessageFeedback component with thumbs up/down buttons - Positive feedback submits immediately with success toast - Negative feedback opens dialog for optional text input - Integrate feedback buttons on all AI assistant messages - Add success Snackbar confirmation message - Translation keys added to ai.json (feedback section) Backend Features: - Add POST /api/v1/ai/feedback endpoint - Create FeedbackDto with conversation ID validation - Implement submitFeedback service method - Store feedback in conversation metadata with timestamps - Add audit logging for feedback submissions - Fix conversationId regex validation to support nanoid format Legal & Compliance: - Implement complete EULA acceptance flow with modal - Create reusable legal content components (Terms, Privacy, EULA) - Add LegalDocumentViewer for nested modal viewing - Cookie Consent Banner with GDPR compliance - Legal pages with AppShell navigation - EULA acceptance tracking in user entity Branding Updates: - Rebrand from "Maternal App" to "ParentFlow" - Update all icons (72px to 512px) from high-res source - PWA manifest updated with ParentFlow branding - Contact email: hello@parentflow.com - Address: Serbota 3, Bucharest, Romania Bug Fixes: - Fix chat endpoint validation (support nanoid conversation IDs) - Fix EULA acceptance API call (use apiClient vs hardcoded localhost) - Fix icon loading errors with proper PNG generation Documentation: - Mark 11 high-priority features as complete in REMAINING_FEATURES.md - Update feature statistics: 73/139 complete (53%) - All high-priority features now complete! 🎉 Files Changed: Frontend: 21 files (components, pages, locales, icons) Backend: 6 files (controller, service, DTOs, migrations) Docs: 1 file (REMAINING_FEATURES.md) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
72
maternal-web/components/legal/EULACheck.tsx
Normal file
72
maternal-web/components/legal/EULACheck.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useAuth } from '@/lib/auth/AuthContext';
|
||||
import { EULADialog } from './EULADialog';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import apiClient from '@/lib/api/client';
|
||||
|
||||
export function EULACheck() {
|
||||
const { user, logout } = useAuth();
|
||||
const router = useRouter();
|
||||
const [showDialog, setShowDialog] = useState(false);
|
||||
const [checking, setChecking] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
// Only check EULA acceptance for authenticated users
|
||||
if (user) {
|
||||
console.log('🔍 Checking EULA acceptance:', {
|
||||
userId: user.id,
|
||||
eulaAcceptedAt: user.eulaAcceptedAt,
|
||||
eulaVersion: user.eulaVersion,
|
||||
});
|
||||
|
||||
// Show dialog if user hasn't accepted EULA
|
||||
if (!user.eulaAcceptedAt) {
|
||||
console.log('⚠️ User has not accepted EULA, showing dialog');
|
||||
setShowDialog(true);
|
||||
} else {
|
||||
console.log('✅ EULA already accepted on', user.eulaAcceptedAt);
|
||||
}
|
||||
}
|
||||
setChecking(false);
|
||||
}, [user]);
|
||||
|
||||
const handleAccept = async () => {
|
||||
try {
|
||||
console.log('✅ User accepted EULA, calling API...');
|
||||
|
||||
const response = await apiClient.post('/api/v1/auth/eula/accept', {
|
||||
version: '2025-10-04',
|
||||
});
|
||||
|
||||
console.log('✅ EULA acceptance recorded:', response.data);
|
||||
|
||||
// Reload user data to get updated EULA acceptance
|
||||
window.location.reload();
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to accept EULA:', error);
|
||||
alert('Failed to accept EULA. Please try again.');
|
||||
}
|
||||
};
|
||||
|
||||
const handleDecline = async () => {
|
||||
console.log('❌ User declined EULA, logging out...');
|
||||
alert('You must accept the Terms of Service, Privacy Policy, and EULA to use ParentFlow.');
|
||||
await logout();
|
||||
router.push('/login');
|
||||
};
|
||||
|
||||
// Don't render anything while checking or if user hasn't loaded
|
||||
if (checking || !user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<EULADialog
|
||||
open={showDialog}
|
||||
onAccept={handleAccept}
|
||||
onDecline={handleDecline}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user