improve frontend layout with a new table format for better user experience and clarity in transaction details.
This commit is contained in:
parent
79d29f52a1
commit
9c4b7a307a
2 changed files with 135 additions and 19 deletions
|
|
@ -8,7 +8,57 @@ window.app = Vue.createApp({
|
||||||
transactions: [],
|
transactions: [],
|
||||||
loading: true,
|
loading: true,
|
||||||
error: null,
|
error: null,
|
||||||
showFiatValues: false // Hide fiat values by default
|
showFiatValues: false, // Hide fiat values by default
|
||||||
|
transactionColumns: [
|
||||||
|
{
|
||||||
|
name: 'date',
|
||||||
|
label: 'Date',
|
||||||
|
align: 'left',
|
||||||
|
field: row => row.transaction_time || row.created_at,
|
||||||
|
format: val => val,
|
||||||
|
sortable: true,
|
||||||
|
sort: (a, b, rowA, rowB) => {
|
||||||
|
// Sort by most recent first
|
||||||
|
const dateA = new Date(rowA.transaction_time || rowA.created_at);
|
||||||
|
const dateB = new Date(rowB.transaction_time || rowB.created_at);
|
||||||
|
return dateB - dateA;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'amount_sats',
|
||||||
|
label: 'Bitcoin',
|
||||||
|
align: 'right',
|
||||||
|
field: 'amount_sats',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'amount_fiat',
|
||||||
|
label: 'Fiat Amount',
|
||||||
|
align: 'right',
|
||||||
|
field: 'amount_fiat',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'type',
|
||||||
|
label: 'Type',
|
||||||
|
align: 'center',
|
||||||
|
field: 'transaction_type',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'status',
|
||||||
|
label: 'Status',
|
||||||
|
align: 'center',
|
||||||
|
field: 'status',
|
||||||
|
sortable: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
transactionPagination: {
|
||||||
|
sortBy: 'date',
|
||||||
|
descending: true,
|
||||||
|
page: 1,
|
||||||
|
rowsPerPage: 10
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -41,6 +91,14 @@ window.app = Vue.createApp({
|
||||||
return new Date(dateString).toLocaleDateString()
|
return new Date(dateString).toLocaleDateString()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
formatTime(dateString) {
|
||||||
|
if (!dateString) return ''
|
||||||
|
return new Date(dateString).toLocaleTimeString('en-US', {
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
formatSats(amount) {
|
formatSats(amount) {
|
||||||
if (!amount) return '0 sats'
|
if (!amount) return '0 sats'
|
||||||
return new Intl.NumberFormat('en-US').format(amount) + ' sats'
|
return new Intl.NumberFormat('en-US').format(amount) + ' sats'
|
||||||
|
|
@ -64,10 +122,15 @@ window.app = Vue.createApp({
|
||||||
try {
|
try {
|
||||||
const {data} = await LNbits.api.request(
|
const {data} = await LNbits.api.request(
|
||||||
'GET',
|
'GET',
|
||||||
'/satmachineclient/api/v1/dashboard/transactions?limit=10',
|
'/satmachineclient/api/v1/dashboard/transactions?limit=50',
|
||||||
this.g.user.wallets[0].inkey
|
this.g.user.wallets[0].inkey
|
||||||
)
|
)
|
||||||
this.transactions = data
|
// Sort transactions by most recent first
|
||||||
|
this.transactions = data.sort((a, b) => {
|
||||||
|
const dateA = new Date(a.transaction_time || a.created_at)
|
||||||
|
const dateB = new Date(b.transaction_time || b.created_at)
|
||||||
|
return dateB - dateA
|
||||||
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error loading transactions:', error)
|
console.error('Error loading transactions:', error)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,30 +143,83 @@
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
<!-- Recent Transactions -->
|
<!-- Transaction History -->
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<h6 class="text-subtitle2 q-my-none q-mb-md">Recent Transactions</h6>
|
<div class="row items-center q-mb-md">
|
||||||
<div v-if="transactions.length === 0" class="text-grey text-center q-pa-md">
|
<div class="col">
|
||||||
No transactions yet
|
<h6 class="text-subtitle2 q-my-none">Transaction History</h6>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
icon="refresh"
|
||||||
|
@click="loadTransactions"
|
||||||
|
:loading="loading"
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
Refresh
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<q-list v-else>
|
|
||||||
<q-item v-for="tx in transactions" :key="tx.id">
|
<q-table
|
||||||
<q-item-section>
|
:rows="transactions"
|
||||||
<q-item-label>${formatSats(tx.amount_sats)}</q-item-label>
|
:columns="transactionColumns"
|
||||||
<q-item-label caption>${formatCurrency(tx.amount_fiat)} • ${formatDate(tx.transaction_time || tx.created_at)}</q-item-label>
|
row-key="id"
|
||||||
</q-item-section>
|
:pagination="transactionPagination"
|
||||||
<q-item-section side>
|
:loading="loading"
|
||||||
|
flat
|
||||||
|
bordered
|
||||||
|
:no-data-label="'No transactions yet - start your DCA journey!'"
|
||||||
|
>
|
||||||
|
<template v-slot:body-cell-amount_sats="props">
|
||||||
|
<q-td :props="props">
|
||||||
|
<div class="text-weight-medium text-orange-8">
|
||||||
|
${formatSats(props.row.amount_sats)}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-slot:body-cell-amount_fiat="props">
|
||||||
|
<q-td :props="props">
|
||||||
|
<div class="text-weight-medium">
|
||||||
|
${formatCurrency(props.row.amount_fiat)}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-slot:body-cell-date="props">
|
||||||
|
<q-td :props="props">
|
||||||
|
<div>${formatDate(props.row.transaction_time || props.row.created_at)}</div>
|
||||||
|
<div class="text-caption text-grey">
|
||||||
|
${formatTime(props.row.transaction_time || props.row.created_at)}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-slot:body-cell-status="props">
|
||||||
|
<q-td :props="props">
|
||||||
<q-chip
|
<q-chip
|
||||||
:color="tx.status === 'confirmed' ? 'positive' : 'warning'"
|
:color="props.row.status === 'confirmed' ? 'positive' : props.row.status === 'failed' ? 'negative' : 'warning'"
|
||||||
text-color="white"
|
text-color="white"
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
${tx.status}
|
${props.row.status}
|
||||||
</q-chip>
|
</q-chip>
|
||||||
</q-item-section>
|
</q-td>
|
||||||
</q-item>
|
</template>
|
||||||
</q-list>
|
|
||||||
|
<template v-slot:body-cell-type="props">
|
||||||
|
<q-td :props="props">
|
||||||
|
<q-badge
|
||||||
|
:color="props.row.transaction_type === 'flow' ? 'blue' : 'purple'"
|
||||||
|
:label="props.row.transaction_type.toUpperCase()"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</template>
|
||||||
|
</q-table>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue