mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-05-19 11:28:49 +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:
@@ -62,7 +62,7 @@ export default function MonthlyDetail({ detail, loading }: MonthlyDetailProps) {
|
||||
{detail.income_items.map((item) => (
|
||||
<div key={item.id} className="flex items-center justify-between text-sm">
|
||||
<span className="truncate mr-2">{item.name}</span>
|
||||
<span className="font-mono text-primary whitespace-nowrap">
|
||||
<span data-sensitive className="font-mono text-primary whitespace-nowrap">
|
||||
{formatAmount(item.amount, 'CRC')}
|
||||
</span>
|
||||
</div>
|
||||
@@ -70,7 +70,7 @@ export default function MonthlyDetail({ detail, loading }: MonthlyDetailProps) {
|
||||
<Separator />
|
||||
<div className="flex items-center justify-between font-semibold text-sm">
|
||||
<span>Total</span>
|
||||
<span className="font-mono text-primary">
|
||||
<span data-sensitive className="font-mono text-primary">
|
||||
{formatAmount(detail.total_projected_income, 'CRC')}
|
||||
</span>
|
||||
</div>
|
||||
@@ -96,7 +96,7 @@ export default function MonthlyDetail({ detail, loading }: MonthlyDetailProps) {
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-right whitespace-nowrap">
|
||||
<div data-sensitive className="text-right whitespace-nowrap">
|
||||
<span className="font-mono">{formatAmount(item.amount, 'CRC')}</span>
|
||||
{item.used_actual && item.projected_amount != null && (
|
||||
<span className="block text-[10px] text-muted-foreground font-mono line-through">
|
||||
@@ -112,7 +112,7 @@ export default function MonthlyDetail({ detail, loading }: MonthlyDetailProps) {
|
||||
<Separator />
|
||||
<div className="flex items-center justify-between font-semibold text-sm">
|
||||
<span>Total Fijos</span>
|
||||
<span className="font-mono">
|
||||
<span data-sensitive className="font-mono">
|
||||
{formatAmount(detail.total_projected_expenses, 'CRC')}
|
||||
</span>
|
||||
</div>
|
||||
@@ -139,7 +139,7 @@ export default function MonthlyDetail({ detail, loading }: MonthlyDetailProps) {
|
||||
<span>{meta.label}</span>
|
||||
<span className="text-xs text-muted-foreground">({src.count})</span>
|
||||
</div>
|
||||
<span className="font-mono whitespace-nowrap">
|
||||
<span data-sensitive className="font-mono whitespace-nowrap">
|
||||
{formatAmount(src.net, 'CRC')}
|
||||
</span>
|
||||
</div>
|
||||
@@ -153,7 +153,7 @@ export default function MonthlyDetail({ detail, loading }: MonthlyDetailProps) {
|
||||
<Info className="w-3 h-3 text-muted-foreground" />
|
||||
<span className="text-muted-foreground">No cubierto por fijos</span>
|
||||
</div>
|
||||
<span className="font-mono">{formatAmount(detail.uncovered_actual, 'CRC')}</span>
|
||||
<span data-sensitive className="font-mono">{formatAmount(detail.uncovered_actual, 'CRC')}</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
@@ -176,13 +176,13 @@ export default function MonthlyDetail({ detail, loading }: MonthlyDetailProps) {
|
||||
{detail.savings_items.map((item) => (
|
||||
<div key={item.id} className="flex items-center justify-between text-sm">
|
||||
<span>{item.name}</span>
|
||||
<span className="font-mono">{formatAmount(item.amount, 'CRC')}</span>
|
||||
<span data-sensitive className="font-mono">{formatAmount(item.amount, 'CRC')}</span>
|
||||
</div>
|
||||
))}
|
||||
<Separator />
|
||||
<div className="flex items-center justify-between font-semibold text-sm">
|
||||
<span>Total Ahorro</span>
|
||||
<span className="font-mono">
|
||||
<span data-sensitive className="font-mono">
|
||||
{formatAmount(detail.total_projected_savings, 'CRC')}
|
||||
</span>
|
||||
</div>
|
||||
@@ -198,19 +198,19 @@ export default function MonthlyDetail({ detail, loading }: MonthlyDetailProps) {
|
||||
<CardContent className="pt-6 space-y-3">
|
||||
<div className="flex items-center justify-between text-sm">
|
||||
<span>Total Ingresos</span>
|
||||
<span className="font-mono font-medium text-primary">
|
||||
<span data-sensitive className="font-mono font-medium text-primary">
|
||||
+{formatAmount(detail.total_projected_income, 'CRC')}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-sm">
|
||||
<span>Gran Total Egresos</span>
|
||||
<span className="font-mono font-medium">
|
||||
<span data-sensitive className="font-mono font-medium">
|
||||
-{formatAmount(detail.gran_total_egresos, 'CRC')}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-sm">
|
||||
<span>Ahorro</span>
|
||||
<span className="font-mono font-medium">
|
||||
<span data-sensitive className="font-mono font-medium">
|
||||
-{formatAmount(detail.total_projected_savings, 'CRC')}
|
||||
</span>
|
||||
</div>
|
||||
@@ -218,6 +218,7 @@ export default function MonthlyDetail({ detail, loading }: MonthlyDetailProps) {
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="font-semibold">Balance Neto</span>
|
||||
<span
|
||||
data-sensitive
|
||||
className={cn(
|
||||
'font-mono font-bold text-lg',
|
||||
detail.net_balance >= 0 ? 'text-primary' : 'text-destructive',
|
||||
|
||||
@@ -106,7 +106,7 @@ export default function RecurringItemsManager({
|
||||
<DataTableColumnHeader column={column} title="Monto" className="justify-end" />
|
||||
),
|
||||
cell: ({ row }) => (
|
||||
<span className="font-mono text-sm">
|
||||
<span data-sensitive className="font-mono text-sm">
|
||||
{formatAmount(row.original.amount, row.original.currency)}
|
||||
</span>
|
||||
),
|
||||
|
||||
@@ -120,19 +120,19 @@ export default function YearlyOverview({
|
||||
<span className="ml-1.5 inline-block w-1.5 h-1.5 rounded-full bg-primary" />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="text-right font-mono text-sm text-primary">
|
||||
<TableCell data-sensitive className="text-right font-mono text-sm text-primary">
|
||||
{formatAmount(m.projected_income, 'CRC')}
|
||||
</TableCell>
|
||||
<TableCell className="text-right font-mono text-sm">
|
||||
<TableCell data-sensitive className="text-right font-mono text-sm">
|
||||
{formatAmount(m.projected_fixed_expenses, 'CRC')}
|
||||
</TableCell>
|
||||
<TableCell className="text-right font-mono text-sm text-muted-foreground">
|
||||
<TableCell data-sensitive className="text-right font-mono text-sm text-muted-foreground">
|
||||
{formatAmount(m.uncovered_actual, 'CRC')}
|
||||
</TableCell>
|
||||
<TableCell className="text-right font-mono text-sm font-medium">
|
||||
<TableCell data-sensitive className="text-right font-mono text-sm font-medium">
|
||||
{formatAmount(m.gran_total_egresos, 'CRC')}
|
||||
</TableCell>
|
||||
<TableCell className="text-right font-mono text-sm text-muted-foreground">
|
||||
<TableCell data-sensitive className="text-right font-mono text-sm text-muted-foreground">
|
||||
{formatAmount(m.projected_savings, 'CRC')}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
@@ -145,13 +145,14 @@ export default function YearlyOverview({
|
||||
>
|
||||
{isBeforeFreshStart
|
||||
? '—'
|
||||
: <>
|
||||
: <span data-sensitive>
|
||||
{m.carryover_balance >= 0 ? '+' : ''}
|
||||
{formatAmount(m.carryover_balance, 'CRC')}
|
||||
</>
|
||||
</span>
|
||||
}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
data-sensitive
|
||||
className={cn(
|
||||
'text-right font-mono text-sm font-semibold',
|
||||
m.net_balance >= 0 ? 'text-primary' : 'text-destructive',
|
||||
@@ -193,8 +194,10 @@ export default function YearlyOverview({
|
||||
{m.balance_overridden && (
|
||||
<Pencil className="w-3 h-3 text-amber-500 shrink-0" />
|
||||
)}
|
||||
{m.cumulative_balance >= 0 ? '+' : ''}
|
||||
{formatAmount(m.cumulative_balance, 'CRC')}
|
||||
<span data-sensitive>
|
||||
{m.cumulative_balance >= 0 ? '+' : ''}
|
||||
{formatAmount(m.cumulative_balance, 'CRC')}
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
</TableCell>
|
||||
|
||||
Reference in New Issue
Block a user