mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-05-19 14:08:47 +02:00
Add privacy mode toggle to blur sensitive financial amounts
All checks were successful
Deploy to VPS / deploy (push) Successful in 14s
All checks were successful
Deploy to VPS / deploy (push) Successful in 14s
Eye/EyeOff icon next to theme toggle. Persists in localStorage. Applies CSS blur to all elements marked with data-sensitive attribute across Dashboard, Budget, Pensions, Salarios, and Transactions pages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -151,7 +151,7 @@ export default function Budget() {
|
||||
<Card>
|
||||
<CardContent className="pt-4 pb-3 px-4">
|
||||
<p className="text-xs text-muted-foreground">Ingresos Anuales</p>
|
||||
<p className="text-lg font-bold font-mono text-primary">
|
||||
<p data-sensitive className="text-lg font-bold font-mono text-primary">
|
||||
{formatAmount(projection.annual_income, 'CRC')}
|
||||
</p>
|
||||
</CardContent>
|
||||
@@ -159,7 +159,7 @@ export default function Budget() {
|
||||
<Card>
|
||||
<CardContent className="pt-4 pb-3 px-4">
|
||||
<p className="text-xs text-muted-foreground">Egresos Anuales</p>
|
||||
<p className="text-lg font-bold font-mono">
|
||||
<p data-sensitive className="text-lg font-bold font-mono">
|
||||
{formatAmount(projection.annual_expenses, 'CRC')}
|
||||
</p>
|
||||
</CardContent>
|
||||
@@ -167,7 +167,7 @@ export default function Budget() {
|
||||
<Card>
|
||||
<CardContent className="pt-4 pb-3 px-4">
|
||||
<p className="text-xs text-muted-foreground">Ahorro Anual</p>
|
||||
<p className="text-lg font-bold font-mono">
|
||||
<p data-sensitive className="text-lg font-bold font-mono">
|
||||
{formatAmount(projection.annual_savings, 'CRC')}
|
||||
</p>
|
||||
</CardContent>
|
||||
@@ -176,6 +176,7 @@ export default function Budget() {
|
||||
<CardContent className="pt-4 pb-3 px-4">
|
||||
<p className="text-xs text-muted-foreground">Balance Neto Anual</p>
|
||||
<p
|
||||
data-sensitive
|
||||
className={cn(
|
||||
'text-lg font-bold font-mono',
|
||||
projection.annual_net >= 0 ? 'text-primary' : 'text-destructive',
|
||||
|
||||
@@ -94,7 +94,7 @@ function AccountRow({
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className={cn('text-lg font-bold font-mono tracking-tight', isLiability && 'text-destructive')}>
|
||||
<span data-sensitive className={cn('text-lg font-bold font-mono tracking-tight', isLiability && 'text-destructive')}>
|
||||
{formatAmount(account.balance, account.currency)}
|
||||
</span>
|
||||
<button
|
||||
@@ -106,7 +106,7 @@ function AccountRow({
|
||||
<Pencil className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
{isLiability && account.next_payment != null && (
|
||||
<span className="text-xs font-mono text-destructive/60 ml-2">
|
||||
<span data-sensitive className="text-xs font-mono text-destructive/60 ml-2">
|
||||
Next: {formatAmount(account.next_payment, account.currency)}
|
||||
</span>
|
||||
)}
|
||||
@@ -215,10 +215,10 @@ export default function Dashboard() {
|
||||
<Card>
|
||||
<CardContent className="px-4 py-3">
|
||||
<div className="flex items-center justify-between text-sm font-mono text-muted-foreground">
|
||||
<span>Net <span className="text-foreground font-bold">{netWorthBreakdown.net < 0 ? '-' : ''}{formatAmount(netWorthBreakdown.net, 'CRC')}</span></span>
|
||||
<span>Net <span data-sensitive className="text-foreground font-bold">{netWorthBreakdown.net < 0 ? '-' : ''}{formatAmount(netWorthBreakdown.net, 'CRC')}</span></span>
|
||||
<div className="flex gap-4">
|
||||
<span>Assets <span className="text-foreground">{formatAmount(netWorthBreakdown.assets, 'CRC')}</span></span>
|
||||
<span>Liabilities <span className="text-foreground">{formatAmount(netWorthBreakdown.liabilities, 'CRC')}</span></span>
|
||||
<span>Assets <span data-sensitive className="text-foreground">{formatAmount(netWorthBreakdown.assets, 'CRC')}</span></span>
|
||||
<span>Liabilities <span data-sensitive className="text-foreground">{formatAmount(netWorthBreakdown.liabilities, 'CRC')}</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
@@ -262,8 +262,8 @@ export default function Dashboard() {
|
||||
<CardContent className="p-4">
|
||||
<span className="text-xs font-medium text-muted-foreground uppercase tracking-wider">USD/CRC Exchange Rate</span>
|
||||
<div className="flex items-baseline gap-3 mt-1">
|
||||
<span className="text-lg font-bold font-mono">Buy: ₡{exchangeRate.buy_rate.toFixed(2)}</span>
|
||||
<span className="text-lg font-bold font-mono text-muted-foreground">Sell: ₡{exchangeRate.sell_rate.toFixed(2)}</span>
|
||||
<span data-sensitive className="text-lg font-bold font-mono">Buy: ₡{exchangeRate.buy_rate.toFixed(2)}</span>
|
||||
<span data-sensitive className="text-lg font-bold font-mono text-muted-foreground">Sell: ₡{exchangeRate.sell_rate.toFixed(2)}</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -306,7 +306,7 @@ export default function Dashboard() {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<span className={cn(
|
||||
<span data-sensitive className={cn(
|
||||
'font-mono text-sm font-medium shrink-0 ml-4',
|
||||
tx.transaction_type !== 'COMPRA' && 'text-primary'
|
||||
)}>
|
||||
|
||||
@@ -229,7 +229,7 @@ function ChartTooltipContent({
|
||||
/>
|
||||
<span className="text-muted-foreground">{entry.name}</span>
|
||||
</span>
|
||||
<span className="font-mono font-medium text-foreground">{formatCRC(entry.value)}</span>
|
||||
<span data-sensitive className="font-mono font-medium text-foreground">{formatCRC(entry.value)}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -440,7 +440,7 @@ export default function Pensions() {
|
||||
<p className="text-xs text-muted-foreground uppercase tracking-wider font-medium">
|
||||
Balance actual
|
||||
</p>
|
||||
<p className="text-xl font-bold font-mono mt-0.5 leading-tight">
|
||||
<p data-sensitive className="text-xl font-bold font-mono mt-0.5 leading-tight">
|
||||
{formatCRC(fund.startBalance)}
|
||||
</p>
|
||||
{snap && (
|
||||
@@ -456,19 +456,19 @@ export default function Pensions() {
|
||||
<div className="space-y-1.5 text-xs">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-muted-foreground">Aportes</span>
|
||||
<span className="font-mono font-medium">
|
||||
<span data-sensitive className="font-mono font-medium">
|
||||
{formatCRC(snap.aportes)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-muted-foreground">Rendimientos</span>
|
||||
<span className="font-mono font-medium text-emerald-500">
|
||||
<span data-sensitive className="font-mono font-medium text-emerald-500">
|
||||
{formatCRC(snap.rendimientos)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-muted-foreground">Comisión</span>
|
||||
<span className="font-mono font-medium text-destructive">
|
||||
<span data-sensitive className="font-mono font-medium text-destructive">
|
||||
{formatCRC(snap.comision)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -477,7 +477,7 @@ export default function Pensions() {
|
||||
<div className="space-y-1.5 text-xs">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-muted-foreground">Aporte mensual</span>
|
||||
<span className="font-mono font-medium">
|
||||
<span data-sensitive className="font-mono font-medium">
|
||||
{formatCRC(fund.monthlyContribution)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -606,7 +606,7 @@ export default function Pensions() {
|
||||
{fund.isDividend ? `Dividendos ${fund.annualRate}%` : `${fund.annualRate}% anual`}
|
||||
</p>
|
||||
)}
|
||||
<p className="text-lg font-bold font-mono" style={{ color: fund.color }}>
|
||||
<p data-sensitive className="text-lg font-bold font-mono" style={{ color: fund.color }}>
|
||||
{earned >= 0 ? '+' : ''}{formatCRC(earned)}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">en rendimientos</p>
|
||||
@@ -686,6 +686,7 @@ export default function Pensions() {
|
||||
Valor en {years} {years === 1 ? 'año' : 'años'}
|
||||
</p>
|
||||
<p
|
||||
data-sensitive
|
||||
className="text-lg font-bold font-mono leading-tight"
|
||||
style={{ color: fund.color }}
|
||||
>
|
||||
@@ -855,7 +856,7 @@ export default function Pensions() {
|
||||
{' — '}
|
||||
{new Date(snap.period_end).toLocaleDateString('es-CR', { month: 'short', year: '2-digit' })}
|
||||
</span>
|
||||
<span className="font-mono font-medium">{formatCRC(snap.saldo_final)}</span>
|
||||
<span data-sensitive className="font-mono font-medium">{formatCRC(snap.saldo_final)}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -64,7 +64,7 @@ export default function Salarios() {
|
||||
accessorKey: 'amount',
|
||||
header: ({ column }) => <DataTableColumnHeader column={column} title="Monto" />,
|
||||
cell: ({ row }) => (
|
||||
<span className="font-mono font-bold text-primary">
|
||||
<span data-sensitive className="font-mono font-bold text-primary">
|
||||
+{formatAmount(row.original.amount, row.original.currency)}
|
||||
</span>
|
||||
),
|
||||
@@ -126,7 +126,7 @@ export default function Salarios() {
|
||||
<Banknote className="w-4 h-4" />
|
||||
<span className="text-xs font-medium uppercase tracking-wider">Total acumulado</span>
|
||||
</div>
|
||||
<span className="text-2xl font-bold font-mono text-primary">
|
||||
<span data-sensitive className="text-2xl font-bold font-mono text-primary">
|
||||
{formatAmount(summary.total_amount, 'CRC')}
|
||||
</span>
|
||||
</CardContent>
|
||||
|
||||
@@ -72,10 +72,10 @@ export default function Transactions() {
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
{transactions.length} transactions
|
||||
{totalCRC !== 0 && (
|
||||
<> · <span className="font-mono text-foreground">{formatAmount(totalCRC, 'CRC')}</span></>
|
||||
<> · <span data-sensitive className="font-mono text-foreground">{formatAmount(totalCRC, 'CRC')}</span></>
|
||||
)}
|
||||
{totalUSD !== 0 && (
|
||||
<> · <span className="font-mono text-foreground">{formatAmount(totalUSD, 'USD')}</span></>
|
||||
<> · <span data-sensitive className="font-mono text-foreground">{formatAmount(totalUSD, 'USD')}</span></>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user