Add balance page and sidebar link for dashboard
Introduces a new balance page displaying cryptocurrency balances and withdrawal functionality. Updates the sidebar configuration to include a link to the balance page with a wallet icon.
This commit is contained in:
168
app/dashboard/balance/page.tsx
Normal file
168
app/dashboard/balance/page.tsx
Normal file
@@ -0,0 +1,168 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import Dashboard from "@/components/dashboard/dashboard";
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Wallet, Bitcoin, Coins, DollarSign, ArrowUpRight } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
// Mock data for balances
|
||||
const mockBalances = {
|
||||
bitcoin: {
|
||||
symbol: "BTC",
|
||||
name: "Bitcoin",
|
||||
balance: 0.054321,
|
||||
usdValue: 2350.45,
|
||||
icon: Bitcoin,
|
||||
color: "text-orange-500",
|
||||
},
|
||||
litecoin: {
|
||||
symbol: "LTC",
|
||||
name: "Litecoin",
|
||||
balance: 12.345678,
|
||||
usdValue: 987.65,
|
||||
icon: Coins,
|
||||
color: "text-blue-500",
|
||||
},
|
||||
monero: {
|
||||
symbol: "XMR",
|
||||
name: "Monero",
|
||||
balance: 5.678901,
|
||||
usdValue: 1123.89,
|
||||
icon: DollarSign,
|
||||
color: "text-orange-600",
|
||||
},
|
||||
};
|
||||
|
||||
export default function BalancePage() {
|
||||
const [isWithdrawing, setIsWithdrawing] = useState<{
|
||||
bitcoin: boolean;
|
||||
litecoin: boolean;
|
||||
monero: boolean;
|
||||
}>({
|
||||
bitcoin: false,
|
||||
litecoin: false,
|
||||
monero: false,
|
||||
});
|
||||
|
||||
const handleWithdrawal = async (currency: "bitcoin" | "litecoin" | "monero") => {
|
||||
setIsWithdrawing((prev) => ({ ...prev, [currency]: true }));
|
||||
|
||||
try {
|
||||
// Simulate API call
|
||||
await new Promise((resolve) => setTimeout(resolve, 1500));
|
||||
|
||||
toast.success("Withdrawal Request Submitted", {
|
||||
description: `Your withdrawal request for ${mockBalances[currency].name} has been submitted successfully.`,
|
||||
});
|
||||
} catch (error) {
|
||||
toast.error("Withdrawal Failed", {
|
||||
description: `Failed to submit withdrawal request for ${mockBalances[currency].name}. Please try again.`,
|
||||
});
|
||||
} finally {
|
||||
setIsWithdrawing((prev) => ({ ...prev, [currency]: false }));
|
||||
}
|
||||
};
|
||||
|
||||
const totalUsdValue = Object.values(mockBalances).reduce(
|
||||
(sum, currency) => sum + currency.usdValue,
|
||||
0
|
||||
);
|
||||
|
||||
return (
|
||||
<Dashboard>
|
||||
<div className="space-y-6">
|
||||
{/* Header */}
|
||||
<div>
|
||||
<h1 className="text-2xl font-semibold text-gray-900 dark:text-white flex items-center">
|
||||
<Wallet className="mr-2 h-6 w-6" />
|
||||
Balance
|
||||
</h1>
|
||||
<p className="mt-1 text-muted-foreground">
|
||||
View your cryptocurrency balances and request withdrawals
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Total Balance Card */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Total Balance</CardTitle>
|
||||
<CardDescription>Combined value of all cryptocurrencies</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold">
|
||||
${totalUsdValue.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground mt-2">
|
||||
Equivalent in USD
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Currency Balance Cards */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
{Object.entries(mockBalances).map(([key, currency]) => {
|
||||
const Icon = currency.icon;
|
||||
return (
|
||||
<Card key={key}>
|
||||
<CardHeader>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<Icon className={`h-5 w-5 ${currency.color}`} />
|
||||
<CardTitle className="text-lg">{currency.name}</CardTitle>
|
||||
</div>
|
||||
</div>
|
||||
<CardDescription>{currency.symbol}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2">
|
||||
<div>
|
||||
<div className="text-2xl font-bold">
|
||||
{currency.balance.toLocaleString("en-US", {
|
||||
minimumFractionDigits: 6,
|
||||
maximumFractionDigits: 8,
|
||||
})}
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{currency.symbol}
|
||||
</div>
|
||||
</div>
|
||||
<div className="pt-2 border-t">
|
||||
<div className="text-lg font-semibold">
|
||||
${currency.usdValue.toLocaleString("en-US", {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground">USD Value</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button
|
||||
onClick={() => handleWithdrawal(key as "bitcoin" | "litecoin" | "monero")}
|
||||
disabled={isWithdrawing[key as keyof typeof isWithdrawing]}
|
||||
className="w-full"
|
||||
variant="outline"
|
||||
>
|
||||
{isWithdrawing[key as keyof typeof isWithdrawing] ? (
|
||||
<>
|
||||
<div className="h-4 w-4 border-2 border-current border-t-transparent rounded-full animate-spin mr-2" />
|
||||
Processing...
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<ArrowUpRight className="h-4 w-4 mr-2" />
|
||||
Request Withdrawal
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</Dashboard>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Home, Package, Box, Truck, Settings, FolderTree, MessageCircle, BarChart3, Tag, Users, TrendingUp, Shield } from "lucide-react"
|
||||
import { Home, Package, Box, Truck, Settings, FolderTree, MessageCircle, BarChart3, Tag, Users, TrendingUp, Shield, Wallet } from "lucide-react"
|
||||
|
||||
export const sidebarConfig = [
|
||||
{
|
||||
@@ -30,6 +30,7 @@ export const sidebarConfig = [
|
||||
{ name: "Shipping", href: "/dashboard/shipping", icon: Truck },
|
||||
{ name: "Promotions", href: "/dashboard/promotions", icon: Tag },
|
||||
{ name: "Storefront", href: "/dashboard/storefront", icon: Settings },
|
||||
{ name: "Balance", href: "/dashboard/balance", icon: Wallet },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"commitHash": "fcba1a8",
|
||||
"buildTime": "2025-10-30T01:13:38.854Z"
|
||||
"commitHash": "928d94c",
|
||||
"buildTime": "2025-10-31T00:03:09.717Z"
|
||||
}
|
||||
Reference in New Issue
Block a user