/** * Visual flow diagram showing transaction inputs and outputs. * Creates a Sankey-style visualization of fund flow. */ import { Link } from 'react-router-dom'; import { ArrowRight, Coins, Wallet, Gift } from 'lucide-react'; import { truncateHash, formatSynor } from '../lib/utils'; import type { ExplorerInput, ExplorerOutput } from '../lib/types'; interface TransactionFlowDiagramProps { inputs: ExplorerInput[]; outputs: ExplorerOutput[]; isCoinbase: boolean; totalInput: number; totalOutput: number; fee: number; } export default function TransactionFlowDiagram({ inputs, outputs, isCoinbase, totalInput, totalOutput, fee, }: TransactionFlowDiagramProps) { // Calculate percentages for visual sizing const maxValue = Math.max(totalInput, totalOutput); return (
{/* Background gradient */}
{/* Header */}

Transaction Flow

{!isCoinbase && fee > 0 && (
Fee: {formatSynor(fee, 4)}
)}
{/* Inputs Column */}
Inputs
{isCoinbase ? ( ) : (
{inputs.map((input, i) => ( ))}
)} {/* Total input */} {!isCoinbase && (
Total Input
{formatSynor(totalInput, 4)}
)}
{/* Center Flow Arrow */}
{/* Animated flow lines */}
{/* Background track */}
{/* Animated particles */}
{/* Central transaction icon */}
{/* Top fade */}
{/* Bottom fade */}
{/* Outputs Column */}
Outputs
{outputs.map((output, i) => ( ))}
{/* Total output */}
Total Output
{formatSynor(totalOutput, 4)}
{/* Flow summary bar */}
{/* Input portion */}
{/* Output portion */}
{/* CSS for flow animation */}
); } function CoinbaseInput() { return (
Block Reward
Coinbase Transaction
); } interface InputNodeProps { input: ExplorerInput; percentage: number; } function InputNode({ input, percentage }: InputNodeProps) { const barWidth = Math.max(20, Math.min(100, percentage)); return (
{/* Value bar background */}
{input.address ? ( {truncateHash(input.address, 8, 8)} ) : ( Unknown )}
{input.value !== undefined && ( -{formatSynor(input.value, 2)} )}
); } interface OutputNodeProps { output: ExplorerOutput; index: number; percentage: number; } function OutputNode({ output, percentage }: OutputNodeProps) { const barWidth = Math.max(20, Math.min(100, percentage)); return (
{/* Value bar background */}
{output.address ? ( {truncateHash(output.address, 8, 8)} ) : ( {output.scriptType} )}
+{formatSynor(output.value, 2)}
); }