fix: "hide balance" on Crypto tab only masked the chart's header number

The eye toggle lived as local state inside CryptoHistoryChart, so it only
masked the big total figure — the holdings table, allocation card, and
stats tiles below stayed fully visible. Lifted `hidden` to CryptoPage and
threaded it through every money-displaying section (chart, stats row,
allocation list, holdings table, trade history modal) via a shared
maskAmount() helper.

Percentages (1h/24h/7d%, profit/loss %) stay visible on purpose — a
relative change doesn't reveal the actual amount of money involved, only
absolute currency figures and coin quantities (which combined with a
visible price also reveal an amount) are masked.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01855PiW5Wd8n4aRW4n9kByY
This commit is contained in:
ZProger
2026-08-30 04:43:30 +03:00
parent 4ea83a9cda
commit 5f34d0a612
7 changed files with 80 additions and 35 deletions

View File

@@ -21,6 +21,11 @@ function formatSyncedAt(iso: string): string {
export function CryptoPage() {
const { t } = useTranslation();
const [range, setRange] = useState<CryptoRange>("30d");
// Single "hide balance" switch for the whole tab — owned here so every
// money-displaying section (chart, stats, allocation, table, trade
// history) masks together instead of the toggle only affecting whichever
// component happened to own it.
const [hidden, setHidden] = useState(false);
const { data, isLoading } = useCryptoHoldings();
const { data: history, isLoading: isHistoryLoading } = useCryptoHistory(range);
const refresh = useRefreshCryptoPrices();
@@ -40,11 +45,18 @@ export function CryptoPage() {
return (
<div className="space-y-5">
<CryptoHistoryChart history={history} isLoading={isHistoryLoading} range={range} onRangeChange={setRange} />
<CryptoHistoryChart
history={history}
isLoading={isHistoryLoading}
range={range}
onRangeChange={setRange}
hidden={hidden}
onToggleHidden={() => setHidden((prev) => !prev)}
/>
<CryptoStatsRow holdings={holdings} isLoading={isLoading} />
<CryptoStatsRow holdings={holdings} isLoading={isLoading} hidden={hidden} />
<CryptoAllocationCard holdings={holdings} isLoading={isLoading} />
<CryptoAllocationCard holdings={holdings} isLoading={isLoading} hidden={hidden} />
<Card>
<CardHeader className="flex-col items-stretch gap-3 sm:flex-row sm:items-center">
@@ -75,6 +87,7 @@ export function CryptoPage() {
{data?.error_key && <p className="mb-3 text-sm text-danger">{t(`crypto.syncError.${data.error_key}`)}</p>}
<CryptoHoldingsTable
items={holdings}
hidden={hidden}
onTrade={setTradingHolding}
onViewHistory={setHistoryHolding}
onDelete={handleDelete}
@@ -90,6 +103,7 @@ export function CryptoPage() {
open={historyHolding !== null}
onClose={() => setHistoryHolding(null)}
holding={historyHolding}
hidden={hidden}
/>
</div>
);