feat: payment status badge in listing-card, webhook debug info, UX fixes
This commit is contained in:
@@ -7,7 +7,7 @@ let cachedRates = null
|
||||
|
||||
class ListingCard extends HTMLElement {
|
||||
static get observedAttributes() {
|
||||
return ['listing-id', 'title', 'price', 'currency', 'location', 'image', 'owner-id']
|
||||
return ['listing-id', 'title', 'price', 'currency', 'location', 'image', 'owner-id', 'payment-status']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
@@ -129,6 +129,13 @@ class ListingCard extends HTMLElement {
|
||||
</a>
|
||||
` : ''
|
||||
|
||||
const paymentStatus = this.getAttribute('payment-status')
|
||||
const paymentBadge = paymentStatus === 'processing'
|
||||
? /* html */`<span class="payment-badge payment-processing"><span class="pulse-dot"></span>${t('payment.awaitingConfirmation')}</span>`
|
||||
: paymentStatus === 'pending'
|
||||
? /* html */`<span class="payment-badge payment-pending">${t('payment.pending')}</span>`
|
||||
: ''
|
||||
|
||||
this.innerHTML = /* html */`
|
||||
${ownerBadge}
|
||||
<a href="#/listing/${escapeHTML(id)}" class="listing-link">
|
||||
@@ -136,6 +143,7 @@ class ListingCard extends HTMLElement {
|
||||
${image
|
||||
? `<img src="${escapeHTML(image)}" alt="${escapeHTML(title)}" loading="lazy">`
|
||||
: placeholderSvg}
|
||||
${paymentBadge}
|
||||
</div>
|
||||
<div class="listing-info">
|
||||
<h3 class="listing-title">${escapeHTML(title)}</h3>
|
||||
@@ -220,6 +228,45 @@ style.textContent = /* css */`
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
listing-card .payment-badge {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: var(--space-xs) var(--space-sm);
|
||||
font-size: var(--font-size-xs);
|
||||
font-weight: var(--font-weight-medium);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
listing-card .payment-processing {
|
||||
background: rgba(230, 167, 0, 0.9);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
listing-card .payment-pending {
|
||||
background: rgba(230, 167, 0, 0.9);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
listing-card .pulse-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: var(--radius-full);
|
||||
background: #fff;
|
||||
animation: card-pulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes card-pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.3; }
|
||||
}
|
||||
|
||||
listing-card .listing-image img {
|
||||
|
||||
@@ -744,7 +744,25 @@ class PageCreate extends HTMLElement {
|
||||
})
|
||||
|
||||
clearPendingInvoice(listingId)
|
||||
router.navigate(`/listing/${listingId}`)
|
||||
this.showPaymentSuccess()
|
||||
}
|
||||
|
||||
showPaymentSuccess() {
|
||||
this.innerHTML = /* html */`
|
||||
<div class="create-page">
|
||||
<div class="payment-success">
|
||||
<div class="success-icon">
|
||||
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
<polyline points="12 6 12 12 16 14"></polyline>
|
||||
</svg>
|
||||
</div>
|
||||
<h2>${t('payment.processing')}</h2>
|
||||
<p>${t('payment.awaitingHint')}</p>
|
||||
<a href="#/my-listings" class="btn btn-primary">${t('profile.myListings')}</a>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
showError(message) {
|
||||
@@ -993,5 +1011,28 @@ style.textContent = /* css */`
|
||||
page-create .btn-link:hover {
|
||||
color: var(--color-primary-hover);
|
||||
}
|
||||
|
||||
page-create .payment-success {
|
||||
text-align: center;
|
||||
padding: var(--space-3xl) 0;
|
||||
}
|
||||
|
||||
page-create .success-icon {
|
||||
color: var(--color-warning, #e6a700);
|
||||
margin-bottom: var(--space-lg);
|
||||
}
|
||||
|
||||
page-create .payment-success h2 {
|
||||
margin-bottom: var(--space-md);
|
||||
}
|
||||
|
||||
page-create .payment-success p {
|
||||
color: var(--color-text-secondary);
|
||||
margin-bottom: var(--space-xl);
|
||||
max-width: 400px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
line-height: 1.5;
|
||||
}
|
||||
`
|
||||
document.head.appendChild(style)
|
||||
|
||||
@@ -164,7 +164,7 @@ class PageListing extends HTMLElement {
|
||||
? new Date(this.listing.date_created).toLocaleDateString()
|
||||
: ''
|
||||
|
||||
this.innerHTML = /* html */`
|
||||
this.innerHTML = /* html */`
|
||||
<article class="listing-detail">
|
||||
<!-- Two Column Layout -->
|
||||
<div class="listing-layout">
|
||||
@@ -1000,7 +1000,7 @@ style.textContent = /* css */`
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Payment Processing Badge */
|
||||
/* Payment Processing Badge (sidebar) */
|
||||
page-listing .payment-processing-card {
|
||||
background: var(--color-bg-secondary);
|
||||
border: 1px solid var(--color-warning, #e6a700);
|
||||
|
||||
@@ -71,6 +71,16 @@ class PageMyListings extends HTMLElement {
|
||||
document.querySelector('auth-modal')?.show()
|
||||
}
|
||||
|
||||
getStatusBadge(listing) {
|
||||
if (listing.status === 'archived') {
|
||||
return `<span class="status-badge status-archived">${t('myListings.status.archived')}</span>`
|
||||
}
|
||||
if (listing.status === 'draft' && listing.payment_status !== 'processing' && listing.payment_status !== 'pending') {
|
||||
return `<span class="status-badge status-draft">${t('myListings.status.draft')}</span>`
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
render() {
|
||||
this.innerHTML = /* html */`
|
||||
<div class="my-listings-page">
|
||||
@@ -136,9 +146,7 @@ class PageMyListings extends HTMLElement {
|
||||
const imageId = listing.images?.[0]?.directus_files_id?.id || listing.images?.[0]?.directus_files_id
|
||||
const imageUrl = imageId ? directus.getThumbnailUrl(imageId, 300) : ''
|
||||
const locationName = listing.location?.name || ''
|
||||
const statusBadge = listing.status !== 'published'
|
||||
? `<span class="status-badge status-${listing.status}">${t(`myListings.status.${listing.status}`)}</span>`
|
||||
: ''
|
||||
const statusBadge = this.getStatusBadge(listing)
|
||||
|
||||
return /* html */`
|
||||
<div class="listing-wrapper">
|
||||
@@ -151,6 +159,7 @@ class PageMyListings extends HTMLElement {
|
||||
location="${escapeHTML(locationName)}"
|
||||
image="${imageUrl}"
|
||||
owner-id="${listing.user_created || ''}"
|
||||
payment-status="${listing.payment_status || ''}"
|
||||
></listing-card>
|
||||
</div>
|
||||
`
|
||||
|
||||
@@ -327,6 +327,7 @@ class DirectusService {
|
||||
'price',
|
||||
'currency',
|
||||
'condition',
|
||||
'payment_status',
|
||||
'date_created',
|
||||
'user_created',
|
||||
'images.directus_files_id.id',
|
||||
@@ -379,6 +380,7 @@ class DirectusService {
|
||||
'shipping',
|
||||
'shipping_cost',
|
||||
'views',
|
||||
'payment_status',
|
||||
'expires_at',
|
||||
'monero_address',
|
||||
'date_created',
|
||||
|
||||
Reference in New Issue
Block a user