You've already forked isop-mirror
feat: add internship retrieval and display functionality
This commit is contained in:
@@ -2,11 +2,36 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\Internship;
|
||||
use App\Models\InternshipStatus;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class InternshipController extends Controller
|
||||
{
|
||||
public function all()
|
||||
{
|
||||
$internships = Internship::where('user_id', auth()->id())->get()->makeHidden(['created_at', 'updated_at']);
|
||||
|
||||
$internships->each(function ($internship) {
|
||||
$internship->company = Company::find($internship->company_id)->makeHidden(['created_at', 'updated_at']);
|
||||
unset($internship->company_id);
|
||||
});
|
||||
|
||||
$internships->each(function ($internship) {
|
||||
$internship->contact = User::find($internship->company->contact)->makeHidden(['created_at', 'updated_at', 'email_verified_at']);
|
||||
unset($internship->company->contact);
|
||||
});
|
||||
|
||||
$internships->each(function ($internship) {
|
||||
$internship->status = InternshipStatus::whereColumn('internship_id', '=', $internship->id)->get()->first()->makeHidden(['created_at', 'updated_at', 'id']);
|
||||
$internship->status->modified_by = User::find($internship->status->modified_by)->makeHidden(['created_at', 'updated_at', 'email_verified_at']);
|
||||
});
|
||||
|
||||
return response()->json($internships);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\Auth\RegisteredUserController;
|
||||
use App\Http\Controllers\InternshipController;
|
||||
use App\Models\Company;
|
||||
use App\Models\StudentData;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -20,4 +21,6 @@ Route::middleware(['auth:sanctum'])->get('/user', function (Request $request) {
|
||||
|
||||
Route::post('/password-reset', [RegisteredUserController::class, 'reset_password'])
|
||||
->middleware(['guest', 'throttle:6,1'])
|
||||
->name('password.reset');
|
||||
->name('password.reset');
|
||||
|
||||
Route::get('/internships', [InternshipController::class, 'all'])->middleware(['auth'])->name("api.internships");
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { prettyInternshipStatus } from '~/types/internship_status';
|
||||
import type { Internship } from '~/types/internships';
|
||||
import type { User } from '~/types/user';
|
||||
|
||||
definePageMeta({
|
||||
@@ -12,15 +14,95 @@ useSeoMeta({
|
||||
ogDescription: "Portál študenta",
|
||||
});
|
||||
|
||||
const headers = [
|
||||
{ title: 'Firma', key: 'company', align: 'left' },
|
||||
{ title: 'Od', key: 'start', align: 'left' },
|
||||
{ title: 'Do', key: 'end', align: 'left' },
|
||||
{ title: 'Ročník', key: 'year_of_study', align: 'middle' },
|
||||
{ title: 'Semester', key: 'semester', align: 'middle' },
|
||||
{ title: 'Stav', key: 'status', align: 'middle' },
|
||||
{ title: 'Operácie', key: 'ops', align: 'middle' },
|
||||
];
|
||||
|
||||
const user = useSanctumUser<User>();
|
||||
const { data, status, error } = await useSanctumFetch<Internship[]>('/api/internships');
|
||||
|
||||
const serverItems = [
|
||||
{
|
||||
company: "Kutil s.r.o.",
|
||||
start: "01.01.2025",
|
||||
end: "30.01.2025",
|
||||
year_of_study: 1,
|
||||
semester: "zinmý",
|
||||
status: "Zadané",
|
||||
}
|
||||
];
|
||||
const totalItems = 0;
|
||||
const loading = false;
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-container fluid>
|
||||
<v-card id="footer-card">
|
||||
<v-card id="page-container-card">
|
||||
<h1>Vitajte, {{ user?.name }}</h1>
|
||||
<hr />
|
||||
<small>{{ user?.student_data?.study_field }}, {{ user?.student_data?.personal_email }}</small>
|
||||
|
||||
<!-- spacer -->
|
||||
<div style="height: 40px;"></div>
|
||||
|
||||
<v-btn prepend-icon="mdi-plus" color="blue" class="mr-2">
|
||||
Pridať
|
||||
</v-btn>
|
||||
<v-btn prepend-icon="mdi-pencil" color="orange" class="mr-2">
|
||||
Môj profil
|
||||
</v-btn>
|
||||
|
||||
<!-- spacer -->
|
||||
<div style="height: 40px;"></div>
|
||||
|
||||
<h3>Moje praxe</h3>
|
||||
<v-table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-for="header in headers" :class="'text-' + header.align">
|
||||
<strong>{{ header.title }}</strong>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="item in data">
|
||||
<td>{{ item.company.name }}</td>
|
||||
<td>{{ item.start }}</td>
|
||||
<td>{{ item.end }}</td>
|
||||
<td>{{ item.year_of_study }}</td>
|
||||
<td>{{ item.semester === "WINTER" ? "Zimný" : "Letný" }}</td>
|
||||
<td>
|
||||
<v-btn class="m-1" density="compact" base-color="grey">
|
||||
{{ prettyInternshipStatus(item.status.status) }}
|
||||
</v-btn>
|
||||
</td>
|
||||
<td class="text-left">
|
||||
<v-btn class="m-1 op-btn" density="compact" append-icon="mdi-pencil" base-color="orange"
|
||||
@click="() => { }">Editovať</v-btn>
|
||||
<v-btn class="m-1 op-btn" density="compact" append-icon="mdi-trash-can-outline"
|
||||
base-color="red" @click="async () => { }">Zmazať</v-btn>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</v-table>
|
||||
</v-card>
|
||||
</v-container>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
#page-container-card {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.op-btn {
|
||||
margin: 10px;
|
||||
}
|
||||
</style>
|
||||
35
frontend/app/types/internship_status.ts
Normal file
35
frontend/app/types/internship_status.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { User } from "./user";
|
||||
|
||||
export interface InternshipStatusData {
|
||||
internship_id: number;
|
||||
user_id: string;
|
||||
status: InternshipStatus;
|
||||
changed: string;
|
||||
note: string;
|
||||
modified_by: User;
|
||||
};
|
||||
|
||||
export enum InternshipStatus {
|
||||
SUBMITTED = 'SUBMITTED',
|
||||
CONFIRMED = 'CONFIRMED',
|
||||
DENIED = 'DENIED',
|
||||
DEFENDED = 'DEFENDED',
|
||||
NOT_DEFENDED = 'NOT_DEFENDED'
|
||||
};
|
||||
|
||||
export function prettyInternshipStatus(status: InternshipStatus) {
|
||||
switch (status) {
|
||||
case InternshipStatus.SUBMITTED:
|
||||
return "Zadané";
|
||||
case InternshipStatus.CONFIRMED:
|
||||
return "Potvrdené";
|
||||
case InternshipStatus.DENIED:
|
||||
return "Zamítnuté";
|
||||
case InternshipStatus.DEFENDED:
|
||||
return "Obhájené";
|
||||
case InternshipStatus.NOT_DEFENDED:
|
||||
return "Neobhájené";
|
||||
default:
|
||||
throw new Error("Unknown status");
|
||||
}
|
||||
}
|
||||
26
frontend/app/types/internships.ts
Normal file
26
frontend/app/types/internships.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { CompanyData } from "./company_data";
|
||||
import type { InternshipStatusData } from "./internship_status";
|
||||
|
||||
export interface Internship {
|
||||
id: number;
|
||||
user_id: string;
|
||||
company: CompanyData;
|
||||
start: string;
|
||||
end: string;
|
||||
year_of_study: number;
|
||||
semester: string;
|
||||
position_description: string;
|
||||
agreement?: Uint8Array;
|
||||
status: InternshipStatusData;
|
||||
};
|
||||
|
||||
export interface NewInternship {
|
||||
user_id: string;
|
||||
company_id: string;
|
||||
start: number;
|
||||
end: number;
|
||||
year_of_study: boolean;
|
||||
semester: string;
|
||||
position_description: string;
|
||||
agreement?: Uint8Array;
|
||||
};
|
||||
Reference in New Issue
Block a user