Implement oc2 listing improvements

This commit is contained in:
fatihalp 2026-03-07 20:21:11 +03:00
parent b1293d3960
commit dbe1dc97ce
2 changed files with 274 additions and 40 deletions

View File

@ -59,6 +59,7 @@
$reportEmail = config('mail.from.address', 'support@example.com');
$reportUrl = 'mailto:'.$reportEmail.'?subject='.rawurlencode('Report listing #'.$listing->getKey());
$shareUrl = route('listings.show', $listing);
$overviewItems = collect([
['label' => 'Listing ID', 'value' => '#'.$listing->getKey()],
@ -108,6 +109,20 @@
@endif
</div>
<div class="lt-gallery-utility">
<button
type="button"
class="lt-icon-btn"
data-listing-share
data-share-url="{{ $shareUrl }}"
data-share-title="{{ $displayTitle }}"
aria-label="Share listing"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9">
<path d="M15 8a3 3 0 1 0-2.83-4H12a3 3 0 0 0 .17 1L8.91 6.94a3 3 0 0 0-1.91-.69 3 3 0 1 0 1.91 5.31l3.27 1.94A3 3 0 0 0 12 15a3 3 0 1 0 2.82 4H15a3 3 0 0 0-.17-1l-3.26-1.94a3 3 0 0 0 0-3.12L14.83 10A3 3 0 0 0 15 10h0a3 3 0 0 0 0-2Z"/>
</svg>
</button>
@auth
<form method="POST" action="{{ route('favorites.listings.toggle', $listing) }}">
@csrf
@ -129,6 +144,7 @@
</a>
@endauth
</div>
</div>
@if($initialGalleryImage)
<img src="{{ $initialGalleryImage }}" alt="{{ $displayTitle }}" data-gallery-main>
@ -171,13 +187,13 @@
<section class="lt-card lt-summary-card">
<div class="lt-summary-copy">
<p class="lt-overline">{{ $listing->category?->name ?? 'Marketplace listing' }}</p>
<h1 class="lt-title">{{ $displayTitle }}</h1>
<div class="lt-price">{{ $priceLabel }}</div>
<p class="lt-subtitle">
<span>{{ $locationLabel !== '' ? $locationLabel : 'Location not specified' }}</span>
<span aria-hidden="true">·</span>
<span>{{ $postedAgo }}</span>
</p>
<h1 class="lt-title">{{ $displayTitle }}</h1>
<div class="lt-summary-meta-row">
<span class="lt-summary-meta-item">{{ $locationLabel !== '' ? $locationLabel : 'Location not specified' }}</span>
<span class="lt-summary-meta-item">{{ $publishedAt }}</span>
</div>
<p class="lt-subtitle">{{ $postedAgo }}</p>
</div>
<div class="lt-overview-grid">
@ -348,6 +364,56 @@
</aside>
</div>
<div class="lt-mobile-actions">
<div class="lt-mobile-actions-shell">
<div class="lt-mobile-actions-row">
@if(! $listing->user)
<button type="button" class="lt-btn" disabled>Unavailable</button>
@elseif($canContactSeller)
@if($existingConversationId)
<a href="{{ route('panel.inbox.index', ['conversation' => $existingConversationId]) }}" class="lt-btn">
Message
</a>
@else
<form method="POST" action="{{ route('conversations.start', $listing) }}" class="lt-action-form">
@csrf
<button type="submit" class="lt-btn">Message</button>
</form>
@endif
@elseif($isOwnListing)
<button type="button" class="lt-btn" disabled>Your listing</button>
@else
<a href="{{ route('login') }}" class="lt-btn">Message</a>
@endif
@if($primaryContactHref)
<a href="{{ $primaryContactHref }}" class="lt-btn lt-btn-outline">{{ $primaryContactLabel }}</a>
@else
<button type="button" class="lt-btn lt-btn-outline" disabled>No contact</button>
@endif
</div>
@if(! $listing->user)
<button type="button" class="lt-btn lt-btn-main" disabled>Unavailable</button>
@elseif($canContactSeller)
@if($existingConversationId)
<a href="{{ route('panel.inbox.index', ['conversation' => $existingConversationId]) }}" class="lt-btn lt-btn-main">
Make offer
</a>
@else
<form method="POST" action="{{ route('conversations.start', $listing) }}" class="lt-action-form">
@csrf
<button type="submit" class="lt-btn lt-btn-main">Make offer</button>
</form>
@endif
@elseif($isOwnListing)
<button type="button" class="lt-btn lt-btn-main" disabled>Manage listing</button>
@else
<a href="{{ route('login') }}" class="lt-btn lt-btn-main">Make offer</a>
@endif
</div>
</div>
@if(($relatedListings ?? collect())->isNotEmpty() || ($themePillCategories ?? collect())->isNotEmpty())
<section class="lt-related">
@if(($relatedListings ?? collect())->isNotEmpty())
@ -485,6 +551,32 @@
track.scrollBy({ left: amount(), behavior: 'smooth' });
});
});
document.querySelectorAll('[data-listing-share]').forEach((button) => {
button.addEventListener('click', async () => {
const url = button.dataset.shareUrl || window.location.href;
const title = button.dataset.shareTitle || document.title;
if (navigator.share) {
try {
await navigator.share({ title, url });
return;
} catch (error) {
if (error?.name === 'AbortError') {
return;
}
}
}
try {
await navigator.clipboard.writeText(url);
button.classList.add('is-active');
window.setTimeout(() => button.classList.remove('is-active'), 1200);
} catch (error) {
window.prompt('Copy this link', url);
}
});
});
})();
</script>
@endsection

View File

@ -849,6 +849,12 @@ summary::-webkit-details-marker {
gap: 8px;
}
.lt-gallery-utility {
display: flex;
align-items: center;
gap: 10px;
}
.lt-badge {
display: inline-flex;
align-items: center;
@ -997,12 +1003,30 @@ summary::-webkit-details-marker {
}
.lt-subtitle {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 12px;
margin-top: 10px;
color: var(--oc-muted);
font-size: 1rem;
font-size: 0.92rem;
line-height: 1.5;
}
.lt-summary-meta-row {
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
margin-top: 18px;
padding-top: 16px;
border-top: 1px solid rgba(29, 29, 31, 0.08);
}
.lt-summary-meta-item {
color: #4b5563;
font-size: 0.92rem;
line-height: 1.5;
}
.lt-summary-meta-item:last-child {
text-align: right;
}
.lt-overview-grid {
@ -1294,6 +1318,10 @@ summary::-webkit-details-marker {
margin-top: 30px;
}
.lt-mobile-actions {
display: none;
}
.lt-related-head {
display: flex;
justify-content: space-between;
@ -1513,7 +1541,7 @@ summary::-webkit-details-marker {
@media (max-width: 720px) {
.lt-wrap {
padding: 18px 12px 40px;
padding: 18px 12px calc(130px + env(safe-area-inset-bottom, 0px));
}
.lt-card {
@ -1522,28 +1550,103 @@ summary::-webkit-details-marker {
.lt-media-card,
.lt-summary-card,
.lt-detail-card,
.lt-side-card {
.lt-detail-card {
padding: 14px;
}
.lt-media-card {
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
box-shadow: none;
backdrop-filter: none;
}
.lt-gallery-main,
.lt-gallery-main img,
.lt-gallery-main-empty {
min-height: 360px;
min-height: 420px;
}
.lt-gallery-main {
border-radius: 0;
background: #2b2d31;
box-shadow: none;
}
.lt-gallery-main::after {
display: none;
}
.lt-gallery-main img {
padding: 26px;
padding: 0;
object-fit: contain;
}
.lt-title {
max-width: none;
font-size: 2rem;
font-size: 1.18rem;
line-height: 1.45;
letter-spacing: -0.02em;
}
.lt-price {
font-size: 1.8rem;
margin-top: 0;
font-size: 1.95rem;
}
.lt-overline,
.lt-overview-grid,
.lt-gallery-pills,
.lt-side-card,
.lt-contact-strip,
.lt-report,
.lt-policy {
display: none;
}
.lt-gallery-top {
align-items: flex-start;
}
.lt-gallery-utility {
margin-left: auto;
}
.lt-icon-btn,
.lt-gallery-nav {
border-color: rgba(255, 255, 255, 0.14);
background: rgba(29, 29, 31, 0.52);
color: #ffffff;
box-shadow: none;
backdrop-filter: blur(12px);
}
.lt-summary-card {
position: relative;
z-index: 3;
margin-top: -22px;
border-radius: 22px 22px 0 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
background: rgba(255, 255, 255, 0.98);
}
.lt-summary-card + .lt-detail-card {
margin-top: 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
box-shadow: 0 18px 36px rgba(15, 23, 42, 0.06);
}
.lt-summary-meta-row {
margin-top: 14px;
padding-top: 14px;
}
.lt-summary-meta-item {
font-size: 0.84rem;
}
.lt-overview-grid,
@ -1566,6 +1669,36 @@ summary::-webkit-details-marker {
.lt-rel-photo {
height: 156px;
}
.lt-mobile-actions {
display: block;
position: fixed;
right: 0;
bottom: 0;
left: 0;
z-index: 45;
padding: 10px 10px calc(10px + env(safe-area-inset-bottom, 0px));
background: linear-gradient(180deg, rgba(245, 245, 247, 0) 0%, rgba(245, 245, 247, 0.88) 28%, rgba(245, 245, 247, 0.98) 100%);
backdrop-filter: blur(14px);
}
.lt-mobile-actions-shell {
display: grid;
gap: 10px;
max-width: 28rem;
margin: 0 auto;
padding: 10px;
border: 1px solid rgba(29, 29, 31, 0.08);
border-radius: 22px;
background: rgba(255, 255, 255, 0.96);
box-shadow: 0 18px 40px rgba(15, 23, 42, 0.12);
}
.lt-mobile-actions-row {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
}
}
@media (max-width: 480px) {
@ -1581,11 +1714,7 @@ summary::-webkit-details-marker {
.lt-gallery-main,
.lt-gallery-main img,
.lt-gallery-main-empty {
min-height: 300px;
}
.lt-gallery-main img {
padding: 18px;
min-height: 392px;
}
.lt-gallery-top {
@ -1605,6 +1734,10 @@ summary::-webkit-details-marker {
padding: 16px;
}
.lt-summary-card {
margin-top: -18px;
}
.lt-seller-name {
font-size: 1.35rem;
}
@ -1612,6 +1745,15 @@ summary::-webkit-details-marker {
.lt-contact-strip {
flex-direction: column;
}
.lt-mobile-actions {
padding-inline: 4px;
}
.lt-mobile-actions-shell {
border-radius: 18px;
padding: 8px;
}
}
html {