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:
80
maternal-web/components/legal/LegalDocumentViewer.tsx
Normal file
80
maternal-web/components/legal/LegalDocumentViewer.tsx
Normal file
@@ -0,0 +1,80 @@
|
||||
'use client';
|
||||
|
||||
import {
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
DialogContent,
|
||||
DialogActions,
|
||||
Button,
|
||||
Typography,
|
||||
Box,
|
||||
IconButton,
|
||||
} from '@mui/material';
|
||||
import { Close } from '@mui/icons-material';
|
||||
import { TermsContent } from './TermsContent';
|
||||
import { PrivacyContent } from './PrivacyContent';
|
||||
import { EULAContent } from './EULAContent';
|
||||
|
||||
interface LegalDocumentViewerProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
documentType: 'terms' | 'privacy' | 'eula' | 'cookies';
|
||||
title: string;
|
||||
}
|
||||
|
||||
export function LegalDocumentViewer({ open, onClose, documentType, title }: LegalDocumentViewerProps) {
|
||||
const lastUpdated = 'October 4, 2025';
|
||||
|
||||
const getContent = () => {
|
||||
switch (documentType) {
|
||||
case 'terms':
|
||||
return <TermsContent />;
|
||||
case 'privacy':
|
||||
return <PrivacyContent />;
|
||||
case 'eula':
|
||||
return <EULAContent />;
|
||||
default:
|
||||
return (
|
||||
<Typography color="error">
|
||||
Document content not available. Please visit the{' '}
|
||||
<a href={`/legal/${documentType}`} target="_blank" rel="noopener">
|
||||
full page
|
||||
</a>
|
||||
.
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
maxWidth="md"
|
||||
fullWidth
|
||||
sx={{
|
||||
zIndex: (theme) => theme.zIndex.modal + 1, // Ensure this dialog appears above the EULA dialog
|
||||
}}
|
||||
>
|
||||
<DialogTitle sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<Typography variant="h6">{title}</Typography>
|
||||
<IconButton onClick={onClose} size="small" aria-label="close">
|
||||
<Close />
|
||||
</IconButton>
|
||||
</DialogTitle>
|
||||
|
||||
<DialogContent dividers sx={{ maxHeight: '60vh', overflowY: 'auto' }}>
|
||||
<Typography variant="body2" color="text.secondary" paragraph>
|
||||
Last Updated: {lastUpdated}
|
||||
</Typography>
|
||||
{getContent()}
|
||||
</DialogContent>
|
||||
|
||||
<DialogActions sx={{ p: 2 }}>
|
||||
<Button onClick={onClose} variant="contained" color="primary">
|
||||
Close
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user