mirror of
https://github.com/openclassify/openclassify.git
synced 2026-04-14 11:12:09 -05:00
Konsolide et Filament V5 partner kim
This commit is contained in:
parent
40b5e0d01a
commit
3428bd3e43
@ -2,10 +2,7 @@
|
||||
namespace Modules\Listing\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Listing\Models\Listing;
|
||||
use Modules\Listing\Support\ListingPanelHelper;
|
||||
|
||||
class ListingController extends Controller
|
||||
{
|
||||
@ -24,29 +21,21 @@ class ListingController extends Controller
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view('listing::create', [
|
||||
'currencies' => ListingPanelHelper::currencyCodes(),
|
||||
]);
|
||||
if (! auth()->check()) {
|
||||
return redirect()->route('filament.partner.auth.login');
|
||||
}
|
||||
|
||||
return redirect()->route('filament.partner.resources.listings.create', ['tenant' => auth()->id()]);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
public function store()
|
||||
{
|
||||
$currencies = ListingPanelHelper::currencyCodes();
|
||||
if (! auth()->check()) {
|
||||
return redirect()->route('filament.partner.auth.login');
|
||||
}
|
||||
|
||||
$data = $request->validate([
|
||||
'title' => 'required|string|min:3|max:255',
|
||||
'description' => 'nullable|string',
|
||||
'price' => 'nullable|numeric|min:0',
|
||||
'currency' => ['nullable', 'string', 'size:3', Rule::in($currencies)],
|
||||
'city' => 'nullable|string|max:120',
|
||||
'country' => 'nullable|string|max:120',
|
||||
'category_id' => 'nullable|integer',
|
||||
'contact_email' => 'nullable|email',
|
||||
'contact_phone' => 'nullable|string',
|
||||
]);
|
||||
|
||||
$listing = Listing::createFromFrontend($data, auth()->id());
|
||||
|
||||
return redirect()->route('listings.show', $listing)->with('success', 'Listing created!');
|
||||
return redirect()
|
||||
->route('filament.partner.resources.listings.create', ['tenant' => auth()->id()])
|
||||
->with('success', 'Use the Partner Panel to create listings.');
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
@extends('app::layouts.app')
|
||||
@section('content')
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="max-w-2xl mx-auto">
|
||||
<h1 class="text-2xl font-bold mb-6">Post a New Listing</h1>
|
||||
<form method="POST" action="{{ route('listings.store') }}" class="bg-white rounded-lg shadow-md p-6 space-y-4">
|
||||
@csrf
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">Title *</label>
|
||||
<input type="text" name="title" value="{{ old('title') }}" required class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
@error('title')<p class="text-red-500 text-sm mt-1">{{ $message }}</p>@enderror
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">Description</label>
|
||||
<textarea name="description" rows="4" class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">{{ old('description') }}</textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">Price</label>
|
||||
<input type="number" name="price" value="{{ old('price') }}" step="0.01" class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
@error('price')<p class="text-red-500 text-sm mt-1">{{ $message }}</p>@enderror
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">Currency</label>
|
||||
<select name="currency" class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
@php($defaultCurrency = old('currency', $currencies[0] ?? 'USD'))
|
||||
@foreach(($currencies ?? ['USD']) as $currency)
|
||||
<option value="{{ $currency }}" @selected($defaultCurrency === $currency)>{{ $currency }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('currency')<p class="text-red-500 text-sm mt-1">{{ $message }}</p>@enderror
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">City</label>
|
||||
<input type="text" name="city" value="{{ old('city') }}" class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
@error('city')<p class="text-red-500 text-sm mt-1">{{ $message }}</p>@enderror
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">Country</label>
|
||||
<input type="text" name="country" value="{{ old('country') }}" class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
@error('country')<p class="text-red-500 text-sm mt-1">{{ $message }}</p>@enderror
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">Contact Email</label>
|
||||
<input type="email" name="contact_email" value="{{ old('contact_email') }}" class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
@error('contact_email')<p class="text-red-500 text-sm mt-1">{{ $message }}</p>@enderror
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">Contact Phone</label>
|
||||
<input type="text" name="contact_phone" value="{{ old('contact_phone') }}" class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
@error('contact_phone')<p class="text-red-500 text-sm mt-1">{{ $message }}</p>@enderror
|
||||
</div>
|
||||
<button type="submit" class="w-full bg-blue-600 text-white py-3 rounded-lg hover:bg-blue-700 transition font-medium">Post Listing</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@ -5,6 +5,6 @@ use Modules\Listing\Http\Controllers\ListingController;
|
||||
Route::middleware('web')->prefix('listings')->name('listings.')->group(function () {
|
||||
Route::get('/', [ListingController::class, 'index'])->name('index');
|
||||
Route::get('/create', [ListingController::class, 'create'])->name('create');
|
||||
Route::post('/', [ListingController::class, 'store'])->name('store')->middleware('auth');
|
||||
Route::post('/', [ListingController::class, 'store'])->name('store');
|
||||
Route::get('/{listing}', [ListingController::class, 'show'])->name('show');
|
||||
});
|
||||
|
||||
27
app/Http/Controllers/Auth/PartnerAuthGatewayController.php
Normal file
27
app/Http/Controllers/Auth/PartnerAuthGatewayController.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\PartnerSocialRegistrationAvailability;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class PartnerAuthGatewayController extends Controller
|
||||
{
|
||||
public function login(): RedirectResponse
|
||||
{
|
||||
return redirect()->route('filament.partner.auth.login');
|
||||
}
|
||||
|
||||
public function register(): RedirectResponse | Response
|
||||
{
|
||||
if (PartnerSocialRegistrationAvailability::isAvailable()) {
|
||||
return redirect()
|
||||
->route('filament.partner.auth.login')
|
||||
->with('success', __('Registration is available via social login providers.'));
|
||||
}
|
||||
|
||||
return response()->view('auth.registration-disabled', status: Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\Partner;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Modules\Listing\Models\Listing;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$myListings = Listing::where('user_id', auth()->id())->latest()->paginate(10);
|
||||
$stats = [
|
||||
'total' => Listing::where('user_id', auth()->id())->count(),
|
||||
'active' => Listing::where('user_id', auth()->id())->where('status', 'active')->count(),
|
||||
];
|
||||
return view('partner.dashboard', compact('myListings', 'stats'));
|
||||
}
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\Partner;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Modules\Listing\Models\Listing;
|
||||
|
||||
class ListingController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$listings = Listing::where('user_id', auth()->id())->latest()->paginate(15);
|
||||
return view('partner.listings.index', compact('listings'));
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,7 @@ use App\Settings\GeneralSettings;
|
||||
use BezhanSalleh\LanguageSwitch\LanguageSwitch;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\View;
|
||||
@ -22,8 +23,25 @@ class AppServiceProvider extends ServiceProvider
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
Route::pattern('tenant', '[0-9]+');
|
||||
View::addNamespace('app', resource_path('views'));
|
||||
|
||||
app()->booted(function (): void {
|
||||
foreach (app('router')->getRoutes() as $route) {
|
||||
$name = $route->getName();
|
||||
|
||||
if (! is_string($name) || ! str_starts_with($name, 'filament.partner.')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! str_contains($route->uri(), '{tenant}')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$route->where('tenant', '[0-9]+');
|
||||
}
|
||||
});
|
||||
|
||||
$fallbackName = config('app.name', 'OpenClassify');
|
||||
$fallbackLocale = config('app.locale', 'en');
|
||||
$fallbackCurrencies = $this->normalizeCurrencies(config('app.currencies', ['USD']));
|
||||
|
||||
48
app/Support/PartnerSocialRegistrationAvailability.php
Normal file
48
app/Support/PartnerSocialRegistrationAvailability.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Support;
|
||||
|
||||
use App\Settings\GeneralSettings;
|
||||
use Throwable;
|
||||
|
||||
class PartnerSocialRegistrationAvailability
|
||||
{
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
private const PROVIDERS = ['google', 'facebook', 'apple'];
|
||||
|
||||
public static function isAvailable(): bool
|
||||
{
|
||||
foreach (self::PROVIDERS as $provider) {
|
||||
if (self::providerEnabled($provider) && self::providerCredentialsReady($provider)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function providerEnabled(string $provider): bool
|
||||
{
|
||||
try {
|
||||
/** @var GeneralSettings $settings */
|
||||
$settings = app(GeneralSettings::class);
|
||||
|
||||
return match ($provider) {
|
||||
'google' => (bool) ($settings->enable_google_login ?? false),
|
||||
'facebook' => (bool) ($settings->enable_facebook_login ?? false),
|
||||
'apple' => (bool) ($settings->enable_apple_login ?? false),
|
||||
default => false,
|
||||
};
|
||||
} catch (Throwable) {
|
||||
return (bool) config("services.{$provider}.enabled", false);
|
||||
}
|
||||
}
|
||||
|
||||
private static function providerCredentialsReady(string $provider): bool
|
||||
{
|
||||
return filled(config("services.{$provider}.client_id"))
|
||||
&& filled(config("services.{$provider}.client_secret"));
|
||||
}
|
||||
}
|
||||
23
resources/views/auth/registration-disabled.blade.php
Normal file
23
resources/views/auth/registration-disabled.blade.php
Normal file
@ -0,0 +1,23 @@
|
||||
@extends('app::layouts.app')
|
||||
|
||||
@section('title', 'Registration Disabled')
|
||||
|
||||
@section('content')
|
||||
<div class="container mx-auto px-4 py-16">
|
||||
<div class="max-w-2xl mx-auto bg-white rounded-xl shadow-sm border border-gray-100 p-8 text-center">
|
||||
<h1 class="text-2xl font-bold text-gray-900">Registration is currently disabled</h1>
|
||||
<p class="mt-3 text-gray-600">
|
||||
Partner registration is available only when at least one social login provider is enabled by the admin.
|
||||
</p>
|
||||
|
||||
<div class="mt-6 flex items-center justify-center gap-3">
|
||||
<a href="{{ route('home') }}" class="px-4 py-2 rounded-lg border border-gray-300 text-gray-700 hover:bg-gray-50">
|
||||
Back Home
|
||||
</a>
|
||||
<a href="{{ route('filament.partner.auth.login') }}" class="px-4 py-2 rounded-lg bg-blue-600 text-white hover:bg-blue-700">
|
||||
Partner Login
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@ -18,14 +18,14 @@
|
||||
</a>
|
||||
|
||||
@auth
|
||||
<form method="POST" action="{{ route('logout') }}">
|
||||
<form method="POST" action="{{ route('filament.partner.auth.logout') }}">
|
||||
@csrf
|
||||
<button type="submit" class="px-4 py-2 rounded-lg bg-red-600 text-white hover:bg-red-700">
|
||||
Çıkış Yap
|
||||
</button>
|
||||
</form>
|
||||
@else
|
||||
<a href="{{ route('login') }}" class="px-4 py-2 rounded-lg bg-blue-600 text-white hover:bg-blue-700">
|
||||
<a href="{{ route('filament.partner.auth.login') }}" class="px-4 py-2 rounded-lg bg-blue-600 text-white hover:bg-blue-700">
|
||||
Giriş Yap
|
||||
</a>
|
||||
@endauth
|
||||
|
||||
@ -7,6 +7,15 @@
|
||||
$whatsappNumber = $generalSettings['whatsapp'] ?? null;
|
||||
$whatsappDigits = preg_replace('/\D+/', '', (string) $whatsappNumber);
|
||||
$whatsappUrl = $whatsappDigits !== '' ? 'https://wa.me/' . $whatsappDigits : null;
|
||||
$partnerLoginRoute = route('filament.partner.auth.login');
|
||||
$partnerRegisterRoute = route('register');
|
||||
$partnerLogoutRoute = route('filament.partner.auth.logout');
|
||||
$partnerCreateRoute = auth()->check()
|
||||
? route('filament.partner.resources.listings.create', ['tenant' => auth()->id()])
|
||||
: $partnerLoginRoute;
|
||||
$partnerDashboardRoute = auth()->check()
|
||||
? route('filament.partner.pages.dashboard', ['tenant' => auth()->id()])
|
||||
: $partnerLoginRoute;
|
||||
@endphp
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" dir="{{ in_array(app()->getLocale(), ['ar']) ? 'rtl' : 'ltr' }}">
|
||||
@ -19,11 +28,6 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>body { font-family: 'Inter', sans-serif; } [dir="rtl"] { text-align: right; }</style>
|
||||
</head>
|
||||
@php
|
||||
$partnerCreateRoute = auth()->check() && \Illuminate\Support\Facades\Route::has('filament.partner.resources.listings.create')
|
||||
? route('filament.partner.resources.listings.create', ['tenant' => auth()->id()])
|
||||
: route('listings.create');
|
||||
@endphp
|
||||
<body class="bg-gray-50">
|
||||
<nav class="bg-white shadow-sm border-b sticky top-0 z-50">
|
||||
<div class="container mx-auto px-4">
|
||||
@ -58,16 +62,16 @@
|
||||
<button class="text-gray-600 hover:text-blue-600">{{ auth()->user()->name }}</button>
|
||||
<div class="absolute right-0 mt-1 bg-white shadow-lg rounded-lg border hidden group-hover:block z-50 w-40">
|
||||
<a href="{{ route('profile.show') }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-50">My Profile</a>
|
||||
<a href="{{ route('partner.dashboard') }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-50">Dashboard</a>
|
||||
<form method="POST" action="{{ route('logout') }}">
|
||||
<a href="{{ $partnerDashboardRoute }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-50">Dashboard</a>
|
||||
<form method="POST" action="{{ $partnerLogoutRoute }}">
|
||||
@csrf
|
||||
<button type="submit" class="w-full text-left px-4 py-2 text-sm text-red-600 hover:bg-gray-50">Logout</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<a href="{{ route('login') }}" class="text-gray-600 hover:text-blue-600 transition">{{ __('messages.login') }}</a>
|
||||
<a href="{{ route('register') }}" class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition text-sm">{{ __('messages.register') }}</a>
|
||||
<a href="{{ $partnerLoginRoute }}" class="text-gray-600 hover:text-blue-600 transition">{{ __('messages.login') }}</a>
|
||||
<a href="{{ $partnerRegisterRoute }}" class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition text-sm">{{ __('messages.register') }}</a>
|
||||
@endauth
|
||||
</div>
|
||||
</div>
|
||||
@ -98,8 +102,8 @@
|
||||
<div>
|
||||
<h4 class="text-white font-medium mb-4">Account</h4>
|
||||
<ul class="space-y-2 text-sm">
|
||||
<li><a href="{{ route('login') }}" class="hover:text-white transition">Login</a></li>
|
||||
<li><a href="{{ route('register') }}" class="hover:text-white transition">Register</a></li>
|
||||
<li><a href="{{ $partnerLoginRoute }}" class="hover:text-white transition">Login</a></li>
|
||||
<li><a href="{{ $partnerRegisterRoute }}" class="hover:text-white transition">Register</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@ -1,59 +0,0 @@
|
||||
@extends('app::layouts.app')
|
||||
@section('title', 'Dashboard')
|
||||
@section('content')
|
||||
@php($partnerCreateRoute = route('filament.partner.resources.listings.create', ['tenant' => auth()->id()]))
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<h1 class="text-3xl font-bold mb-8">My Dashboard</h1>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
|
||||
<div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100">
|
||||
<div class="text-gray-500 text-sm font-medium">Total Listings</div>
|
||||
<div class="text-3xl font-bold text-blue-600 mt-1">{{ $stats['total'] }}</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100">
|
||||
<div class="text-gray-500 text-sm font-medium">Active Listings</div>
|
||||
<div class="text-3xl font-bold text-green-600 mt-1">{{ $stats['active'] }}</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100">
|
||||
<div class="text-gray-500 text-sm font-medium">Quick Actions</div>
|
||||
<a href="{{ $partnerCreateRoute }}" class="mt-2 block text-center bg-orange-500 text-white py-2 rounded-lg hover:bg-orange-600 transition text-sm">+ Post New Listing</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm overflow-hidden">
|
||||
<div class="px-6 py-4 border-b flex justify-between items-center">
|
||||
<h2 class="font-semibold text-gray-900">My Listings</h2>
|
||||
<a href="{{ route('partner.listings.index') }}" class="text-blue-600 text-sm hover:underline">View all</a>
|
||||
</div>
|
||||
<table class="w-full">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="text-left px-6 py-3 text-xs font-medium text-gray-500 uppercase">Title</th>
|
||||
<th class="text-left px-6 py-3 text-xs font-medium text-gray-500 uppercase">Price</th>
|
||||
<th class="text-left px-6 py-3 text-xs font-medium text-gray-500 uppercase">Status</th>
|
||||
<th class="text-left px-6 py-3 text-xs font-medium text-gray-500 uppercase">Date</th>
|
||||
<th class="text-left px-6 py-3 text-xs font-medium text-gray-500 uppercase">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse($myListings as $listing)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-6 py-4 font-medium text-gray-900">{{ \Illuminate\Support\Str::limit($listing->title, 40) }}</td>
|
||||
<td class="px-6 py-4 text-green-600 font-medium">{{ $listing->price ? number_format($listing->price, 0).' '.$listing->currency : 'Free' }}</td>
|
||||
<td class="px-6 py-4">
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium {{ $listing->status === 'active' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800' }}">
|
||||
{{ ucfirst($listing->status) }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-gray-500 text-sm">{{ $listing->created_at->format('M d, Y') }}</td>
|
||||
<td class="px-6 py-4">
|
||||
<a href="{{ route('listings.show', $listing) }}" class="text-blue-600 hover:underline text-sm">View</a>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="5" class="px-6 py-8 text-center text-gray-500">No listings yet. <a href="{{ $partnerCreateRoute }}" class="text-blue-600 hover:underline">Post your first listing!</a></td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="px-6 py-4">{{ $myListings->links() }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@ -1,32 +0,0 @@
|
||||
@extends('app::layouts.app')
|
||||
@section('title', 'My Listings')
|
||||
@section('content')
|
||||
@php($partnerCreateRoute = route('filament.partner.resources.listings.create', ['tenant' => auth()->id()]))
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-2xl font-bold">My Listings</h1>
|
||||
<a href="{{ $partnerCreateRoute }}" class="bg-orange-500 text-white px-4 py-2 rounded-lg hover:bg-orange-600 transition">+ New Listing</a>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
@forelse($listings as $listing)
|
||||
<div class="bg-white rounded-xl shadow-sm overflow-hidden border">
|
||||
<div class="p-4">
|
||||
<div class="flex justify-between items-start">
|
||||
<h3 class="font-semibold text-gray-900 truncate">{{ $listing->title }}</h3>
|
||||
<span class="ml-2 text-xs px-2 py-1 rounded {{ $listing->status === 'active' ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-600' }}">{{ ucfirst($listing->status) }}</span>
|
||||
</div>
|
||||
<p class="text-green-600 font-bold mt-1">{{ $listing->price ? number_format($listing->price, 0).' '.$listing->currency : 'Free' }}</p>
|
||||
<p class="text-gray-400 text-xs mt-1">{{ $listing->created_at->format('M d, Y') }}</p>
|
||||
<a href="{{ route('listings.show', $listing) }}" class="mt-3 block text-center border border-blue-600 text-blue-600 py-1.5 rounded hover:bg-blue-600 hover:text-white transition text-sm">View</a>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="col-span-3 text-center py-12 text-gray-500">
|
||||
<p>No listings yet.</p>
|
||||
<a href="{{ $partnerCreateRoute }}" class="mt-3 inline-block bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700 transition">Post Your First Listing</a>
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
<div class="mt-6">{{ $listings->links() }}</div>
|
||||
</div>
|
||||
@endsection
|
||||
@ -7,30 +7,17 @@ use App\Http\Controllers\Auth\EmailVerificationPromptController;
|
||||
use App\Http\Controllers\Auth\NewPasswordController;
|
||||
use App\Http\Controllers\Auth\PasswordController;
|
||||
use App\Http\Controllers\Auth\PasswordResetLinkController;
|
||||
use App\Http\Controllers\Auth\RegisteredUserController;
|
||||
use App\Http\Controllers\Auth\SocialAuthController;
|
||||
use App\Http\Controllers\Auth\PartnerAuthGatewayController;
|
||||
use App\Http\Controllers\Auth\VerifyEmailController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::middleware('guest')->group(function () {
|
||||
Route::get('register', [RegisteredUserController::class, 'create'])
|
||||
Route::get('register', [PartnerAuthGatewayController::class, 'register'])
|
||||
->name('register');
|
||||
|
||||
Route::post('register', [RegisteredUserController::class, 'store']);
|
||||
|
||||
Route::get('login', [AuthenticatedSessionController::class, 'create'])
|
||||
Route::get('login', [PartnerAuthGatewayController::class, 'login'])
|
||||
->name('login');
|
||||
|
||||
Route::post('login', [AuthenticatedSessionController::class, 'store']);
|
||||
|
||||
Route::get('auth/{provider}/redirect', [SocialAuthController::class, 'redirect'])
|
||||
->whereIn('provider', ['google', 'facebook', 'apple'])
|
||||
->name('auth.social.redirect');
|
||||
|
||||
Route::get('auth/{provider}/callback', [SocialAuthController::class, 'callback'])
|
||||
->whereIn('provider', ['google', 'facebook', 'apple'])
|
||||
->name('auth.social.callback');
|
||||
|
||||
Route::get('forgot-password', [PasswordResetLinkController::class, 'create'])
|
||||
->name('password.request');
|
||||
|
||||
|
||||
@ -2,16 +2,25 @@
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use App\Http\Controllers\HomeController;
|
||||
use App\Http\Controllers\LanguageController;
|
||||
use App\Http\Controllers\Partner\DashboardController;
|
||||
use App\Http\Controllers\Partner\ListingController as PartnerListingController;
|
||||
|
||||
Route::get('/', [HomeController::class, 'index'])->name('home');
|
||||
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard')->middleware('auth');
|
||||
Route::get('/lang/{locale}', [LanguageController::class, 'switch'])->name('lang.switch');
|
||||
|
||||
Route::middleware('auth')->prefix('partner')->name('partner.')->group(function () {
|
||||
Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
|
||||
Route::get('/listings', [PartnerListingController::class, 'index'])->name('listings.index');
|
||||
});
|
||||
$redirectToPartner = static function (string $routeName) {
|
||||
if (! auth()->check()) {
|
||||
return redirect()->route('filament.partner.auth.login');
|
||||
}
|
||||
|
||||
return redirect()->route($routeName, ['tenant' => auth()->id()]);
|
||||
};
|
||||
|
||||
Route::get('/dashboard', fn () => $redirectToPartner('filament.partner.pages.dashboard'))
|
||||
->name('dashboard');
|
||||
|
||||
Route::get('/partner', fn () => $redirectToPartner('filament.partner.pages.dashboard'))
|
||||
->name('partner.dashboard');
|
||||
|
||||
Route::get('/partner/listings', fn () => $redirectToPartner('filament.partner.resources.listings.index'))
|
||||
->name('partner.listings.index');
|
||||
|
||||
require __DIR__.'/auth.php';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user