feat: add verifiable listings (proof of possession) with verification widget, badge on cards/detail, i18n (7 langs), fix edit prefill for location/monero, prevent edit/delete on pending listings
This commit is contained in:
@@ -6,7 +6,7 @@ import { favoritesService } from '../services/favorites.js'
|
||||
|
||||
class ListingCard extends HTMLElement {
|
||||
static get observedAttributes() {
|
||||
return ['listing-id', 'title', 'price', 'currency', 'location', 'image', 'owner-id', 'payment-status', 'status', 'priority']
|
||||
return ['listing-id', 'title', 'price', 'currency', 'location', 'image', 'owner-id', 'payment-status', 'status', 'priority', 'verified']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
@@ -103,8 +103,9 @@ class ListingCard extends HTMLElement {
|
||||
const paymentStatus = this.getAttribute('payment-status')
|
||||
const status = this.getAttribute('status')
|
||||
const isDeleted = status === 'deleted'
|
||||
const isPending = status === 'draft' && paymentStatus !== 'paid'
|
||||
|
||||
const ownerBadge = (this.isOwner && !isDeleted) ? /* html */`
|
||||
const ownerBadge = (this.isOwner && !isDeleted && !isPending) ? /* html */`
|
||||
<a href="#/edit/${escapeHTML(id)}" class="owner-badge" title="${t('listing.edit')}">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path>
|
||||
@@ -141,13 +142,16 @@ class ListingCard extends HTMLElement {
|
||||
${paymentBadge}
|
||||
</div>
|
||||
<div class="listing-info">
|
||||
<h3 class="listing-title">${escapeHTML(title)}</h3>
|
||||
<div class="listing-price-wrapper">
|
||||
<p class="listing-price">${priceDisplay}</p>
|
||||
${secondaryPrice ? `<p class="listing-price-secondary">${secondaryPrice}</p>` : ''}
|
||||
</div>
|
||||
<h3 class="listing-title">${escapeHTML(title)}</h3>
|
||||
<div class="listing-price-wrapper">
|
||||
<p class="listing-price">${priceDisplay}</p>
|
||||
${secondaryPrice ? `<p class="listing-price-secondary">${secondaryPrice}</p>` : ''}
|
||||
</div>
|
||||
<div class="listing-meta-row">
|
||||
${this.getAttribute('verified') === 'true' ? `<span class="listing-verified-badge">${t('verification.badge')}</span>` : ''}
|
||||
<p class="listing-location">${escapeHTML(location)}</p>
|
||||
</div>
|
||||
</div>
|
||||
</${linkTag}>
|
||||
${!isDeleted ? /* html */`
|
||||
<button
|
||||
@@ -331,6 +335,19 @@ style.textContent = /* css */`
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
listing-card .listing-meta-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-xs);
|
||||
}
|
||||
|
||||
listing-card .listing-verified-badge {
|
||||
font-size: var(--font-size-xs);
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-success);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
listing-card .listing-location {
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--color-text-muted);
|
||||
|
||||
Reference in New Issue
Block a user