File: /home/u756937133/domains/swingersnest.com/public_html/resources/views/pages/listings/show.blade.php
@extends('layouts.app')
@section('title', ($club->meta_title ?? ($club->name ?? 'Club Details')) . ' - ' . config('app.name'))
@section('meta_description', $club->meta_description ?? substr(strip_tags($club->description ?? ''), 0, 155))
@push('head')
@if($club)
{{-- Meta Description --}}
<meta name="description" content="{{ $club->meta_description ?? substr(strip_tags($club->description ?? ''), 0, 155) }}">
{{-- Meta Keywords --}}
@if($club->meta_keywords)
<meta name="keywords" content="{{ $club->meta_keywords }}">
@endif
{{-- Canonical URL --}}
@if($club->canonical_url)
<link rel="canonical" href="{{ $club->canonical_url }}">
@else
<link rel="canonical" href="{{ url()->current() }}">
@endif
{{-- Robots Meta --}}
@if($club->noindex || $club->nofollow)
<meta name="robots" content="{{ ($club->noindex ? 'noindex' : 'index') }}, {{ ($club->nofollow ? 'nofollow' : 'follow') }}">
@endif
{{-- Open Graph Meta Tags --}}
<meta property="og:type" content="website">
<meta property="og:title" content="{{ $club->og_title ?? $club->meta_title ?? $club->name }}">
<meta property="og:description" content="{{ $club->og_description ?? $club->meta_description ?? substr(strip_tags($club->description ?? ''), 0, 155) }}">
<meta property="og:url" content="{{ url()->current() }}">
@if($club->og_image)
<meta property="og:image" content="{{ asset('storage/' . $club->og_image) }}">
@elseif($club->thumbnail)
<meta property="og:image" content="{{ asset('storage/' . $club->thumbnail) }}">
@endif
<meta property="og:site_name" content="{{ config('app.name') }}">
{{-- Twitter Card Meta Tags --}}
<meta name="twitter:card" content="{{ $club->twitter_card ?? 'summary_large_image' }}">
<meta name="twitter:title" content="{{ $club->twitter_title ?? $club->meta_title ?? $club->name }}">
<meta name="twitter:description" content="{{ $club->twitter_description ?? $club->meta_description ?? substr(strip_tags($club->description ?? ''), 0, 155) }}">
@if($club->twitter_image)
<meta name="twitter:image" content="{{ asset('storage/' . $club->twitter_image) }}">
@elseif($club->thumbnail)
<meta name="twitter:image" content="{{ asset('storage/' . $club->thumbnail) }}">
@endif
{{-- Schema.org JSON-LD --}}
@if(isset($club->schema_type) && $club->schema_type)
@php
$schemaData = [
'@context' => 'https://schema.org',
'@type' => $club->schema_type ?? 'LocalBusiness',
'name' => $club->name ?? '',
'description' => strip_tags($club->description ?? ''),
];
if (isset($club->address) && $club->address) {
$address = [
'@type' => 'PostalAddress',
'streetAddress' => $club->address ?? '',
];
if (isset($club->city_name) && $club->city_name) {
$address['addressLocality'] = $club->city_name;
}
if (isset($club->state_name) && $club->state_name) {
$address['addressRegion'] = $club->state_name;
}
if (isset($club->country_name) && $club->country_name) {
$address['addressCountry'] = $club->country_name;
}
$schemaData['address'] = $address;
}
if (isset($club->phone) && $club->phone) {
$schemaData['telephone'] = $club->phone;
}
if (isset($club->email) && $club->email) {
$schemaData['email'] = $club->email;
}
if (isset($club->website) && $club->website) {
$schemaData['url'] = $club->website;
}
if (isset($club->thumbnail) && $club->thumbnail) {
$schemaData['image'] = asset('storage/' . $club->thumbnail);
}
$schemaData['aggregateRating'] = [
'@type' => 'AggregateRating',
'ratingValue' => round((float)($club->rating ?? 0), 1),
'reviewCount' => (int)($club->reviews_count ?? 0),
];
@endphp
<script type="application/ld+json">
{!! json_encode($schemaData, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) !!}
</script>
@endif
@endif
@endpush
@section('full-width')
<style>
.listing-show-page .gradient-text {
background: linear-gradient(to right, var(--sn-purple), var(--sn-gold));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.listing-show-page .club-details-section {
background: #ffffff;
border: 1px solid rgba(107, 63, 160, 0.12);
border-radius: 8px;
padding: 1rem;
margin-bottom: 1rem;
box-shadow: 0 10px 30px rgba(43, 15, 58, 0.08);
}
.listing-show-page .club-details-label {
color: var(--sn-text-muted);
font-size: 0.75rem;
margin-bottom: 0.25rem;
display: block;
}
.listing-show-page .club-details-value {
color: var(--sn-text-main);
font-size: 0.875rem;
font-weight: 600;
}
.listing-show-page .gallery-container {
position: relative;
width: 100%;
background: var(--sn-bg-lavender);
border-radius: 8px;
overflow: hidden;
margin-bottom: 1rem;
border: 1px solid rgba(107, 63, 160, 0.12);
}
.listing-show-page .gallery-main {
position: relative;
width: 100%;
height: 380px;
background: var(--sn-bg-lavender);
overflow: hidden;
}
.listing-show-page .gallery-slider { position: relative; width: 100%; height: 100%; }
.listing-show-page .gallery-slide {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
opacity: 0;
transition: opacity 0.4s ease;
}
.listing-show-page .gallery-slide.active { opacity: 1; z-index: 2; }
.listing-show-page .gallery-slide img,
.listing-show-page .gallery-slide video { width: 100%; height: 100%; object-fit: cover; }
.listing-show-page .gallery-nav {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: rgba(107, 63, 160, 0.85);
color: #fff;
border: none;
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 10;
transition: all 0.3s ease;
font-size: 1.25rem;
}
.listing-show-page .gallery-nav:hover {
background: var(--sn-gold);
color: var(--sn-dark);
}
.listing-show-page .gallery-nav.prev { left: 20px; }
.listing-show-page .gallery-nav.next { right: 20px; }
.listing-show-page .gallery-thumbnails {
display: flex;
gap: 2px;
padding: 6px;
background: #ffffff;
border-top: 1px solid rgba(107, 63, 160, 0.12);
overflow-x: auto;
}
.listing-show-page .gallery-thumbnail {
flex-shrink: 0;
width: 64px;
height: 48px;
cursor: pointer;
border: 2px solid transparent;
border-radius: 4px;
overflow: hidden;
transition: all 0.3s ease;
background: var(--sn-bg-soft);
}
.listing-show-page .gallery-thumbnail:hover {
border-color: var(--sn-purple);
transform: scale(1.05);
}
.listing-show-page .gallery-thumbnail.active {
border-color: var(--sn-purple);
box-shadow: 0 0 8px rgba(107, 63, 160, 0.3);
}
.listing-show-page .gallery-thumbnail img,
.listing-show-page .gallery-thumbnail video { width: 100%; height: 100%; object-fit: cover; }
.listing-show-page .gallery-thumbnail .placeholder-image,
.listing-show-page .gallery-placeholder {
display: flex;
align-items: center;
justify-content: center;
color: var(--sn-text-muted);
}
.listing-show-page .gallery-placeholder { flex-direction: column; height: 100%; }
.listing-show-page .gallery-placeholder i { font-size: 3rem; margin-bottom: 0.5rem; }
.listing-show-page .gallery-thumbnail .placeholder-image { width: 100%; height: 100%; font-size: 1.25rem; }
.listing-show-page .details-info-box {
background: #ffffff;
border: 1px solid rgba(107, 63, 160, 0.12);
border-radius: 8px;
padding: 1.25rem;
min-height: 160px;
box-shadow: 0 10px 30px rgba(43, 15, 58, 0.08);
}
.listing-show-page .review-card {
transition: transform 0.2s ease, box-shadow 0.2s ease;
background: #ffffff;
border: 1px solid rgba(107, 63, 160, 0.12);
box-shadow: 0 10px 30px rgba(43, 15, 58, 0.08);
}
.listing-show-page .review-card:hover {
transform: translateY(-2px);
box-shadow: 0 10px 30px rgba(43, 15, 58, 0.12);
border-color: var(--sn-purple);
}
.listing-show-page .star-rating .star { color: var(--sn-gold); }
.listing-show-page .star-rating .star-empty { color: var(--sn-text-muted); }
.listing-show-page .placeholder-image {
background: var(--sn-bg-lavender);
display: flex;
align-items: center;
justify-content: center;
color: var(--sn-text-muted);
}
@media (max-width: 768px) {
.listing-show-page .gallery-main { height: 280px; }
.listing-show-page .gallery-nav { width: 36px; height: 36px; font-size: 1rem; }
.listing-show-page .gallery-thumbnail { width: 52px; height: 40px; }
}
</style>
<div class="listing-show-page min-h-screen" style="background-color: var(--sn-bg-soft); color: var(--sn-text-main);">
<div class="py-4 md:py-5 border-b" style="background-color: var(--sn-bg-lavender); border-color: rgba(107,63,160,0.12);">
<div class="container mx-auto px-4">
<div class="flex flex-col md:flex-row items-start md:items-center justify-between gap-3">
<div class="flex-1">
@if($club)
<h1 class="text-xl md:text-2xl font-bold mb-1.5" style="color: var(--sn-text-heading);">{{ $club->name ?? 'Club Name' }}</h1>
<p class="text-sm" style="color: var(--sn-text-muted);">
<i class="ri-map-pin-line inline-block mr-1"></i>
{{ $club->address ?? '' }}{{ isset($club->address) && isset($club->city_name) ? ', ' : '' }}{{ $club->city_name ?? ($club->city ?? 'N/A') }}{{ isset($club->state_name) ? ', ' . $club->state_name : '' }}{{ isset($club->country_name) ? ', ' . $club->country_name : '' }}
</p>
@endif
</div>
@if($club && isset($club->country_slug))
<div class="flex-shrink-0">
<a href="{{ route('listings.index') }}?meet=1" class="btn btn-secondary inline-flex items-center justify-center px-5 py-2 text-sm font-medium rounded-[12px] whitespace-nowrap">
Meet People in {{ $club->country_name ?? 'Your Location' }}
</a>
</div>
@endif
</div>
</div>
</div>
@if($club)
<div class="container mx-auto px-4 py-5">
<!-- Gallery Section -->
<div class="gallery-container" id="gallery-container">
@php
// Prepare media items (images and videos)
$displayMedia = [];
$images = isset($club->photos) && is_array($club->photos) ? $club->photos : [];
$videos = isset($club->videos) && is_array($club->videos) ? $club->videos : [];
// Add thumbnail first if available
if (isset($club->thumbnail)) {
$displayMedia[] = ['type' => 'image', 'url' => $club->thumbnail];
}
// Add all images
foreach ($images as $img) {
// Skip if it's the same as thumbnail
if (!isset($club->thumbnail) || $img !== $club->thumbnail) {
$displayMedia[] = ['type' => 'image', 'url' => $img];
}
}
// Add all videos
foreach ($videos as $vid) {
$displayMedia[] = ['type' => 'video', 'url' => $vid];
}
// If no media, add placeholder
if (empty($displayMedia) && isset($club->thumbnail)) {
$displayMedia = [['type' => 'image', 'url' => $club->thumbnail]];
}
@endphp
<!-- Main Gallery Display -->
<div class="gallery-main">
@if(count($displayMedia) > 0)
<div class="gallery-slider" id="gallery-slider">
@foreach($displayMedia as $index => $media)
<div class="gallery-slide {{ $index === 0 ? 'active' : '' }}" data-media-index="{{ $index }}">
@if($media['type'] === 'video')
<video
src="{{ asset($media['url']) }}"
controls
class="w-full h-full"
onerror="this.style.display='none'; this.nextElementSibling.style.display='flex';"
>
Your browser does not support the video tag.
</video>
<div class="gallery-placeholder" style="display: none;">
<i class="ri-video-line"></i>
<span>Video not available</span>
</div>
@else
<img
src="{{ asset($media['url']) }}"
alt="Gallery {{ $index + 1 }}"
onerror="this.onerror=null; this.src='data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'800\' height=\'500\'%3E%3Crect fill=\'%231f2937\' width=\'800\' height=\'500\'/%3E%3Ctext fill=\'%236b7280\' font-family=\'sans-serif\' font-size=\'18\' x=\'50%25\' y=\'50%25\' text-anchor=\'middle\' dy=\'.3em\'%3ENo Image%3C/text%3E%3C/svg%3E';"
>
@endif
</div>
@endforeach
</div>
@if(count($displayMedia) > 1)
<button class="gallery-nav prev" id="gallery-prev">
<i class="ri-arrow-left-s-line"></i>
</button>
<button class="gallery-nav next" id="gallery-next">
<i class="ri-arrow-right-s-line"></i>
</button>
@endif
@else
<div class="gallery-placeholder">
<i class="ri-image-line"></i>
<span>No media available</span>
</div>
@endif
</div>
<!-- Gallery Thumbnails -->
@if(count($displayMedia) > 1)
<div class="gallery-thumbnails" id="gallery-thumbnails">
@foreach($displayMedia as $thumbIndex => $thumbMedia)
<div class="gallery-thumbnail {{ $thumbIndex === 0 ? 'active' : '' }}" data-thumb-index="{{ $thumbIndex }}">
@if($thumbMedia['type'] === 'video')
<video
src="{{ asset($thumbMedia['url']) }}"
class="w-full h-full"
onerror="this.style.display='none'; this.nextElementSibling.style.display='flex';"
></video>
<div class="placeholder-image" style="display: none;">
<i class="ri-video-line"></i>
</div>
@else
<img
src="{{ asset($thumbMedia['url']) }}"
alt="Thumbnail {{ $thumbIndex + 1 }}"
onerror="this.onerror=null; this.src='data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'80\' height=\'60\'%3E%3Crect fill=\'%231f2937\' width=\'80\' height=\'60\'/%3E%3Ctext fill=\'%236b7280\' font-family=\'sans-serif\' font-size=\'10\' x=\'50%25\' y=\'50%25\' text-anchor=\'middle\' dy=\'.3em\'%3ENo Image%3C/text%3E%3C/svg%3E';"
>
@endif
</div>
@endforeach
</div>
@endif
</div>
<!-- All Club Information in One Section -->
<div class="club-details-section mb-4">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-4">
@if(isset($club->phone))
<div>
<label class="club-details-label">Phone</label>
<div class="club-details-value">
<a href="tel:{{ $club->phone }}" class="sn-link transition-colors" style="color: var(--sn-purple);">
{{ $club->phone }}
</a>
</div>
</div>
@endif
@if(isset($club->email))
<div>
<label class="club-details-label">Email</label>
<div class="club-details-value">
<a href="mailto:{{ $club->email }}" class="sn-link transition-colors break-all" style="color: var(--sn-purple);">
{{ $club->email }}
</a>
</div>
</div>
@endif
@if(isset($club->website))
<div>
<label class="club-details-label">Website</label>
<div class="club-details-value">
<a href="{{ $club->website }}" target="_blank" class="sn-link transition-colors break-all" style="color: var(--sn-purple);">
{{ $club->website }}
</a>
</div>
</div>
@endif
@if(isset($club->sdc_username))
<div>
<label class="club-details-label">SDC Username</label>
<div class="club-details-value">
{{ $club->sdc_username }}
</div>
</div>
@endif
@if(isset($club->type))
<div>
<label class="club-details-label">Type</label>
<div class="club-details-value">
<span class="px-2.5 py-0.5 rounded-full text-xs" style="background: var(--sn-bg-lavender); color: var(--sn-text-main);">
{{ $club->type }}
</span>
</div>
</div>
@endif
@if(isset($club->city_name) || isset($club->city))
<div>
<label class="club-details-label">City</label>
<div class="club-details-value">
{{ $club->city_name ?? $club->city ?? 'N/A' }}
</div>
</div>
@endif
@if(isset($club->country_name) && $club->country_name)
<div>
<label class="club-details-label">Country</label>
<div class="club-details-value">
{{ $club->country_name }}
</div>
</div>
@endif
@if(isset($club->rating) && $club->rating > 0)
<div>
<label class="club-details-label">Rating</label>
<div class="club-details-value">
<div class="flex items-center gap-2">
<div class="star-rating flex gap-1">
@for($i = 1; $i <= 5; $i++)
@if($i <= round($club->rating))
<i class="ri-star-fill star text-base"></i>
@else
<i class="ri-star-line star-empty text-base"></i>
@endif
@endfor
</div>
<span class="text-xs" style="color: var(--sn-text-muted);">({{ $club->reviews_count ?? 0 }} reviews)</span>
</div>
</div>
</div>
@endif
</div>
@if((isset($club->membership_fees) && count($club->membership_fees) > 0) || (isset($club->sdc_discount) && $club->sdc_discount > 0))
<div class="border-t pt-4 mb-4" style="border-color: rgba(107,63,160,0.12);">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
@if(isset($club->membership_fees) && count($club->membership_fees) > 0)
<div>
<h3 class="text-base font-bold mb-2" style="color: var(--sn-purple);">Membership fees</h3>
<ul class="space-y-1 text-sm" style="color: var(--sn-text-main);">
@foreach($club->membership_fees as $fee)
<li>{{ $fee }}</li>
@endforeach
</ul>
@if(isset($club->membership_note))
<p class="text-xs mt-2 italic" style="color: var(--sn-text-muted);">{{ $club->membership_note }}</p>
@endif
</div>
@endif
@if(isset($club->sdc_discount) && $club->sdc_discount > 0)
<div>
<h3 class="text-base font-bold mb-2 flex items-center gap-2" style="color: var(--sn-purple);">
Discounts
<i class="ri-star-fill text-sm" style="color: var(--sn-gold);"></i>
</h3>
<p class="text-lg font-bold" style="color: var(--sn-text-heading);">{{ $club->sdc_discount }}%</p>
</div>
@endif
</div>
</div>
@endif
<div class="border-t pt-4" style="border-color: rgba(107,63,160,0.12);">
<h2 class="text-base font-bold mb-2" style="color: var(--sn-text-heading);">Description</h2>
<div class="text-sm leading-relaxed" style="color: var(--sn-text-main);">
@if(isset($club->full_description) && $club->full_description)
<div class="whitespace-pre-wrap">{!! $club->full_description !!}</div>
@elseif(isset($club->description) && $club->description)
<div class="whitespace-pre-wrap">{{ $club->description }}</div>
@elseif(isset($club->additional_info) && $club->additional_info)
<div>{!! $club->additional_info !!}</div>
@else
<p class="italic" style="color: var(--sn-text-muted);">No additional information available.</p>
@endif
</div>
</div>
</div>
<!-- Reviews Section -->
@if(count($reviews) > 0)
<div class="mb-4">
<h2 class="text-lg font-bold mb-4" style="color: var(--sn-text-heading);">Reviews</h2>
@foreach($reviews as $review)
<div class="review-card rounded-lg p-4 mb-4">
<div class="flex flex-col md:flex-row gap-4">
<div class="flex-shrink-0 flex items-start gap-3">
@if(isset($review['user']['avatar']) && $review['user']['avatar'])
<img src="{{ asset($review['user']['avatar']) }}" alt="{{ $review['user']['username'] }}" class="w-10 h-10 rounded-full border-2" style="border-color: var(--sn-purple);" onerror="this.style.display='none'; this.nextElementSibling.style.display='flex';">
@endif
<div class="w-10 h-10 rounded-full flex items-center justify-center text-sm font-bold border-2 {{ isset($review['user']['avatar']) && $review['user']['avatar'] ? 'hidden' : '' }}" style="background: linear-gradient(135deg, var(--sn-purple), var(--sn-gold)); color: #fff; border-color: var(--sn-purple);">
{{ strtoupper(substr($review['user']['username'] ?? 'U', 0, 1)) }}
</div>
<div>
<p class="text-sm font-bold" style="color: var(--sn-text-heading);">{{ $review['user']['username'] ?? 'Anonymous' }}</p>
</div>
</div>
<div class="flex-1">
<div class="star-rating flex gap-1 mb-2">
@for($i = 1; $i <= 5; $i++)
@if($i <= ($review['rating'] ?? 0))
<i class="ri-star-fill star text-base" style="color: var(--sn-gold);"></i>
@else
<i class="ri-star-line star-empty text-base" style="color: var(--sn-text-muted);"></i>
@endif
@endfor
</div>
@if(isset($review['comment_heading']) && $review['comment_heading'])
<h4 class="text-base font-semibold mb-1" style="color: var(--sn-purple);">{{ $review['comment_heading'] }}</h4>
@endif
<p class="mb-2 text-sm leading-relaxed" style="color: var(--sn-text-main);">{{ $review['comment'] ?? 'No comment provided.' }}</p>
<div class="flex items-center gap-2 text-xs" style="color: var(--sn-text-muted);">
<i class="ri-calendar-line"></i>
<span>
@if(isset($review['created_at']))
{{ \Carbon\Carbon::parse($review['created_at'])->format('M d Y h:i A') }}
@else
{{ $review['date'] ?? 'Unknown date' }}
@endif
</span>
</div>
</div>
</div>
</div>
@endforeach
@php $isPaginator = is_object($reviews) && method_exists($reviews, 'hasPages'); @endphp
@if($isPaginator && $reviews->hasPages())
<div class="mt-4 flex justify-center">{{ $reviews->links('pagination.tailwind-simple') }}</div>
@elseif(!$isPaginator && is_array($reviews) && count($reviews) > 0 && count($reviews) >= 10)
<div class="mt-4 text-center">
<button id="load-more-reviews" class="btn btn-secondary px-5 py-2 text-sm font-medium rounded-[12px]">Load More Reviews</button>
</div>
@endif
</div>
@endif
<!-- Write a Review -->
<div class="mt-5 mb-4 flex flex-wrap items-center justify-between gap-3">
<div>
@if(count($reviews) > 0)
<h2 class="text-base font-bold" style="color: var(--sn-text-heading);">Share your experience</h2>
<p class="text-xs mt-0.5" style="color: var(--sn-text-muted);">Have you visited? Write a review.</p>
@else
<h2 class="text-base font-bold" style="color: var(--sn-text-heading);">Be the first to review</h2>
<p class="text-xs mt-0.5" style="color: var(--sn-text-muted);">Share your experience with this listing.</p>
@endif
</div>
@auth
<button type="button" id="listing-show-review-btn" class="btn btn-primary inline-flex items-center justify-center gap-1.5 px-5 py-2 text-sm font-medium rounded-[12px]">
<i class="ri-edit-line"></i>
Write a Review
</button>
@else
<a href="{{ route('login') }}?redirect={{ urlencode(request()->url()) }}" class="btn btn-primary inline-flex items-center justify-center gap-1.5 px-5 py-2 text-sm font-medium rounded-[12px]">
<i class="ri-edit-line"></i>
Log in to write a review
</a>
@endauth
</div>
@auth
<!-- Review Modal (listing detail page) -->
<div id="listing-show-review-modal" class="hidden fixed inset-0 z-50 overflow-y-auto flex items-center justify-center p-4" style="background: rgba(43,15,58,0.2);">
<div class="rounded-2xl shadow-xl max-w-2xl w-full border relative" style="background-color: #ffffff; border-color: rgba(107,63,160,0.12); box-shadow: 0 10px 30px rgba(43,15,58,0.12);">
<button type="button" id="listing-show-review-close" class="absolute top-3 right-3 transition-colors hover:opacity-70" style="color: var(--sn-text-muted);" aria-label="Close">
<i class="ri-close-line text-xl"></i>
</button>
<div class="p-4 border-b" style="border-color: rgba(107,63,160,0.12);">
<h2 class="text-lg font-bold mb-1.5" style="color: var(--sn-text-heading);">Write a Review</h2>
<div class="flex items-center gap-3">
@if($club->thumbnail ?? null)
<img id="listing-show-review-thumb" src="{{ $club->thumbnail }}" alt="{{ $club->name }}" class="w-12 h-12 object-cover rounded-lg" style="border: 1px solid rgba(107,63,160,0.2);">
@else
<div class="w-12 h-12 rounded-lg flex items-center justify-center" style="background: var(--sn-bg-lavender); color: var(--sn-purple);"><i class="ri-image-line text-xl"></i></div>
@endif
<div>
<h3 id="listing-show-review-name" class="text-base font-semibold" style="color: var(--sn-text-heading);">{{ $club->name ?? 'Club' }}</h3>
<p id="listing-show-review-location" class="text-xs" style="color: var(--sn-text-muted);">{{ trim(implode(', ', array_filter([$club->address ?? '', $club->city_name ?? $club->city ?? '', $club->state_name ?? '', $club->country_name ?? '']))) ?: 'N/A' }}</p>
</div>
</div>
</div>
<form id="listing-show-review-form" action="{{ route('listings.review.store', $club->id) }}" method="POST" class="p-4">
@csrf
<div class="mb-4">
<label class="block text-sm font-semibold mb-1.5" style="color: var(--sn-text-heading);">Rating *</label>
<div class="listing-show-star-rating flex gap-1.5 cursor-pointer select-none">
@for($i = 1; $i <= 5; $i++)
<i class="ri-star-line text-2xl transition-colors" style="color: var(--sn-gold);" data-rating="{{ $i }}"></i>
@endfor
</div>
<input type="hidden" id="listing-show-selected-rating" name="rating" required>
<p class="text-red-500 text-sm mt-1 hidden" id="listing-show-rating-error">Please select a rating</p>
</div>
<div class="mb-4">
<label for="listing-show-comment_heading" class="block text-sm font-semibold mb-1.5" style="color: var(--sn-text-heading);">Review Title (Optional)</label>
<input type="text" id="listing-show-comment_heading" name="comment_heading" maxlength="255" class="w-full px-4 py-2 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--sn-purple)]" style="background-color: var(--sn-bg-soft); border: 1px solid rgba(107,63,160,0.12); color: var(--sn-text-main);" placeholder="Give your review a title...">
</div>
<div class="mb-6">
<label for="listing-show-comment" class="block font-semibold mb-2" style="color: var(--sn-text-heading);">Your Review *</label>
<textarea id="listing-show-comment" name="comment" rows="6" required maxlength="5000" class="w-full px-4 py-2 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--sn-purple)] resize-none" style="background-color: var(--sn-bg-soft); border: 1px solid rgba(107,63,160,0.12); color: var(--sn-text-main);" placeholder="Share your experience..."></textarea>
</div>
<div class="flex gap-2">
<button type="submit" id="listing-show-review-submit" class="btn btn-primary flex-1 px-5 py-2 text-sm font-medium rounded-[12px] disabled:opacity-60 disabled:cursor-not-allowed">
<span id="listing-show-review-submit-text">Submit Review</span>
<span id="listing-show-review-submit-loading" class="hidden">Submitting...</span>
</button>
<button type="button" id="listing-show-review-cancel" class="btn btn-tertiary px-5 py-2 text-sm font-medium rounded-[12px]">Cancel</button>
</div>
</form>
</div>
</div>
@endauth
</div>
@else
<div class="container mx-auto px-4 py-8">
<div class="rounded-lg p-6 text-center border" style="background-color: var(--sn-bg-lavender); border-color: rgba(107,63,160,0.12);">
<i class="ri-building-line text-4xl mb-3" style="color: var(--sn-text-muted);"></i>
<h2 class="text-lg font-semibold mb-1.5" style="color: var(--sn-text-heading);">Club Not Found</h2>
<p class="mb-4 text-sm" style="color: var(--sn-text-muted);">The club you're looking for doesn't exist or has been removed.</p>
<a href="{{ route('listings.index') }}" class="btn btn-primary inline-flex items-center justify-center px-5 py-2 text-sm font-medium rounded-[12px]">Back to Listings</a>
</div>
</div>
@endif
</div>
@endsection
@push('scripts')
<script>
document.addEventListener('DOMContentLoaded', function() {
// Gallery Slider Functionality
const galleryContainer = document.getElementById('gallery-container');
if (!galleryContainer) return;
const gallerySlider = document.getElementById('gallery-slider');
const slides = gallerySlider ? Array.from(gallerySlider.querySelectorAll('.gallery-slide')) : [];
const prevBtn = document.getElementById('gallery-prev');
const nextBtn = document.getElementById('gallery-next');
const thumbnails = document.querySelectorAll('.gallery-thumbnail');
if (slides.length === 0) return;
let currentSlide = 0;
function showSlide(index) {
if (slides.length === 0) return;
let actualIndex = index;
if (actualIndex >= slides.length) {
actualIndex = 0;
} else if (actualIndex < 0) {
actualIndex = slides.length - 1;
}
// Hide all slides
slides.forEach((slide) => {
slide.classList.remove('active');
slide.style.display = 'none';
});
// Show active slide
if (slides[actualIndex]) {
slides[actualIndex].style.display = 'block';
slides[actualIndex].classList.add('active');
currentSlide = actualIndex;
}
// Update thumbnails
thumbnails.forEach((thumb, idx) => {
thumb.classList.remove('active');
if (idx === actualIndex) {
thumb.classList.add('active');
}
});
}
function nextSlide() {
if (slides.length === 0) return;
const next = (currentSlide + 1) % slides.length;
showSlide(next);
}
function prevSlide() {
if (slides.length === 0) return;
const prev = (currentSlide - 1 + slides.length) % slides.length;
showSlide(prev);
}
// Thumbnail click functionality
thumbnails.forEach((thumb, index) => {
thumb.addEventListener('click', function() {
showSlide(index);
});
});
// Navigation buttons
if (nextBtn) {
nextBtn.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
nextSlide();
});
}
if (prevBtn) {
prevBtn.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
prevSlide();
});
}
// Initialize - show first slide
if (slides.length > 0) {
showSlide(0);
}
// Hide navigation if only one slide
if (slides.length <= 1) {
if (prevBtn) prevBtn.style.display = 'none';
if (nextBtn) nextBtn.style.display = 'none';
}
});
// Listing show – Review modal
const reviewBtn = document.getElementById('listing-show-review-btn');
const reviewModal = document.getElementById('listing-show-review-modal');
const reviewForm = document.getElementById('listing-show-review-form');
const reviewClose = document.getElementById('listing-show-review-close');
const reviewCancel = document.getElementById('listing-show-review-cancel');
let reviewSelectedRating = 0;
function openListingShowReviewModal() {
if (!reviewModal || !reviewForm) return;
reviewForm.reset();
reviewSelectedRating = 0;
const ratingInput = document.getElementById('listing-show-selected-rating');
if (ratingInput) ratingInput.value = '';
updateListingShowStars(0);
const err = document.getElementById('listing-show-rating-error');
if (err) err.classList.add('hidden');
const submitBtn = document.getElementById('listing-show-review-submit');
const submitText = document.getElementById('listing-show-review-submit-text');
const submitLoading = document.getElementById('listing-show-review-submit-loading');
if (submitBtn) submitBtn.disabled = false;
if (submitText) submitText.classList.remove('hidden');
if (submitLoading) submitLoading.classList.add('hidden');
reviewModal.classList.remove('hidden');
document.body.style.overflow = 'hidden';
}
function closeListingShowReviewModal() {
if (!reviewModal) return;
reviewModal.classList.add('hidden');
document.body.style.overflow = 'auto';
}
function updateListingShowStars(rating) {
const stars = document.querySelectorAll('.listing-show-star-rating i');
stars.forEach(function(star, index) {
if (index < rating) {
star.classList.remove('ri-star-line');
star.classList.add('ri-star-fill');
} else {
star.classList.remove('ri-star-fill');
star.classList.add('ri-star-line');
}
});
}
if (reviewBtn) {
reviewBtn.addEventListener('click', function(e) {
e.preventDefault();
openListingShowReviewModal();
});
}
if (reviewClose) reviewClose.addEventListener('click', closeListingShowReviewModal);
if (reviewCancel) reviewCancel.addEventListener('click', closeListingShowReviewModal);
if (reviewModal) {
reviewModal.addEventListener('click', function(e) {
if (e.target === reviewModal) closeListingShowReviewModal();
});
}
const starContainer = document.querySelector('.listing-show-star-rating');
const ratingInput = document.getElementById('listing-show-selected-rating');
if (starContainer && ratingInput) {
starContainer.addEventListener('click', function(e) {
const star = e.target.closest('i[data-rating]');
if (!star) return;
const r = parseInt(star.getAttribute('data-rating'), 10) || 0;
if (r < 1 || r > 5) return;
reviewSelectedRating = r;
ratingInput.value = r;
updateListingShowStars(r);
document.getElementById('listing-show-rating-error').classList.add('hidden');
});
starContainer.addEventListener('mouseover', function(e) {
const star = e.target.closest('i[data-rating]');
if (!star) return;
const r = parseInt(star.getAttribute('data-rating'), 10) || 0;
if (r >= 1 && r <= 5) updateListingShowStars(r);
});
starContainer.addEventListener('mouseout', function() {
updateListingShowStars(reviewSelectedRating);
});
}
if (reviewForm) {
reviewForm.addEventListener('submit', function(e) {
const r = document.getElementById('listing-show-selected-rating');
const comment = document.getElementById('listing-show-comment');
const submitBtn = document.getElementById('listing-show-review-submit');
const submitText = document.getElementById('listing-show-review-submit-text');
const submitLoading = document.getElementById('listing-show-review-submit-loading');
const err = document.getElementById('listing-show-rating-error');
if (!r || !r.value || parseInt(r.value, 10) < 1 || parseInt(r.value, 10) > 5) {
e.preventDefault();
if (err) err.classList.remove('hidden');
return;
}
if (!comment || comment.value.trim().length < 10) {
e.preventDefault();
alert('Please write a review comment (at least 10 characters).');
return;
}
if (err) err.classList.add('hidden');
if (submitBtn) submitBtn.disabled = true;
if (submitText) submitText.classList.add('hidden');
if (submitLoading) submitLoading.classList.remove('hidden');
});
}
</script>
@endpush