UNPKG

bigblocks

Version:

Complete Bitcoin UI component library - authentication, social, wallet, market, inscriptions, and blockchain interactions for React

83 lines (82 loc) 6.54 kB
"use client"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { CheckCircledIcon, ClockIcon, Cross2Icon, ExternalLinkIcon, InfoCircledIcon, UpdateIcon, } from "@radix-ui/react-icons"; import { cn } from "../../lib/utils.js"; import { Alert, AlertDescription } from "../ui/alert.js"; import { Badge } from "../ui/badge.js"; import { Button } from "../ui/button.js"; import { Card, CardContent } from "../ui/card.js"; import { Progress } from "../ui/progress.js"; export var TransactionStatus; (function (TransactionStatus) { TransactionStatus["Preparing"] = "preparing"; TransactionStatus["Broadcasting"] = "broadcasting"; TransactionStatus["Pending"] = "pending"; TransactionStatus["Confirmed"] = "confirmed"; TransactionStatus["Failed"] = "failed"; })(TransactionStatus || (TransactionStatus = {})); export function TransactionProgress({ status, txid, confirmations = 0, requiredConfirmations = 6, error, estimatedTime, onRetry, onClose, showDetails = true, className = "", }) { const getStatusIcon = () => { switch (status) { case TransactionStatus.Preparing: return _jsx(UpdateIcon, { className: "animate-spin h-5 w-5" }); case TransactionStatus.Broadcasting: return _jsx(UpdateIcon, { className: "animate-spin h-5 w-5" }); case TransactionStatus.Pending: return _jsx(ClockIcon, { className: "h-5 w-5" }); case TransactionStatus.Confirmed: return _jsx(CheckCircledIcon, { className: "h-5 w-5 text-green-600" }); case TransactionStatus.Failed: return _jsx(Cross2Icon, { className: "h-5 w-5 text-destructive" }); } }; const getStatusText = () => { switch (status) { case TransactionStatus.Preparing: return "Preparing transaction..."; case TransactionStatus.Broadcasting: return "Broadcasting to network..."; case TransactionStatus.Pending: return `Waiting for confirmations (${confirmations}/${requiredConfirmations})`; case TransactionStatus.Confirmed: return "Transaction confirmed!"; case TransactionStatus.Failed: return "Transaction failed"; } }; const getStatusColor = () => { switch (status) { case TransactionStatus.Preparing: case TransactionStatus.Broadcasting: return "default"; case TransactionStatus.Pending: return "secondary"; case TransactionStatus.Confirmed: return "default"; // Will use green text color in the badge case TransactionStatus.Failed: return "destructive"; } }; const getProgress = () => { if (status === TransactionStatus.Preparing) return 10; if (status === TransactionStatus.Broadcasting) return 30; if (status === TransactionStatus.Pending) { return 30 + (70 * confirmations) / requiredConfirmations; } if (status === TransactionStatus.Confirmed) return 100; return 0; }; const formatTime = (seconds) => { if (seconds < 60) return `${seconds} seconds`; const minutes = Math.floor(seconds / 60); return `${minutes} minute${minutes > 1 ? "s" : ""}`; }; return (_jsx(Card, { className: className, children: _jsx(CardContent, { className: "pt-6", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [getStatusIcon(), _jsx("p", { className: "text-base font-medium", children: getStatusText() })] }), _jsx(Badge, { variant: getStatusColor(), className: cn(status === TransactionStatus.Pending && "bg-amber-100 text-amber-900", status === TransactionStatus.Confirmed && "bg-green-100 text-green-900"), children: status.charAt(0).toUpperCase() + status.slice(1) })] }), status !== TransactionStatus.Failed && (_jsx(Progress, { value: getProgress(), className: cn("w-full", status === TransactionStatus.Pending && "[&>div]:bg-amber-500", status === TransactionStatus.Confirmed && "[&>div]:bg-green-500") })), showDetails && txid && (_jsxs("dl", { className: "space-y-2", children: [_jsxs("div", { className: "flex", children: [_jsx("dt", { className: "text-sm text-muted-foreground min-w-[120px]", children: "Transaction" }), _jsx("dd", { className: "text-sm", children: _jsxs("a", { href: `https://whatsonchain.com/tx/${txid}`, target: "_blank", rel: "noopener noreferrer", className: "text-primary hover:underline inline-flex items-center gap-1", children: [txid.substring(0, 8), "...", txid.substring(txid.length - 8), _jsx(ExternalLinkIcon, { className: "h-3 w-3" })] }) })] }), status === TransactionStatus.Pending && (_jsxs("div", { className: "flex", children: [_jsx("dt", { className: "text-sm text-muted-foreground min-w-[120px]", children: "Confirmations" }), _jsxs("dd", { className: "text-sm", children: [confirmations, " / ", requiredConfirmations] })] })), estimatedTime && status === TransactionStatus.Pending && (_jsxs("div", { className: "flex", children: [_jsx("dt", { className: "text-sm text-muted-foreground min-w-[120px]", children: "Est. Time" }), _jsx("dd", { className: "text-sm", children: formatTime(estimatedTime) })] }))] })), status === TransactionStatus.Failed && error && (_jsxs(Alert, { variant: "destructive", children: [_jsx(InfoCircledIcon, { className: "h-4 w-4" }), _jsx(AlertDescription, { children: error })] })), (onRetry || onClose) && (_jsxs("div", { className: "flex gap-2 justify-end", children: [status === TransactionStatus.Failed && onRetry && (_jsx(Button, { onClick: onRetry, variant: "default", size: "sm", children: "Retry Transaction" })), status === TransactionStatus.Confirmed && onClose && (_jsx(Button, { onClick: onClose, variant: "secondary", size: "sm", children: "Close" }))] })), status === TransactionStatus.Pending && (_jsxs(Alert, { className: "bg-blue-50 border-blue-200", children: [_jsx(InfoCircledIcon, { className: "h-4 w-4 text-blue-600" }), _jsx(AlertDescription, { className: "text-blue-900", children: "Your transaction has been broadcast. Bitcoin transactions typically confirm within 10-30 minutes." })] }))] }) }) })); }