diff --git a/backend/app/Http/Controllers/InternshipController.php b/backend/app/Http/Controllers/InternshipController.php index e017c0d..0b92405 100644 --- a/backend/app/Http/Controllers/InternshipController.php +++ b/backend/app/Http/Controllers/InternshipController.php @@ -2,7 +2,6 @@ namespace App\Http\Controllers; -use App\Models\Company; use App\Models\Internship; use App\Models\InternshipStatusData; use App\Models\User; @@ -310,9 +309,18 @@ class InternshipController extends Controller /** * Remove the specified resource from storage. */ - public function destroy(Internship $internship) + public function destroy(int $id) { - // + $internship = Internship::find($id); + + if (!$internship) { + return response()->json([ + 'message' => 'No such internship exists.' + ], 400); + } + $internship->delete(); + + return response()->noContent(); } private function validateNewInternship(Request $request) diff --git a/backend/routes/api.php b/backend/routes/api.php index 4f38751..b08c666 100644 --- a/backend/routes/api.php +++ b/backend/routes/api.php @@ -46,6 +46,7 @@ Route::prefix('/internships')->group(function () { Route::prefix('/{id}')->middleware("auth:sanctum")->group(function () { Route::get("/", [InternshipController::class, 'get'])->name("api.internships.get"); + Route::delete("/", [InternshipController::class, 'destroy'])->middleware(AdministratorOnly::class)->name("api.internships.delete"); Route::put("/status", [InternshipStatusDataController::class, 'update'])->name("api.internships.status.update"); Route::get("/statuses", [InternshipStatusDataController::class, 'get'])->name("api.internships.get"); Route::get("/next-statuses", [InternshipStatusDataController::class, 'get_next_states'])->name("api.internships.status.next.get"); diff --git a/frontend/app/components/InternshipListView.vue b/frontend/app/components/InternshipListView.vue index 3be0a6b..80fd1bd 100644 --- a/frontend/app/components/InternshipListView.vue +++ b/frontend/app/components/InternshipListView.vue @@ -2,6 +2,7 @@ import type { Internship } from '~/types/internships'; import type { Paginated } from '~/types/pagination'; import { prettyInternshipStatus } from '~/types/internship_status'; +import { FetchError } from 'ofetch'; const props = defineProps<{ mode: 'admin' | 'company' | 'student'; @@ -17,6 +18,8 @@ const filters = ref({ const page = ref(1); const itemsPerPage = ref(15); const totalItems = ref(0); +const deleteConfirmDialog = ref(false); +const internshipToDelete = ref(null); const allHeaders = [ { title: "Študent", key: "student.name", sortable: false }, @@ -34,7 +37,8 @@ const headers = props.mode === 'company' ? allHeaders.filter(header => header.key !== "company.name") : allHeaders; -const { data, error, pending } = await useLazySanctumFetch>('/api/internships', () => ({ +const client = useSanctumClient(); +const { data, error, pending, refresh } = await useLazySanctumFetch>('/api/internships', () => ({ params: { ...filters.value, page: page.value, @@ -53,7 +57,33 @@ watch(filters, async () => { }, { deep: true }); async function delteInternship(internship: Internship) { - // TODO: unimplemented + pending.value = true; + + try { + await client(`/api/internships/${internship.id}`, { + method: 'DELETE', + }); + await refresh(); + } catch (e) { + if (e instanceof FetchError) { + alert(`Chyba pri mazaní stáže: ${e.statusMessage ?? e.message}`); + } + } finally { + pending.value = false; + } +} + +function openDeleteDialog(internship: Internship) { + internshipToDelete.value = internship; + deleteConfirmDialog.value = true; +} + +async function confirmDeletion(confirm: boolean) { + if (confirm && internshipToDelete.value) { + await delteInternship(internshipToDelete.value); + } + deleteConfirmDialog.value = false; + internshipToDelete.value = null; } @@ -94,14 +124,38 @@ async function delteInternship(internship: Internship) { :to="`/dashboard/${mode}/internships/edit/${item.id}`" /> - + + + + + + + Nový API kľúč + + + +

Ste si istý, že chcete vymazať tento záznam?

+
+ + + + + Áno + + + Zrusiť + + +
+