diff --git a/Modules/Admin/Filament/Pages/ManageGeneralSettings.php b/Modules/Admin/Filament/Pages/ManageGeneralSettings.php
index 85acc0d70..56992c914 100644
--- a/Modules/Admin/Filament/Pages/ManageGeneralSettings.php
+++ b/Modules/Admin/Filament/Pages/ManageGeneralSettings.php
@@ -97,29 +97,29 @@ class ManageGeneralSettings extends SettingsPage
return $schema
->components([
TextInput::make('site_name')
- ->label('Site Adı')
+ ->label('Site Name')
->default($defaults['site_name'])
->required()
->maxLength(255),
Textarea::make('site_description')
- ->label('Site Açıklaması')
+ ->label('Site Description')
->default($defaults['site_description'])
->rows(3)
->maxLength(500),
Select::make('media_disk')
- ->label('Medya Depolama')
+ ->label('Media Storage')
->options(MediaStorage::options())
->default($defaults['media_disk'])
->required()
->native(false)
- ->helperText('İlan resimleri, videolar, logo ve slide görselleri için kullanılacak depolama sürücüsü.'),
+ ->helperText('Storage driver used for listing images, videos, the site logo, and home slide visuals.'),
HomeSlideFormSchema::make(
$defaults['home_slides'],
fn ($state): array => $this->normalizeHomeSlides($state, MediaStorage::activeDisk()),
),
Hidden::make('site_logo_disk'),
FileUpload::make('site_logo')
- ->label('Site Logosu')
+ ->label('Site Logo')
->image()
->disk(fn (Get $get): string => MediaStorage::storedDisk($get('site_logo_disk'), $get('media_disk')))
->directory('settings')
@@ -133,32 +133,32 @@ class ManageGeneralSettings extends SettingsPage
);
}),
TextInput::make('sender_name')
- ->label('Gönderici Adı')
+ ->label('Sender Name')
->default($defaults['sender_name'])
->required()
->maxLength(120),
TextInput::make('sender_email')
- ->label('Gönderici E-postası')
+ ->label('Sender Email')
->email()
->default($defaults['sender_email'])
->required()
->maxLength(255),
Select::make('default_language')
- ->label('Varsayılan Dil')
+ ->label('Default Language')
->options($this->localeOptions())
->default($defaults['default_language'])
->required()
->searchable(),
CountryCodeSelect::make('default_country_code')
- ->label('Varsayılan Ülke')
+ ->label('Default Country')
->default($defaults['default_country_code'])
->required()
- ->helperText('Panel formlarında varsayılan ülke olarak kullanılır.'),
+ ->helperText('Used as the default country in panel forms.'),
TagsInput::make('currencies')
- ->label('Para Birimleri')
+ ->label('Currencies')
->placeholder('TRY')
->default($defaults['currencies'])
- ->helperText('TRY, USD, EUR gibi 3 harfli para birimi kodları ekleyin.')
+ ->helperText('Add 3-letter currency codes such as TRY, USD, or EUR.')
->required()
->rules(['array', 'min:1'])
->afterStateHydrated(fn (TagsInput $component, $state) => $component->state($this->normalizeCurrencies($state)))
@@ -181,19 +181,19 @@ class ManageGeneralSettings extends SettingsPage
->default($defaults['whatsapp'])
->nullable()
->formatAsYouType()
- ->helperText('Uluslararası format kullanın. Örnek: +905551112233'),
+ ->helperText('Use international format. Example: +905551112233'),
Toggle::make('enable_google_maps')
- ->label('Google Maps Aktif')
+ ->label('Google Maps Enabled')
->default($defaults['enable_google_maps']),
TextInput::make('google_maps_api_key')
- ->label('Google Maps API Anahtarı')
+ ->label('Google Maps API Key')
->password()
->revealable()
->nullable()
->maxLength(255)
- ->helperText('İlan formlarındaki harita alanlarını açmak için gereklidir.'),
+ ->helperText('Required to enable map fields in listing forms.'),
Toggle::make('enable_google_login')
- ->label('Google ile Giriş Aktif')
+ ->label('Google Login Enabled')
->default($defaults['enable_google_login']),
TextInput::make('google_client_id')
->label('Google Client ID')
@@ -206,7 +206,7 @@ class ManageGeneralSettings extends SettingsPage
->nullable()
->maxLength(255),
Toggle::make('enable_facebook_login')
- ->label('Facebook ile Giriş Aktif')
+ ->label('Facebook Login Enabled')
->default($defaults['enable_facebook_login']),
TextInput::make('facebook_client_id')
->label('Facebook Client ID')
@@ -219,7 +219,7 @@ class ManageGeneralSettings extends SettingsPage
->nullable()
->maxLength(255),
Toggle::make('enable_apple_login')
- ->label('Apple ile Giriş Aktif')
+ ->label('Apple Login Enabled')
->default($defaults['enable_apple_login']),
TextInput::make('apple_client_id')
->label('Apple Client ID')
@@ -241,13 +241,13 @@ class ManageGeneralSettings extends SettingsPage
return [
'site_name' => $siteName,
- 'site_description' => 'Alim satim icin hizli ve guvenli ilan platformu.',
+ 'site_description' => 'A fast and secure marketplace for buying and selling.',
'media_disk' => MediaStorage::defaultDriver(),
'home_slides' => $this->defaultHomeSlides(),
'site_logo_disk' => null,
'sender_name' => $siteName,
'sender_email' => (string) config('mail.from.address', 'info@' . $siteHost),
- 'default_language' => in_array(config('app.locale'), array_keys($this->localeOptions()), true) ? (string) config('app.locale') : 'tr',
+ 'default_language' => in_array(config('app.locale'), array_keys($this->localeOptions()), true) ? (string) config('app.locale') : 'en',
'default_country_code' => CountryCodeManager::normalizeCountryCode(config('app.default_country_code', '+90')),
'currencies' => $this->normalizeCurrencies(config('app.currencies', ['TRY'])),
'linkedin_url' => 'https://www.linkedin.com/company/openclassify',
@@ -264,7 +264,7 @@ class ManageGeneralSettings extends SettingsPage
{
$labels = [
'en' => 'English',
- 'tr' => 'Türkçe',
+ 'tr' => 'Turkish',
];
return collect(config('app.available_locales', ['en']))
diff --git a/Modules/Category/routes/web.php b/Modules/Category/routes/web.php
index 760490fc6..5ce9962d6 100644
--- a/Modules/Category/routes/web.php
+++ b/Modules/Category/routes/web.php
@@ -2,6 +2,8 @@
use Illuminate\Support\Facades\Route;
use Modules\Category\Http\Controllers\CategoryController;
-Route::prefix('categories')->name('categories.')->group(function () {
- Route::get('/', [CategoryController::class, 'index'])->name('index');
+Route::middleware('web')->group(function () {
+ Route::prefix('categories')->name('categories.')->group(function () {
+ Route::get('/', [CategoryController::class, 'index'])->name('index');
+ });
});
diff --git a/Modules/Conversation/App/Http/Controllers/ConversationController.php b/Modules/Conversation/App/Http/Controllers/ConversationController.php
index 0b8150e83..d11e548f4 100644
--- a/Modules/Conversation/App/Http/Controllers/ConversationController.php
+++ b/Modules/Conversation/App/Http/Controllers/ConversationController.php
@@ -3,11 +3,13 @@
namespace Modules\Conversation\App\Http\Controllers;
use App\Http\Controllers\Controller;
+use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
use Illuminate\View\View;
use Modules\Conversation\App\Models\Conversation;
+use Modules\Conversation\App\Models\ConversationMessage;
use Modules\Conversation\App\Support\QuickMessageCatalog;
use Modules\Listing\Models\Listing;
use Throwable;
@@ -56,28 +58,45 @@ class ConversationController extends Controller
]);
}
- public function start(Request $request, Listing $listing): RedirectResponse
+ public function start(Request $request, Listing $listing): RedirectResponse | JsonResponse
{
if (! $this->messagingTablesReady()) {
- return back()->with('error', 'Mesajlaşma altyapısı henüz hazır değil.');
+ if ($request->expectsJson()) {
+ return response()->json(['message' => 'Messaging is not available yet.'], 503);
+ }
+
+ return back()->with('error', 'Messaging is not available yet.');
}
$user = $request->user();
if (! $listing->user_id) {
- return back()->with('error', 'Bu ilan için mesajlaşma açılamadı.');
+ if ($request->expectsJson()) {
+ return response()->json(['message' => 'A conversation cannot be started for this listing.'], 422);
+ }
+
+ return back()->with('error', 'A conversation cannot be started for this listing.');
}
if ((int) $listing->user_id === (int) $user->getKey()) {
- return back()->with('error', 'Kendi ilanına mesaj gönderemezsin.');
+ if ($request->expectsJson()) {
+ return response()->json(['message' => 'You cannot message your own listing.'], 422);
+ }
+
+ return back()->with('error', 'You cannot message your own listing.');
+ }
+
+ $messageBody = trim((string) $request->string('message'));
+
+ if ($request->expectsJson() && $messageBody === '') {
+ return response()->json(['message' => 'Message cannot be empty.'], 422);
}
$conversation = Conversation::openForListingBuyer($listing, (int) $user->getKey());
$user->favoriteListings()->syncWithoutDetaching([$listing->getKey()]);
- $messageBody = trim((string) $request->string('message'));
-
+ $message = null;
if ($messageBody !== '') {
$message = $conversation->messages()->create([
'sender_id' => $user->getKey(),
@@ -87,15 +106,23 @@ class ConversationController extends Controller
$conversation->forceFill(['last_message_at' => $message->created_at])->save();
}
+ if ($request->expectsJson()) {
+ return $this->conversationJsonResponse($conversation, $message, (int) $user->getKey());
+ }
+
return redirect()
->route('panel.inbox.index', array_merge($this->inboxFilters($request), ['conversation' => $conversation->getKey()]))
- ->with('success', $messageBody !== '' ? 'Mesaj gönderildi.' : 'Sohbet açıldı.');
+ ->with('success', $messageBody !== '' ? 'Message sent.' : 'Conversation started.');
}
- public function send(Request $request, Conversation $conversation): RedirectResponse
+ public function send(Request $request, Conversation $conversation): RedirectResponse | JsonResponse
{
if (! $this->messagingTablesReady()) {
- return back()->with('error', 'Mesajlaşma altyapısı henüz hazır değil.');
+ if ($request->expectsJson()) {
+ return response()->json(['message' => 'Messaging is not available yet.'], 503);
+ }
+
+ return back()->with('error', 'Messaging is not available yet.');
}
$user = $request->user();
@@ -112,7 +139,11 @@ class ConversationController extends Controller
$messageBody = trim($payload['message']);
if ($messageBody === '') {
- return back()->with('error', 'Mesaj boş olamaz.');
+ if ($request->expectsJson()) {
+ return response()->json(['message' => 'Message cannot be empty.'], 422);
+ }
+
+ return back()->with('error', 'Message cannot be empty.');
}
$message = $conversation->messages()->create([
@@ -122,9 +153,32 @@ class ConversationController extends Controller
$conversation->forceFill(['last_message_at' => $message->created_at])->save();
+ if ($request->expectsJson()) {
+ return $this->conversationJsonResponse($conversation, $message, $userId);
+ }
+
return redirect()
->route('panel.inbox.index', array_merge($this->inboxFilters($request), ['conversation' => $conversation->getKey()]))
- ->with('success', 'Mesaj gönderildi.');
+ ->with('success', 'Message sent.');
+ }
+
+ private function conversationJsonResponse(Conversation $conversation, ?ConversationMessage $message, int $userId): JsonResponse
+ {
+ return response()->json([
+ 'conversation_id' => (int) $conversation->getKey(),
+ 'send_url' => route('conversations.messages.send', $conversation),
+ 'message' => $message ? $this->messagePayload($message, $userId) : null,
+ ]);
+ }
+
+ private function messagePayload(ConversationMessage $message, int $userId): array
+ {
+ return [
+ 'id' => (int) $message->getKey(),
+ 'body' => (string) $message->body,
+ 'time' => $message->created_at?->format('H:i') ?? now()->format('H:i'),
+ 'is_mine' => (int) $message->sender_id === $userId,
+ ];
}
private function inboxFilters(Request $request): array
diff --git a/Modules/Conversation/App/Support/QuickMessageCatalog.php b/Modules/Conversation/App/Support/QuickMessageCatalog.php
index 7792a705d..2680437a7 100644
--- a/Modules/Conversation/App/Support/QuickMessageCatalog.php
+++ b/Modules/Conversation/App/Support/QuickMessageCatalog.php
@@ -7,10 +7,10 @@ class QuickMessageCatalog
public static function all(): array
{
return [
- 'Merhaba',
- 'İlan hâlâ satışta mı?',
- 'Son fiyat nedir?',
- 'Teşekkürler',
+ 'Hi',
+ 'Is this listing still available?',
+ 'What is your best price?',
+ 'Thanks',
];
}
}
diff --git a/Modules/Conversation/resources/views/inbox.blade.php b/Modules/Conversation/resources/views/inbox.blade.php
index edf96e25c..d40c0d5ad 100644
--- a/Modules/Conversation/resources/views/inbox.blade.php
+++ b/Modules/Conversation/resources/views/inbox.blade.php
@@ -1,44 +1,44 @@
@extends('app::layouts.app')
-@section('title', 'Gelen Kutusu')
+@section('title', 'Inbox')
@section('content')
@include('panel.partials.sidebar', ['activeMenu' => 'inbox'])
-
+
+ @include('panel.partials.page-header', [
+ 'title' => 'Inbox',
+ 'description' => 'Read and reply to buyer messages from the same panel shell used across the site.',
+ 'actions' => $requiresLogin ?? false
+ ? new \Illuminate\Support\HtmlString('Log in ')
+ : null,
+ ])
+
+
@if($requiresLogin ?? false)
-
+
Inbox
-
Stay on this page and log in when you want to access your conversations.
+
Stay on this page and log in when you want to access your conversations.
-
- Log in
-
@endif
-
-
Hızlı Filtreler
+
Filters
@@ -57,17 +57,17 @@
@if($conversationImage)
@else
-
İlan
+
Listing
@endif
-
{{ $partner?->name ?? 'Kullanıcı' }}
+
{{ $partner?->name ?? 'User' }}
{{ $conversation->last_message_at?->format('d.m.Y') }}
-
{{ $conversationListing?->title ?? 'İlan silinmiş' }}
+
{{ $conversationListing?->title ?? 'Listing removed' }}
- {{ $lastMessage !== '' ? $lastMessage : 'Henüz mesaj yok' }}
+ {{ $lastMessage !== '' ? $lastMessage : 'No messages yet' }}
@if($conversation->unread_count > 0)
@@ -79,7 +79,7 @@
@empty
- Henüz bir sohbetin yok.
+ No conversations yet.
@endforelse
@@ -101,8 +101,8 @@
{{ strtoupper(substr((string) ($activePartner?->name ?? 'K'), 0, 1)) }}
-
{{ $activePartner?->name ?? 'Kullanıcı' }}
-
{{ $activeListing?->title ?? 'İlan silinmiş' }}
+
{{ $activePartner?->name ?? 'User' }}
+
{{ $activeListing?->title ?? 'Listing removed' }}
@if($activePriceLabel)
{{ $activePriceLabel }}
@@ -125,8 +125,8 @@
@empty
-
Henüz mesaj yok.
-
Aşağıdaki hazır metinlerden birini seçebilir veya yeni mesaj yazabilirsin.
+
No messages yet.
+
Use a quick reply or send the first message below.
@endforelse
@@ -148,8 +148,8 @@
+
diff --git a/Modules/Conversation/routes/web.php b/Modules/Conversation/routes/web.php
index 7b1bc3a23..b5acdfb42 100644
--- a/Modules/Conversation/routes/web.php
+++ b/Modules/Conversation/routes/web.php
@@ -3,11 +3,13 @@
use Illuminate\Support\Facades\Route;
use Modules\Conversation\App\Http\Controllers\ConversationController;
-Route::prefix('panel')->name('panel.')->group(function () {
- Route::get('/inbox', [ConversationController::class, 'inbox'])->name('inbox.index');
-});
+Route::middleware('web')->group(function () {
+ Route::prefix('panel')->name('panel.')->group(function () {
+ Route::get('/inbox', [ConversationController::class, 'inbox'])->name('inbox.index');
+ });
-Route::middleware('auth')->name('conversations.')->group(function () {
- Route::post('/listings/{listing}/conversation', [ConversationController::class, 'start'])->name('start');
- Route::post('/conversations/{conversation}/messages', [ConversationController::class, 'send'])->name('messages.send');
+ Route::middleware('auth')->name('conversations.')->group(function () {
+ Route::post('/listings/{listing}/conversation', [ConversationController::class, 'start'])->name('start');
+ Route::post('/conversations/{conversation}/messages', [ConversationController::class, 'send'])->name('messages.send');
+ });
});
diff --git a/Modules/Favorite/App/Http/Controllers/FavoriteController.php b/Modules/Favorite/App/Http/Controllers/FavoriteController.php
index e140cc3e2..1bae61310 100644
--- a/Modules/Favorite/App/Http/Controllers/FavoriteController.php
+++ b/Modules/Favorite/App/Http/Controllers/FavoriteController.php
@@ -11,10 +11,15 @@ use Modules\Conversation\App\Models\Conversation;
use Modules\Favorite\App\Models\FavoriteSearch;
use Modules\Listing\Models\Listing;
use Modules\User\App\Models\User;
+use Modules\User\App\Support\AuthRedirector;
use Throwable;
class FavoriteController extends Controller
{
+ public function __construct(private AuthRedirector $redirector)
+ {
+ }
+
public function index(Request $request)
{
$activeTab = (string) $request->string('tab', 'listings');
@@ -126,7 +131,7 @@ class FavoriteController extends Controller
{
$isNowFavorite = $request->user()->toggleFavoriteListing($listing);
- return back()->with('success', $isNowFavorite ? 'İlan favorilere eklendi.' : 'İlan favorilerden kaldırıldı.');
+ return $this->redirectBack($request)->with('success', $isNowFavorite ? 'Listing added to favorites.' : 'Listing removed from favorites.');
}
public function toggleSeller(Request $request, User $seller)
@@ -134,12 +139,12 @@ class FavoriteController extends Controller
$user = $request->user();
if ((int) $user->getKey() === (int) $seller->getKey()) {
- return back()->with('error', 'Kendi hesabını favorilere ekleyemezsin.');
+ return $this->redirectBack($request)->with('error', 'You cannot favorite your own account.');
}
$isNowFavorite = $user->toggleFavoriteSeller($seller);
- return back()->with('success', $isNowFavorite ? 'Satıcı favorilere eklendi.' : 'Satıcı favorilerden kaldırıldı.');
+ return $this->redirectBack($request)->with('success', $isNowFavorite ? 'Seller added to favorites.' : 'Seller removed from favorites.');
}
public function storeSearch(Request $request)
@@ -155,7 +160,7 @@ class FavoriteController extends Controller
]);
if ($filters === []) {
- return back()->with('error', 'Favoriye eklemek için en az bir filtre seçmelisin.');
+ return back()->with('error', 'Select at least one filter before saving a search.');
}
$signature = FavoriteSearch::signatureFor($filters);
@@ -178,10 +183,10 @@ class FavoriteController extends Controller
);
if (! $favoriteSearch->wasRecentlyCreated) {
- return back()->with('success', 'Bu arama zaten favorilerinde.');
+ return back()->with('success', 'This search is already in your favorites.');
}
- return back()->with('success', 'Arama favorilere eklendi.');
+ return back()->with('success', 'Search added to favorites.');
}
public function destroySearch(Request $request, FavoriteSearch $favoriteSearch)
@@ -192,7 +197,7 @@ class FavoriteController extends Controller
$favoriteSearch->delete();
- return back()->with('success', 'Favori arama silindi.');
+ return back()->with('success', 'Saved search deleted.');
}
private function tableExists(string $table): bool
@@ -211,4 +216,15 @@ class FavoriteController extends Controller
'query' => request()->query(),
]);
}
+
+ private function redirectBack(Request $request): \Illuminate\Http\RedirectResponse
+ {
+ $target = $this->redirector->sanitize((string) $request->input('redirect_to', ''));
+
+ if ($target !== null) {
+ return redirect()->to($target);
+ }
+
+ return back();
+ }
}
diff --git a/Modules/Favorite/App/Models/FavoriteSearch.php b/Modules/Favorite/App/Models/FavoriteSearch.php
index 07130acc1..c424eb1a2 100644
--- a/Modules/Favorite/App/Models/FavoriteSearch.php
+++ b/Modules/Favorite/App/Models/FavoriteSearch.php
@@ -51,6 +51,6 @@ class FavoriteSearch extends Model
$labelParts[] = $categoryName;
}
- return $labelParts !== [] ? implode(' · ', $labelParts) : 'Filtreli arama';
+ return $labelParts !== [] ? implode(' · ', $labelParts) : 'Filtered search';
}
}
diff --git a/Modules/Favorite/resources/views/index.blade.php b/Modules/Favorite/resources/views/index.blade.php
index 63b3a2ce6..ab5fa414e 100644
--- a/Modules/Favorite/resources/views/index.blade.php
+++ b/Modules/Favorite/resources/views/index.blade.php
@@ -1,6 +1,6 @@
@extends('app::layouts.app')
-@section('title', 'Favoriler')
+@section('title', 'Favorites')
@section('content')
@@ -29,25 +29,25 @@
], fn ($value) => !is_null($value) && $value !== '');
@endphp
-
Favori Listem
+
Saved Listings
@@ -55,9 +55,9 @@
- İlan Başlığı
- Fiyat
- Mesajlaşma
+ Listing
+ Price
+ Messaging
@@ -65,7 +65,7 @@
@forelse($favoriteListings as $listing)
@php
$listingImage = $listing->getFirstMediaUrl('listing-images');
- $priceLabel = $listing->price ? number_format((float) $listing->price, 0).' '.$listing->currency : 'Ücretsiz';
+ $priceLabel = $listing->price ? number_format((float) $listing->price, 0).' '.$listing->currency : 'Free';
$meta = collect([
$listing->category?->name,
$listing->city,
@@ -82,15 +82,15 @@
@if($listingImage)
@else
- Görsel yok
+ No image
@endif
{{ $listing->title }}
-
{{ $meta !== '' ? $meta : 'Kategori / konum bilgisi yok' }}
-
Favoriye eklenme: {{ $listing->pivot->created_at?->format('d.m.Y') }}
+
{{ $meta !== '' ? $meta : 'No category or location data' }}
+
Saved on: {{ $listing->pivot->created_at?->format('M j, Y') }}
@@ -99,31 +99,31 @@
@if($canMessageListing)
@if($conversationId)
- Sohbete Git
+ Open chat
@else
@endif
@else
- {{ $isOwnListing ? 'Kendi ilanın' : 'Satıcı bilgisi yok' }}
+ {{ $isOwnListing ? 'Your own listing' : 'Seller unavailable' }}
@endif
@empty
- Henüz favori ilan bulunmuyor.
+ No saved listings yet.
@endforelse
@@ -132,7 +132,7 @@
- * Son 1 yıl içinde favoriye eklediğiniz ilanlar listelenmektedir.
+ * Listings saved within the last year are shown here.
@if($favoriteListings?->hasPages())
@@ -142,8 +142,8 @@
@if($activeTab === 'searches')
-
Favori Aramalar
-
Kayıtlı aramalarına tek tıkla geri dön.
+
Saved Searches
+
Return to your saved searches with one click.
@forelse($favoriteSearches as $favoriteSearch)
@@ -155,29 +155,29 @@
@endphp
-
{{ $favoriteSearch->label ?: 'Kayıtlı arama' }}
+
{{ $favoriteSearch->label ?: 'Saved search' }}
- @if($favoriteSearch->search_term) Arama: "{{ $favoriteSearch->search_term }}" · @endif
- @if($favoriteSearch->category) Kategori: {{ $favoriteSearch->category->name }} · @endif
- Kaydedilme: {{ $favoriteSearch->created_at?->format('d.m.Y H:i') }}
+ @if($favoriteSearch->search_term) Search: "{{ $favoriteSearch->search_term }}" · @endif
+ @if($favoriteSearch->category) Category: {{ $favoriteSearch->category->name }} · @endif
+ Saved: {{ $favoriteSearch->created_at?->format('M j, Y H:i') }}
@empty
- Henüz favori arama eklenmedi.
+ No saved searches yet.
@endforelse
@@ -188,32 +188,32 @@
@if($activeTab === 'sellers')
-
Favori Satıcılar
-
Takip etmek istediğin satıcıları burada yönetebilirsin.
+
Saved Sellers
+
Manage the sellers you want to follow here.
@forelse($favoriteSellers as $seller)
-
+
@empty
- Henüz favori satıcı eklenmedi.
+ No saved sellers yet.
@endforelse
diff --git a/Modules/Favorite/routes/web.php b/Modules/Favorite/routes/web.php
index 12afcf09b..79d30bf97 100644
--- a/Modules/Favorite/routes/web.php
+++ b/Modules/Favorite/routes/web.php
@@ -3,13 +3,15 @@
use Illuminate\Support\Facades\Route;
use Modules\Favorite\App\Http\Controllers\FavoriteController;
-Route::prefix('favorites')->name('favorites.')->group(function () {
- Route::get('/', [FavoriteController::class, 'index'])->name('index');
-});
+Route::middleware('web')->group(function () {
+ Route::prefix('favorites')->name('favorites.')->group(function () {
+ Route::get('/', [FavoriteController::class, 'index'])->name('index');
+ });
-Route::middleware('auth')->prefix('favorites')->name('favorites.')->group(function () {
- Route::post('/listings/{listing}/toggle', [FavoriteController::class, 'toggleListing'])->name('listings.toggle');
- Route::post('/sellers/{seller}/toggle', [FavoriteController::class, 'toggleSeller'])->name('sellers.toggle');
- Route::post('/searches', [FavoriteController::class, 'storeSearch'])->name('searches.store');
- Route::delete('/searches/{favoriteSearch}', [FavoriteController::class, 'destroySearch'])->name('searches.destroy');
+ Route::middleware('auth')->prefix('favorites')->name('favorites.')->group(function () {
+ Route::post('/listings/{listing}/toggle', [FavoriteController::class, 'toggleListing'])->name('listings.toggle');
+ Route::post('/sellers/{seller}/toggle', [FavoriteController::class, 'toggleSeller'])->name('sellers.toggle');
+ Route::post('/searches', [FavoriteController::class, 'storeSearch'])->name('searches.store');
+ Route::delete('/searches/{favoriteSearch}', [FavoriteController::class, 'destroySearch'])->name('searches.destroy');
+ });
});
diff --git a/Modules/Listing/Database/Seeders/ListingSeeder.php b/Modules/Listing/Database/Seeders/ListingSeeder.php
index f037f9db2..ea7d84f50 100644
--- a/Modules/Listing/Database/Seeders/ListingSeeder.php
+++ b/Modules/Listing/Database/Seeders/ListingSeeder.php
@@ -25,13 +25,13 @@ class ListingSeeder extends Seeder
];
private const TITLE_PREFIXES = [
- 'Temiz kullanılmış',
- 'Az kullanılmış',
- 'Fırsat ürün',
- 'Uygun fiyatlı',
- 'Sahibinden',
- 'Kaçırılmayacak',
- 'Bakımlı',
+ 'Clean',
+ 'Lightly used',
+ 'Special offer',
+ 'Well priced',
+ 'Owner listed',
+ 'Must-see',
+ 'Well kept',
];
public function run(): void
@@ -100,7 +100,7 @@ class ListingSeeder extends Seeder
private function resolveTurkeyCities(): Collection
{
if (! class_exists(City::class) || ! Schema::hasTable('cities') || ! Schema::hasTable('countries')) {
- return collect(['İstanbul', 'Ankara', 'İzmir', 'Bursa', 'Antalya']);
+ return collect(['Istanbul', 'Ankara', 'Izmir', 'Bursa', 'Antalya']);
}
$turkey = Country::query()
@@ -108,7 +108,7 @@ class ListingSeeder extends Seeder
->first(['id']);
if (! $turkey) {
- return collect(['İstanbul', 'Ankara', 'İzmir', 'Bursa', 'Antalya']);
+ return collect(['Istanbul', 'Ankara', 'Izmir', 'Bursa', 'Antalya']);
}
$cities = City::query()
@@ -122,7 +122,7 @@ class ListingSeeder extends Seeder
return $cities->isNotEmpty()
? $cities
- : collect(['İstanbul', 'Ankara', 'İzmir', 'Bursa', 'Antalya']);
+ : collect(['Istanbul', 'Ankara', 'Izmir', 'Bursa', 'Antalya']);
}
private function buildListingData(
@@ -147,7 +147,7 @@ class ListingSeeder extends Seeder
private function resolveLocation(int $index, Collection $countries, Collection $turkeyCities): array
{
$turkeyCountry = $countries->first(fn ($country): bool => strtoupper((string) $country->code) === 'TR');
- $turkeyName = trim((string) ($turkeyCountry->name ?? 'Türkiye')) ?: 'Türkiye';
+ $turkeyName = trim((string) ($turkeyCountry->name ?? 'Turkey')) ?: 'Turkey';
$useForeignCountry = $countries->count() > 1 && $index % 4 === 0;
@@ -161,8 +161,8 @@ class ListingSeeder extends Seeder
$countryName = trim((string) ($selected->name ?? ''));
return [
- 'country' => $countryName !== '' ? $countryName : 'Türkiye',
- 'city' => $countryName !== '' ? $countryName : 'İstanbul',
+ 'country' => $countryName !== '' ? $countryName : 'Turkey',
+ 'city' => $countryName !== '' ? $countryName : 'Istanbul',
];
}
}
@@ -171,7 +171,7 @@ class ListingSeeder extends Seeder
return [
'country' => $turkeyName,
- 'city' => $city !== '' ? $city : 'İstanbul',
+ 'city' => $city !== '' ? $city : 'Istanbul',
];
}
@@ -180,7 +180,7 @@ class ListingSeeder extends Seeder
$prefix = self::TITLE_PREFIXES[$index % count(self::TITLE_PREFIXES)];
$categoryName = trim((string) $category->name);
- return sprintf('%s %s ilanı', $prefix, $categoryName !== '' ? $categoryName : 'ürün');
+ return sprintf('%s %s listing', $prefix, $categoryName !== '' ? $categoryName : 'item');
}
private function buildDescription(Category $category, string $city, string $country): string
@@ -189,9 +189,9 @@ class ListingSeeder extends Seeder
$location = trim(collect([$city, $country])->filter()->join(', '));
return sprintf(
- '%s kategorisinde, durum olarak sorunsuz ve kullanıma hazırdır. Teslimat noktası: %s. Detaylar için mesaj atabilirsiniz.',
- $categoryName !== '' ? $categoryName : 'Ürün',
- $location !== '' ? $location : 'Türkiye'
+ 'Listed in %s, in clean condition and ready to use. Pickup area: %s. Message for more details.',
+ $categoryName !== '' ? $categoryName : 'Item',
+ $location !== '' ? $location : 'Turkey'
);
}
@@ -244,7 +244,7 @@ class ListingSeeder extends Seeder
if (! is_file($imageAbsolutePath)) {
if ($this->command) {
- $this->command->warn("Gorsel bulunamadi: {$imageRelativePath}");
+ $this->command->warn("Image not found: {$imageRelativePath}");
}
return;
diff --git a/Modules/Listing/Http/Controllers/ListingController.php b/Modules/Listing/Http/Controllers/ListingController.php
index 26b45f36c..6efcc8945 100644
--- a/Modules/Listing/Http/Controllers/ListingController.php
+++ b/Modules/Listing/Http/Controllers/ListingController.php
@@ -33,6 +33,9 @@ class ListingController extends Controller
$cityId = request()->integer('city');
$cityId = $cityId > 0 ? $cityId : null;
+ $sellerUserId = request()->integer('user');
+ $sellerUserId = $sellerUserId > 0 ? $sellerUserId : null;
+
$minPriceInput = trim((string) request('min_price', ''));
$maxPriceInput = trim((string) request('max_price', ''));
$minPrice = is_numeric($minPriceInput) ? max((float) $minPriceInput, 0) : null;
@@ -70,6 +73,7 @@ class ListingController extends Controller
'search' => $search,
'country' => $selectedCountryName,
'city' => $selectedCityName,
+ 'user_id' => $sellerUserId,
'min_price' => $minPrice,
'max_price' => $maxPrice,
'date_filter' => $dateFilter,
@@ -136,6 +140,7 @@ class ListingController extends Controller
'categoryId',
'countryId',
'cityId',
+ 'sellerUserId',
'minPriceInput',
'maxPriceInput',
'dateFilter',
@@ -184,6 +189,7 @@ class ListingController extends Controller
$isListingFavorited = false;
$isSellerFavorited = false;
$existingConversationId = null;
+ $detailConversation = null;
if (auth()->check()) {
$userId = (int) auth()->id();
@@ -205,6 +211,17 @@ class ListingController extends Controller
(int) $listing->getKey(),
$userId,
);
+
+ if ($existingConversationId) {
+ $detailConversation = Conversation::query()
+ ->forUser($userId)
+ ->find($existingConversationId);
+
+ if ($detailConversation) {
+ $detailConversation->loadThread();
+ $detailConversation->markAsReadFor($userId);
+ }
+ }
}
}
@@ -214,6 +231,7 @@ class ListingController extends Controller
'isSellerFavorited',
'presentableCustomFields',
'existingConversationId',
+ 'detailConversation',
'gallery',
'listingVideos',
'relatedListings',
@@ -239,7 +257,7 @@ class ListingController extends Controller
return redirect()
->route('panel.listings.create')
- ->with('success', 'İlan oluşturma ekranına yönlendirildin.');
+ ->with('success', 'You were redirected to the listing creation screen.');
}
private function resolveLocationFilters(
diff --git a/Modules/Listing/Models/Listing.php b/Modules/Listing/Models/Listing.php
index 15a079f20..f9255a805 100644
--- a/Modules/Listing/Models/Listing.php
+++ b/Modules/Listing/Models/Listing.php
@@ -146,6 +146,7 @@ class Listing extends Model implements HasMedia
$search = trim((string) ($filters['search'] ?? ''));
$country = isset($filters['country']) ? trim((string) $filters['country']) : null;
$city = isset($filters['city']) ? trim((string) $filters['city']) : null;
+ $userId = isset($filters['user_id']) && is_numeric($filters['user_id']) ? (int) $filters['user_id'] : null;
$minPrice = is_numeric($filters['min_price'] ?? null) ? max((float) $filters['min_price'], 0) : null;
$maxPrice = is_numeric($filters['max_price'] ?? null) ? max((float) $filters['max_price'], 0) : null;
$dateFilter = (string) ($filters['date_filter'] ?? 'all');
@@ -154,6 +155,7 @@ class Listing extends Model implements HasMedia
$query
->searchTerm($search)
->forCategoryIds(is_array($categoryIds) ? $categoryIds : null)
+ ->when(! is_null($userId) && $userId > 0, fn (Builder $builder) => $builder->where('user_id', $userId))
->when($country !== null && $country !== '', fn (Builder $builder) => $builder->where('country', $country))
->when($city !== null && $city !== '', fn (Builder $builder) => $builder->where('city', $city))
->when(! is_null($minPrice), fn (Builder $builder) => $builder->whereNotNull('price')->where('price', '>=', $minPrice))
@@ -259,7 +261,7 @@ class Listing extends Model implements HasMedia
public function panelPriceLabel(): string
{
if (is_null($this->price)) {
- return 'Ücretsiz';
+ return 'Free';
}
return number_format((float) $this->price, 2, ',', '.').' '.($this->currency ?? 'TL');
@@ -269,24 +271,24 @@ class Listing extends Model implements HasMedia
{
return match ($this->statusValue()) {
'sold' => [
- 'label' => 'Satıldı',
+ 'label' => 'Sold',
'badge_class' => 'is-success',
- 'hint' => 'İlan satıldı olarak işaretlendi.',
+ 'hint' => 'This listing is marked as sold.',
],
'expired' => [
- 'label' => 'Süresi doldu',
+ 'label' => 'Expired',
'badge_class' => 'is-danger',
- 'hint' => 'Yeniden yayına alınmayı bekliyor.',
+ 'hint' => 'This listing is waiting to be republished.',
],
'pending' => [
- 'label' => 'İncelemede',
+ 'label' => 'Pending review',
'badge_class' => 'is-warning',
- 'hint' => 'Moderasyon onayı bekleniyor.',
+ 'hint' => 'Waiting for moderation approval.',
],
default => [
- 'label' => 'Yayında',
+ 'label' => 'Live',
'badge_class' => 'is-primary',
- 'hint' => 'Şu anda ziyaretçilere görünüyor.',
+ 'hint' => 'Visible to visitors right now.',
],
};
}
@@ -298,7 +300,7 @@ class Listing extends Model implements HasMedia
trim((string) $this->country),
])->filter()->values();
- return $parts->isNotEmpty() ? $parts->implode(', ') : 'Konum belirtilmedi';
+ return $parts->isNotEmpty() ? $parts->implode(', ') : 'Location not specified';
}
public function panelPublishedAt(): ?Carbon
@@ -320,16 +322,16 @@ class Listing extends Model implements HasMedia
public function panelExpirySummary(): string
{
if (! $this->expires_at) {
- return 'Süre sınırı yok';
+ return 'No expiry limit';
}
$expiresAt = $this->expires_at->copy()->startOfDay();
$days = Carbon::today()->diffInDays($expiresAt, false);
return match (true) {
- $days > 0 => $days.' gün kaldı',
- $days === 0 => 'Bugün sona eriyor',
- default => abs($days).' gün önce sona erdi',
+ $days > 0 => $days.' days left',
+ $days === 0 => 'Ends today',
+ default => 'Expired '.abs($days).' days ago',
};
}
@@ -340,8 +342,8 @@ class Listing extends Model implements HasMedia
}
return [
- 'label' => $total.' video',
- 'detail' => $ready.' hazır'.($pending > 0 ? ', '.$pending.' işleniyor' : ''),
+ 'label' => $total.' videos',
+ 'detail' => $ready.' ready'.($pending > 0 ? ', '.$pending.' processing' : ''),
];
}
diff --git a/Modules/Listing/Support/ListingCustomFieldSchemaBuilder.php b/Modules/Listing/Support/ListingCustomFieldSchemaBuilder.php
index a5ef96481..43731d971 100644
--- a/Modules/Listing/Support/ListingCustomFieldSchemaBuilder.php
+++ b/Modules/Listing/Support/ListingCustomFieldSchemaBuilder.php
@@ -66,12 +66,12 @@ class ListingCustomFieldSchemaBuilder
$label = $field?->label ?: Str::headline((string) $key);
if (is_bool($value)) {
- $displayValue = $value ? 'Evet' : 'Hayır';
+ $displayValue = $value ? 'Yes' : 'No';
} elseif (is_array($value)) {
$displayValue = implode(', ', array_map(fn ($item): string => (string) $item, $value));
} elseif ($field?->type === ListingCustomField::TYPE_DATE) {
try {
- $displayValue = Carbon::parse((string) $value)->format('d.m.Y');
+ $displayValue = Carbon::parse((string) $value)->format('M j, Y');
} catch (\Throwable) {
$displayValue = (string) $value;
}
diff --git a/Modules/Listing/resources/views/index.blade.php b/Modules/Listing/resources/views/index.blade.php
index b744e299c..561bb9a1b 100644
--- a/Modules/Listing/resources/views/index.blade.php
+++ b/Modules/Listing/resources/views/index.blade.php
@@ -1,450 +1,7 @@
@extends('app::layouts.app')
+
+@section('title', trim((string) ($selectedCategory?->name ?? '')) !== '' ? trim((string) $selectedCategory->name).' Listings and Prices' : 'All Listings and Prices')
+
@section('content')
-@php
- $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ı'
- : 'İkinci El Araba İlanları ve Fiyatları';
- $canSaveSearch = $search !== '' || ! is_null($categoryId);
- $normalizeQuery = static fn ($value): bool => ! is_null($value) && $value !== '';
- $baseCategoryQuery = array_filter([
- 'search' => $search !== '' ? $search : null,
- 'country' => $countryId,
- 'city' => $cityId,
- 'min_price' => $minPriceInput !== '' ? $minPriceInput : null,
- 'max_price' => $maxPriceInput !== '' ? $maxPriceInput : null,
- 'date_filter' => $dateFilter !== 'all' ? $dateFilter : null,
- 'sort' => $sort !== 'smart' ? $sort : null,
- ], $normalizeQuery);
- $clearFiltersQuery = array_filter([
- 'search' => $search !== '' ? $search : null,
- ], $normalizeQuery);
-@endphp
-
-
-
{{ $pageTitle }}
-
-
-
-
-
-
Kategoriler
-
-
-
- @php
- $allCategoriesLink = route('listings.index', $baseCategoryQuery);
- @endphp
-
- Tüm İlanlar
- {{ number_format($allListingsCount, 0, ',', '.') }}
-
-
- @foreach($categories as $category)
- @php
- $categoryCount = (int) $category->active_listing_total;
- $isSelectedParent = (int) $categoryId === (int) $category->id;
- $categoryUrl = route('listings.index', array_filter(array_merge($baseCategoryQuery, [
- 'category' => $category->id,
- ]), $normalizeQuery));
- @endphp
-
- {{ $category->name }}
- {{ number_format($categoryCount, 0, ',', '.') }}
-
-
- @foreach($category->children as $childCategory)
- @php
- $isSelectedChild = (int) $categoryId === (int) $childCategory->id;
- $childUrl = route('listings.index', array_filter(array_merge($baseCategoryQuery, [
- 'category' => $childCategory->id,
- ]), $normalizeQuery));
- @endphp
-
- {{ $childCategory->name }}
- {{ number_format((int) $childCategory->active_listing_total, 0, ',', '.') }}
-
- @endforeach
- @endforeach
-
-
-
-
-
-
-
-
-
- {{ $activeCategoryName !== '' ? 'İkinci El '.$activeCategoryName.' kategorisinde' : 'İkinci El Araba kategorisinde' }}
- {{ number_format($resultListingsCount, 0, ',', '.') }}
- ilan bulundu
-
-
-
-
- @if($listings->isEmpty())
-
- Bu filtreye uygun ilan bulunamadı.
-
- @else
-
- @foreach($listings as $listing)
- @php
- $listingImage = $listing->getFirstMediaUrl('listing-images');
- $isFavorited = in_array($listing->id, $favoriteListingIds ?? [], true);
- $priceValue = ! is_null($listing->price) ? (float) $listing->price : null;
- $locationParts = array_filter([
- trim((string) ($listing->city ?? '')),
- trim((string) ($listing->country ?? '')),
- ], fn ($value) => $value !== '');
- $locationText = implode(', ', $locationParts);
- @endphp
-
-
- @if($listingImage)
-
-
-
- @else
-
-
-
-
-
- @endif
-
- @if($listing->is_featured)
-
- Öne Çıkan
-
- @endif
-
-
- @auth
-
- @else
-
- ♥
-
- @endauth
-
-
-
-
-
- @endforeach
-
- @endif
-
-
- {{ $listings->links() }}
-
-
-
-
-
-
+ @include('listing::partials.index-content')
@endsection
diff --git a/Modules/Listing/resources/views/partials/index-content.blade.php b/Modules/Listing/resources/views/partials/index-content.blade.php
new file mode 100644
index 000000000..df506b651
--- /dev/null
+++ b/Modules/Listing/resources/views/partials/index-content.blade.php
@@ -0,0 +1,454 @@
+@php
+ $allListingsCount = isset($allListingsTotal) ? (int) $allListingsTotal : (int) $listings->total();
+ $resultListingsCount = isset($filteredListingsTotal) ? (int) $filteredListingsTotal : (int) $listings->total();
+ $activeCategoryName = $selectedCategory?->name ? trim((string) $selectedCategory->name) : '';
+ $seoHeading = $activeCategoryName !== ''
+ ? $activeCategoryName.' Listings and Prices'
+ : 'All Listings and Prices';
+ $canSaveSearch = $search !== '' || ! is_null($categoryId);
+ $normalizeQuery = static fn ($value): bool => ! is_null($value) && $value !== '';
+ $baseCategoryQuery = array_filter([
+ 'search' => $search !== '' ? $search : null,
+ 'user' => $sellerUserId ?? null,
+ 'country' => $countryId,
+ 'city' => $cityId,
+ 'min_price' => $minPriceInput !== '' ? $minPriceInput : null,
+ 'max_price' => $maxPriceInput !== '' ? $maxPriceInput : null,
+ 'date_filter' => $dateFilter !== 'all' ? $dateFilter : null,
+ 'sort' => $sort !== 'smart' ? $sort : null,
+ ], $normalizeQuery);
+ $clearFiltersQuery = array_filter([
+ 'search' => $search !== '' ? $search : null,
+ 'user' => $sellerUserId ?? null,
+ ], $normalizeQuery);
+@endphp
+
+
+
{{ $seoHeading }}
+
+
+
+
+
+
+
+ {{ number_format($resultListingsCount) }}
+ {{ $activeCategoryName !== '' ? ' listings found in '.$activeCategoryName : ' listings found' }}
+
+
+
+
+ @if($listings->isEmpty())
+
+ No listings match this filter.
+
+ @else
+
+ @foreach($listings as $listing)
+ @php
+ $listingImage = $listing->getFirstMediaUrl('listing-images');
+ $isFavorited = in_array($listing->id, $favoriteListingIds ?? [], true);
+ $priceValue = ! is_null($listing->price) ? (float) $listing->price : null;
+ $locationParts = array_filter([
+ trim((string) ($listing->city ?? '')),
+ trim((string) ($listing->country ?? '')),
+ ], fn ($value) => $value !== '');
+ $locationText = implode(', ', $locationParts);
+ @endphp
+
+
+ @if($listingImage)
+
+
+
+ @else
+
+
+
+
+
+ @endif
+
+ @if($listing->is_featured)
+
+ Featured
+
+ @endif
+
+
+ @auth
+
+ @else
+
+ ♥
+
+ @endauth
+
+
+
+
+
+ @endforeach
+
+ @endif
+
+
+ {{ $listings->links() }}
+
+
+
+
+
+
diff --git a/Modules/Listing/resources/views/show.blade.php b/Modules/Listing/resources/views/show.blade.php
index a219646e4..50e27b959 100644
--- a/Modules/Listing/resources/views/show.blade.php
+++ b/Modules/Listing/resources/views/show.blade.php
@@ -42,32 +42,32 @@
@if($listing->user && (int) $listing->user->id !== (int) auth()->id())
@if($existingConversationId)
- Sohbete Git
+ Open chat
@else
@endif
@endif
@else
- Giriş yap ve favorile
+ Log in to save
@endauth
@@ -79,7 +79,7 @@
@if(($presentableCustomFields ?? []) !== [])
-
İlan Özellikleri
+
Listing details
@foreach($presentableCustomFields as $field)
diff --git a/Modules/Listing/resources/views/themes/default/index.blade.php b/Modules/Listing/resources/views/themes/default/index.blade.php
index b744e299c..561bb9a1b 100644
--- a/Modules/Listing/resources/views/themes/default/index.blade.php
+++ b/Modules/Listing/resources/views/themes/default/index.blade.php
@@ -1,450 +1,7 @@
@extends('app::layouts.app')
+
+@section('title', trim((string) ($selectedCategory?->name ?? '')) !== '' ? trim((string) $selectedCategory->name).' Listings and Prices' : 'All Listings and Prices')
+
@section('content')
-@php
- $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ı'
- : 'İkinci El Araba İlanları ve Fiyatları';
- $canSaveSearch = $search !== '' || ! is_null($categoryId);
- $normalizeQuery = static fn ($value): bool => ! is_null($value) && $value !== '';
- $baseCategoryQuery = array_filter([
- 'search' => $search !== '' ? $search : null,
- 'country' => $countryId,
- 'city' => $cityId,
- 'min_price' => $minPriceInput !== '' ? $minPriceInput : null,
- 'max_price' => $maxPriceInput !== '' ? $maxPriceInput : null,
- 'date_filter' => $dateFilter !== 'all' ? $dateFilter : null,
- 'sort' => $sort !== 'smart' ? $sort : null,
- ], $normalizeQuery);
- $clearFiltersQuery = array_filter([
- 'search' => $search !== '' ? $search : null,
- ], $normalizeQuery);
-@endphp
-
-
-
{{ $pageTitle }}
-
-
-
-
-
-
Kategoriler
-
-
-
- @php
- $allCategoriesLink = route('listings.index', $baseCategoryQuery);
- @endphp
-
- Tüm İlanlar
- {{ number_format($allListingsCount, 0, ',', '.') }}
-
-
- @foreach($categories as $category)
- @php
- $categoryCount = (int) $category->active_listing_total;
- $isSelectedParent = (int) $categoryId === (int) $category->id;
- $categoryUrl = route('listings.index', array_filter(array_merge($baseCategoryQuery, [
- 'category' => $category->id,
- ]), $normalizeQuery));
- @endphp
-
- {{ $category->name }}
- {{ number_format($categoryCount, 0, ',', '.') }}
-
-
- @foreach($category->children as $childCategory)
- @php
- $isSelectedChild = (int) $categoryId === (int) $childCategory->id;
- $childUrl = route('listings.index', array_filter(array_merge($baseCategoryQuery, [
- 'category' => $childCategory->id,
- ]), $normalizeQuery));
- @endphp
-
- {{ $childCategory->name }}
- {{ number_format((int) $childCategory->active_listing_total, 0, ',', '.') }}
-
- @endforeach
- @endforeach
-
-
-
-
-
-
-
-
-
- {{ $activeCategoryName !== '' ? 'İkinci El '.$activeCategoryName.' kategorisinde' : 'İkinci El Araba kategorisinde' }}
- {{ number_format($resultListingsCount, 0, ',', '.') }}
- ilan bulundu
-
-
-
-
- @if($listings->isEmpty())
-
- Bu filtreye uygun ilan bulunamadı.
-
- @else
-
- @foreach($listings as $listing)
- @php
- $listingImage = $listing->getFirstMediaUrl('listing-images');
- $isFavorited = in_array($listing->id, $favoriteListingIds ?? [], true);
- $priceValue = ! is_null($listing->price) ? (float) $listing->price : null;
- $locationParts = array_filter([
- trim((string) ($listing->city ?? '')),
- trim((string) ($listing->country ?? '')),
- ], fn ($value) => $value !== '');
- $locationText = implode(', ', $locationParts);
- @endphp
-
-
- @if($listingImage)
-
-
-
- @else
-
-
-
-
-
- @endif
-
- @if($listing->is_featured)
-
- Öne Çıkan
-
- @endif
-
-
- @auth
-
- @else
-
- ♥
-
- @endauth
-
-
-
-
-
- @endforeach
-
- @endif
-
-
- {{ $listings->links() }}
-
-
-
-
-
-
+ @include('listing::partials.index-content')
@endsection
diff --git a/Modules/Listing/resources/views/themes/default/show.blade.php b/Modules/Listing/resources/views/themes/default/show.blade.php
index 58a27991f..244530ac1 100644
--- a/Modules/Listing/resources/views/themes/default/show.blade.php
+++ b/Modules/Listing/resources/views/themes/default/show.blade.php
@@ -42,32 +42,32 @@
@if($listing->user && (int) $listing->user->id !== (int) auth()->id())
@if($existingConversationId)
- Sohbete Git
+ Open chat
@else
@endif
@endif
@else
- Giriş yap ve favorile
+ Log in to save
@endauth
@@ -92,7 +92,7 @@
@endif
@if(($presentableCustomFields ?? []) !== [])
-
İlan Özellikleri
+
Listing details
@foreach($presentableCustomFields as $field)
diff --git a/Modules/Listing/resources/views/themes/otoplus/index.blade.php b/Modules/Listing/resources/views/themes/otoplus/index.blade.php
index b744e299c..561bb9a1b 100644
--- a/Modules/Listing/resources/views/themes/otoplus/index.blade.php
+++ b/Modules/Listing/resources/views/themes/otoplus/index.blade.php
@@ -1,450 +1,7 @@
@extends('app::layouts.app')
+
+@section('title', trim((string) ($selectedCategory?->name ?? '')) !== '' ? trim((string) $selectedCategory->name).' Listings and Prices' : 'All Listings and Prices')
+
@section('content')
-@php
- $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ı'
- : 'İkinci El Araba İlanları ve Fiyatları';
- $canSaveSearch = $search !== '' || ! is_null($categoryId);
- $normalizeQuery = static fn ($value): bool => ! is_null($value) && $value !== '';
- $baseCategoryQuery = array_filter([
- 'search' => $search !== '' ? $search : null,
- 'country' => $countryId,
- 'city' => $cityId,
- 'min_price' => $minPriceInput !== '' ? $minPriceInput : null,
- 'max_price' => $maxPriceInput !== '' ? $maxPriceInput : null,
- 'date_filter' => $dateFilter !== 'all' ? $dateFilter : null,
- 'sort' => $sort !== 'smart' ? $sort : null,
- ], $normalizeQuery);
- $clearFiltersQuery = array_filter([
- 'search' => $search !== '' ? $search : null,
- ], $normalizeQuery);
-@endphp
-
-
-
{{ $pageTitle }}
-
-
-
-
-
-
Kategoriler
-
-
-
- @php
- $allCategoriesLink = route('listings.index', $baseCategoryQuery);
- @endphp
-
- Tüm İlanlar
- {{ number_format($allListingsCount, 0, ',', '.') }}
-
-
- @foreach($categories as $category)
- @php
- $categoryCount = (int) $category->active_listing_total;
- $isSelectedParent = (int) $categoryId === (int) $category->id;
- $categoryUrl = route('listings.index', array_filter(array_merge($baseCategoryQuery, [
- 'category' => $category->id,
- ]), $normalizeQuery));
- @endphp
-
- {{ $category->name }}
- {{ number_format($categoryCount, 0, ',', '.') }}
-
-
- @foreach($category->children as $childCategory)
- @php
- $isSelectedChild = (int) $categoryId === (int) $childCategory->id;
- $childUrl = route('listings.index', array_filter(array_merge($baseCategoryQuery, [
- 'category' => $childCategory->id,
- ]), $normalizeQuery));
- @endphp
-
- {{ $childCategory->name }}
- {{ number_format((int) $childCategory->active_listing_total, 0, ',', '.') }}
-
- @endforeach
- @endforeach
-
-
-
-
-
-
-
-
-
- {{ $activeCategoryName !== '' ? 'İkinci El '.$activeCategoryName.' kategorisinde' : 'İkinci El Araba kategorisinde' }}
- {{ number_format($resultListingsCount, 0, ',', '.') }}
- ilan bulundu
-
-
-
-
- @if($listings->isEmpty())
-
- Bu filtreye uygun ilan bulunamadı.
-
- @else
-
- @foreach($listings as $listing)
- @php
- $listingImage = $listing->getFirstMediaUrl('listing-images');
- $isFavorited = in_array($listing->id, $favoriteListingIds ?? [], true);
- $priceValue = ! is_null($listing->price) ? (float) $listing->price : null;
- $locationParts = array_filter([
- trim((string) ($listing->city ?? '')),
- trim((string) ($listing->country ?? '')),
- ], fn ($value) => $value !== '');
- $locationText = implode(', ', $locationParts);
- @endphp
-
-
- @if($listingImage)
-
-
-
- @else
-
-
-
-
-
- @endif
-
- @if($listing->is_featured)
-
- Öne Çıkan
-
- @endif
-
-
- @auth
-
- @else
-
- ♥
-
- @endauth
-
-
-
-
-
- @endforeach
-
- @endif
-
-
- {{ $listings->links() }}
-
-
-
-
-
-
+ @include('listing::partials.index-content')
@endsection
diff --git a/Modules/Listing/resources/views/themes/otoplus/show.blade.php b/Modules/Listing/resources/views/themes/otoplus/show.blade.php
index 86827157b..e2930b6f2 100644
--- a/Modules/Listing/resources/views/themes/otoplus/show.blade.php
+++ b/Modules/Listing/resources/views/themes/otoplus/show.blade.php
@@ -40,6 +40,12 @@
$referenceCode = '#'.str_pad((string) $listing->getKey(), 8, '0', STR_PAD_LEFT);
$canContactSeller = $listing->user && (! auth()->check() || (int) auth()->id() !== (int) $listing->user_id);
$isOwnListing = auth()->check() && (int) auth()->id() === (int) $listing->user_id;
+ $canStartConversation = auth()->check() && $listing->user && ! $isOwnListing;
+ $loginRedirectRoute = route('login', ['redirect' => request()->fullUrl()]);
+ $chatConversation = $detailConversation ?? null;
+ $chatMessages = $chatConversation?->messages ?? collect();
+ $chatSendUrl = $chatConversation ? route('conversations.messages.send', $chatConversation) : '';
+ $chatStartUrl = route('conversations.start', $listing);
$primaryContactHref = null;
$primaryContactLabel = 'Call';
@@ -51,13 +57,6 @@
$primaryContactLabel = 'Email';
}
- $mapQuery = filled($listing->latitude) && filled($listing->longitude)
- ? trim((string) $listing->latitude).','.trim((string) $listing->longitude)
- : str_replace(' / ', ', ', $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 '.$referenceCode);
$shareUrl = route('listings.show', $listing);
@@ -358,21 +357,12 @@
@if(! $listing->user)
Unavailable
- @elseif($canContactSeller)
- @if($existingConversationId)
-
- Message
-
- @else
-
- @endif
+ @elseif($canStartConversation)
+
Message
@elseif($isOwnListing)
Your listing
@else
-
Message
+
Message
@endif
@if($primaryContactHref)
@@ -382,49 +372,21 @@
@endif
- @if(! $listing->user)
-
Unavailable
- @elseif($canContactSeller)
- @if($existingConversationId)
-
- Make offer
-
- @else
-
- @endif
+ @else
+
Save seller
+ @endauth
@elseif($isOwnListing)
-
Manage listing
- @else
-
Make offer
+
Your account
@endif
-
-
- @if($mapUrl)
-
- View map
-
- @else
-
View map
- @endif
-
- @if($listing->user && ! $isOwnListing)
- @auth
-
- @else
-
Save seller
- @endauth
- @else
-
{{ $isOwnListing ? 'Your account' : 'Save seller' }}
- @endif
-
@@ -441,21 +403,12 @@
@if(! $listing->user)
Unavailable
- @elseif($canContactSeller)
- @if($existingConversationId)
-
- Message
-
- @else
-
- @endif
+ @elseif($canStartConversation)
+
Message
@elseif($isOwnListing)
Your listing
@else
-
Message
+
Message
@endif
@if($primaryContactHref)
@@ -465,27 +418,76 @@
@endif
- @if(! $listing->user)
-
Unavailable
- @elseif($canContactSeller)
- @if($existingConversationId)
-
- Make offer
-
- @else
-
- @endif
+ @else
+
Save seller
+ @endauth
@elseif($isOwnListing)
-
Manage listing
- @else
-
Make offer
+
Your account
@endif
+ @if($canStartConversation)
+
+ @endif
+
@if(($relatedListings ?? collect())->isNotEmpty() || ($themePillCategories ?? collect())->isNotEmpty())