Files
jobifygarden/resources/views/jobs/index.blade.php
T
2026-04-04 18:19:34 +03:00

214 lines
11 KiB
PHP

@extends('layouts.app')
@section('title', 'Browse Jobs - JobifyGarden | ' . number_format($jobs->total()) . ' Opportunities')
@section('description', 'Browse ' . number_format($jobs->total()) . ' job opportunities. Filter by location, job type, experience level, and more to find your perfect role.')
@section('canonical', route('jobs.index'))
@push('structured_data')
<script type="application/ld+json">
{!! json_encode(app(\App\Services\SeoService::class)->generateBreadcrumbStructuredData([
['name' => 'Home', 'url' => route('home')],
['name' => 'Jobs', 'url' => route('jobs.index')]
]), JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) !!}
</script>
<script type="application/ld+json">
{
"{{ '@' }}context": "https://schema.org",
"{{ '@' }}type": "CollectionPage",
"name": "Browse Jobs",
"description": "Browse thousands of job opportunities from multiple sources",
"url": "{{ route('jobs.index') }}"
}
</script>
@endpush
@section('content')
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<!-- Page Header -->
<div class="py-8">
<h1 class="text-3xl font-bold text-gray-900 mb-2">Browse Jobs</h1>
<p class="text-gray-600">{{ $jobs->total() }} jobs found</p>
</div>
<div class="grid grid-cols-1 lg:grid-cols-4 gap-8">
<!-- Filters Sidebar -->
<aside class="lg:col-span-1">
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 sticky top-4"
x-data="{
showFilters: true,
jobType: '{{ $filters['job_type'] ?? '' }}',
experienceLevel: '{{ $filters['experience_level'] ?? '' }}',
remote: {{ ($filters['remote'] ?? false) ? 'true' : 'false' }}
}">
<div class="flex justify-between items-center mb-4">
<h2 class="text-lg font-semibold text-gray-900">Filters</h2>
@if(!empty(array_filter($filters)))
<a href="{{ route('jobs.index') }}" class="text-sm text-emerald-600 hover:text-emerald-700">Clear all</a>
@endif
</div>
<form action="{{ route('jobs.index') }}" method="GET" class="space-y-6">
<!-- Keywords -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Keywords</label>
<input type="text"
name="keywords"
value="{{ $filters['keywords'] ?? '' }}"
placeholder="Job title, skills..."
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-emerald-500 focus:border-emerald-500">
</div>
<!-- Location -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Location</label>
<input type="text"
name="location"
value="{{ $filters['location'] ?? '' }}"
placeholder="City, state, or country"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-emerald-500 focus:border-emerald-500">
</div>
<!-- Category -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Category</label>
<select name="category_id"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-emerald-500 focus:border-emerald-500">
<option value="">All Categories</option>
@foreach($categories as $category)
<option value="{{ $category->id }}" {{ ($filters['category_id'] ?? '') == $category->id ? 'selected' : '' }}>
{{ $category->name }} ({{ $category->jobs_count }})
</option>
@endforeach
</select>
</div>
<!-- Job Type -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Job Type</label>
<select name="job_type"
x-model="jobType"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-emerald-500 focus:border-emerald-500">
<option value="">All Types</option>
@foreach($filterOptions['job_types'] ?? [] as $type)
<option value="{{ $type }}">{{ ucfirst(str_replace('_', ' ', $type)) }}</option>
@endforeach
</select>
</div>
<!-- Experience Level -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Experience Level</label>
<select name="experience_level"
x-model="experienceLevel"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-emerald-500 focus:border-emerald-500">
<option value="">All Levels</option>
@foreach($filterOptions['experience_levels'] ?? [] as $level)
<option value="{{ $level }}">{{ ucfirst(str_replace('_', ' ', $level)) }}</option>
@endforeach
</select>
</div>
<!-- Remote -->
<div>
<label class="flex items-center">
<input type="checkbox"
name="remote"
value="1"
x-model="remote"
{{ ($filters['remote'] ?? false) ? 'checked' : '' }}
class="rounded border-gray-300 text-emerald-600 focus:ring-emerald-500">
<span class="ml-2 text-sm text-gray-700">Remote jobs only</span>
</label>
</div>
<!-- Salary Range -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Minimum Salary</label>
<input type="number"
name="salary_min"
value="{{ $filters['salary_min'] ?? '' }}"
placeholder="e.g., 50000"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-emerald-500 focus:border-emerald-500">
</div>
<!-- Posted Within -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Posted Within</label>
<select name="posted_within"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-emerald-500 focus:border-emerald-500">
<option value="">Any time</option>
<option value="1" {{ ($filters['posted_within'] ?? '') == '1' ? 'selected' : '' }}>Last 24 hours</option>
<option value="7" {{ ($filters['posted_within'] ?? '') == '7' ? 'selected' : '' }}>Last 7 days</option>
<option value="30" {{ ($filters['posted_within'] ?? '') == '30' ? 'selected' : '' }}>Last 30 days</option>
</select>
</div>
<!-- Submit Button -->
<button type="submit"
class="w-full px-4 py-2 bg-emerald-600 hover:bg-emerald-700 text-white font-medium rounded-md transition-colors duration-200">
Apply Filters
</button>
</form>
</div>
</aside>
<!-- Jobs List -->
<div class="lg:col-span-3">
<!-- Sort Options -->
<div class="mb-6 flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
<div class="text-sm text-gray-600">
Showing {{ $jobs->firstItem() ?? 0 }} - {{ $jobs->lastItem() ?? 0 }} of {{ $jobs->total() }} jobs
</div>
<form action="{{ route('jobs.index') }}" method="GET" class="flex items-center gap-2">
<!-- Preserve existing filters -->
@foreach($filters as $key => $value)
@if($key !== 'sort' && $value)
<input type="hidden" name="{{ $key }}" value="{{ $value }}">
@endif
@endforeach
<label class="text-sm text-gray-700">Sort by:</label>
<select name="sort"
onchange="this.form.submit()"
class="px-3 py-1.5 border border-gray-300 rounded-md text-sm focus:ring-emerald-500 focus:border-emerald-500">
<option value="posted_at_desc" {{ ($filters['sort'] ?? 'posted_at_desc') === 'posted_at_desc' ? 'selected' : '' }}>Newest First</option>
<option value="posted_at_asc" {{ ($filters['sort'] ?? '') === 'posted_at_asc' ? 'selected' : '' }}>Oldest First</option>
<option value="salary_desc" {{ ($filters['sort'] ?? '') === 'salary_desc' ? 'selected' : '' }}>Highest Salary</option>
<option value="salary_asc" {{ ($filters['sort'] ?? '') === 'salary_asc' ? 'selected' : '' }}>Lowest Salary</option>
</select>
</form>
</div>
<!-- Job Listings -->
@if($jobs->count() > 0)
<div class="space-y-4">
@foreach($jobs as $job)
<x-job-card :job="$job" />
@endforeach
</div>
<!-- Pagination -->
<div class="mt-8">
{{ $jobs->appends($filters)->links() }}
</div>
@else
<div class="bg-white rounded-lg border border-gray-200 p-12 text-center">
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<h3 class="mt-2 text-sm font-medium text-gray-900">No jobs found</h3>
<p class="mt-1 text-sm text-gray-500">Try adjusting your search or filter criteria.</p>
<div class="mt-6">
<a href="{{ route('jobs.index') }}"
class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-emerald-700 bg-emerald-100 hover:bg-emerald-200">
Clear all filters
</a>
</div>
</div>
@endif
</div>
</div>
</div>
@endsection