diff --git a/backend/app/Http/Controllers/InternshipController.php b/backend/app/Http/Controllers/InternshipController.php index 0be763f..b5dea8d 100644 --- a/backend/app/Http/Controllers/InternshipController.php +++ b/backend/app/Http/Controllers/InternshipController.php @@ -135,6 +135,56 @@ class InternshipController extends Controller return response()->json($internship); } + public function get_agreement(int $id) { + $user = auth()->user(); + $internship = Internship::find($id); + + if(!$internship) { + return response()->json([ + 'message' => 'No such internship exists.' + ], 400); + } + + if(!$internship->agreement) { + return response()->json([ + 'message' => 'No agreement file exists for this internship.' + ], 404); + } + + if($user->role !== 'ADMIN' && $internship->user_id !== $user->id && $user->id !== $internship->company->contact) { + abort(403, 'Unauthorized'); + } + + return response($internship->agreement, 200) + ->header('Content-Type', 'application/pdf') + ->header('Content-Disposition', 'attachment; filename="agreement_' . $id . '.pdf"'); + } + + public function get_report(int $id) { + $user = auth()->user(); + $internship = Internship::find($id); + + if(!$internship) { + return response()->json([ + 'message' => 'No such internship exists.' + ], 400); + } + + if(!$internship->report) { + return response()->json([ + 'message' => 'No report file exists for this internship.' + ], 404); + } + + if($user->role !== 'ADMIN' && $internship->user_id !== $user->id && $user->id !== $internship->company->contact) { + abort(403, 'Unauthorized'); + } + + return response($internship->report, 200) + ->header('Content-Type', 'application/pdf') + ->header('Content-Disposition', 'attachment; filename="report_' . $id . '.pdf"'); + } + /** * Display a listing of the resource. */ diff --git a/backend/routes/api.php b/backend/routes/api.php index a25dc1f..35bae9d 100644 --- a/backend/routes/api.php +++ b/backend/routes/api.php @@ -42,6 +42,8 @@ Route::prefix('/internships')->group(function () { Route::put("/status", [InternshipStatusController::class, 'update'])->name("api.internships.status.update"); Route::get("/statuses", [InternshipStatusController::class, 'get'])->name("api.internships.get"); Route::get("/next-statuses", [InternshipStatusController::class, 'get_next_states'])->name("api.internships.status.next.get"); + Route::get("/agreement", [InternshipController::class, 'get_agreement'])->name("api.internships.agreement.get"); + Route::get("/report", [InternshipController::class, 'get_report'])->name("api.internships.report.get"); Route::post("/documents", [InternshipController::class, 'update_documents'])->name("api.internships.documents.set"); Route::post("/basic", [InternshipController::class, 'update_basic'])->name("api.internships.update.basic"); }); diff --git a/frontend/app/components/InternshipDocumentEditor.vue b/frontend/app/components/InternshipDocumentEditor.vue index 965c699..903a9ce 100644 --- a/frontend/app/components/InternshipDocumentEditor.vue +++ b/frontend/app/components/InternshipDocumentEditor.vue @@ -25,6 +25,26 @@ const report_confirmed = ref(props.internship.report_confirmed); const client = useSanctumClient(); const user = useSanctumUser(); +function triggerDownload(file: Blob, file_name: string) { + const url = window.URL.createObjectURL(file); + const link = document.createElement('a'); + link.href = url; + link.download = `${file_name}.pdf`; + link.target = "_blank"; + link.click(); + window.URL.revokeObjectURL(url); +} + +async function downloadAgreement() { + const agreement: Blob = await client(`/api/internships/${props.internship.id}/agreement`); + triggerDownload(agreement, `agreement-${props.internship.id}`); +} + +async function downloadReport() { + const report: Blob = await client(`/api/internships/${props.internship.id}/report`); + triggerDownload(report, `report-${props.internship.id}`); +} + async function onSubmit() { error.value = null; loading.value = true; @@ -72,7 +92,14 @@ async function onSubmit() { + text="V systéme je už nahratá zmluva/dohoda. Ak chcete nahradiť existujúcu verziu, vyberte súbor, alebo v opačnom prípade nechajte toto pole nevyplnené."> + +
+ + + Stiahnuť + +
+ text="V systéme je už nahratý výkaz. Ak chcete nahradiť existujúcu verziu, vyberte súbor, alebo v opačnom prípade nechajte toto pole nevyplnené."> + +
+ + + Stiahnuť + + - - + +
- + Uloziť diff --git a/frontend/app/components/InternshipDocumentViewer.vue b/frontend/app/components/InternshipDocumentViewer.vue index 5e96484..a517b78 100644 --- a/frontend/app/components/InternshipDocumentViewer.vue +++ b/frontend/app/components/InternshipDocumentViewer.vue @@ -4,6 +4,28 @@ import type { Internship } from '~/types/internships'; const props = defineProps<{ internship: Internship }>(); + +const client = useSanctumClient(); + +function triggerDownload(file: Blob, file_name: string) { + const url = window.URL.createObjectURL(file); + const link = document.createElement('a'); + link.href = url; + link.download = `${file_name}.pdf`; + link.target = "_blank"; + link.click(); + window.URL.revokeObjectURL(url); +} + +async function downloadAgreement() { + const agreement: Blob = await client(`/api/internships/${props.internship.id}/agreement`); + triggerDownload(agreement, `agreement-${props.internship.id}`); +} + +async function downloadReport() { + const report: Blob = await client(`/api/internships/${props.internship.id}/report`); + triggerDownload(report, `report-${props.internship.id}`); +}