mirror of
https://github.com/openclassify/openclassify.git
synced 2026-04-14 11:12:09 -05:00
Remove policy restrictions for guys
This commit is contained in:
parent
3428bd3e43
commit
cf313e750f
@ -10,22 +10,29 @@ use Cheesegrits\FilamentGoogleMaps\Fields\Map;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Components\Utilities\Get;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\SpatieMediaLibraryImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\Filter;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Filters\TernaryFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Modules\Admin\Filament\Resources\ListingResource\Pages;
|
||||
use Modules\Category\Models\Category;
|
||||
use Modules\Listing\Models\Listing;
|
||||
use Modules\Listing\Support\ListingPanelHelper;
|
||||
use Tapp\FilamentCountryCodeField\Forms\Components\CountryCodeSelect;
|
||||
use Modules\Location\Models\City;
|
||||
use Modules\Location\Models\Country;
|
||||
use UnitEnum;
|
||||
use Ysfkaya\FilamentPhoneInput\Forms\PhoneInput;
|
||||
|
||||
@ -49,16 +56,37 @@ class ListingResource extends Resource
|
||||
->default(fn () => ListingPanelHelper::defaultCurrency())
|
||||
->required(),
|
||||
Select::make('category_id')->label('Category')->options(fn () => Category::where('is_active', true)->pluck('name', 'id'))->searchable()->nullable(),
|
||||
Select::make('user_id')->relationship('user', 'email')->label('Owner')->searchable()->preload()->nullable(),
|
||||
StateFusionSelect::make('status')->required(),
|
||||
PhoneInput::make('contact_phone')->defaultCountry(CountryCodeManager::defaultCountryIso2())->nullable(),
|
||||
TextInput::make('contact_email')->email()->maxLength(255),
|
||||
Toggle::make('is_featured')->default(false),
|
||||
TextInput::make('city')->maxLength(100),
|
||||
CountryCodeSelect::make('country')
|
||||
Select::make('country')
|
||||
->label('Country')
|
||||
->default(fn () => CountryCodeManager::defaultCountryCode())
|
||||
->formatStateUsing(fn ($state): ?string => CountryCodeManager::countryCodeFromLabelOrCode($state))
|
||||
->dehydrateStateUsing(fn ($state, ?Listing $record): ?string => CountryCodeManager::normalizeStoredCountry($state ?? $record?->country)),
|
||||
->options(fn (): array => Country::query()
|
||||
->orderBy('name')
|
||||
->pluck('name', 'name')
|
||||
->all())
|
||||
->searchable()
|
||||
->preload()
|
||||
->live()
|
||||
->afterStateUpdated(fn ($state, $set) => $set('city', null))
|
||||
->nullable(),
|
||||
Select::make('city')
|
||||
->label('City')
|
||||
->options(function (Get $get): array {
|
||||
$country = $get('country');
|
||||
|
||||
return City::query()
|
||||
->where('is_active', true)
|
||||
->when($country, fn (Builder $query, string $country): Builder => $query->whereHas('country', fn (Builder $countryQuery): Builder => $countryQuery->where('name', $country)))
|
||||
->orderBy('name')
|
||||
->pluck('name', 'name')
|
||||
->all();
|
||||
})
|
||||
->searchable()
|
||||
->preload()
|
||||
->nullable(),
|
||||
Map::make('location')
|
||||
->label('Location')
|
||||
->visible(fn (): bool => ListingPanelHelper::googleMapsEnabled())
|
||||
@ -90,15 +118,58 @@ class ListingResource extends Resource
|
||||
TextColumn::make('id')->sortable(),
|
||||
TextColumn::make('title')->searchable()->sortable()->limit(40),
|
||||
TextColumn::make('category.name')->label('Category'),
|
||||
TextColumn::make('user.email')->label('Owner')->searchable()->toggleable(),
|
||||
TextColumn::make('price')
|
||||
->currency(fn (Listing $record): string => $record->currency ?: ListingPanelHelper::defaultCurrency())
|
||||
->sortable(),
|
||||
StateFusionSelectColumn::make('status'),
|
||||
IconColumn::make('is_featured')->boolean()->label('Featured'),
|
||||
TextColumn::make('city'),
|
||||
TextColumn::make('country'),
|
||||
TextColumn::make('created_at')->dateTime()->sortable(),
|
||||
])->filters([
|
||||
StateFusionSelectFilter::make('status'),
|
||||
SelectFilter::make('category_id')
|
||||
->label('Category')
|
||||
->relationship('category', 'name')
|
||||
->searchable()
|
||||
->preload(),
|
||||
SelectFilter::make('user_id')
|
||||
->label('Owner')
|
||||
->relationship('user', 'email')
|
||||
->searchable()
|
||||
->preload(),
|
||||
SelectFilter::make('country')
|
||||
->options(fn (): array => Country::query()
|
||||
->orderBy('name')
|
||||
->pluck('name', 'name')
|
||||
->all())
|
||||
->searchable(),
|
||||
SelectFilter::make('city')
|
||||
->options(fn (): array => City::query()
|
||||
->orderBy('name')
|
||||
->pluck('name', 'name')
|
||||
->all())
|
||||
->searchable(),
|
||||
TernaryFilter::make('is_featured')->label('Featured'),
|
||||
Filter::make('created_at')
|
||||
->label('Created Date')
|
||||
->schema([
|
||||
DatePicker::make('from')->label('From'),
|
||||
DatePicker::make('until')->label('Until'),
|
||||
])
|
||||
->query(fn (Builder $query, array $data): Builder => $query
|
||||
->when($data['from'] ?? null, fn (Builder $query, string $date): Builder => $query->whereDate('created_at', '>=', $date))
|
||||
->when($data['until'] ?? null, fn (Builder $query, string $date): Builder => $query->whereDate('created_at', '<=', $date))),
|
||||
Filter::make('price')
|
||||
->label('Price Range')
|
||||
->schema([
|
||||
TextInput::make('min')->numeric()->label('Min'),
|
||||
TextInput::make('max')->numeric()->label('Max'),
|
||||
])
|
||||
->query(fn (Builder $query, array $data): Builder => $query
|
||||
->when($data['min'] ?? null, fn (Builder $query, string $amount): Builder => $query->where('price', '>=', (float) $amount))
|
||||
->when($data['max'] ?? null, fn (Builder $query, string $amount): Builder => $query->where('price', '<=', (float) $amount))),
|
||||
])->actions([
|
||||
EditAction::make(),
|
||||
Action::make('activities')
|
||||
|
||||
@ -11,6 +11,7 @@ use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\TernaryFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Modules\Admin\Filament\Resources\LocationResource\Pages;
|
||||
use Modules\Location\Models\Country;
|
||||
@ -22,6 +23,8 @@ class LocationResource extends Resource
|
||||
protected static string | BackedEnum | null $navigationIcon = 'heroicon-o-globe-alt';
|
||||
protected static string | UnitEnum | null $navigationGroup = 'Settings';
|
||||
protected static ?string $label = 'Country';
|
||||
protected static ?string $pluralLabel = 'Countries';
|
||||
protected static ?int $navigationSort = 2;
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
@ -38,9 +41,13 @@ class LocationResource extends Resource
|
||||
return $table->columns([
|
||||
TextColumn::make('id')->sortable(),
|
||||
TextColumn::make('name')->searchable()->sortable(),
|
||||
TextColumn::make('code'),
|
||||
TextColumn::make('code')->searchable()->sortable(),
|
||||
TextColumn::make('phone_code'),
|
||||
TextColumn::make('cities_count')->counts('cities')->label('Cities')->sortable(),
|
||||
IconColumn::make('is_active')->boolean(),
|
||||
TextColumn::make('created_at')->dateTime()->sortable()->toggleable(isToggledHiddenByDefault: true),
|
||||
])->filters([
|
||||
TernaryFilter::make('is_active')->label('Active'),
|
||||
])->actions([
|
||||
EditAction::make(),
|
||||
Action::make('activities')
|
||||
|
||||
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Category\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use Modules\Category\Models\Category;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class CategoryPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:Category');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, Category $category): bool
|
||||
{
|
||||
return $authUser->can('View:Category');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:Category');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, Category $category): bool
|
||||
{
|
||||
return $authUser->can('Update:Category');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, Category $category): bool
|
||||
{
|
||||
return $authUser->can('Delete:Category');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, Category $category): bool
|
||||
{
|
||||
return $authUser->can('Restore:Category');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, Category $category): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:Category');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:Category');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:Category');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, Category $category): bool
|
||||
{
|
||||
return $authUser->can('Replicate:Category');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:Category');
|
||||
}
|
||||
|
||||
}
|
||||
@ -8,10 +8,23 @@ class ListingController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$search = trim((string) request('search', ''));
|
||||
|
||||
$listings = Listing::query()
|
||||
->publicFeed()
|
||||
->paginate(12);
|
||||
return view('listing::index', compact('listings'));
|
||||
->when($search !== '', function ($query) use ($search): void {
|
||||
$query->where(function ($searchQuery) use ($search): void {
|
||||
$searchQuery
|
||||
->where('title', 'like', "%{$search}%")
|
||||
->orWhere('description', 'like', "%{$search}%")
|
||||
->orWhere('city', 'like', "%{$search}%")
|
||||
->orWhere('country', 'like', "%{$search}%");
|
||||
});
|
||||
})
|
||||
->paginate(12)
|
||||
->withQueryString();
|
||||
|
||||
return view('listing::index', compact('listings', 'search'));
|
||||
}
|
||||
|
||||
public function show(Listing $listing)
|
||||
|
||||
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Listing\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use Modules\Listing\Models\Listing;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class ListingPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:Listing');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, Listing $listing): bool
|
||||
{
|
||||
return $authUser->can('View:Listing');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:Listing');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, Listing $listing): bool
|
||||
{
|
||||
return $authUser->can('Update:Listing');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, Listing $listing): bool
|
||||
{
|
||||
return $authUser->can('Delete:Listing');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, Listing $listing): bool
|
||||
{
|
||||
return $authUser->can('Restore:Listing');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, Listing $listing): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:Listing');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:Listing');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:Listing');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, Listing $listing): bool
|
||||
{
|
||||
return $authUser->can('Replicate:Listing');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:Listing');
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Location\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use Modules\Location\Models\Country;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class CountryPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:Country');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, Country $country): bool
|
||||
{
|
||||
return $authUser->can('View:Country');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:Country');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, Country $country): bool
|
||||
{
|
||||
return $authUser->can('Update:Country');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, Country $country): bool
|
||||
{
|
||||
return $authUser->can('Delete:Country');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, Country $country): bool
|
||||
{
|
||||
return $authUser->can('Restore:Country');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, Country $country): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:Country');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:Country');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:Country');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, Country $country): bool
|
||||
{
|
||||
return $authUser->can('Replicate:Country');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:Country');
|
||||
}
|
||||
|
||||
}
|
||||
@ -46,10 +46,6 @@ class User extends Authenticatable implements FilamentUser, HasTenants, HasAvata
|
||||
|
||||
public function canAccessPanel(Panel $panel): bool
|
||||
{
|
||||
if ((string) $this->status !== 'active') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return match ($panel->getId()) {
|
||||
'admin' => $this->hasRole('admin'),
|
||||
'partner' => true,
|
||||
|
||||
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use TallCms\Cms\Models\CmsCategory;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class CmsCategoryPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:CmsCategory');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, CmsCategory $cmsCategory): bool
|
||||
{
|
||||
return $authUser->can('View:CmsCategory');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:CmsCategory');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, CmsCategory $cmsCategory): bool
|
||||
{
|
||||
return $authUser->can('Update:CmsCategory');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, CmsCategory $cmsCategory): bool
|
||||
{
|
||||
return $authUser->can('Delete:CmsCategory');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, CmsCategory $cmsCategory): bool
|
||||
{
|
||||
return $authUser->can('Restore:CmsCategory');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, CmsCategory $cmsCategory): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:CmsCategory');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:CmsCategory');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:CmsCategory');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, CmsCategory $cmsCategory): bool
|
||||
{
|
||||
return $authUser->can('Replicate:CmsCategory');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:CmsCategory');
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use TallCms\Cms\Models\CmsComment;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class CmsCommentPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:CmsComment');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, CmsComment $cmsComment): bool
|
||||
{
|
||||
return $authUser->can('View:CmsComment');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:CmsComment');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, CmsComment $cmsComment): bool
|
||||
{
|
||||
return $authUser->can('Update:CmsComment');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, CmsComment $cmsComment): bool
|
||||
{
|
||||
return $authUser->can('Delete:CmsComment');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, CmsComment $cmsComment): bool
|
||||
{
|
||||
return $authUser->can('Restore:CmsComment');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, CmsComment $cmsComment): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:CmsComment');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:CmsComment');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:CmsComment');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, CmsComment $cmsComment): bool
|
||||
{
|
||||
return $authUser->can('Replicate:CmsComment');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:CmsComment');
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use TallCms\Cms\Models\CmsPage;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class CmsPagePolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:CmsPage');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, CmsPage $cmsPage): bool
|
||||
{
|
||||
return $authUser->can('View:CmsPage');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:CmsPage');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, CmsPage $cmsPage): bool
|
||||
{
|
||||
return $authUser->can('Update:CmsPage');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, CmsPage $cmsPage): bool
|
||||
{
|
||||
return $authUser->can('Delete:CmsPage');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, CmsPage $cmsPage): bool
|
||||
{
|
||||
return $authUser->can('Restore:CmsPage');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, CmsPage $cmsPage): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:CmsPage');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:CmsPage');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:CmsPage');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, CmsPage $cmsPage): bool
|
||||
{
|
||||
return $authUser->can('Replicate:CmsPage');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:CmsPage');
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use TallCms\Cms\Models\CmsPost;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class CmsPostPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:CmsPost');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, CmsPost $cmsPost): bool
|
||||
{
|
||||
return $authUser->can('View:CmsPost');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:CmsPost');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, CmsPost $cmsPost): bool
|
||||
{
|
||||
return $authUser->can('Update:CmsPost');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, CmsPost $cmsPost): bool
|
||||
{
|
||||
return $authUser->can('Delete:CmsPost');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, CmsPost $cmsPost): bool
|
||||
{
|
||||
return $authUser->can('Restore:CmsPost');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, CmsPost $cmsPost): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:CmsPost');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:CmsPost');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:CmsPost');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, CmsPost $cmsPost): bool
|
||||
{
|
||||
return $authUser->can('Replicate:CmsPost');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:CmsPost');
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use TallCms\Cms\Models\MediaCollection;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class MediaCollectionPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:MediaCollection');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, MediaCollection $mediaCollection): bool
|
||||
{
|
||||
return $authUser->can('View:MediaCollection');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:MediaCollection');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, MediaCollection $mediaCollection): bool
|
||||
{
|
||||
return $authUser->can('Update:MediaCollection');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, MediaCollection $mediaCollection): bool
|
||||
{
|
||||
return $authUser->can('Delete:MediaCollection');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, MediaCollection $mediaCollection): bool
|
||||
{
|
||||
return $authUser->can('Restore:MediaCollection');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, MediaCollection $mediaCollection): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:MediaCollection');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:MediaCollection');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:MediaCollection');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, MediaCollection $mediaCollection): bool
|
||||
{
|
||||
return $authUser->can('Replicate:MediaCollection');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:MediaCollection');
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use Spatie\Permission\Models\Role;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class RolePolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:Role');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, Role $role): bool
|
||||
{
|
||||
return $authUser->can('View:Role');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:Role');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, Role $role): bool
|
||||
{
|
||||
return $authUser->can('Update:Role');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, Role $role): bool
|
||||
{
|
||||
return $authUser->can('Delete:Role');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, Role $role): bool
|
||||
{
|
||||
return $authUser->can('Restore:Role');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, Role $role): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:Role');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:Role');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:Role');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, Role $role): bool
|
||||
{
|
||||
return $authUser->can('Replicate:Role');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:Role');
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use TallCms\Cms\Models\TallcmsContactSubmission;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class TallcmsContactSubmissionPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:TallcmsContactSubmission');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, TallcmsContactSubmission $tallcmsContactSubmission): bool
|
||||
{
|
||||
return $authUser->can('View:TallcmsContactSubmission');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:TallcmsContactSubmission');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, TallcmsContactSubmission $tallcmsContactSubmission): bool
|
||||
{
|
||||
return $authUser->can('Update:TallcmsContactSubmission');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, TallcmsContactSubmission $tallcmsContactSubmission): bool
|
||||
{
|
||||
return $authUser->can('Delete:TallcmsContactSubmission');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, TallcmsContactSubmission $tallcmsContactSubmission): bool
|
||||
{
|
||||
return $authUser->can('Restore:TallcmsContactSubmission');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, TallcmsContactSubmission $tallcmsContactSubmission): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:TallcmsContactSubmission');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:TallcmsContactSubmission');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:TallcmsContactSubmission');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, TallcmsContactSubmission $tallcmsContactSubmission): bool
|
||||
{
|
||||
return $authUser->can('Replicate:TallcmsContactSubmission');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:TallcmsContactSubmission');
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use TallCms\Cms\Models\TallcmsMedia;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class TallcmsMediaPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:TallcmsMedia');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, TallcmsMedia $tallcmsMedia): bool
|
||||
{
|
||||
return $authUser->can('View:TallcmsMedia');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:TallcmsMedia');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, TallcmsMedia $tallcmsMedia): bool
|
||||
{
|
||||
return $authUser->can('Update:TallcmsMedia');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, TallcmsMedia $tallcmsMedia): bool
|
||||
{
|
||||
return $authUser->can('Delete:TallcmsMedia');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, TallcmsMedia $tallcmsMedia): bool
|
||||
{
|
||||
return $authUser->can('Restore:TallcmsMedia');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, TallcmsMedia $tallcmsMedia): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:TallcmsMedia');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:TallcmsMedia');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:TallcmsMedia');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, TallcmsMedia $tallcmsMedia): bool
|
||||
{
|
||||
return $authUser->can('Replicate:TallcmsMedia');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:TallcmsMedia');
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use TallCms\Cms\Models\TallcmsMenu;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class TallcmsMenuPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:TallcmsMenu');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, TallcmsMenu $tallcmsMenu): bool
|
||||
{
|
||||
return $authUser->can('View:TallcmsMenu');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:TallcmsMenu');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, TallcmsMenu $tallcmsMenu): bool
|
||||
{
|
||||
return $authUser->can('Update:TallcmsMenu');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, TallcmsMenu $tallcmsMenu): bool
|
||||
{
|
||||
return $authUser->can('Delete:TallcmsMenu');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, TallcmsMenu $tallcmsMenu): bool
|
||||
{
|
||||
return $authUser->can('Restore:TallcmsMenu');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, TallcmsMenu $tallcmsMenu): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:TallcmsMenu');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:TallcmsMenu');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:TallcmsMenu');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, TallcmsMenu $tallcmsMenu): bool
|
||||
{
|
||||
return $authUser->can('Replicate:TallcmsMenu');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:TallcmsMenu');
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,67 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class UserPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:User');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('View:User');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:User');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Update:User');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Delete:User');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Restore:User');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:User');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:User');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:User');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Replicate:User');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:User');
|
||||
}
|
||||
|
||||
}
|
||||
@ -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\Gate;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
@ -23,6 +24,14 @@ class AppServiceProvider extends ServiceProvider
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
Gate::before(function ($user): null | bool {
|
||||
if (method_exists($user, 'hasRole') && $user->hasRole('admin')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
Route::pattern('tenant', '[0-9]+');
|
||||
View::addNamespace('app', resource_path('views'));
|
||||
|
||||
|
||||
@ -1,95 +1,210 @@
|
||||
@extends('app::layouts.app')
|
||||
@section('content')
|
||||
<div class="bg-gradient-to-br from-blue-600 to-blue-800 text-white py-16">
|
||||
<div class="container mx-auto px-4 text-center">
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-4">{{ __('messages.find_what_you_need') }}</h1>
|
||||
<p class="text-blue-200 text-lg mb-8">{{ __('messages.hero_subtitle') }}</p>
|
||||
<form action="{{ route('listings.index') }}" method="GET" class="max-w-2xl mx-auto">
|
||||
<div class="flex bg-white rounded-xl overflow-hidden shadow-lg">
|
||||
<input type="text" name="search" placeholder="{{ __('messages.search_placeholder') }}" class="flex-1 px-5 py-4 text-gray-800 focus:outline-none text-lg">
|
||||
<button type="submit" class="bg-orange-500 hover:bg-orange-600 text-white px-8 py-4 font-semibold transition">{{ __('messages.search') }}</button>
|
||||
@php
|
||||
$menuCategories = $categories->take(8);
|
||||
$heroListing = $featuredListings->first() ?? $recentListings->first();
|
||||
$heroImage = $heroListing?->getFirstMediaUrl('listing-images');
|
||||
$listingCards = $recentListings->take(6);
|
||||
$trendGradients = [
|
||||
'from-emerald-500 to-teal-600',
|
||||
'from-rose-500 to-pink-600',
|
||||
'from-fuchsia-500 to-rose-600',
|
||||
'from-sky-500 to-blue-600',
|
||||
'from-amber-500 to-orange-600',
|
||||
'from-cyan-500 to-indigo-600',
|
||||
'from-red-500 to-rose-600',
|
||||
'from-violet-500 to-purple-600',
|
||||
];
|
||||
@endphp
|
||||
|
||||
<div class="max-w-[1320px] mx-auto px-4 py-5 md:py-7 space-y-7">
|
||||
<section class="bg-white border border-slate-200 rounded-2xl px-2 py-2 overflow-x-auto">
|
||||
<div class="flex items-center gap-2 min-w-max">
|
||||
<a href="{{ route('categories.index') }}" class="inline-flex items-center gap-2 px-4 py-2.5 rounded-full bg-slate-900 text-white text-sm font-semibold">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M4 6h16M4 12h16M4 18h16"/>
|
||||
</svg>
|
||||
Tüm Kategoriler
|
||||
</a>
|
||||
@foreach($menuCategories as $category)
|
||||
<a href="{{ route('categories.show', $category) }}" class="px-4 py-2.5 rounded-full text-sm font-medium text-slate-700 hover:bg-slate-100 transition whitespace-nowrap">
|
||||
{{ $category->name }}
|
||||
</a>
|
||||
@endforeach
|
||||
<a href="{{ route('listings.index') }}" class="px-4 py-2.5 rounded-full text-sm font-medium text-slate-700 hover:bg-slate-100 transition whitespace-nowrap">
|
||||
{{ __('messages.listings') }}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="relative overflow-hidden rounded-[28px] bg-gradient-to-r from-blue-900 via-blue-700 to-blue-600 text-white shadow-xl">
|
||||
<div class="absolute -top-20 -left-24 w-80 h-80 rounded-full bg-blue-400/20 blur-3xl"></div>
|
||||
<div class="absolute -bottom-24 right-10 w-80 h-80 rounded-full bg-cyan-300/20 blur-3xl"></div>
|
||||
<div class="relative grid lg:grid-cols-[1fr,1.1fr] gap-6 items-center px-8 md:px-12 py-12 md:py-14">
|
||||
<div>
|
||||
<p class="text-sm uppercase tracking-[0.22em] text-blue-200 font-semibold mb-4">OpenClassify Marketplace</p>
|
||||
<h1 class="text-4xl md:text-5xl leading-tight font-extrabold max-w-xl">
|
||||
İlan ücreti ödemeden ürününü hızla sat!
|
||||
</h1>
|
||||
<p class="mt-4 text-blue-100 text-base md:text-lg max-w-xl">
|
||||
{{ __('messages.hero_subtitle') }}
|
||||
</p>
|
||||
<div class="mt-8 flex flex-wrap items-center gap-3">
|
||||
<a href="{{ route('listings.index') }}" class="bg-white text-blue-900 px-8 py-3 rounded-full font-semibold hover:bg-blue-50 transition">
|
||||
İncele
|
||||
</a>
|
||||
@auth
|
||||
<a href="{{ route('filament.partner.resources.listings.create', ['tenant' => auth()->id()]) }}" class="border border-blue-200/60 px-8 py-3 rounded-full font-semibold hover:bg-white/10 transition">
|
||||
{{ __('messages.post_listing') }}
|
||||
</a>
|
||||
@else
|
||||
<a href="{{ route('filament.partner.auth.login') }}" class="border border-blue-200/60 px-8 py-3 rounded-full font-semibold hover:bg-white/10 transition">
|
||||
{{ __('messages.post_listing') }}
|
||||
</a>
|
||||
@endauth
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white border-b py-4">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="flex justify-center space-x-8 text-center text-sm text-gray-600">
|
||||
<div><span class="font-bold text-blue-600 text-lg">{{ $listingCount ?? 0 }}</span><br>Active Listings</div>
|
||||
<div><span class="font-bold text-blue-600 text-lg">{{ $categoryCount ?? 0 }}</span><br>Categories</div>
|
||||
<div><span class="font-bold text-blue-600 text-lg">{{ $userCount ?? 0 }}</span><br>Users</div>
|
||||
<div class="mt-8 flex items-center gap-2">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-white/40"></span>
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-white/40"></span>
|
||||
<span class="w-7 h-2.5 rounded-full bg-white"></span>
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-white/40"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container mx-auto px-4 py-12">
|
||||
<h2 class="text-2xl font-bold mb-6">{{ __('messages.browse_categories') }}</h2>
|
||||
<div class="grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-8 gap-4">
|
||||
@foreach($categories as $category)
|
||||
<a href="{{ route('categories.show', $category) }}" class="bg-white rounded-xl p-4 text-center shadow-sm hover:shadow-md transition hover:-translate-y-1 transform">
|
||||
<div class="text-3xl mb-2">{{ $category->icon ?? '📦' }}</div>
|
||||
<div class="text-xs font-medium text-gray-700 truncate">{{ $category->name }}</div>
|
||||
<div class="relative h-[310px] md:h-[360px]">
|
||||
<div class="absolute left-6 md:left-10 bottom-0 w-32 md:w-40 h-[250px] md:h-[300px] bg-slate-950 rounded-[32px] shadow-2xl p-2 rotate-[-8deg]">
|
||||
<div class="w-full h-full rounded-[24px] bg-white overflow-hidden">
|
||||
<div class="px-3 py-2 border-b border-slate-100">
|
||||
<p class="text-rose-500 text-sm font-bold">OpenClassify</p>
|
||||
<p class="text-[10px] text-slate-400 mt-1">Ürün, kategori, satıcı ara</p>
|
||||
</div>
|
||||
<div class="p-2 space-y-2">
|
||||
<div class="h-10 rounded-xl bg-slate-100"></div>
|
||||
<div class="grid grid-cols-3 gap-2">
|
||||
<div class="h-9 rounded-lg bg-blue-100"></div>
|
||||
<div class="h-9 rounded-lg bg-emerald-100"></div>
|
||||
<div class="h-9 rounded-lg bg-amber-100"></div>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<div class="h-14 rounded-xl bg-slate-100"></div>
|
||||
<div class="h-14 rounded-xl bg-slate-100"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute right-0 bottom-0 w-[78%] h-[88%] rounded-[28px] bg-gradient-to-br from-white/20 to-blue-500/40 border border-white/20 shadow-2xl flex items-end justify-center p-4">
|
||||
@if($heroImage)
|
||||
<img src="{{ $heroImage }}" alt="{{ $heroListing?->title }}" class="w-full h-full object-cover rounded-2xl">
|
||||
@else
|
||||
<div class="w-full h-full rounded-2xl bg-white/90 text-slate-800 flex flex-col justify-center items-center gap-3">
|
||||
<span class="text-6xl">🚗</span>
|
||||
<p class="text-sm font-semibold px-4 text-center">Görsel eklendiğinde burada öne çıkan ilan yer alacak.</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-2xl font-bold text-slate-900">Trend Kategoriler</h2>
|
||||
<a href="{{ route('categories.index') }}" class="text-sm font-semibold text-rose-500 hover:text-rose-600 transition">Tümünü Gör</a>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-8 gap-3">
|
||||
@foreach($menuCategories as $index => $category)
|
||||
<a href="{{ route('categories.show', $category) }}" class="group rounded-2xl overflow-hidden bg-white border border-slate-200 hover:shadow-md transition">
|
||||
<div class="h-20 bg-gradient-to-r {{ $trendGradients[$index % count($trendGradients)] }} relative">
|
||||
<span class="absolute -bottom-4 right-4 text-3xl drop-shadow">{{ $category->icon ?? '📦' }}</span>
|
||||
</div>
|
||||
<div class="px-3 py-3">
|
||||
<p class="text-xs font-semibold text-slate-800 leading-tight h-9 overflow-hidden">{{ $category->name }}</p>
|
||||
</div>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="text-center mt-6">
|
||||
<a href="{{ route('categories.index') }}" class="text-blue-600 hover:underline font-medium">View all categories →</a>
|
||||
</div>
|
||||
</div>
|
||||
@if($featuredListings->count())
|
||||
<div class="bg-gray-100 py-12">
|
||||
<div class="container mx-auto px-4">
|
||||
<h2 class="text-2xl font-bold mb-6">⭐ Featured Listings</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
@foreach($featuredListings as $listing)
|
||||
<div class="bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg transition">
|
||||
<div class="bg-gradient-to-br from-blue-100 to-blue-200 h-48 flex items-center justify-center">
|
||||
<svg class="w-16 h-16 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<h3 class="font-semibold text-gray-900 truncate">{{ $listing->title }}</h3>
|
||||
<p class="text-green-600 font-bold text-lg">{{ $listing->price ? number_format($listing->price, 0).' '.$listing->currency : 'Free' }}</p>
|
||||
<p class="text-gray-500 text-sm">{{ $listing->city }}</p>
|
||||
<a href="{{ route('listings.show', $listing) }}" class="mt-3 block text-center bg-blue-600 text-white py-2 rounded-lg hover:bg-blue-700 transition text-sm">View Details</a>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-2xl font-bold text-slate-900">Popüler İkinci El İlanlar</h2>
|
||||
<div class="hidden sm:flex items-center gap-2 text-sm text-slate-500">
|
||||
<span class="w-8 h-8 rounded-full border border-slate-300 grid place-items-center">‹</span>
|
||||
<span class="w-8 h-8 rounded-full border border-slate-300 grid place-items-center">›</span>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="container mx-auto px-4 py-12">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h2 class="text-2xl font-bold">{{ __('messages.recent_listings') }}</h2>
|
||||
<a href="{{ route('listings.index') }}" class="text-blue-600 hover:underline font-medium">View all →</a>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
||||
@foreach($recentListings as $listing)
|
||||
<div class="bg-white rounded-xl shadow-sm overflow-hidden hover:shadow-md transition border border-gray-100">
|
||||
<div class="bg-gray-100 h-44 flex items-center justify-center">
|
||||
<svg class="w-12 h-12 text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<h3 class="font-medium text-gray-900 truncate text-sm">{{ $listing->title }}</h3>
|
||||
<p class="text-green-600 font-bold">{{ $listing->price ? number_format($listing->price, 0).' '.$listing->currency : 'Free' }}</p>
|
||||
<div class="flex justify-between items-center mt-2">
|
||||
<p class="text-gray-400 text-xs">{{ $listing->city }}</p>
|
||||
<p class="text-gray-400 text-xs">{{ $listing->created_at->diffForHumans() }}</p>
|
||||
</div>
|
||||
<a href="{{ route('listings.show', $listing) }}" class="mt-2 block text-center border border-blue-600 text-blue-600 py-1.5 rounded-lg hover:bg-blue-600 hover:text-white transition text-sm">View</a>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-blue-600 text-white py-12 mt-8">
|
||||
<div class="container mx-auto px-4 text-center">
|
||||
<h2 class="text-3xl font-bold mb-4">{{ __('messages.sell_something') }}</h2>
|
||||
<p class="text-blue-200 mb-6">Post your first listing for free!</p>
|
||||
@auth
|
||||
<a href="{{ route('filament.partner.resources.listings.create', ['tenant' => auth()->id()]) }}" class="bg-orange-500 text-white px-8 py-3 rounded-xl hover:bg-orange-600 transition font-semibold text-lg">Post a Free Ad</a>
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
@forelse($listingCards as $listing)
|
||||
@php
|
||||
$listingImage = $listing->getFirstMediaUrl('listing-images');
|
||||
$priceLabel = $listing->price ? number_format((float) $listing->price, 0).' '.$listing->currency : __('messages.free');
|
||||
$locationLabel = trim(collect([$listing->city, $listing->country])->filter()->join(', '));
|
||||
@endphp
|
||||
<article class="rounded-2xl border border-slate-200 bg-white overflow-hidden shadow-sm hover:shadow-md transition">
|
||||
<div class="relative h-64 md:h-[290px] bg-slate-100">
|
||||
@if($listingImage)
|
||||
<img src="{{ $listingImage }}" alt="{{ $listing->title }}" class="w-full h-full object-cover">
|
||||
@else
|
||||
<a href="{{ route('register') }}" class="bg-white text-blue-600 px-8 py-3 rounded-xl hover:bg-gray-100 transition font-semibold text-lg">Get Started Free</a>
|
||||
<div class="w-full h-full grid place-items-center text-slate-400">
|
||||
<svg class="w-14 h-14" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.7" d="M4 16l4.5-4.5a2 2 0 012.8 0L16 16m-1.5-1.5l1.8-1.8a2 2 0 012.8 0L21 14m-7-8h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
||||
</svg>
|
||||
</div>
|
||||
@endif
|
||||
<div class="absolute top-3 left-3 flex items-center gap-2">
|
||||
@if($listing->is_featured)
|
||||
<span class="bg-amber-300 text-amber-950 text-xs font-bold px-2.5 py-1 rounded-full">Öne Çıkan</span>
|
||||
@endif
|
||||
<span class="bg-sky-500 text-white text-xs font-semibold px-2.5 py-1 rounded-full">Büyük İlan</span>
|
||||
</div>
|
||||
<button type="button" class="absolute top-3 right-3 w-9 h-9 rounded-full bg-white/90 text-slate-500 grid place-items-center hover:text-rose-500 transition">♡</button>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="rounded-lg bg-emerald-50 text-emerald-700 text-xs font-semibold px-3 py-1.5 text-center mb-3">
|
||||
Elden al, kartla öde!
|
||||
</div>
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<p class="text-3xl font-extrabold tracking-tight text-slate-900">{{ $priceLabel }}</p>
|
||||
<h3 class="text-xl font-semibold text-slate-800 mt-1 truncate">{{ $listing->title }}</h3>
|
||||
</div>
|
||||
<span class="text-xs text-blue-600 bg-blue-50 px-2 py-1 rounded-full font-semibold">12 taksit</span>
|
||||
</div>
|
||||
<div class="mt-5 flex items-center justify-between text-sm text-slate-500">
|
||||
<span class="truncate">{{ $locationLabel !== '' ? $locationLabel : 'Konum belirtilmedi' }}</span>
|
||||
<span>{{ $listing->created_at->diffForHumans() }}</span>
|
||||
</div>
|
||||
<a href="{{ route('listings.show', $listing) }}" class="mt-4 inline-flex items-center gap-2 text-sm font-semibold text-blue-700 hover:text-blue-900 transition">
|
||||
İlan detayını aç
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M9 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
@empty
|
||||
<div class="col-span-2 border border-dashed border-slate-300 bg-white rounded-2xl py-20 text-center text-slate-500">
|
||||
Henüz ilan bulunmuyor.
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="rounded-3xl bg-slate-900 text-white px-8 py-10 md:p-12">
|
||||
<div class="grid md:grid-cols-[1fr,auto] gap-6 items-center">
|
||||
<div>
|
||||
<h2 class="text-3xl md:text-4xl font-extrabold">{{ __('messages.sell_something') }}</h2>
|
||||
<p class="text-slate-300 mt-3">Dakikalar içinde ücretsiz ilan oluştur, binlerce alıcıya ulaş.</p>
|
||||
</div>
|
||||
@auth
|
||||
<a href="{{ route('filament.partner.resources.listings.create', ['tenant' => auth()->id()]) }}" class="inline-flex items-center justify-center rounded-full bg-rose-500 hover:bg-rose-600 px-8 py-3 font-semibold transition whitespace-nowrap">
|
||||
Hemen İlan Ver
|
||||
</a>
|
||||
@else
|
||||
<a href="{{ route('register') }}" class="inline-flex items-center justify-center rounded-full bg-white text-slate-900 hover:bg-slate-100 px-8 py-3 font-semibold transition whitespace-nowrap">
|
||||
Ücretsiz Başla
|
||||
</a>
|
||||
@endauth
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@ -10,12 +10,24 @@
|
||||
$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;
|
||||
$partnerCreateRoute = route('partner.listings.create');
|
||||
$partnerDashboardRoute = auth()->check()
|
||||
? route('filament.partner.pages.dashboard', ['tenant' => auth()->id()])
|
||||
: $partnerLoginRoute;
|
||||
$availableLocales = config('app.available_locales', ['en']);
|
||||
$localeLabels = [
|
||||
'en' => 'English',
|
||||
'tr' => 'Türkçe',
|
||||
'ar' => 'العربية',
|
||||
'zh' => '中文',
|
||||
'es' => 'Español',
|
||||
'fr' => 'Français',
|
||||
'de' => 'Deutsch',
|
||||
'pt' => 'Português',
|
||||
'ru' => 'Русский',
|
||||
'ja' => '日本語',
|
||||
];
|
||||
$isHomePage = request()->routeIs('home');
|
||||
@endphp
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" dir="{{ in_array(app()->getLocale(), ['ar']) ? 'rtl' : 'ltr' }}">
|
||||
@ -25,89 +37,184 @@
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
<title>{{ $siteName }} @hasSection('title') - @yield('title') @endif</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<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>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Pacifico&family=Sora:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--oc-bg: #f5f6fa;
|
||||
--oc-surface: #ffffff;
|
||||
--oc-border: #e4e7ef;
|
||||
--oc-text: #191e2b;
|
||||
--oc-muted: #667085;
|
||||
--oc-primary: #ff4365;
|
||||
--oc-primary-soft: #ffe7ed;
|
||||
--oc-chip: #f1f3f8;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Sora', sans-serif;
|
||||
background: radial-gradient(circle at top right, #fce6ef 0%, #f5f6fa 28%);
|
||||
color: var(--oc-text);
|
||||
}
|
||||
|
||||
.brand-mark {
|
||||
font-family: 'Pacifico', cursive;
|
||||
}
|
||||
|
||||
.market-nav-surface {
|
||||
background: rgba(255, 255, 255, 0.88);
|
||||
backdrop-filter: saturate(180%) blur(8px);
|
||||
border-bottom: 1px solid var(--oc-border);
|
||||
}
|
||||
|
||||
.search-shell {
|
||||
border: 1px solid #d9ddea;
|
||||
background: #fbfcff;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.chip-btn {
|
||||
border: 1px solid #d9ddea;
|
||||
background: var(--oc-chip);
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(120deg, #ff516e, #ff2f57);
|
||||
color: #fff;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
[dir="rtl"] {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<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">
|
||||
<div class="flex items-center justify-between h-16">
|
||||
<a href="{{ route('home') }}" class="text-2xl font-bold text-blue-600 flex items-center gap-2">
|
||||
<body class="min-h-screen">
|
||||
<nav class="market-nav-surface sticky top-0 z-50">
|
||||
<div class="max-w-[1320px] mx-auto px-4 py-4">
|
||||
<div class="flex items-center gap-3 md:gap-4">
|
||||
<a href="{{ route('home') }}" class="shrink-0 flex items-center gap-2">
|
||||
@if($siteLogoUrl)
|
||||
<img src="{{ $siteLogoUrl }}" alt="{{ $siteName }}" class="h-9 w-auto rounded">
|
||||
@endif
|
||||
<span>{{ $siteName }}</span>
|
||||
<span class="brand-mark text-3xl text-rose-500 leading-none">{{ $siteName }}</span>
|
||||
</a>
|
||||
<div class="hidden md:flex items-center space-x-6">
|
||||
<a href="{{ route('home') }}" class="text-gray-600 hover:text-blue-600 transition">{{ __('messages.home') }}</a>
|
||||
<a href="{{ route('categories.index') }}" class="text-gray-600 hover:text-blue-600 transition">{{ __('messages.categories') }}</a>
|
||||
<a href="{{ route('listings.index') }}" class="text-gray-600 hover:text-blue-600 transition">{{ __('messages.listings') }}</a>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<div class="relative group">
|
||||
<button class="flex items-center text-gray-600 hover:text-blue-600 transition px-2 py-1 rounded border text-sm">
|
||||
🌐 {{ strtoupper(app()->getLocale()) }}
|
||||
<form action="{{ route('listings.index') }}" method="GET" class="hidden lg:flex flex-1 search-shell items-center gap-2 px-4 py-2.5">
|
||||
<svg class="w-5 h-5 text-rose-500 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M21 21l-4.35-4.35m1.6-5.05a7.25 7.25 0 11-14.5 0 7.25 7.25 0 0114.5 0z"/>
|
||||
</svg>
|
||||
<input
|
||||
type="text"
|
||||
name="search"
|
||||
value="{{ request('search') }}"
|
||||
placeholder="{{ __('messages.search_placeholder') }}"
|
||||
class="w-full bg-transparent text-sm text-slate-700 placeholder:text-slate-400 focus:outline-none"
|
||||
>
|
||||
<button type="submit" class="text-xs font-semibold text-slate-500 hover:text-slate-700 transition">
|
||||
{{ __('messages.search') }}
|
||||
</button>
|
||||
<div class="absolute right-0 mt-1 bg-white shadow-lg rounded-lg border hidden group-hover:block z-50 w-32">
|
||||
@foreach(config('app.available_locales', ['en']) as $locale)
|
||||
<a href="{{ route('lang.switch', $locale) }}" class="block px-4 py-2 text-sm hover:bg-gray-50 {{ app()->getLocale() === $locale ? 'font-bold text-blue-600' : 'text-gray-700' }}">
|
||||
{{ ['en'=>'English','tr'=>'Türkçe','ar'=>'العربية','zh'=>'中文','es'=>'Español','fr'=>'Français','de'=>'Deutsch','pt'=>'Português','ru'=>'Русский','ja'=>'日本語'][$locale] ?? $locale }}
|
||||
</form>
|
||||
<button type="button" class="chip-btn hidden md:flex items-center gap-2 px-4 py-2 text-sm text-slate-700">
|
||||
<svg class="w-4 h-4 text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M12 21s7-6.2 7-11a7 7 0 10-14 0c0 4.8 7 11 7 11z"/>
|
||||
<circle cx="12" cy="10" r="2.3" stroke-width="1.8" />
|
||||
</svg>
|
||||
<span>Istanbul, Türkiye</span>
|
||||
<svg class="w-4 h-4 text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M6 9l6 6 6-6"/>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="ml-auto flex items-center gap-2 md:gap-3">
|
||||
<details class="relative">
|
||||
<summary class="chip-btn list-none cursor-pointer px-3 py-2 text-xs md:text-sm text-slate-700">
|
||||
{{ strtoupper(app()->getLocale()) }}
|
||||
</summary>
|
||||
<div class="absolute right-0 mt-2 bg-white border border-slate-200 shadow-lg rounded-xl overflow-hidden min-w-28">
|
||||
@foreach($availableLocales as $locale)
|
||||
<a href="{{ route('lang.switch', $locale) }}" class="block px-3 py-2 text-sm hover:bg-slate-50 {{ app()->getLocale() === $locale ? 'font-semibold text-rose-500' : 'text-slate-700' }}">
|
||||
{{ $localeLabels[$locale] ?? strtoupper($locale) }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
@auth
|
||||
<a href="{{ $partnerCreateRoute }}" class="bg-orange-500 text-white px-4 py-2 rounded-lg hover:bg-orange-600 transition font-medium text-sm">+ Post Ad</a>
|
||||
<div class="relative group">
|
||||
<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="{{ $partnerDashboardRoute }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-50">Dashboard</a>
|
||||
<form method="POST" action="{{ $partnerLogoutRoute }}">
|
||||
<a href="{{ $partnerDashboardRoute }}" class="hidden sm:inline-flex text-sm font-medium text-slate-600 hover:text-slate-900 transition">Panel</a>
|
||||
<a href="{{ $partnerCreateRoute }}" class="btn-primary px-4 md:px-5 py-2 text-sm font-semibold shadow-sm hover:brightness-95 transition">
|
||||
+ {{ __('messages.post_listing') }}
|
||||
</a>
|
||||
<form method="POST" action="{{ $partnerLogoutRoute }}" class="hidden sm:block">
|
||||
@csrf
|
||||
<button type="submit" class="w-full text-left px-4 py-2 text-sm text-red-600 hover:bg-gray-50">Logout</button>
|
||||
<button type="submit" class="text-sm text-slate-500 hover:text-rose-500 transition">{{ __('messages.logout') }}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<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>
|
||||
<a href="{{ $partnerLoginRoute }}" class="bg-rose-50 text-rose-500 px-4 md:px-5 py-2 rounded-full text-sm font-semibold hover:bg-rose-100 transition">
|
||||
{{ __('messages.login') }}
|
||||
</a>
|
||||
<a href="{{ $partnerCreateRoute }}" class="btn-primary px-4 md:px-5 py-2 text-sm font-semibold shadow-sm hover:brightness-95 transition">
|
||||
{{ __('messages.post_listing') }}
|
||||
</a>
|
||||
@endauth
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3 lg:hidden">
|
||||
<form action="{{ route('listings.index') }}" method="GET" class="search-shell flex items-center gap-2 px-3 py-2.5">
|
||||
<svg class="w-4 h-4 text-rose-500 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M21 21l-4.35-4.35m1.6-5.05a7.25 7.25 0 11-14.5 0 7.25 7.25 0 0114.5 0z"/>
|
||||
</svg>
|
||||
<input
|
||||
type="text"
|
||||
name="search"
|
||||
value="{{ request('search') }}"
|
||||
placeholder="{{ __('messages.search_placeholder') }}"
|
||||
class="w-full bg-transparent text-sm text-slate-700 placeholder:text-slate-400 focus:outline-none"
|
||||
>
|
||||
<button type="submit" class="text-xs text-slate-500">{{ __('messages.search') }}</button>
|
||||
</form>
|
||||
</div>
|
||||
@if(! $isHomePage)
|
||||
<div class="mt-3 flex items-center gap-2 text-sm overflow-x-auto pb-1">
|
||||
<a href="{{ route('home') }}" class="chip-btn whitespace-nowrap px-4 py-2 hover:bg-slate-100 transition">{{ __('messages.home') }}</a>
|
||||
<a href="{{ route('categories.index') }}" class="chip-btn whitespace-nowrap px-4 py-2 hover:bg-slate-100 transition">{{ __('messages.categories') }}</a>
|
||||
<a href="{{ route('listings.index') }}" class="chip-btn whitespace-nowrap px-4 py-2 hover:bg-slate-100 transition">{{ __('messages.listings') }}</a>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</nav>
|
||||
@if(session('success'))
|
||||
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 text-center">{{ session('success') }}</div>
|
||||
<div class="max-w-[1320px] mx-auto px-4 pt-3">
|
||||
<div class="bg-emerald-100 border border-emerald-300 text-emerald-800 px-4 py-3 rounded-xl text-sm">{{ session('success') }}</div>
|
||||
</div>
|
||||
@endif
|
||||
@if(session('error'))
|
||||
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 text-center">{{ session('error') }}</div>
|
||||
<div class="max-w-[1320px] mx-auto px-4 pt-3">
|
||||
<div class="bg-rose-100 border border-rose-300 text-rose-700 px-4 py-3 rounded-xl text-sm">{{ session('error') }}</div>
|
||||
</div>
|
||||
@endif
|
||||
<main>@yield('content')</main>
|
||||
<footer class="bg-gray-800 text-gray-400 mt-16 py-12">
|
||||
<div class="container mx-auto px-4">
|
||||
<footer class="mt-14 bg-slate-900 text-slate-300">
|
||||
<div class="max-w-[1320px] mx-auto px-4 py-12">
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
|
||||
<div>
|
||||
<h3 class="text-white font-bold text-lg mb-4">{{ $siteName }}</h3>
|
||||
<p class="text-sm">{{ $siteDescription }}</p>
|
||||
<h3 class="text-white font-semibold text-lg mb-3">{{ $siteName }}</h3>
|
||||
<p class="text-sm text-slate-400 leading-relaxed">{{ $siteDescription }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-white font-medium mb-4">Quick Links</h4>
|
||||
<h4 class="text-white font-medium mb-4">Hızlı Linkler</h4>
|
||||
<ul class="space-y-2 text-sm">
|
||||
<li><a href="{{ route('home') }}" class="hover:text-white transition">Home</a></li>
|
||||
<li><a href="{{ route('categories.index') }}" class="hover:text-white transition">Categories</a></li>
|
||||
<li><a href="{{ route('listings.index') }}" class="hover:text-white transition">All Listings</a></li>
|
||||
<li><a href="{{ route('home') }}" class="hover:text-white transition">Ana Sayfa</a></li>
|
||||
<li><a href="{{ route('categories.index') }}" class="hover:text-white transition">Kategoriler</a></li>
|
||||
<li><a href="{{ route('listings.index') }}" class="hover:text-white transition">Tüm İlanlar</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-white font-medium mb-4">Account</h4>
|
||||
<h4 class="text-white font-medium mb-4">Hesap</h4>
|
||||
<ul class="space-y-2 text-sm">
|
||||
<li><a href="{{ $partnerLoginRoute }}" class="hover:text-white transition">Login</a></li>
|
||||
<li><a href="{{ $partnerRegisterRoute }}" class="hover:text-white transition">Register</a></li>
|
||||
<li><a href="{{ $partnerLoginRoute }}" class="hover:text-white transition">{{ __('messages.login') }}</a></li>
|
||||
<li><a href="{{ $partnerRegisterRoute }}" class="hover:text-white transition">{{ __('messages.register') }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-white font-medium mb-4">Connect</h4>
|
||||
<h4 class="text-white font-medium mb-4">Bağlantılar</h4>
|
||||
<ul class="space-y-2 text-sm mb-4">
|
||||
@if($linkedinUrl)
|
||||
<li><a href="{{ $linkedinUrl }}" target="_blank" rel="noopener" class="hover:text-white transition">LinkedIn</a></li>
|
||||
@ -119,18 +226,18 @@
|
||||
<li><a href="{{ $whatsappUrl }}" target="_blank" rel="noopener" class="hover:text-white transition">WhatsApp</a></li>
|
||||
@endif
|
||||
@if(!$linkedinUrl && !$instagramUrl && !$whatsappUrl)
|
||||
<li>No social links added yet.</li>
|
||||
<li>Henüz sosyal bağlantı eklenmedi.</li>
|
||||
@endif
|
||||
</ul>
|
||||
<h4 class="text-white font-medium mb-3">Languages</h4>
|
||||
<h4 class="text-white font-medium mb-3">Diller</h4>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
@foreach(config('app.available_locales', ['en']) as $locale)
|
||||
@foreach($availableLocales as $locale)
|
||||
<a href="{{ route('lang.switch', $locale) }}" class="text-xs {{ app()->getLocale() === $locale ? 'text-white' : 'hover:text-white' }} transition">{{ strtoupper($locale) }}</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-700 mt-8 pt-8 text-center text-sm">
|
||||
<div class="border-t border-slate-700 mt-8 pt-8 text-center text-sm text-slate-400">
|
||||
<p>© {{ date('Y') }} {{ $siteName }}. All rights reserved.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -23,4 +23,7 @@ Route::get('/partner', fn () => $redirectToPartner('filament.partner.pages.dashb
|
||||
Route::get('/partner/listings', fn () => $redirectToPartner('filament.partner.resources.listings.index'))
|
||||
->name('partner.listings.index');
|
||||
|
||||
Route::get('/partner/listings/create', fn () => $redirectToPartner('filament.partner.resources.listings.create'))
|
||||
->name('partner.listings.create');
|
||||
|
||||
require __DIR__.'/auth.php';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user