diff --git a/Modules/Listing/Http/Controllers/ListingController.php b/Modules/Listing/Http/Controllers/ListingController.php
index f39665b17..26b45f36c 100644
--- a/Modules/Listing/Http/Controllers/ListingController.php
+++ b/Modules/Listing/Http/Controllers/ListingController.php
@@ -89,6 +89,8 @@ class ListingController extends Controller
])
->applyBrowseSort($sort);
+ $filteredListingsTotal = (clone $listingsQuery)->count();
+
$listings = $listingsQuery
->paginate(16)
->withQueryString();
@@ -146,6 +148,7 @@ class ListingController extends Controller
'isCurrentSearchSaved',
'conversationListingMap',
'allListingsTotal',
+ 'filteredListingsTotal',
));
}
diff --git a/Modules/Listing/Models/Listing.php b/Modules/Listing/Models/Listing.php
index 1e801237b..192d84010 100644
--- a/Modules/Listing/Models/Listing.php
+++ b/Modules/Listing/Models/Listing.php
@@ -5,6 +5,7 @@ use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
@@ -90,6 +91,19 @@ class Listing extends Model implements HasMedia
return $query->where('status', 'active');
}
+ public function scopeOwnedByUser(Builder $query, int | string | null $userId): Builder
+ {
+ return $query->where('user_id', $userId);
+ }
+
+ public function scopeForPanelStatus(Builder $query, string $status): Builder
+ {
+ return match ($status) {
+ 'sold', 'expired', 'pending', 'active' => $query->where('status', $status),
+ default => $query,
+ };
+ }
+
public function scopeSearchTerm(Builder $query, string $search): Builder
{
$search = trim($search);
@@ -206,6 +220,73 @@ class Listing extends Model implements HasMedia
return $primary->concat($fallback)->values();
}
+ public static function panelStatusOptions(): array
+ {
+ return [
+ 'pending' => 'Pending',
+ 'active' => 'Active',
+ 'sold' => 'Sold',
+ 'expired' => 'Expired',
+ ];
+ }
+
+ public static function panelStatusCountsForUser(int | string $userId): array
+ {
+ $counts = static::query()
+ ->ownedByUser($userId)
+ ->selectRaw('status, COUNT(*) as aggregate')
+ ->groupBy('status')
+ ->pluck('aggregate', 'status');
+
+ return [
+ 'all' => (int) $counts->sum(),
+ 'sold' => (int) ($counts['sold'] ?? 0),
+ 'expired' => (int) ($counts['expired'] ?? 0),
+ ];
+ }
+
+ public function statusValue(): string
+ {
+ return $this->status instanceof ListingStatus
+ ? $this->status->getValue()
+ : (string) $this->status;
+ }
+
+ public function statusLabel(): string
+ {
+ return match ($this->statusValue()) {
+ 'sold' => 'Sold',
+ 'expired' => 'Expired',
+ 'pending' => 'Pending',
+ default => 'Active',
+ };
+ }
+
+ public function updateFromPanel(array $attributes): void
+ {
+ $payload = Arr::only($attributes, [
+ 'title',
+ 'description',
+ 'price',
+ 'status',
+ 'contact_phone',
+ 'contact_email',
+ 'country',
+ 'city',
+ 'expires_at',
+ ]);
+
+ if (array_key_exists('currency', $attributes)) {
+ $payload['currency'] = ListingPanelHelper::normalizeCurrency($attributes['currency']);
+ }
+
+ if (array_key_exists('custom_fields', $attributes)) {
+ $payload['custom_fields'] = $attributes['custom_fields'];
+ }
+
+ $this->forceFill($payload)->save();
+ }
+
public static function createFromFrontend(array $data, null | int | string $userId): self
{
$baseSlug = Str::slug((string) ($data['title'] ?? 'listing'));
diff --git a/Modules/Listing/resources/views/index.blade.php b/Modules/Listing/resources/views/index.blade.php
index bf13efa86..b744e299c 100644
--- a/Modules/Listing/resources/views/index.blade.php
+++ b/Modules/Listing/resources/views/index.blade.php
@@ -1,7 +1,8 @@
@extends('app::layouts.app')
@section('content')
@php
- $totalListings = isset($allListingsTotal) ? (int) $allListingsTotal : (int) $listings->total();
+ $allListingsCount = isset($allListingsTotal) ? (int) $allListingsTotal : (int) $listings->total();
+ $resultListingsCount = isset($filteredListingsTotal) ? (int) $filteredListingsTotal : (int) $listings->total();
$activeCategoryName = $selectedCategory?->name ? trim((string) $selectedCategory->name) : '';
$pageTitle = $activeCategoryName !== ''
? 'İkinci El '.$activeCategoryName.' İlanları ve Fiyatları'
@@ -38,7 +39,7 @@
@endphp
Tüm İlanlar
- {{ number_format($totalListings, 0, ',', '.') }}
+ {{ number_format($allListingsCount, 0, ',', '.') }}
@foreach($categories as $category)
@@ -161,7 +162,7 @@
{{ $activeCategoryName !== '' ? 'İkinci El '.$activeCategoryName.' kategorisinde' : 'İkinci El Araba kategorisinde' }}
- {{ number_format($totalListings, 0, ',', '.') }}
+ {{ number_format($resultListingsCount, 0, ',', '.') }}
ilan bulundu
diff --git a/Modules/Listing/resources/views/themes/default/index.blade.php b/Modules/Listing/resources/views/themes/default/index.blade.php
index bf13efa86..b744e299c 100644
--- a/Modules/Listing/resources/views/themes/default/index.blade.php
+++ b/Modules/Listing/resources/views/themes/default/index.blade.php
@@ -1,7 +1,8 @@
@extends('app::layouts.app')
@section('content')
@php
- $totalListings = isset($allListingsTotal) ? (int) $allListingsTotal : (int) $listings->total();
+ $allListingsCount = isset($allListingsTotal) ? (int) $allListingsTotal : (int) $listings->total();
+ $resultListingsCount = isset($filteredListingsTotal) ? (int) $filteredListingsTotal : (int) $listings->total();
$activeCategoryName = $selectedCategory?->name ? trim((string) $selectedCategory->name) : '';
$pageTitle = $activeCategoryName !== ''
? 'İkinci El '.$activeCategoryName.' İlanları ve Fiyatları'
@@ -38,7 +39,7 @@
@endphp
Tüm İlanlar
- {{ number_format($totalListings, 0, ',', '.') }}
+ {{ number_format($allListingsCount, 0, ',', '.') }}
@foreach($categories as $category)
@@ -161,7 +162,7 @@
{{ $activeCategoryName !== '' ? 'İkinci El '.$activeCategoryName.' kategorisinde' : 'İkinci El Araba kategorisinde' }}
- {{ number_format($totalListings, 0, ',', '.') }}
+ {{ number_format($resultListingsCount, 0, ',', '.') }}
ilan bulundu
diff --git a/Modules/Listing/resources/views/themes/otoplus/index.blade.php b/Modules/Listing/resources/views/themes/otoplus/index.blade.php
index bf13efa86..b744e299c 100644
--- a/Modules/Listing/resources/views/themes/otoplus/index.blade.php
+++ b/Modules/Listing/resources/views/themes/otoplus/index.blade.php
@@ -1,7 +1,8 @@
@extends('app::layouts.app')
@section('content')
@php
- $totalListings = isset($allListingsTotal) ? (int) $allListingsTotal : (int) $listings->total();
+ $allListingsCount = isset($allListingsTotal) ? (int) $allListingsTotal : (int) $listings->total();
+ $resultListingsCount = isset($filteredListingsTotal) ? (int) $filteredListingsTotal : (int) $listings->total();
$activeCategoryName = $selectedCategory?->name ? trim((string) $selectedCategory->name) : '';
$pageTitle = $activeCategoryName !== ''
? 'İkinci El '.$activeCategoryName.' İlanları ve Fiyatları'
@@ -38,7 +39,7 @@
@endphp
Tüm İlanlar
- {{ number_format($totalListings, 0, ',', '.') }}
+ {{ number_format($allListingsCount, 0, ',', '.') }}
@foreach($categories as $category)
@@ -161,7 +162,7 @@
{{ $activeCategoryName !== '' ? 'İkinci El '.$activeCategoryName.' kategorisinde' : 'İkinci El Araba kategorisinde' }}
- {{ number_format($totalListings, 0, ',', '.') }}
+ {{ number_format($resultListingsCount, 0, ',', '.') }}
ilan bulundu
diff --git a/Modules/Listing/resources/views/themes/otoplus/show.blade.php b/Modules/Listing/resources/views/themes/otoplus/show.blade.php
index ad9414ef3..b99422819 100644
--- a/Modules/Listing/resources/views/themes/otoplus/show.blade.php
+++ b/Modules/Listing/resources/views/themes/otoplus/show.blade.php
@@ -3,70 +3,149 @@
@section('content')
@php
$title = trim((string) ($listing->title ?? ''));
- $displayTitle = $title !== '' ? $title : 'İlan başlığı yok';
+ $displayTitle = $title !== '' ? $title : 'Untitled listing';
- $priceLabel = 'Fiyat sorunuz';
+ $priceLabel = 'Price on request';
if (! is_null($listing->price)) {
$priceValue = (float) $listing->price;
+ $formattedPrice = number_format($priceValue, 2, '.', ',');
+ $formattedPrice = rtrim(rtrim($formattedPrice, '0'), '.');
$priceLabel = $priceValue > 0
- ? number_format($priceValue, 0, ',', '.').' '.($listing->currency ?: 'TL')
- : 'Ücretsiz';
+ ? $formattedPrice.' '.($listing->currency ?: 'TRY')
+ : 'Free';
}
$locationLabel = collect([$listing->city, $listing->country])
->filter(fn ($value) => is_string($value) && trim($value) !== '')
->implode(', ');
- $publishedAt = $listing->created_at?->format('d M Y');
- $galleryImages = collect($gallery ?? [])->values()->all();
+ $publishedAt = $listing->created_at?->format('M j, Y') ?? 'Recently';
+ $postedAgo = $listing->created_at?->diffForHumans() ?? 'Listed recently';
+ $galleryImages = collect($gallery ?? [])
+ ->filter(fn ($value) => is_string($value) && trim($value) !== '')
+ ->values()
+ ->all();
$initialGalleryImage = $galleryImages[0] ?? null;
+ $galleryCount = count($galleryImages);
- $sellerName = trim((string) ($listing->user?->name ?? 'Satıcı'));
- $sellerInitial = strtoupper(substr($sellerName, 0, 1));
+ $description = trim((string) ($listing->description ?? ''));
+ $displayDescription = $description !== '' ? $description : 'No description added for this listing.';
+
+ $sellerName = trim((string) ($listing->user?->name ?? 'Marketplace Seller'));
+ $sellerInitial = mb_strtoupper(mb_substr($sellerName, 0, 1));
$sellerMemberText = $listing->user?->created_at
- ? $listing->user->created_at->format('M Y').' tarihinden beri üye'
- : 'Yeni üye';
+ ? 'Member since '.$listing->user->created_at->format('M Y')
+ : 'New seller';
+
+ $canContactSeller = $listing->user && (! auth()->check() || (int) auth()->id() !== (int) $listing->user_id);
+ $isOwnListing = auth()->check() && (int) auth()->id() === (int) $listing->user_id;
+
+ $primaryContactHref = null;
+ $primaryContactLabel = 'Call';
+ if (filled($listing->contact_phone)) {
+ $primaryContactHref = 'tel:'.preg_replace('/\s+/', '', (string) $listing->contact_phone);
+ $primaryContactLabel = 'Call';
+ } elseif (filled($listing->contact_email)) {
+ $primaryContactHref = 'mailto:'.$listing->contact_email;
+ $primaryContactLabel = 'Email';
+ }
+
+ $mapQuery = filled($listing->latitude) && filled($listing->longitude)
+ ? trim((string) $listing->latitude).','.trim((string) $listing->longitude)
+ : $locationLabel;
+ $mapUrl = $mapQuery !== ''
+ ? 'https://www.google.com/maps/search/?api=1&query='.urlencode($mapQuery)
+ : null;
+
+ $reportEmail = config('mail.from.address', 'support@example.com');
+ $reportUrl = 'mailto:'.$reportEmail.'?subject='.rawurlencode('Report listing #'.$listing->getKey());
+
+ $overviewItems = collect([
+ ['label' => 'Listing ID', 'value' => '#'.$listing->getKey()],
+ ['label' => 'Category', 'value' => $listing->category?->name ?? 'General'],
+ ['label' => 'Location', 'value' => $locationLabel !== '' ? $locationLabel : 'Not specified'],
+ ['label' => 'Published', 'value' => $publishedAt],
+ ])
+ ->filter(fn (array $item) => trim((string) $item['value']) !== '')
+ ->values();
+
+ $detailItems = collect($presentableCustomFields ?? [])
+ ->map(fn (array $field) => [
+ 'label' => trim((string) ($field['label'] ?? '')),
+ 'value' => trim((string) ($field['value'] ?? '')),
+ ])
+ ->filter(fn (array $field) => $field['label'] !== '' && $field['value'] !== '')
+ ->values();
+
+ if ($detailItems->isEmpty()) {
+ $detailItems = $overviewItems;
+ }
@endphp
-