mirror of
https://github.com/getAlby/hub.git
synced 2026-08-13 12:33:39 +02:00
feat: replace wallet balance toggle with Lightning / On-chain tabs (#2306)
* feat: prototype balance switcher variants on wallet screen Adds two switcher styles (icon-only segmented control and tab-style control) alongside the original "Spending Balance ⇅" toggle, with a floating dev-only variant toggle for side-by-side comparison. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: replace balance toggle with tab switcher Drops the icon-only and original variants plus the dev preview toggle, keeping just the Lightning / On-chain tab switcher and a wider gap to the balance underneath. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor: use shadcn Tabs primitive for balance switcher Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor: type balance switcher icons with LucideIcon Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor: only render balance switcher when on-chain wallet exists Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: note lucide-react *Icon suffix convention in AGENTS.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
This commit is contained in:
parent
15be274f24
commit
bb9249c767
4 changed files with 42 additions and 37 deletions
|
|
@ -180,6 +180,7 @@ Code under `frontend/platform_specific/http/` and `frontend/platform_specific/wa
|
|||
- **Keep layouts flat** — avoid nesting cards inside cards or wrapping elements in unnecessary bordered containers. Prefer clear, flat visual hierarchy.
|
||||
- **Match existing spacing patterns** — before adding new components, check sibling components for consistent padding, margins, and gaps. Ensure sibling elements have equal dimensions where appropriate.
|
||||
- **Write copy from the user's perspective** — Alby Hub IS the wallet; don't explain what a lightning wallet is or tell the user to "connect to a wallet" when they're already inside one. Keep UI copy concise and use the product's own vocabulary (sats, connections, apps).
|
||||
- **Use the `*Icon` suffix when importing lucide-react icons** (e.g., `ZapIcon`, `BitcoinIcon`, `ArrowDownIcon`) — both forms are valid lucide exports, but this codebase consistently uses the suffixed alias. Don't mix styles.
|
||||
- Strict TypeScript — no `any` types.
|
||||
- Functional components with hooks only.
|
||||
- SWR for server state; Zustand for client state (stores in `frontend/src/state/`).
|
||||
|
|
|
|||
32
frontend/src/components/wallet/BalanceSwitcher.tsx
Normal file
32
frontend/src/components/wallet/BalanceSwitcher.tsx
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import { BitcoinIcon, type LucideIcon, ZapIcon } from "lucide-react";
|
||||
import { Link } from "react-router";
|
||||
import { Tabs, TabsList, TabsTrigger } from "src/components/ui/tabs";
|
||||
|
||||
type Mode = "lightning" | "onchain";
|
||||
|
||||
const items: { mode: Mode; to: string; label: string; Icon: LucideIcon }[] = [
|
||||
{ mode: "lightning", to: "/wallet", label: "Lightning", Icon: ZapIcon },
|
||||
{
|
||||
mode: "onchain",
|
||||
to: "/wallet/onchain",
|
||||
label: "On-chain",
|
||||
Icon: BitcoinIcon,
|
||||
},
|
||||
];
|
||||
|
||||
export function BalanceSwitcher({ active }: { active: Mode }) {
|
||||
return (
|
||||
<Tabs value={active}>
|
||||
<TabsList>
|
||||
{items.map(({ mode, to, label, Icon }) => (
|
||||
<TabsTrigger key={mode} value={mode} asChild>
|
||||
<Link to={to}>
|
||||
<Icon />
|
||||
{label}
|
||||
</Link>
|
||||
</TabsTrigger>
|
||||
))}
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,10 +1,5 @@
|
|||
import {
|
||||
AlertTriangleIcon,
|
||||
ArrowDownIcon,
|
||||
ArrowDownUpIcon,
|
||||
ArrowUpIcon,
|
||||
} from "lucide-react";
|
||||
import { Link, useNavigate } from "react-router";
|
||||
import { AlertTriangleIcon, ArrowDownIcon, ArrowUpIcon } from "lucide-react";
|
||||
import { Link } from "react-router";
|
||||
import { FormattedBitcoinAmount } from "src/components/FormattedBitcoinAmount";
|
||||
import FormattedFiatAmount from "src/components/FormattedFiatAmount";
|
||||
import LowReceivingCapacityAlert from "src/components/LowReceivingCapacityAlert";
|
||||
|
|
@ -15,6 +10,7 @@ import {
|
|||
AlertTitle,
|
||||
} from "src/components/ui/alert.tsx";
|
||||
import { LinkButton } from "src/components/ui/custom/link-button";
|
||||
import { BalanceSwitcher } from "src/components/wallet/BalanceSwitcher";
|
||||
import { useBalances } from "src/hooks/useBalances";
|
||||
import { useChannels } from "src/hooks/useChannels";
|
||||
import { useInfo } from "src/hooks/useInfo";
|
||||
|
|
@ -23,7 +19,6 @@ export default function Lightning() {
|
|||
const { hasChannelManagement } = useInfo();
|
||||
const { data: balances } = useBalances(true);
|
||||
const { data: channels } = useChannels();
|
||||
const navigate = useNavigate();
|
||||
|
||||
if (!balances) {
|
||||
return null;
|
||||
|
|
@ -76,22 +71,8 @@ export default function Lightning() {
|
|||
</Alert>
|
||||
)}
|
||||
<div className="flex w-full flex-col items-center gap-8 pt-12 pb-16 text-center">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
{hasChannelManagement ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/wallet/onchain")}
|
||||
aria-label="Toggle balance mode, currently Lightning Balance"
|
||||
className="inline-flex items-center justify-center gap-1 text-xs font-medium leading-none uppercase text-muted-foreground transition-colors hover:text-foreground"
|
||||
>
|
||||
Lightning Balance
|
||||
<ArrowDownUpIcon aria-hidden className="size-3 shrink-0" />
|
||||
</button>
|
||||
) : (
|
||||
<span className="text-xs font-medium leading-none uppercase text-muted-foreground">
|
||||
Lightning Balance
|
||||
</span>
|
||||
)}
|
||||
<div className="flex flex-col items-center gap-8">
|
||||
{hasChannelManagement && <BalanceSwitcher active="lightning" />}
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<div className="text-5xl md:text-6xl font-medium balance sensitive slashed-zero leading-none">
|
||||
<FormattedBitcoinAmount
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
import { ArrowDownIcon, ArrowDownUpIcon, ArrowUpIcon } from "lucide-react";
|
||||
import { useNavigate } from "react-router";
|
||||
import { ArrowDownIcon, ArrowUpIcon } from "lucide-react";
|
||||
import { FormattedBitcoinAmount } from "src/components/FormattedBitcoinAmount";
|
||||
import FormattedFiatAmount from "src/components/FormattedFiatAmount";
|
||||
import { OnchainTransactionsList } from "src/components/OnchainTransactionsList";
|
||||
import { LinkButton } from "src/components/ui/custom/link-button";
|
||||
import { BalanceSwitcher } from "src/components/wallet/BalanceSwitcher";
|
||||
import { useBalances } from "src/hooks/useBalances";
|
||||
|
||||
export default function Onchain() {
|
||||
const { data: balances } = useBalances(true);
|
||||
const navigate = useNavigate();
|
||||
|
||||
if (!balances) {
|
||||
return null;
|
||||
|
|
@ -17,16 +16,8 @@ export default function Onchain() {
|
|||
return (
|
||||
<>
|
||||
<div className="flex w-full flex-col items-center gap-8 pt-12 pb-16 text-center">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/wallet")}
|
||||
aria-label="Toggle balance mode, currently On-chain Balance"
|
||||
className="inline-flex items-center justify-center gap-1 text-xs font-medium leading-none uppercase text-muted-foreground transition-colors hover:text-foreground"
|
||||
>
|
||||
On-chain Balance
|
||||
<ArrowDownUpIcon aria-hidden className="size-3 shrink-0" />
|
||||
</button>
|
||||
<div className="flex flex-col items-center gap-8">
|
||||
<BalanceSwitcher active="onchain" />
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<div className="text-5xl md:text-6xl font-medium balance sensitive slashed-zero leading-none">
|
||||
<FormattedBitcoinAmount
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue