fix(mail): reactive page (refresh stats + status on scan/connect) + center donut+legend
Two small fixes blocking real "feierabend":
1. Stats-Counter veraltet nach Scan/Connect/Disconnect:
- mail.tsx hatte zwei separate Data-Sources: useMailStatus (accounts +
errors + heartbeat) und useMailStats (blockedByDay + blockedByConnection)
- onScanSuccess + onIntervalChanged + OAuth-onSuccess + disconnect-handler
refreshten nur useMailStatus → der Account-Collapsible-Counter (kommt
aus useMailStats.blockedByConnection) blieb veraltet
- Beobachtet: GMX-Scan-Button meldet "90 blockiert" als Feedback, aber
Card-Header zeigt weiter 60
- Fix: refreshAll() = refresh() + refreshStats() parallel. Alle reactive
callsites (4 Stellen) auf refreshAll umgestellt
- useMailStats hatte refresh schon exportiert (Z. 153), nur nicht
verdrahtet
2. Donut + Legend horizontal zentriert:
- vorher: alignItems center (vertikal), Legend flex:1 → linksbündig mit
Legend bis Card-Rand gestreckt
- jetzt: justifyContent center + Legend ohne flex:1 → Block in der Mitte
mit Whitespace links/rechts
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
30ed4b90b4
commit
4580a197dd
@ -255,7 +255,16 @@ export default function MailScreen() {
|
|||||||
useMailStatus(plan);
|
useMailStatus(plan);
|
||||||
const { disconnect, disconnecting } = useMailDisconnect();
|
const { disconnect, disconnecting } = useMailDisconnect();
|
||||||
const hasAccounts = accounts.length > 0;
|
const hasAccounts = accounts.length > 0;
|
||||||
const { blockedByDay, blockedByConnection } = useMailStats(hasAccounts);
|
const { blockedByDay, blockedByConnection, refresh: refreshStats } = useMailStats(hasAccounts);
|
||||||
|
|
||||||
|
// Globaler Refresh-Handler für alle reactive-Trigger (Scan-Success,
|
||||||
|
// Interval-Change, Connect/Disconnect): refresht beide Datenquellen
|
||||||
|
// parallel — useMailStatus (accounts, connect-errors, heartbeat) UND
|
||||||
|
// useMailStats (blockedByDay, blockedByConnection für Charts + Counter).
|
||||||
|
const refreshAll = () => {
|
||||||
|
refresh();
|
||||||
|
refreshStats();
|
||||||
|
};
|
||||||
|
|
||||||
const [sheetVisible, setSheetVisible] = useState(false);
|
const [sheetVisible, setSheetVisible] = useState(false);
|
||||||
const [successVisible, setSuccessVisible] = useState(false);
|
const [successVisible, setSuccessVisible] = useState(false);
|
||||||
@ -290,11 +299,11 @@ export default function MailScreen() {
|
|||||||
await disconnect(id);
|
await disconnect(id);
|
||||||
setDisconnectingId(null);
|
setDisconnectingId(null);
|
||||||
if (expandedAccount === id) setExpandedAccount(null);
|
if (expandedAccount === id) setExpandedAccount(null);
|
||||||
refresh();
|
refreshAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleConnectSuccess() {
|
function handleConnectSuccess() {
|
||||||
refresh();
|
refreshAll();
|
||||||
if (pendingOAuthConnectionId) {
|
if (pendingOAuthConnectionId) {
|
||||||
setOauthTitleSheetConnectionId(pendingOAuthConnectionId);
|
setOauthTitleSheetConnectionId(pendingOAuthConnectionId);
|
||||||
setPendingOAuthConnectionId(null);
|
setPendingOAuthConnectionId(null);
|
||||||
@ -509,11 +518,11 @@ export default function MailScreen() {
|
|||||||
expanded={expandedAccount === account.id}
|
expanded={expandedAccount === account.id}
|
||||||
onToggle={() => toggleAccount(account.id)}
|
onToggle={() => toggleAccount(account.id)}
|
||||||
onDisconnect={handleDisconnect}
|
onDisconnect={handleDisconnect}
|
||||||
onIntervalChanged={refresh}
|
onIntervalChanged={refreshAll}
|
||||||
onEditSuccess={handleConnectSuccess}
|
onEditSuccess={handleConnectSuccess}
|
||||||
disconnecting={disconnectingId === account.id && disconnecting}
|
disconnecting={disconnectingId === account.id && disconnecting}
|
||||||
blockedLast30d={connStat?.count}
|
blockedLast30d={connStat?.count}
|
||||||
onScanSuccess={refresh}
|
onScanSuccess={refreshAll}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@ -533,7 +542,7 @@ export default function MailScreen() {
|
|||||||
connectionId={oauthTitleSheetConnectionId}
|
connectionId={oauthTitleSheetConnectionId}
|
||||||
currentTitle={null}
|
currentTitle={null}
|
||||||
onClose={() => { setOauthTitleSheetConnectionId(null); setSuccessVisible(true); }}
|
onClose={() => { setOauthTitleSheetConnectionId(null); setSuccessVisible(true); }}
|
||||||
onSuccess={() => { setOauthTitleSheetConnectionId(null); setSuccessVisible(true); refresh(); }}
|
onSuccess={() => { setOauthTitleSheetConnectionId(null); setSuccessVisible(true); refreshAll(); }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@ -98,14 +98,14 @@ export function MailDistributionChart({ data, hero, totalBlocked, isLegend }: Pr
|
|||||||
paddingBottom: 12,
|
paddingBottom: 12,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 16 }}>
|
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 16 }}>
|
||||||
<HalfDonut
|
<HalfDonut
|
||||||
segments={segments}
|
segments={segments}
|
||||||
centerValue={centerValue}
|
centerValue={centerValue}
|
||||||
centerLabel={centerLabel}
|
centerLabel={centerLabel}
|
||||||
width={DONUT_WIDTH}
|
width={DONUT_WIDTH}
|
||||||
/>
|
/>
|
||||||
<View style={{ flex: 1, gap: 5 }}>
|
<View style={{ gap: 5 }}>
|
||||||
{slices.map((slice) => (
|
{slices.map((slice) => (
|
||||||
<LegendRow key={slice.label} slice={slice} colors={colors} />
|
<LegendRow key={slice.label} slice={slice} colors={colors} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user