Améliorations diverses
This commit is contained in:
@@ -518,8 +518,8 @@ export default function Dashboard() {
|
||||
activeId={activeId}
|
||||
pfuRates={pfuRates}
|
||||
onCapitalMensuel={setCapitalMensuelData}
|
||||
onCellClick={({ platId, platNom, annee, mois, moisLabel }) =>
|
||||
setDrillCell({ platId, platNom, annee, mois, moisLabel })
|
||||
onCellClick={({ platId, platIds, platNom, annee, mois, moisLabel }) =>
|
||||
setDrillCell({ platId, platIds, platNom, annee, mois, moisLabel })
|
||||
}
|
||||
activeCell={drillCell}
|
||||
/>
|
||||
|
||||
@@ -8,6 +8,8 @@ import EmptyState from '../components/EmptyState.jsx';
|
||||
import InvChart from '../components/InvChart.jsx';
|
||||
import InvMensuelTable from '../components/InvMensuelTable.jsx';
|
||||
import { fmtEUR, fmtDate, fmtStatut, memberLabel } from '../utils/format.js';
|
||||
import { usePagination } from '../hooks/usePagination.js';
|
||||
import Pagination from '../components/Pagination.jsx';
|
||||
|
||||
const LOGOS_BASE = '/api/logos/';
|
||||
|
||||
@@ -324,7 +326,7 @@ export default function Plateformes() {
|
||||
const [pfuRates, setPfuRates] = useState([]);
|
||||
|
||||
/* ── État UI ── */
|
||||
const activeTab = searchParams.get('tab') || 'depots-retraits';
|
||||
const activeTab = searchParams.get('tab') || 'remboursements';
|
||||
const setActiveTab = (tab) => setSearchParams(p => { const n = new URLSearchParams(p); n.set('tab', tab); return n; }, { replace: true });
|
||||
const [listFocused, setListFocused] = useState(false);
|
||||
|
||||
@@ -526,6 +528,17 @@ export default function Plateformes() {
|
||||
}, { investi: 0, cap_remb: 0, int_perc: 0, int_perc_net: 0, encours: 0, defaut: 0 }),
|
||||
[chartRows, capRembParInv, rembParInv, reinvestCumulParInv]);
|
||||
|
||||
/* ── Pagination onglet Investissements ── */
|
||||
const sortedChartRows = useMemo(() =>
|
||||
chartRows.slice().sort((a, b) => (a.date_souscription || '') < (b.date_souscription || '') ? -1 : 1),
|
||||
[chartRows]
|
||||
);
|
||||
const {
|
||||
pagedItems: pagedChartRows, page: platInvPage, setPage: setPlatInvPage,
|
||||
pageSize: platInvPageSize, setPageSize: setPlatInvPageSize,
|
||||
totalPages: platInvTotalPages, totalItems: platInvTotalItems, PAGE_SIZES: platInvPageSizes,
|
||||
} = usePagination(sortedChartRows, 'cl_pagesize_plat_inv', [selectedPlatName, selectedYear]);
|
||||
|
||||
/* ── KPI N-1 (pour TrendBadge) ── */
|
||||
const prevTotals = useMemo(() => {
|
||||
const effectiveYear = selectedYear || String(new Date().getFullYear());
|
||||
@@ -1004,7 +1017,7 @@ export default function Plateformes() {
|
||||
)}
|
||||
</span>
|
||||
</th>
|
||||
<th style={{ padding: '7px 10px', background: 'var(--surface-2)', color: 'var(--text)', fontWeight: 600, fontSize: 'var(--fs-xs)', textAlign: 'left', borderRight: '1px solid var(--border)', whiteSpace: 'nowrap' }}>Statut</th>
|
||||
<th className="tip-th-name" style={{ minWidth: 'unset', position: 'static', fontSize: 'var(--fs-xs)', textAlign: 'left' }}>Statut</th>
|
||||
{MOIS_LONG.map((m, i) => (
|
||||
<th key={m} className={`tip-th-month${displayYear === currentYear && i === currentMonth - 1 ? ' tip-th-month-current' : ''}`}>{m}</th>
|
||||
))}
|
||||
@@ -1030,14 +1043,7 @@ export default function Plateformes() {
|
||||
{inv.nom_projet || '—'}
|
||||
</td>
|
||||
<td style={{ padding: '8px 10px', whiteSpace: 'nowrap', borderRight: '1px solid var(--border)' }}>
|
||||
<span style={{
|
||||
display: 'inline-block', padding: '2px 8px', borderRadius: 4,
|
||||
fontSize: 'var(--fs-xs)', fontWeight: 600,
|
||||
background: `var(--b-${inv.statut}-bg, var(--surface-2))`,
|
||||
color: `var(--b-${inv.statut}-fg, var(--text-muted))`,
|
||||
}}>
|
||||
{fmtStatut(inv.statut)}
|
||||
</span>
|
||||
<span className={`badge ${inv.statut}`}>{fmtStatut(inv.statut)}</span>
|
||||
</td>
|
||||
{(() => {
|
||||
const firstNonNull = months.findIndex(v => v !== null);
|
||||
@@ -1163,9 +1169,10 @@ export default function Plateformes() {
|
||||
<div className="solde-chart-wrap" style={{ padding: '24px 24px 16px', marginBottom: 24 }}>
|
||||
<div className="solde-chart-header" style={{ marginBottom: 16 }}>
|
||||
<div className="solde-chart-info">
|
||||
<div style={{ fontSize: 13, color: 'var(--text-muted)' }}>
|
||||
Mouvements de trésorerie · {selectedYear || 'Toutes les années'}
|
||||
</div>
|
||||
<h3 style={{ margin: 0 }}>
|
||||
Mouvements de trésorerie
|
||||
<span style={{ marginLeft: 8, fontWeight: 400, color: 'var(--text-muted)', fontSize: '0.85em' }}>— {selectedYear || 'Toutes les années'}</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div className="solde-chart-controls">
|
||||
<div className="solde-chart-ranges">
|
||||
@@ -1187,6 +1194,22 @@ export default function Plateformes() {
|
||||
onClick={() => setSelectedYear('')}>
|
||||
TOUT
|
||||
</button>
|
||||
<button type="button" className="icon-btn"
|
||||
title={listFocused ? 'Réduire' : 'Agrandir'}
|
||||
style={{ marginLeft: 4 }}
|
||||
onClick={() => setListFocused(v => !v)}>
|
||||
{listFocused ? (
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polyline points="4 14 10 14 10 20"/><polyline points="20 10 14 10 14 4"/>
|
||||
<line x1="10" y1="14" x2="3" y2="21"/><line x1="21" y1="3" x2="14" y2="10"/>
|
||||
</svg>
|
||||
) : (
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/>
|
||||
<line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1380,9 +1403,10 @@ export default function Plateformes() {
|
||||
<div className="solde-chart-wrap" style={{ padding: '24px 24px 16px', marginBottom: 24 }}>
|
||||
<div className="solde-chart-header">
|
||||
<div className="solde-chart-info">
|
||||
<div style={{ fontSize: 13, color: 'var(--text-muted)', marginBottom: 2 }}>
|
||||
Capital investi par investissement · {selectedYear || 'Toutes les années'}
|
||||
</div>
|
||||
<h3 style={{ margin: 0 }}>
|
||||
Capital investi par investissement
|
||||
<span style={{ marginLeft: 8, fontWeight: 400, color: 'var(--text-muted)', fontSize: '0.85em' }}>— {selectedYear || 'Toutes les années'}</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div className="solde-chart-controls">
|
||||
<div className="solde-chart-ranges">
|
||||
@@ -1444,9 +1468,26 @@ export default function Plateformes() {
|
||||
Investissements
|
||||
{selectedYear && <span style={{ marginLeft: 8, fontWeight: 400, color: 'var(--text-muted)', fontSize: '0.85em' }}>— {selectedYear}</span>}
|
||||
</h3>
|
||||
<span style={{ fontSize: 'var(--fs-sm)', color: 'var(--text-muted)' }}>
|
||||
{chartRows.length} investissement{chartRows.length !== 1 ? 's' : ''}
|
||||
</span>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<span style={{ fontSize: 'var(--fs-sm)', color: 'var(--text-muted)' }}>
|
||||
{chartRows.length} investissement{chartRows.length !== 1 ? 's' : ''}
|
||||
</span>
|
||||
<button type="button" className="icon-btn"
|
||||
title={listFocused ? 'Réduire' : 'Agrandir'}
|
||||
onClick={() => setListFocused(v => !v)}>
|
||||
{listFocused ? (
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polyline points="4 14 10 14 10 20"/><polyline points="20 10 14 10 14 4"/>
|
||||
<line x1="10" y1="14" x2="3" y2="21"/><line x1="21" y1="3" x2="14" y2="10"/>
|
||||
</svg>
|
||||
) : (
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/>
|
||||
<line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!chartRows.length ? (
|
||||
@@ -1454,6 +1495,7 @@ export default function Plateformes() {
|
||||
{loading ? 'Chargement…' : 'Aucun investissement'}
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -1467,10 +1509,7 @@ export default function Plateformes() {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{chartRows
|
||||
.slice()
|
||||
.sort((a, b) => (a.date_souscription || '') < (b.date_souscription || '') ? -1 : 1)
|
||||
.map(r => {
|
||||
{pagedChartRows.map(r => {
|
||||
const capInv = r.montant_investi + (reinvestCumulParInv[r.id] || 0);
|
||||
const capRemb = capRembParInv[r.id] || 0;
|
||||
const capRestant = Math.max(0, capInv - capRemb);
|
||||
@@ -1492,6 +1531,13 @@ export default function Plateformes() {
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
<Pagination
|
||||
page={platInvPage} setPage={setPlatInvPage}
|
||||
pageSize={platInvPageSize} setPageSize={setPlatInvPageSize}
|
||||
totalPages={platInvTotalPages} totalItems={platInvTotalItems}
|
||||
PAGE_SIZES={platInvPageSizes}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user