Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions job-board/app/Http/Controllers/EmployerController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace App\Http\Controllers;

use App\Models\Employer;
use Illuminate\Http\Request;

class EmployerController extends Controller
{
public function __construct()
{
$this->authorizeResource(Employer::class);
}

/**
* Show the form for creating a new resource.
*/
public function create()
{
return view('employer.create');
}

/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
auth()->user()->employer()->create(
$request->validate([
'company_name' => 'required|min:3|unique:employers,company_name'
])
);

return redirect()->route('my-jobs.index')
->with('success', 'Your employer account was created. You can post your first job.');
}

/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}

/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
//
}

/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}

/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
}
}
14 changes: 11 additions & 3 deletions job-board/app/Http/Controllers/JobApplicationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,19 @@ public function create(Job $job)
public function store(Job $job, Request $request)
{
$this->authorize('apply', $job);

$validatedData = $request->validate([
'expected_salary' => 'required|min:1|max:1000000',
'cv' => 'required|file|mimes:pdf|max:2048',
]);

$file = $request->file('cv');
$path = $file->store('cvs', 'private');

$job->jobApplications()->create([
'user_id' => $request->user()->id,
...$request->validate([
'expected_salary' => 'required|min:1|max:1000000'
])
'cv_path' => $path,
'expected_salary' => $validatedData['expected_salary'],
]);

return redirect()->route('jobs.show', $job)
Expand Down
48 changes: 1 addition & 47 deletions job-board/app/Http/Controllers/JobController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@

class JobController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
$filters = request()->only(
Expand All @@ -22,58 +19,15 @@ public function index()

return view(
'job.index',
['jobs' => Job::with('employer')->filter($filters)->get()]
['jobs' => Job::with('employer')->filter($filters)->latest()->get()]
);
}

/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}

/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}

/**
* Display the specified resource.
*/
public function show(Job $job)
{
return view(
'job.show',
['job' => $job->load('employer.jobs')]
);
}

/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
//
}

/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}

/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public function index()
'applications' => auth()->user()->jobApplications()
->with([
'job' => fn($query) => $query->withCount('jobApplications')
->withAvg('jobApplications', 'expected_salary'),
->withAvg('jobApplications', 'expected_salary')
->withTrashed(),
'job.employer'
])
->latest()->get()
Expand Down
80 changes: 80 additions & 0 deletions job-board/app/Http/Controllers/MyJobController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace App\Http\Controllers;

use App\Models\Job;
use Illuminate\Http\Request;

class MyJobController extends Controller
{
public function __construct()
{
$this->authorizeResource(Job::class, 'my_job');
}

public function index()
{
return view(
'my_job.index',
[
'jobs' => auth()->user()->employer
->jobs()
->with(['employer', 'jobApplications', 'jobApplications.user'])
->withTrashed()
->get()
]
);
}

public function create()
{
return view('my_job.create');
}

public function store(Request $request)
{
$validatedData = $request->validate([
'title' => 'required|string|max:255',
'location' => 'required|string|max:255',
'salary' => 'required|numeric|min:5000',
'description' => 'required|string',
'experience' => 'required|in:' . implode(',', Job::$experience),
'category' => 'required|in:' . implode(',', Job::$category),
]);

$job = $request->user()->employer->jobs()->create($validatedData);

return redirect()->route('my-jobs.index')
->with('success', 'Job created successfully.');
}

public function edit(Job $myJob)
{
return view('my_job.edit', ['job' => $myJob]);
}

public function update(Request $request, Job $myJob)
{
$validatedData = $request->validate([
'title' => 'required|string|max:255',
'location' => 'required|string|max:255',
'salary' => 'required|numeric|min:5000',
'description' => 'required|string',
'experience' => 'required|in:' . implode(',', Job::$experience),
'category' => 'required|in:' . implode(',', Job::$category),
]);

$myJob->update($validatedData);

return redirect()->route('my-jobs.index')
->with('success', 'Job updated successfully.');
}

public function destroy(Job $myJob)
{
$myJob->delete();

return redirect()->route('my-jobs.index')
->with('success', 'Job deleted successfully.');
}
}
25 changes: 25 additions & 0 deletions job-board/app/Http/Controllers/MyJobCvController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Http\Controllers;

use App\Models\JobApplication;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Storage;

class MyJobCvController extends Controller
{
public function show(JobApplication $jobApplication)
{
$this->authorize('downloadCv', $jobApplication->job);
$path = $jobApplication->cv_path;

if (!Storage::disk('private')->exists($path)) {
abort(Response::HTTP_NOT_FOUND, 'CV not found.');
}

$downloadName = 'cv-' . $jobApplication->id . '.pdf';

return Storage::disk('private')->download($path, $downloadName);
}
}
9 changes: 5 additions & 4 deletions job-board/app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Kernel extends HttpKernel
* @var array<int, class-string|string>
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
Expand All @@ -39,8 +39,8 @@ class Kernel extends HttpKernel
],

'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
Expand All @@ -63,5 +63,6 @@ class Kernel extends HttpKernel
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'employer' => \App\Http\Middleware\Employer::class
];
}
}
27 changes: 27 additions & 0 deletions job-board/app/Http/Middleware/Employer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class Employer
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (null === $request->user() || null === $request->user()->employer) {
return redirect()->route('employer.create')
->with('error', 'You need to register as an employer first!');
// throw new AuthorizationException('You are not a registered employer.');
}

return $next($request);
}
}
2 changes: 2 additions & 0 deletions job-board/app/Models/Employer.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class Employer extends Model
{
use HasFactory;

protected $fillable = ['company_name'];

public function jobs(): HasMany
{
return $this->hasMany(Job::class);
Expand Down
5 changes: 4 additions & 1 deletion job-board/app/Models/Job.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder as QueryBuilder;

class Job extends Model
{
use HasFactory;
use HasFactory, SoftDeletes;

protected $fillable = ['title', 'experience', 'category', 'salary', 'description', 'location'];

public static array $experience = ['entry', 'intermediate', 'senior'];
public static array $category = [
Expand Down
2 changes: 1 addition & 1 deletion job-board/app/Models/JobApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class JobApplication extends Model
{
use HasFactory;

protected $fillable = ['expected_salary', 'user_id', 'job_id'];
protected $fillable = ['expected_salary', 'user_id', 'job_id', 'cv_path'];

public function job(): BelongsTo
{
Expand Down
Loading