Enhance WalletService and WalletPage for improved timestamp handling and layout

- Updated WalletService to robustly handle various timestamp formats, ensuring accurate transaction date representation.
- Enhanced WalletPage layout for better responsiveness, including mobile and desktop views, and improved transaction display with clearer formatting.
- Adjusted transaction item styling for consistency and better user experience across different screen sizes.

These changes improve the reliability and usability of transaction data presentation in the wallet module.
This commit is contained in:
padreug 2025-09-15 00:05:29 +02:00
parent 42b4af8fa5
commit d2a5d90427
2 changed files with 151 additions and 50 deletions

View file

@ -178,52 +178,134 @@ onMounted(() => {
<div v-for="(txs, date) in groupedTransactions" :key="date" class="mb-6">
<div class="text-sm font-medium text-muted-foreground mb-3">{{ date }}</div>
<div class="space-y-2">
<div
v-for="tx in txs"
<div class="space-y-3">
<div
v-for="tx in txs"
:key="tx.id"
class="flex items-center justify-between p-4 rounded-lg border hover:bg-accent/50 transition-colors"
class="p-3 rounded-lg border hover:bg-accent/50 transition-colors"
>
<div class="flex items-center gap-4">
<div
class="p-2 rounded-full bg-background border"
:class="getTransactionColor(tx.type)"
>
<component
:is="getTransactionIcon(tx.type)"
class="h-4 w-4"
/>
</div>
<div>
<p class="font-medium">{{ tx.description }}</p>
<div class="flex items-center gap-2 text-sm text-muted-foreground">
<span>{{
tx.timestamp instanceof Date && !isNaN(tx.timestamp.getTime())
? format(tx.timestamp, 'HH:mm')
: '--:--'
<!-- Mobile Layout: Stack vertically -->
<div class="block sm:hidden">
<!-- Header Row: Icon, Amount, Type -->
<div class="flex items-center justify-between mb-2">
<div class="flex items-center gap-3">
<div
class="p-1.5 rounded-full bg-background border"
:class="getTransactionColor(tx.type)"
>
<component
:is="getTransactionIcon(tx.type)"
class="h-3.5 w-3.5"
/>
</div>
<span class="text-sm text-muted-foreground">{{
(() => {
try {
if (tx.timestamp instanceof Date && !isNaN(tx.timestamp.getTime())) {
return format(tx.timestamp, 'HH:mm')
} else if (tx.timestamp) {
// Try to parse as string or number
const date = new Date(tx.timestamp)
if (!isNaN(date.getTime())) {
return format(date, 'HH:mm')
}
}
return '--:--'
} catch (error) {
console.warn('Failed to format timestamp:', tx.timestamp, error)
return '--:--'
}
})()
}}</span>
<Badge :variant="getStatusColor(tx.status)" class="text-xs">
{{ tx.status }}
</Badge>
<Badge v-if="tx.tag" variant="outline" class="text-xs">
{{ tx.tag }}
</Badge>
</div>
<div class="text-right">
<p
class="font-semibold text-base"
:class="getTransactionColor(tx.type)"
>
{{ tx.type === 'received' ? '+' : '-' }}{{ tx.amount.toLocaleString() }}
</p>
<p class="text-xs text-muted-foreground">sats</p>
</div>
</div>
<!-- Description Row -->
<div class="mb-2">
<p class="font-medium text-sm leading-tight break-words pr-2">{{ tx.description }}</p>
</div>
<!-- Badges Row -->
<div class="flex items-center gap-2 flex-wrap">
<Badge :variant="getStatusColor(tx.status)" class="text-xs">
{{ tx.status }}
</Badge>
<Badge v-if="tx.tag" variant="outline" class="text-xs">
{{ tx.tag }}
</Badge>
<span v-if="tx.fee" class="text-xs text-muted-foreground">
Fee: {{ tx.fee }} sats
</span>
</div>
</div>
<div class="text-right">
<p
class="font-semibold"
:class="getTransactionColor(tx.type)"
>
{{ tx.type === 'received' ? '+' : '-' }}
{{ tx.amount.toLocaleString() }} sats
</p>
<p v-if="tx.fee" class="text-xs text-muted-foreground">
Fee: {{ tx.fee }} sats
</p>
<!-- Desktop Layout: Original horizontal layout -->
<div class="hidden sm:flex items-center justify-between">
<div class="flex items-center gap-4">
<div
class="p-2 rounded-full bg-background border"
:class="getTransactionColor(tx.type)"
>
<component
:is="getTransactionIcon(tx.type)"
class="h-4 w-4"
/>
</div>
<div class="min-w-0 flex-1">
<p class="font-medium truncate">{{ tx.description }}</p>
<div class="flex items-center gap-2 text-sm text-muted-foreground">
<span>{{
(() => {
try {
if (tx.timestamp instanceof Date && !isNaN(tx.timestamp.getTime())) {
return format(tx.timestamp, 'HH:mm')
} else if (tx.timestamp) {
// Try to parse as string or number
const date = new Date(tx.timestamp)
if (!isNaN(date.getTime())) {
return format(date, 'HH:mm')
}
}
return '--:--'
} catch (error) {
console.warn('Failed to format timestamp:', tx.timestamp, error)
return '--:--'
}
})()
}}</span>
<Badge :variant="getStatusColor(tx.status)" class="text-xs">
{{ tx.status }}
</Badge>
<Badge v-if="tx.tag" variant="outline" class="text-xs">
{{ tx.tag }}
</Badge>
</div>
</div>
</div>
<div class="text-right ml-4">
<p
class="font-semibold"
:class="getTransactionColor(tx.type)"
>
{{ tx.type === 'received' ? '+' : '-' }}
{{ tx.amount.toLocaleString() }} sats
</p>
<p v-if="tx.fee" class="text-xs text-muted-foreground">
Fee: {{ tx.fee }} sats
</p>
</div>
</div>
</div>
</div>