You've already forked isop-mirror
feat: add support for deleting internships
This commit is contained in:
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Company;
|
|
||||||
use App\Models\Internship;
|
use App\Models\Internship;
|
||||||
use App\Models\InternshipStatusData;
|
use App\Models\InternshipStatusData;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@@ -310,9 +309,18 @@ class InternshipController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Remove the specified resource from storage.
|
* 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)
|
private function validateNewInternship(Request $request)
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ Route::prefix('/internships')->group(function () {
|
|||||||
|
|
||||||
Route::prefix('/{id}')->middleware("auth:sanctum")->group(function () {
|
Route::prefix('/{id}')->middleware("auth:sanctum")->group(function () {
|
||||||
Route::get("/", [InternshipController::class, 'get'])->name("api.internships.get");
|
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::put("/status", [InternshipStatusDataController::class, 'update'])->name("api.internships.status.update");
|
||||||
Route::get("/statuses", [InternshipStatusDataController::class, 'get'])->name("api.internships.get");
|
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");
|
Route::get("/next-statuses", [InternshipStatusDataController::class, 'get_next_states'])->name("api.internships.status.next.get");
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import type { Internship } from '~/types/internships';
|
import type { Internship } from '~/types/internships';
|
||||||
import type { Paginated } from '~/types/pagination';
|
import type { Paginated } from '~/types/pagination';
|
||||||
import { prettyInternshipStatus } from '~/types/internship_status';
|
import { prettyInternshipStatus } from '~/types/internship_status';
|
||||||
|
import { FetchError } from 'ofetch';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
mode: 'admin' | 'company' | 'student';
|
mode: 'admin' | 'company' | 'student';
|
||||||
@@ -17,6 +18,8 @@ const filters = ref({
|
|||||||
const page = ref(1);
|
const page = ref(1);
|
||||||
const itemsPerPage = ref(15);
|
const itemsPerPage = ref(15);
|
||||||
const totalItems = ref(0);
|
const totalItems = ref(0);
|
||||||
|
const deleteConfirmDialog = ref(false);
|
||||||
|
const internshipToDelete = ref<Internship | null>(null);
|
||||||
|
|
||||||
const allHeaders = [
|
const allHeaders = [
|
||||||
{ title: "Študent", key: "student.name", sortable: false },
|
{ title: "Študent", key: "student.name", sortable: false },
|
||||||
@@ -34,7 +37,8 @@ const headers = props.mode === 'company'
|
|||||||
? allHeaders.filter(header => header.key !== "company.name")
|
? allHeaders.filter(header => header.key !== "company.name")
|
||||||
: allHeaders;
|
: allHeaders;
|
||||||
|
|
||||||
const { data, error, pending } = await useLazySanctumFetch<Paginated<Internship>>('/api/internships', () => ({
|
const client = useSanctumClient();
|
||||||
|
const { data, error, pending, refresh } = await useLazySanctumFetch<Paginated<Internship>>('/api/internships', () => ({
|
||||||
params: {
|
params: {
|
||||||
...filters.value,
|
...filters.value,
|
||||||
page: page.value,
|
page: page.value,
|
||||||
@@ -53,7 +57,33 @@ watch(filters, async () => {
|
|||||||
}, { deep: true });
|
}, { deep: true });
|
||||||
|
|
||||||
async function delteInternship(internship: Internship) {
|
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;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -94,14 +124,38 @@ async function delteInternship(internship: Internship) {
|
|||||||
:to="`/dashboard/${mode}/internships/edit/${item.id}`" />
|
:to="`/dashboard/${mode}/internships/edit/${item.id}`" />
|
||||||
</template>
|
</template>
|
||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
<v-tooltip text="Vymazať">
|
<v-tooltip text="Vymazať" v-if="mode === 'admin'">
|
||||||
<template #activator="{ props }">
|
<template #activator="{ props }">
|
||||||
<v-btn icon="mdi-delete" size="small" variant="text" color="error"
|
<v-btn icon="mdi-delete" size="small" variant="text" color="error"
|
||||||
@click="async () => delteInternship(item)" />
|
@click="() => openDeleteDialog(item)" />
|
||||||
</template>
|
</template>
|
||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
</template>
|
</template>
|
||||||
</v-data-table-server>
|
</v-data-table-server>
|
||||||
|
|
||||||
|
<!-- Delete confirm dialog -->
|
||||||
|
<v-dialog v-model="deleteConfirmDialog" max-width="500px">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title class="text-h5">
|
||||||
|
Nový API kľúč
|
||||||
|
</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<p>Ste si istý, že chcete vymazať tento záznam?</p>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn color="red" variant="text" @click="async () => await confirmDeletion(true)"
|
||||||
|
:loading="pending">
|
||||||
|
Áno
|
||||||
|
</v-btn>
|
||||||
|
<v-btn color="black" variant="text" @click="async () => await confirmDeletion(false)">
|
||||||
|
Zrusiť
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user