diff --git a/backend/app/Http/Controllers/InternshipController.php b/backend/app/Http/Controllers/InternshipController.php index a7d87ff..e017c0d 100644 --- a/backend/app/Http/Controllers/InternshipController.php +++ b/backend/app/Http/Controllers/InternshipController.php @@ -11,33 +11,55 @@ use Mpdf\Mpdf; class InternshipController extends Controller { - public function all() + public function all(Request $request) { - $user = auth()->user(); + $user = $request->user(); - if ($user->role !== 'ADMIN') { - abort(403, 'Unauthorized'); + $request->validate([ + 'year' => 'nullable|integer', + 'company' => 'nullable|string|min:3|max:32', + 'study_programe' => 'nullable|string|min:3|max:32', + 'student' => 'nullable|string|min:3|max:32', + 'page' => 'nullable|integer|min:1', + 'per_page' => 'nullable|integer|min:-1|max:100', + ]); + + $perPage = $request->input('per_page', 15); + + // Handle "All" items (-1) + if ($perPage == -1) { + $perPage = Internship::count(); } - $internships = Internship::all(); - return response()->json($internships); - } - - public function all_my() - { - $user = auth()->user(); - - if ($user->role === 'STUDENT') { - $internships = Internship::whereUserId($user->id)->get(); - } elseif ($user->role === 'EMPLOYER') { - $company = Company::whereContact($user->id)->first(); - if (!$company) { - return response()->json(['message' => 'No company associated with this user.'], 404); - } - $internships = Internship::whereCompanyId($company->id)->get(); - } else { - abort(403, 'Unauthorized'); - } + $internships = Internship::query() + ->with(['student.studentData']) + ->when($request->year, function ($query, $year) { + $query->whereYear('start', $year); + }) + ->when($request->company, function ($query, $company) { + $query->whereHas('company', function ($q) use ($company) { + $q->where('name', 'like', "%$company%"); + }); + }) + ->when($request->study_programe, function ($query, $studyPrograme) { + $query->whereHas('student.studentData', function ($q) use ($studyPrograme) { + $q->where('study_field', 'like', "%$studyPrograme%"); + }); + }) + ->when($request->student, function ($query, $student) { + $query->whereHas('student', function ($q) use ($student) { + $q->where('name', 'like', "%$student%"); + }); + }) + ->when($user->role === 'STUDENT', function ($query) use ($user) { + $query->where('user_id', '=', $user->id); + }) + ->when($user->role === 'EMPLOYER', function ($query) use ($user) { + $query->whereHas('company', function ($q) use ($user) { + $q->where('contact', 'like', $user->id); + }); + }) + ->paginate($perPage); return response()->json($internships); } diff --git a/backend/app/Http/Middleware/AdministratorOnly.php b/backend/app/Http/Middleware/AdministratorOnly.php index 81ae32b..9915ea0 100644 --- a/backend/app/Http/Middleware/AdministratorOnly.php +++ b/backend/app/Http/Middleware/AdministratorOnly.php @@ -15,8 +15,14 @@ class AdministratorOnly */ public function handle(Request $request, Closure $next): Response { - if ($request->user()->role !== 'ADMIN') { - return response(status: 403); + $user = $request->user(); + + if ($user === null) { + abort(403, 'Unauthorized'); + } + + if ($user->role !== 'ADMIN') { + abort(403, 'Unauthorized'); } return $next($request); diff --git a/backend/database/seeders/DatabaseSeeder.php b/backend/database/seeders/DatabaseSeeder.php index 3f17984..7ca6b00 100644 --- a/backend/database/seeders/DatabaseSeeder.php +++ b/backend/database/seeders/DatabaseSeeder.php @@ -28,7 +28,7 @@ class DatabaseSeeder extends Seeder ]); // create employers and companies - User::factory(10) + User::factory(20) ->create([ 'role' => 'EMPLOYER' ]) @@ -39,7 +39,7 @@ class DatabaseSeeder extends Seeder }); // create students - User::factory(10) + User::factory(20) ->create([ 'role' => 'STUDENT' ]) diff --git a/backend/routes/api.php b/backend/routes/api.php index 568f883..4f38751 100644 --- a/backend/routes/api.php +++ b/backend/routes/api.php @@ -42,8 +42,7 @@ Route::post('/password-reset', [RegisteredUserController::class, 'reset_password ->name('password.reset'); Route::prefix('/internships')->group(function () { - Route::get("/", [InternshipController::class, 'all'])->name("api.internships"); - Route::get("/my", [InternshipController::class, 'all_my'])->name("api.internships.my"); + Route::get("/", [InternshipController::class, 'all'])->middleware(['auth:sanctum'])->name("api.internships"); Route::prefix('/{id}')->middleware("auth:sanctum")->group(function () { Route::get("/", [InternshipController::class, 'get'])->name("api.internships.get"); diff --git a/frontend/app/components/InternshipListView.vue b/frontend/app/components/InternshipListView.vue new file mode 100644 index 0000000..3be0a6b --- /dev/null +++ b/frontend/app/components/InternshipListView.vue @@ -0,0 +1,112 @@ + + + + + \ No newline at end of file diff --git a/frontend/app/pages/dashboard/admin/internships/index.vue b/frontend/app/pages/dashboard/admin/internships/index.vue index 8edcfcb..513fc06 100644 --- a/frontend/app/pages/dashboard/admin/internships/index.vue +++ b/frontend/app/pages/dashboard/admin/internships/index.vue @@ -1,7 +1,4 @@ diff --git a/frontend/app/pages/dashboard/company/internships/index.vue b/frontend/app/pages/dashboard/company/internships/index.vue index 9e7bb5b..31748a8 100644 --- a/frontend/app/pages/dashboard/company/internships/index.vue +++ b/frontend/app/pages/dashboard/company/internships/index.vue @@ -1,7 +1,4 @@ @@ -78,12 +39,4 @@ const { data, error, pending } = await useLazySanctumFetch('/api/i padding-left: 10px; padding-right: 10px; } - -.alert { - margin-bottom: 10px; -} - -.op-btn { - margin: 10px; -} \ No newline at end of file diff --git a/frontend/app/pages/dashboard/student/index.vue b/frontend/app/pages/dashboard/student/index.vue index 9be4f41..11c6508 100644 --- a/frontend/app/pages/dashboard/student/index.vue +++ b/frontend/app/pages/dashboard/student/index.vue @@ -1,6 +1,4 @@ @@ -97,8 +50,4 @@ const { data, error, pending } = await useLazySanctumFetch('/api/i padding-left: 10px; padding-right: 10px; } - -.op-btn { - margin: 10px; -} \ No newline at end of file diff --git a/frontend/app/pages/dashboard/student/internship/create.vue b/frontend/app/pages/dashboard/student/internships/create.vue similarity index 100% rename from frontend/app/pages/dashboard/student/internship/create.vue rename to frontend/app/pages/dashboard/student/internships/create.vue diff --git a/frontend/app/pages/dashboard/student/internship/edit/[id].vue b/frontend/app/pages/dashboard/student/internships/edit/[id].vue similarity index 100% rename from frontend/app/pages/dashboard/student/internship/edit/[id].vue rename to frontend/app/pages/dashboard/student/internships/edit/[id].vue diff --git a/frontend/app/types/pagination.ts b/frontend/app/types/pagination.ts new file mode 100644 index 0000000..66f7483 --- /dev/null +++ b/frontend/app/types/pagination.ts @@ -0,0 +1,4 @@ +export type Paginated = { + data: T[], + total: number; +}; \ No newline at end of file