diff --git a/docs/pow-server/btcpay-webhook.php b/docs/pow-server/btcpay-webhook.php index 3243e7b..d1d1edf 100644 --- a/docs/pow-server/btcpay-webhook.php +++ b/docs/pow-server/btcpay-webhook.php @@ -27,7 +27,14 @@ $invoiceId = $payload['invoiceId'] ?? null; if (!$type || !$invoiceId) { http_response_code(400); - echo json_encode(['error' => 'Missing type or invoiceId']); + echo json_encode([ + 'error' => 'Missing type or invoiceId', + 'received' => [ + 'type' => $type, + 'invoiceId' => $invoiceId, + 'keys' => array_keys($payload ?: []), + ], + ]); exit; } diff --git a/js/components/listing-card.js b/js/components/listing-card.js index 69fe2ef..791de0f 100644 --- a/js/components/listing-card.js +++ b/js/components/listing-card.js @@ -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 { ` : '' + const paymentStatus = this.getAttribute('payment-status') + const paymentBadge = paymentStatus === 'processing' + ? /* html */`${t('payment.awaitingConfirmation')}` + : paymentStatus === 'pending' + ? /* html */`${t('payment.pending')}` + : '' + this.innerHTML = /* html */` ${ownerBadge} @@ -136,6 +143,7 @@ class ListingCard extends HTMLElement { ${image ? `${escapeHTML(title)}` : placeholderSvg} + ${paymentBadge}

${escapeHTML(title)}

@@ -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 { diff --git a/js/components/pages/page-create.js b/js/components/pages/page-create.js index 0dd9dc0..b285a9a 100644 --- a/js/components/pages/page-create.js +++ b/js/components/pages/page-create.js @@ -744,7 +744,25 @@ class PageCreate extends HTMLElement { }) clearPendingInvoice(listingId) - router.navigate(`/listing/${listingId}`) + this.showPaymentSuccess() + } + + showPaymentSuccess() { + this.innerHTML = /* html */` +
+ +
+ ` } 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) diff --git a/js/components/pages/page-listing.js b/js/components/pages/page-listing.js index e53cb8d..de581ca 100644 --- a/js/components/pages/page-listing.js +++ b/js/components/pages/page-listing.js @@ -164,7 +164,7 @@ class PageListing extends HTMLElement { ? new Date(this.listing.date_created).toLocaleDateString() : '' - this.innerHTML = /* html */` + this.innerHTML = /* html */`
@@ -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); diff --git a/js/components/pages/page-my-listings.js b/js/components/pages/page-my-listings.js index 3b024da..6c3d98f 100644 --- a/js/components/pages/page-my-listings.js +++ b/js/components/pages/page-my-listings.js @@ -71,6 +71,16 @@ class PageMyListings extends HTMLElement { document.querySelector('auth-modal')?.show() } + getStatusBadge(listing) { + if (listing.status === 'archived') { + return `${t('myListings.status.archived')}` + } + if (listing.status === 'draft' && listing.payment_status !== 'processing' && listing.payment_status !== 'pending') { + return `${t('myListings.status.draft')}` + } + return '' + } + render() { this.innerHTML = /* html */`
@@ -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' - ? `${t(`myListings.status.${listing.status}`)}` - : '' + const statusBadge = this.getStatusBadge(listing) return /* html */`
@@ -151,6 +159,7 @@ class PageMyListings extends HTMLElement { location="${escapeHTML(locationName)}" image="${imageUrl}" owner-id="${listing.user_created || ''}" + payment-status="${listing.payment_status || ''}" >
` diff --git a/js/services/directus.js b/js/services/directus.js index 0683048..e22af51 100644 --- a/js/services/directus.js +++ b/js/services/directus.js @@ -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',