Spaces:
Running
Running
| class TransactionList extends HTMLElement { | |
| constructor() { | |
| super(); | |
| this.transactions = [ | |
| { id: 1, type: 'receive', asset: 'Bitcoin', amount: 0.45, value: 16520, date: '2 mins ago', status: 'completed', icon: 'arrow-down-left' }, | |
| { id: 2, type: 'send', asset: 'Ethereum', amount: 2.1, value: 4250, date: '1 hour ago', status: 'completed', icon: 'arrow-up-right' }, | |
| { id: 3, type: 'swap', asset: 'SOL → USDT', amount: 150, value: 15000, date: '3 hours ago', status: 'pending', icon: 'repeat' }, | |
| { id: 4, type: 'receive', asset: 'Ethereum', amount: 1.5, value: 3050, date: 'Yesterday', status: 'completed', icon: 'arrow-down-left' }, | |
| { id: 5, type: 'send', asset: 'Bitcoin', amount: 0.12, value: 4400, date: '2 days ago', status: 'completed', icon: 'arrow-up-right' }, | |
| ]; | |
| } | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.render(); | |
| } | |
| render() { | |
| const transactionsHTML = this.transactions.map(tx => ` | |
| <div class="group flex items-center justify-between p-4 rounded-2xl hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-all duration-200 border border-transparent hover:border-slate-200 dark:hover:border-slate-600 cursor-pointer"> | |
| <div class="flex items-center gap-4"> | |
| <div class="w-12 h-12 rounded-full flex items-center justify-center ${ | |
| tx.type === 'receive' ? 'bg-emerald-100 dark:bg-emerald-900/30 text-emerald-600 dark:text-emerald-400' : | |
| tx.type === 'send' ? 'bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400' : | |
| 'bg-blue-100 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400' | |
| } group-hover:scale-110 transition-transform duration-200"> | |
| <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
| ${tx.type === 'receive' ? '<line x1="12" y1="5" x2="12" y2="19"></line><polyline points="19 12 12 19 5 12"></polyline>' : | |
| tx.type === 'send' ? '<line x1="12" y1="19" x2="12" y2="5"></line><polyline points="5 12 12 5 19 12"></polyline>' : | |
| '<polyline points="17 1 21 5 17 9"></polyline><path d="M3 11V9a4 4 0 0 1 4-4h14"></path><polyline points="7 23 3 19 7 15"></polyline><path d="M21 13v2a4 4 0 0 1-4 4H3"></path>'} | |
| </svg> | |
| </div> | |
| <div> | |
| <h4 class="font-semibold text-slate-900 dark:text-white capitalize">${tx.type} ${tx.asset}</h4> | |
| <p class="text-sm text-slate-500 dark:text-slate-400">${tx.date}</p> | |
| </div> | |
| </div> | |
| <div class="text-right"> | |
| <p class="font-bold ${tx.type === 'receive' ? 'text-emerald-600 dark:text-emerald-400' : 'text-slate-900 dark:text-white'}"> | |
| ${tx.type === 'receive' ? '+' : '-'}${tx.amount} ${tx.asset.split(' ')[0]} | |
| </p> | |
| <div class="flex items-center justify-end gap-2"> | |
| <span class="text-xs text-slate-500 dark:text-slate-400">$${tx.value.toLocaleString()}</span> | |
| <span class="w-2 h-2 rounded-full ${ | |
| tx.status === 'completed' ? 'bg-emerald-500' : 'bg-amber-500 animate-pulse' | |
| }"></span> | |
| </div> | |
| </div> | |
| </div> | |
| `).join(''); | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: block; | |
| } | |
| .transaction-list { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.5rem; | |
| max-height: 400px; | |
| overflow-y: auto; | |
| padding-right: 0.5rem; | |
| } | |
| .transaction-list::-webkit-scrollbar { | |
| width: 4px; | |
| } | |
| .transaction-list::-webkit-scrollbar-thumb { | |
| background: #cbd5e1; | |
| border-radius: 4px; | |
| } | |
| .dark .transaction-list::-webkit-scrollbar-thumb { | |
| background: #475569; | |
| } | |
| </style> | |
| <div class="transaction-list"> | |
| ${transactionsHTML} | |
| </div> | |
| `; | |
| } | |
| } | |
| customElements.define('transaction-list', TransactionList); |