Skip to content

Commit

Permalink
Merge pull request #183 from Yiroh/Hiding-Data
Browse files Browse the repository at this point in the history
Successfully implemented hiding and showing
  • Loading branch information
afadil authored Dec 15, 2024
2 parents 390b207 + 1472ae7 commit ea77801
Show file tree
Hide file tree
Showing 25 changed files with 514 additions and 439 deletions.
15 changes: 15 additions & 0 deletions src-tauri/gen/schemas/windows-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -4842,6 +4842,21 @@
"type": "string",
"const": "fs:write-files"
},
{
"description": "Allows the log command",
"type": "string",
"const": "log:default"
},
{
"description": "Enables the log command without any pre-configured scope.",
"type": "string",
"const": "log:allow-log"
},
{
"description": "Denies the log command without any pre-configured scope.",
"type": "string",
"const": "log:deny-log"
},
{
"description": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n",
"type": "string",
Expand Down
9 changes: 6 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { SettingsProvider } from '@/lib/settings-provider';
import { PrivacyProvider } from './context/privacy-context';
import { AppRoutes } from './routes';
import { useState } from 'react';

Expand All @@ -18,9 +19,11 @@ function App() {
);
return (
<QueryClientProvider client={queryClient}>
<SettingsProvider>
<AppRoutes />
</SettingsProvider>
<PrivacyProvider>
<SettingsProvider>
<AppRoutes />
</SettingsProvider>
</PrivacyProvider>
</QueryClientProvider>
);
}
Expand Down
11 changes: 11 additions & 0 deletions src/components/amount-display.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { formatAmount } from '@/lib/utils';

interface AmountDisplayProps {
value: number;
currency: string;
isHidden: boolean;
}

export function AmountDisplay({ value, currency, isHidden }: AmountDisplayProps) {
return <span>{isHidden ? '••••' : formatAmount(value, currency)}</span>;
}
27 changes: 18 additions & 9 deletions src/components/custom-pie-chart.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { PieChart, Pie, Cell, Sector, ResponsiveContainer } from 'recharts';
import { formatAmount } from '@/lib/utils';
import { AmountDisplay } from '@/components/amount-display';
import { useBalancePrivacy } from '@/context/privacy-context';

const COLORS = [
'hsl(var(--chart-1))',
Expand All @@ -13,6 +14,7 @@ const COLORS = [
];

const renderActiveShape = (props: any) => {
const { isBalanceHidden } = useBalancePrivacy();
const RADIAN = Math.PI / 180;
const { cx, cy, midAngle, innerRadius, outerRadius, startAngle, endAngle, fill, payload, value } =
props;
Expand Down Expand Up @@ -57,16 +59,23 @@ const renderActiveShape = (props: any) => {
>
{payload.name}
</text>
<text
<foreignObject
x={ex + (cos >= 0 ? 1 : -1) * 6}
y={ey}
dy={12}
textAnchor={textAnchor}
fill="currentColor"
className="text-xs"
y={ey + 4}
width={100}
height={20}
style={{ overflow: 'visible' }}
>
{formatAmount(value, 'USD', false)}
</text>
<div
style={{
textAnchor: textAnchor,
color: 'currentColor',
fontSize: '0.75rem',
}}
>
<AmountDisplay value={value} currency="USD" isHidden={isBalanceHidden} />
</div>
</foreignObject>
</g>
);
};
Expand Down
32 changes: 19 additions & 13 deletions src/components/gain-amount.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import { cn } from '@/lib/utils';
import NumberFlow from '@number-flow/react';
import { useBalancePrivacy } from '@/context/privacy-context';

interface GainAmountProps extends React.HTMLAttributes<HTMLDivElement> {
value: number;
Expand All @@ -17,6 +18,8 @@ export function GainAmount({
displayDecimal = true,
...props
}: GainAmountProps) {
const { isBalanceHidden } = useBalancePrivacy();

return (
<div className={cn('flex flex-col items-end text-right', className)} {...props}>
<div
Expand All @@ -25,19 +28,22 @@ export function GainAmount({
value === 0 ? 'text-foreground' : value > 0 ? 'text-success' : 'text-red-400',
)}
>
{/* <span>{formatAmount(value, currency, displayCurrency)}</span> */}
<NumberFlow
value={value}
isolate={false}
format={{
currency: currency,
style: displayCurrency ? 'currency' : 'decimal',
currencyDisplay: 'narrowSymbol',
minimumFractionDigits: displayDecimal ? 2 : 0,
maximumFractionDigits: displayDecimal ? 2 : 0,
}}
locales={navigator.language || 'en-US'}
/>
{isBalanceHidden ? (
<span>••••</span>
) : (
<NumberFlow
value={value}
isolate={false}
format={{
currency: currency,
style: displayCurrency ? 'currency' : 'decimal',
currencyDisplay: 'narrowSymbol',
minimumFractionDigits: displayDecimal ? 2 : 0,
maximumFractionDigits: displayDecimal ? 2 : 0,
}}
locales={navigator.language || 'en-US'}
/>
)}
</div>
</div>
);
Expand Down
4 changes: 3 additions & 1 deletion src/components/gain-percent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import NumberFlow from '@number-flow/react';

interface GainPercentProps extends React.HTMLAttributes<HTMLDivElement> {
value: number;
animated?: boolean;
}

export function GainPercent({ value, className, ...props }: GainPercentProps) {
export function GainPercent({ value, animated = false, className, ...props }: GainPercentProps) {
return (
<div
className={cn(
Expand All @@ -27,6 +28,7 @@ export function GainPercent({ value, className, ...props }: GainPercentProps) {
)}
<NumberFlow
value={value / 100}
animated={animated}
format={{
style: 'percent',
minimumFractionDigits: 2,
Expand Down
28 changes: 20 additions & 8 deletions src/components/history-chart.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
import { useMemo } from 'react';
import { Area, AreaChart, Tooltip, YAxis } from 'recharts';
import { Area, AreaChart, Tooltip, YAxis, TooltipProps } from 'recharts';
import { NameType, ValueType } from 'recharts/types/component/DefaultTooltipContent';
import { formatAmount, formatDate } from '@/lib/utils';
import { ChartConfig, ChartContainer } from './ui/chart';
import { useBalancePrivacy } from '@/context/privacy-context';
import { GainPercent } from '@/components/gain-percent';

type CustomTooltipProps = {
active: boolean;
payload: { value: number; payload: any }[];
type CustomTooltipProps = TooltipProps<ValueType, NameType> & {
isBalanceHidden: boolean;
};

const CustomTooltip = ({ active, payload }: CustomTooltipProps) => {
const CustomTooltip = ({ active, payload, isBalanceHidden }: CustomTooltipProps) => {
if (active && payload && payload.length) {
const data = payload[0].payload;
return (
<div className="center-items">
<div className="center-items space-y-1">
<p className="font-thin">{formatDate(data.date)}</p>
<p className="label">{formatAmount(payload[0].value, data.currency, false)}</p>
<p className="label">
{isBalanceHidden
? `•••• `
: `${formatAmount(Number(payload[0].value), data.currency, false)} `}
<GainPercent value={data.totalGainPercentage} />
</p>
</div>
);
}
Expand All @@ -25,6 +32,7 @@ const CustomTooltip = ({ active, payload }: CustomTooltipProps) => {
interface HistoryChartData {
date: string;
totalValue: number;
totalGainPercentage: number;
currency: string;
}

Expand All @@ -35,6 +43,8 @@ export function HistoryChart({
data: HistoryChartData[];
interval: '1D' | '1W' | '1M' | '3M' | '1Y' | 'ALL';
}) {
const { isBalanceHidden } = useBalancePrivacy();

const filteredData = useMemo(() => {
if (!data) return [];
const today = new Date();
Expand Down Expand Up @@ -87,7 +97,9 @@ export function HistoryChart({
</linearGradient>
</defs>
{/* @ts-ignore */}
<Tooltip content={<CustomTooltip />} />
<Tooltip
content={(props) => <CustomTooltip {...props} isBalanceHidden={isBalanceHidden} />}
/>
{interval !== 'ALL' && interval !== '1Y' && (
<YAxis hide type="number" domain={['auto', 'auto']} />
)}
Expand Down
18 changes: 18 additions & 0 deletions src/components/privacy-amount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useBalancePrivacy } from '@/context/privacy-context';
import { cn } from '@/lib/utils';
import { formatAmount } from '@/lib/utils';

interface PrivacyAmountProps extends React.HTMLAttributes<HTMLSpanElement> {
value: number;
currency: string;
}

export function PrivacyAmount({ value, currency, className, ...props }: PrivacyAmountProps) {
const { isBalanceHidden } = useBalancePrivacy();

return (
<span className={cn(className)} {...props}>
{isBalanceHidden ? '••••' : formatAmount(value, currency)}
</span>
);
}
26 changes: 26 additions & 0 deletions src/components/privacy-toggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useBalancePrivacy } from '@/context/privacy-context';
import { Button } from '@/components/ui/button';
import { Icons } from '@/components/icons';
import { cn } from '@/lib/utils';

interface PrivacyToggleProps {
className?: string;
}

export function PrivacyToggle({ className }: PrivacyToggleProps) {
const { isBalanceHidden, toggleBalanceVisibility } = useBalancePrivacy();

return (
<Button
variant="secondary"
size="icon"
className={cn('mt-1 h-8 w-8 rounded-full', className)}
onClick={(e) => {
e.stopPropagation();
toggleBalanceVisibility();
}}
>
{isBalanceHidden ? <Icons.Eye className="h-4 w-4" /> : <Icons.EyeOff className="h-4 w-4" />}
</Button>
);
}
10 changes: 10 additions & 0 deletions src/components/quantity-display.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { formatStockQuantity } from '@/lib/utils';

interface QuantityDisplayProps {
value: number;
isHidden: boolean;
}

export function QuantityDisplay({ value, isHidden }: QuantityDisplayProps) {
return <span>{isHidden ? '••••' : formatStockQuantity(value)}</span>;
}
39 changes: 39 additions & 0 deletions src/context/privacy-context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { createContext, useContext, useEffect, useState } from 'react';

interface PrivacyContextType {
isBalanceHidden: boolean;
toggleBalanceVisibility: () => void;
}

const PrivacyContext = createContext<PrivacyContextType | undefined>(undefined);

const STORAGE_KEY = 'privacy-settings';

export function PrivacyProvider({ children }: { children: React.ReactNode }) {
const [isBalanceHidden, setIsBalanceHidden] = useState(() => {
const stored = localStorage.getItem(STORAGE_KEY);
return stored ? JSON.parse(stored) : false;
});

useEffect(() => {
localStorage.setItem(STORAGE_KEY, JSON.stringify(isBalanceHidden));
}, [isBalanceHidden]);

function toggleBalanceVisibility() {
setIsBalanceHidden((prev: boolean) => !prev);
}

return (
<PrivacyContext.Provider value={{ isBalanceHidden, toggleBalanceVisibility }}>
{children}
</PrivacyContext.Provider>
);
}

export function useBalancePrivacy() {
const context = useContext(PrivacyContext);
if (context === undefined) {
throw new Error('useBalancePrivacy must be used within a PrivacyProvider');
}
return context;
}
Loading

0 comments on commit ea77801

Please sign in to comment.