4NK_IA_front/src/views/ConseilView.tsx
Nicolas Cantu bb133d5448 feat: apply white background theme and improve UI styling
- Add Material-UI theme with white background configuration
- Update CSS with white background and light color scheme
- Integrate ThemeProvider and CssBaseline for consistent styling
- Remove dark theme elements and apply clean white design
- Improve typography and color contrast for better readability
2025-09-10 17:55:39 +02:00

243 lines
7.3 KiB
TypeScript

import { useEffect } from 'react'
import {
Box,
Typography,
Paper,
Card,
CardContent,
List,
ListItem,
ListItemText,
ListItemIcon,
Alert,
Chip,
Button,
CircularProgress,
} from '@mui/material'
import {
Lightbulb,
Warning,
CheckCircle,
TrendingUp,
Schedule,
Psychology,
} from '@mui/icons-material'
import { useAppDispatch, useAppSelector } from '../store'
import { getConseil } from '../store/documentSlice'
import { Layout } from '../components/Layout'
export default function ConseilView() {
const dispatch = useAppDispatch()
const { currentDocument, conseilResult, loading } = useAppSelector(
(state) => state.document
)
useEffect(() => {
if (currentDocument && !conseilResult) {
dispatch(getConseil(currentDocument.id))
}
}, [currentDocument, conseilResult, dispatch])
if (!currentDocument) {
return (
<Layout>
<Alert severity="info">
Veuillez d'abord téléverser et sélectionner un document.
</Alert>
</Layout>
)
}
if (loading) {
return (
<Layout>
<Box sx={{ display: 'flex', justifyContent: 'center', mt: 4 }}>
<CircularProgress />
<Typography sx={{ ml: 2 }}>Génération des conseils LLM...</Typography>
</Box>
</Layout>
)
}
if (!conseilResult) {
return (
<Layout>
<Alert severity="warning">
Aucun conseil disponible.
</Alert>
</Layout>
)
}
const getRiskColor = (risk: string) => {
if (risk.toLowerCase().includes('élevé') || risk.toLowerCase().includes('critique')) {
return 'error'
}
if (risk.toLowerCase().includes('moyen') || risk.toLowerCase().includes('modéré')) {
return 'warning'
}
return 'info'
}
return (
<Layout>
<Typography variant="h4" gutterBottom>
<Psychology sx={{ mr: 1, verticalAlign: 'middle' }} />
Conseil LLM
</Typography>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
{/* Analyse LLM */}
<Card>
<CardContent>
<Typography variant="h6" gutterBottom>
<Lightbulb sx={{ mr: 1, verticalAlign: 'middle' }} />
Analyse LLM
</Typography>
<Paper
sx={{
p: 2,
bgcolor: 'grey.50',
border: '1px solid',
borderColor: 'grey.200',
}}
>
<Typography variant="body1" sx={{ whiteSpace: 'pre-wrap' }}>
{conseilResult.analysis}
</Typography>
</Paper>
<Typography variant="caption" color="text.secondary" sx={{ mt: 1, display: 'block' }}>
Généré le {new Date(conseilResult.generatedAt).toLocaleString()}
</Typography>
</CardContent>
</Card>
<Box sx={{ display: 'flex', gap: 3, flexWrap: 'wrap' }}>
{/* Recommandations */}
<Box sx={{ flex: '1 1 300px' }}>
<Card>
<CardContent>
<Typography variant="h6" gutterBottom>
<CheckCircle sx={{ mr: 1, verticalAlign: 'middle' }} />
Recommandations ({conseilResult.recommendations.length})
</Typography>
<List dense>
{conseilResult.recommendations.map((recommendation, index) => (
<ListItem key={index}>
<ListItemIcon>
<CheckCircle color="success" />
</ListItemIcon>
<ListItemText primary={recommendation} />
</ListItem>
))}
</List>
</CardContent>
</Card>
</Box>
{/* Risques identifiés */}
<Box sx={{ flex: '1 1 300px' }}>
<Card>
<CardContent>
<Typography variant="h6" gutterBottom>
<Warning sx={{ mr: 1, verticalAlign: 'middle' }} />
Risques identifiés ({conseilResult.risks.length})
</Typography>
<List dense>
{conseilResult.risks.map((risk, index) => (
<ListItem key={index}>
<ListItemIcon>
<Warning color={getRiskColor(risk) as any} />
</ListItemIcon>
<ListItemText
primary={risk}
primaryTypographyProps={{
color: getRiskColor(risk) === 'error' ? 'error.main' :
getRiskColor(risk) === 'warning' ? 'warning.main' : 'info.main'
}}
/>
</ListItem>
))}
</List>
</CardContent>
</Card>
</Box>
</Box>
{/* Prochaines étapes */}
<Card>
<CardContent>
<Typography variant="h6" gutterBottom>
<TrendingUp sx={{ mr: 1, verticalAlign: 'middle' }} />
Prochaines étapes recommandées
</Typography>
<List>
{conseilResult.nextSteps.map((step, index) => (
<ListItem key={index}>
<ListItemIcon>
<Schedule color="primary" />
</ListItemIcon>
<ListItemText
primary={`Étape ${index + 1}`}
secondary={step}
/>
</ListItem>
))}
</List>
</CardContent>
</Card>
{/* Actions */}
<Card>
<CardContent>
<Typography variant="h6" gutterBottom>
Actions
</Typography>
<Box sx={{ display: 'flex', gap: 2, flexWrap: 'wrap' }}>
<Button
variant="contained"
onClick={() => dispatch(getConseil(currentDocument.id))}
disabled={loading}
>
Régénérer les conseils
</Button>
<Button variant="outlined">
Exporter le rapport
</Button>
<Button variant="outlined">
Partager avec l'équipe
</Button>
</Box>
</CardContent>
</Card>
{/* Résumé exécutif */}
<Paper sx={{ p: 2, bgcolor: 'primary.50' }}>
<Typography variant="h6" gutterBottom>
Résumé exécutif
</Typography>
<Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap', mb: 2 }}>
<Chip
label={`${conseilResult.recommendations.length} recommandations`}
color="success"
variant="outlined"
/>
<Chip
label={`${conseilResult.risks.length} risques identifiés`}
color="warning"
variant="outlined"
/>
<Chip
label={`${conseilResult.nextSteps.length} étapes suivantes`}
color="info"
variant="outlined"
/>
</Box>
<Typography variant="body2" color="text.secondary">
Cette analyse LLM a é générée automatiquement et doit être validée par un expert notarial.
</Typography>
</Paper>
</Box>
</Layout>
)
}