Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/dist-web
/dist-dweb
/tmp
/.tmp
/out-tsc
/release
/gh-pages
Expand Down
6 changes: 3 additions & 3 deletions TDD.md
Original file line number Diff line number Diff line change
Expand Up @@ -1122,7 +1122,7 @@ export function WalletCard({ wallet }: WalletCardProps) {
{wallet.name}
</h3>
{/* 宽容器时显示完整地址 */}
<p className="text-xs text-muted @md:text-sm">
<p className="text-xs text-muted-@md:text-sm">
<span className="@md:hidden">{shortenAddress(wallet.address)}</span>
<span className="hidden @md:inline">{wallet.address}</span>
</p>
Expand All @@ -1133,7 +1133,7 @@ export function WalletCard({ wallet }: WalletCardProps) {
<p className="text-sm @xs:text-base @md:text-lg font-bold">
{formatBalance(wallet.balance)}
</p>
<p className="hidden @md:block text-xs text-muted">
<p className="hidden @md:block text-xs text-muted-foreground">
≈ ${wallet.fiatValue}
</p>
</div>
Expand Down Expand Up @@ -3100,7 +3100,7 @@ export function AuthorizeCard({
/>
<div>
<h3 className="font-medium">{appInfo.name}</h3>
<p className="text-sm text-muted">{appInfo.home}</p>
<p className="text-sm text-muted-foreground">{appInfo.home}</p>
</div>
</div>

Expand Down
Binary file modified e2e/__screenshots__/Desktop-Chrome/01-home-empty.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/__screenshots__/Desktop-Chrome/07-verify-step.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/__screenshots__/Desktop-Chrome/authorize-address-page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/__screenshots__/Desktop-Chrome/home-with-wallet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/__screenshots__/Desktop-Chrome/staking-overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/__screenshots__/Mobile-Chrome/01-home-empty.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/__screenshots__/Mobile-Chrome/07-verify-step.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/__screenshots__/Mobile-Chrome/authorize-address-page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/__screenshots__/Mobile-Chrome/home-with-wallet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/__screenshots__/Mobile-Chrome/migration-complete.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/__screenshots__/Mobile-Chrome/migration-progress.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/__screenshots__/Mobile-Chrome/settings-main.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/__screenshots__/Mobile-Chrome/staking-overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
"clsx": "^2.1.1",
"i18next": "^25.7.1",
"jsqr": "^1.4.0",
"lucide-react": "^0.556.0",
"qrcode.react": "^4.2.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
Expand Down
12 changes: 0 additions & 12 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export default function App() {
return (
<div className="min-h-screen bg-background text-foreground">
<div className="bg-background text-foreground min-h-screen">
<main className="container mx-auto px-4 py-8">
<h1 className="text-2xl font-bold text-primary">BFM Pay</h1>
<p className="mt-2 text-muted">钱包应用开发中...</p>
<h1 className="text-primary text-2xl font-bold">BFM Pay</h1>
<p className="text-muted-foreground mt-2">钱包应用开发中...</p>
</main>
</div>
)
);
}
6 changes: 3 additions & 3 deletions src/components/common/alert.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('Alert', () => {

it('applies info variant by default', () => {
const { container } = render(<Alert>Info alert</Alert>)
expect(container.querySelector('[role="alert"]')).toHaveClass('bg-blue-500/10')
expect(container.querySelector('[role="alert"]')).toHaveClass('bg-info/10')
})

it('applies error variant styles', () => {
Expand All @@ -35,12 +35,12 @@ describe('Alert', () => {

it('applies success variant styles', () => {
const { container } = render(<Alert variant="success">Success alert</Alert>)
expect(container.querySelector('[role="alert"]')).toHaveClass('bg-green-500/10')
expect(container.querySelector('[role="alert"]')).toHaveClass('bg-success/10')
})

it('applies warning variant styles', () => {
const { container } = render(<Alert variant="warning">Warning alert</Alert>)
expect(container.querySelector('[role="alert"]')).toHaveClass('bg-yellow-500/10')
expect(container.querySelector('[role="alert"]')).toHaveClass('bg-warning/10')
})

it('applies custom className', () => {
Expand Down
13 changes: 9 additions & 4 deletions src/components/common/alert.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { cn } from '@/lib/utils';
import { AlertCircle, CheckCircle, Info, AlertTriangle } from 'lucide-react';
import {
IconAlertCircle as AlertCircle,
IconCircleCheck as CheckCircle,
IconInfoCircle as Info,
IconAlertTriangle as AlertTriangle,
} from '@tabler/icons-react';
import type { ReactNode } from 'react';

type AlertVariant = 'info' | 'success' | 'warning' | 'error';
Expand All @@ -14,15 +19,15 @@ interface AlertProps {
const variantConfig = {
info: {
icon: Info,
styles: 'bg-blue-500/10 text-blue-700 dark:text-blue-300',
styles: 'bg-info/10 text-info',
},
success: {
icon: CheckCircle,
styles: 'bg-green-500/10 text-green-700 dark:text-green-300',
styles: 'bg-success/10 text-success',
},
warning: {
icon: AlertTriangle,
styles: 'bg-yellow-500/10 text-yellow-700 dark:text-yellow-300',
styles: 'bg-warning/10 text-warning',
},
error: {
icon: AlertCircle,
Expand Down
123 changes: 68 additions & 55 deletions src/components/common/amount-display.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Meta, StoryObj } from '@storybook/react'
import { AmountDisplay, AmountWithFiat } from './amount-display'
import type { Meta, StoryObj } from '@storybook/react';
import { AmountDisplay, AmountWithFiat } from './amount-display';

const meta: Meta<typeof AmountDisplay> = {
title: 'Common/AmountDisplay',
Expand All @@ -11,29 +11,39 @@ const meta: Meta<typeof AmountDisplay> = {
size: { control: 'select', options: ['xs', 'sm', 'md', 'lg', 'xl'] },
weight: { control: 'select', options: ['normal', 'medium', 'semibold', 'bold'] },
},
}
};

export default meta
type Story = StoryObj<typeof AmountDisplay>
export default meta;
type Story = StoryObj<typeof AmountDisplay>;

export const Default: Story = {
args: {
value: 1234.5678,
symbol: 'USDT',
},
}
};

export const Sizes: Story = {
render: () => (
<div className="flex flex-col gap-2">
<div><AmountDisplay value={1234.56} symbol="USDT" size="xs" /></div>
<div><AmountDisplay value={1234.56} symbol="USDT" size="sm" /></div>
<div><AmountDisplay value={1234.56} symbol="USDT" size="md" /></div>
<div><AmountDisplay value={1234.56} symbol="USDT" size="lg" /></div>
<div><AmountDisplay value={1234.56} symbol="USDT" size="xl" /></div>
<div>
<AmountDisplay value={1234.56} symbol="USDT" size="xs" />
</div>
<div>
<AmountDisplay value={1234.56} symbol="USDT" size="sm" />
</div>
<div>
<AmountDisplay value={1234.56} symbol="USDT" size="md" />
</div>
<div>
<AmountDisplay value={1234.56} symbol="USDT" size="lg" />
</div>
<div>
<AmountDisplay value={1234.56} symbol="USDT" size="xl" />
</div>
</div>
),
}
};

export const WithSign: Story = {
render: () => (
Expand All @@ -42,95 +52,103 @@ export const WithSign: Story = {
<AmountDisplay value={100} sign="always" color="auto" />
<AmountDisplay value={-50} sign="always" color="auto" />
</div>
<p className="text-sm text-muted">sign="always" + color="auto"</p>
<p className="text-muted-foreground text-sm">sign="always" + color="auto"</p>
</div>
),
}
};

export const Compact: Story = {
render: () => (
<div className="flex flex-col gap-2">
<div><AmountDisplay value={1234} compact /> <span className="text-muted text-sm">(1,234)</span></div>
<div><AmountDisplay value={12345} compact /> <span className="text-muted text-sm">(12,345)</span></div>
<div><AmountDisplay value={1234567} compact /> <span className="text-muted text-sm">(1,234,567)</span></div>
<div><AmountDisplay value={1234567890} compact /> <span className="text-muted text-sm">(1,234,567,890)</span></div>
<div>
<AmountDisplay value={1234} compact /> <span className="text-muted-foreground text-sm">(1,234)</span>
</div>
<div>
<AmountDisplay value={12345} compact /> <span className="text-muted-foreground text-sm">(12,345)</span>
</div>
<div>
<AmountDisplay value={1234567} compact /> <span className="text-muted-foreground text-sm">(1,234,567)</span>
</div>
<div>
<AmountDisplay value={1234567890} compact />{' '}
<span className="text-muted-foreground text-sm">(1,234,567,890)</span>
</div>
</div>
),
}
};

export const Hidden: Story = {
args: {
value: 1234.56,
symbol: 'USDT',
hidden: true,
},
}
};

export const MonoFont: Story = {
args: {
value: 1234567.89,
mono: true,
weight: 'semibold',
},
}
};

export const SmallNumbers: Story = {
render: () => (
<div className="flex flex-col gap-2">
<div><AmountDisplay value={0.1} /> <span className="text-muted text-sm">(0.1)</span></div>
<div><AmountDisplay value={0.01} /> <span className="text-muted text-sm">(0.01)</span></div>
<div><AmountDisplay value={0.001} /> <span className="text-muted text-sm">(0.001)</span></div>
<div><AmountDisplay value={0.0001} /> <span className="text-muted text-sm">(0.0001)</span></div>
<div><AmountDisplay value={0.00001} /> <span className="text-muted text-sm">(0.00001)</span></div>
<div>
<AmountDisplay value={0.1} /> <span className="text-muted-foreground text-sm">(0.1)</span>
</div>
<div>
<AmountDisplay value={0.01} /> <span className="text-muted-foreground text-sm">(0.01)</span>
</div>
<div>
<AmountDisplay value={0.001} /> <span className="text-muted-foreground text-sm">(0.001)</span>
</div>
<div>
<AmountDisplay value={0.0001} /> <span className="text-muted-foreground text-sm">(0.0001)</span>
</div>
<div>
<AmountDisplay value={0.00001} /> <span className="text-muted-foreground text-sm">(0.00001)</span>
</div>
</div>
),
}
};

// AmountWithFiat stories
export const WithFiat: Story = {
render: () => (
<div className="flex flex-col gap-4">
<div>
<p className="text-sm text-muted mb-2">Vertical (default)</p>
<AmountWithFiat
value={2.5}
symbol="ETH"
fiatValue={4500}
weight="semibold"
size="lg"
/>
<p className="text-muted-foreground mb-2 text-sm">Vertical (default)</p>
<AmountWithFiat value={2.5} symbol="ETH" fiatValue={4500} weight="semibold" size="lg" />
</div>
<div>
<p className="text-sm text-muted mb-2">Horizontal</p>
<AmountWithFiat
value={100}
symbol="USDT"
fiatValue={100}
layout="horizontal"
/>
<p className="text-muted-foreground mb-2 text-sm">Horizontal</p>
<AmountWithFiat value={100} symbol="USDT" fiatValue={100} layout="horizontal" />
</div>
</div>
),
}
};

export const PriceChange: Story = {
render: () => (
<div className="flex flex-col gap-2">
<div className="flex items-center gap-2">
<span className="text-muted">BTC:</span>
<span className="text-muted-foreground">BTC:</span>
<AmountDisplay value={45000} symbol="$" weight="semibold" />
<AmountDisplay value={5.2} sign="always" color="auto" size="sm" />
<span className="text-sm text-secondary">%</span>
<span className="text-secondary text-sm">%</span>
</div>
<div className="flex items-center gap-2">
<span className="text-muted">ETH:</span>
<span className="text-muted-foreground">ETH:</span>
<AmountDisplay value={1800} symbol="$" weight="semibold" />
<AmountDisplay value={-2.3} sign="always" color="auto" size="sm" />
<span className="text-sm text-destructive">%</span>
<span className="text-destructive text-sm">%</span>
</div>
</div>
),
}
};

export const TokenList: Story = {
render: () => (
Expand All @@ -142,14 +160,9 @@ export const TokenList: Story = {
].map((token) => (
<div key={token.symbol} className="flex items-center justify-between">
<span className="font-medium">{token.symbol}</span>
<AmountWithFiat
value={token.balance}
fiatValue={token.fiat}
weight="semibold"
className="text-right"
/>
<AmountWithFiat value={token.balance} fiatValue={token.fiat} weight="semibold" className="text-right" />
</div>
))}
</div>
),
}
};
Loading