diff --git a/src/components/common/EmptyTransactionTimelineState.tsx b/src/components/common/EmptyTransactionTimelineState.tsx index 6d31a800..5dd7788c 100644 --- a/src/components/common/EmptyTransactionTimelineState.tsx +++ b/src/components/common/EmptyTransactionTimelineState.tsx @@ -1,25 +1,156 @@ +import { useState } from 'react'; import { Button } from '@/components/ui/button'; -import { Clock3 } from 'lucide-react'; +import { Check, Clock3, Copy, XCircle } from 'lucide-react'; + +type CopyState = 'idle' | 'success' | 'error'; + +interface TimelineEntry { + id: string; + action: string; + amount: string; + txHash: string; + timeLabel: string; + status: 'confirmed' | 'pending' | 'failed'; +} + +const TIMELINE_ENTRIES: TimelineEntry[] = [ + { + id: 'entry-1', + action: 'Buy', + amount: '+2 keys', + txHash: '0x2a43bcfdef77ca4c50ef7d38148dd5d7f0149a6e2e20f70f04ce1f4b66fe55dd', + timeLabel: '2m ago', + status: 'confirmed', + }, + { + id: 'entry-2', + action: 'Sell', + amount: '-1 key', + txHash: '0x90c82ac01478b42fcbf9db73a26ed32bd8e50a8917e2408c31c95e9f6a59fc19', + timeLabel: '18m ago', + status: 'pending', + }, + { + id: 'entry-3', + action: 'Buy', + amount: '+3 keys', + txHash: '0x16d2ffbc4297a8c2c3086e07c16e66f47287df0d5a1ce1aef9e448e2f0f3ab51', + timeLabel: '51m ago', + status: 'failed', + }, +]; + +const shortenTxHash = (hash: string) => `${hash.slice(0, 8)}...${hash.slice(-6)}`; const EmptyTransactionTimelineState: React.FC = () => { - return ( - - - - - - - No transactions yet - - - New users will see transaction milestones here after submitting their first buy or sell action. - - - Buy your first key - - - - ); + const [copyStateById, setCopyStateById] = useState>({}); + + const copyTxHash = async (entryId: string, txHash: string) => { + try { + await navigator.clipboard.writeText(txHash); + setCopyStateById(current => ({ ...current, [entryId]: 'success' })); + } catch { + setCopyStateById(current => ({ ...current, [entryId]: 'error' })); + } + + window.setTimeout(() => { + setCopyStateById(current => ({ ...current, [entryId]: 'idle' })); + }, 1300); + }; + + return ( + + + + + + Transaction timeline + + + Recent trade events with quick copy access for tx hashes. + + + + + + + + + {TIMELINE_ENTRIES.map(entry => { + const copyState = copyStateById[entry.id] ?? 'idle'; + const isSuccess = copyState === 'success'; + const isError = copyState === 'error'; + const statusClass = + entry.status === 'confirmed' + ? 'text-emerald-300' + : entry.status === 'pending' + ? 'text-amber-300' + : 'text-rose-300'; + + return ( + + {entry.action} + {entry.amount} + + + + {shortenTxHash(entry.txHash)} + + copyTxHash(entry.id, entry.txHash)} + className="inline-flex size-6 shrink-0 items-center justify-center rounded-md bg-white/5 text-white/55 transition-colors hover:bg-white/10 hover:text-white" + aria-label={ + isSuccess + ? 'Transaction hash copied' + : isError + ? 'Transaction hash copy failed' + : 'Copy transaction hash' + } + > + {isSuccess ? ( + + ) : isError ? ( + + ) : ( + + )} + + + + {isSuccess + ? 'Transaction hash copied to clipboard' + : isError + ? 'Failed to copy transaction hash' + : ''} + + + + {entry.status} + {entry.timeLabel} + + + ); + })} + + + + Open full history + + + + ); }; export default EmptyTransactionTimelineState;
- New users will see transaction milestones here after submitting their first buy or sell action. -
+ Recent trade events with quick copy access for tx hashes. +
{entry.status}
{entry.timeLabel}