('/api/internships');
|
{ }">Editovať
+ :to="'/dashboard/student/internship/edit/' + item.id">Editovať
{ }">Zmazať
|
diff --git a/frontend/app/pages/dashboard/student/internship/edit/[id].vue b/frontend/app/pages/dashboard/student/internship/edit/[id].vue
new file mode 100644
index 0000000..dacf34a
--- /dev/null
+++ b/frontend/app/pages/dashboard/student/internship/edit/[id].vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+ ...
+
+
+
+
+
\ No newline at end of file
From 1de41fda55d24c1afe796da5b944fd61f40fab65 Mon Sep 17 00:00:00 2001
From: br0kenpixel <23280129+br0kenpixel@users.noreply.github.com>
Date: Tue, 28 Oct 2025 10:35:07 +0100
Subject: [PATCH 06/10] feat: add basic internship editor
---
frontend/app/components/InternshipEditor.vue | 133 ++++++++++++++++++
.../app/pages/dashboard/student/index.vue | 2 +-
.../dashboard/student/internship/create.vue | 36 +++++
frontend/app/types/internships.ts | 10 +-
4 files changed, 175 insertions(+), 6 deletions(-)
create mode 100644 frontend/app/components/InternshipEditor.vue
create mode 100644 frontend/app/pages/dashboard/student/internship/create.vue
diff --git a/frontend/app/components/InternshipEditor.vue b/frontend/app/components/InternshipEditor.vue
new file mode 100644
index 0000000..256b86a
--- /dev/null
+++ b/frontend/app/components/InternshipEditor.vue
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Pridať
+
+
+
+
+
diff --git a/frontend/app/pages/dashboard/student/index.vue b/frontend/app/pages/dashboard/student/index.vue
index 51fb996..3f58f3e 100644
--- a/frontend/app/pages/dashboard/student/index.vue
+++ b/frontend/app/pages/dashboard/student/index.vue
@@ -38,7 +38,7 @@ const { data, error } = await useSanctumFetch('/api/internships');
-
+
Pridať
diff --git a/frontend/app/pages/dashboard/student/internship/create.vue b/frontend/app/pages/dashboard/student/internship/create.vue
new file mode 100644
index 0000000..c0a5a4e
--- /dev/null
+++ b/frontend/app/pages/dashboard/student/internship/create.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
+ Vytvorenie praxe
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/app/types/internships.ts b/frontend/app/types/internships.ts
index 3aa05a1..67f9768 100644
--- a/frontend/app/types/internships.ts
+++ b/frontend/app/types/internships.ts
@@ -15,11 +15,11 @@ export interface Internship {
};
export interface NewInternship {
- user_id: string;
- company_id: string;
- start: number;
- end: number;
- year_of_study: boolean;
+ user_id: number;
+ company_id: number;
+ start: string;
+ end: string;
+ year_of_study: number;
semester: string;
position_description: string;
agreement?: Uint8Array;
From 4979b4ddd364055915712d1c1a715970002a996c Mon Sep 17 00:00:00 2001
From: br0kenpixel <23280129+br0kenpixel@users.noreply.github.com>
Date: Fri, 31 Oct 2025 14:19:16 +0100
Subject: [PATCH 07/10] fix: update `CompanyData` types
---
frontend/app/types/company_data.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/frontend/app/types/company_data.ts b/frontend/app/types/company_data.ts
index 8d5f639..5e9e687 100644
--- a/frontend/app/types/company_data.ts
+++ b/frontend/app/types/company_data.ts
@@ -1,9 +1,11 @@
+import type { User } from "./user";
+
export interface CompanyData {
id: number;
name: string;
address: string;
ico: number;
- contact: number;
+ contact: User;
hiring: boolean;
};
From f388f093e35352b64979c58222f0b4521b7452d8 Mon Sep 17 00:00:00 2001
From: br0kenpixel <23280129+br0kenpixel@users.noreply.github.com>
Date: Fri, 31 Oct 2025 14:20:10 +0100
Subject: [PATCH 08/10] feat: implement internship creation and company listing
---
.../Http/Controllers/CompanyController.php | 11 ++++
.../Http/Controllers/InternshipController.php | 54 ++++++++++++++++++-
backend/routes/api.php | 13 ++++-
3 files changed, 76 insertions(+), 2 deletions(-)
diff --git a/backend/app/Http/Controllers/CompanyController.php b/backend/app/Http/Controllers/CompanyController.php
index 171eaad..fce832f 100644
--- a/backend/app/Http/Controllers/CompanyController.php
+++ b/backend/app/Http/Controllers/CompanyController.php
@@ -3,10 +3,21 @@
namespace App\Http\Controllers;
use App\Models\Company;
+use App\Models\User;
use Illuminate\Http\Request;
class CompanyController extends Controller
{
+ public function all_simple() {
+ $companies = Company::all()->makeHidden(['created_at', 'updated_at']);
+
+ $companies->each(function ($company) {
+ $company->contact = User::find($company->contact)->makeHidden(['created_at', 'updated_at', 'email_verified_at']);
+ });
+
+ return response()->json($companies);
+ }
+
/**
* Display a listing of the resource.
*/
diff --git a/backend/app/Http/Controllers/InternshipController.php b/backend/app/Http/Controllers/InternshipController.php
index 69599d1..5d2a680 100644
--- a/backend/app/Http/Controllers/InternshipController.php
+++ b/backend/app/Http/Controllers/InternshipController.php
@@ -53,7 +53,59 @@ class InternshipController extends Controller
*/
public function store(Request $request)
{
- //
+ $user = auth()->user();
+
+ $request->validate([
+ 'company_id' => ['required', 'exists:companies,id'],
+ 'start' => ['required', 'date'],
+ 'end' => ['required', 'date', 'after:start'],
+ 'year_of_study' => ['required', 'integer', 'between:1,5'],
+ 'semester' => ['required', 'in:WINTER,SUMMER'],
+ 'position_description' => ['required', 'string', 'min:1']
+ ]);
+
+ $request->merge([
+ 'start' => date('Y-m-d H:i:s', strtotime($request->start)),
+ 'end' => date('Y-m-d H:i:s', strtotime($request->end))
+ ]);
+
+ // je už nejaká prax ktorá sa časovo prekrýva?
+ $existingInternship = Internship::where('user_id', $user->id)
+ ->where(function ($query) use ($request) {
+ $query->whereBetween('start', [$request->start, $request->end])
+ ->orWhereBetween('end', [$request->start, $request->end])
+ ->orWhere(function ($q) use ($request) {
+ $q->where('start', '<=', $request->start)
+ ->where('end', '>=', $request->end);
+ });
+ })
+ ->exists();
+ if ($existingInternship) {
+ return response()->json([
+ 'message' => 'You already have an internship during this period.'
+ ], 422);
+ }
+
+ $Internship = Internship::create([
+ 'user_id' => $user->id,
+ 'company_id' => $request->company_id,
+ 'start' => $request->start,
+ 'end' => $request->end,
+ 'year_of_study' => $request->year_of_study,
+ 'semester' => $request->semester,
+ 'position_description' => $request->position_description,
+ 'agreement' => null
+ ]);
+
+ InternshipStatus::create([
+ 'internship_id' => $Internship->id,
+ 'status' => 'SUBMITTED',
+ 'changed' => now(),
+ 'note' => null,
+ 'modified_by' => $user->id
+ ]);
+
+ return response()->noContent();
}
/**
diff --git a/backend/routes/api.php b/backend/routes/api.php
index 196a44c..392241f 100644
--- a/backend/routes/api.php
+++ b/backend/routes/api.php
@@ -1,6 +1,7 @@
middleware(['guest', 'throttle:6,1'])
->name('password.reset');
-Route::get('/internships', [InternshipController::class, 'all'])->middleware(['auth'])->name("api.internships");
\ No newline at end of file
+Route::prefix('/internships')->group(function () {
+ Route::get("/", [InternshipController::class, 'all'])->name("api.internships");
+
+ Route::middleware("auth:sanctum")->group(function () {
+ Route::put("/new", [InternshipController::class, 'store'])->name("api.internships.create");
+ });
+});
+
+Route::prefix('/companies')->middleware("auth:sanctum")->group(function () {
+ Route::get("/simple", [CompanyController::class, 'all_simple']);
+});
\ No newline at end of file
From fda5bc2473d97797eb58cc960856fc7b4cd2b1d7 Mon Sep 17 00:00:00 2001
From: br0kenpixel <23280129+br0kenpixel@users.noreply.github.com>
Date: Fri, 31 Oct 2025 14:20:42 +0100
Subject: [PATCH 09/10] feat: implement internship creation interface on
frontend
---
frontend/app/components/InternshipEditor.vue | 36 +++++++++++++++----
.../dashboard/student/internship/create.vue | 36 +++++++++++++++++--
2 files changed, 63 insertions(+), 9 deletions(-)
diff --git a/frontend/app/components/InternshipEditor.vue b/frontend/app/components/InternshipEditor.vue
index 256b86a..29654cb 100644
--- a/frontend/app/components/InternshipEditor.vue
+++ b/frontend/app/components/InternshipEditor.vue
@@ -90,11 +90,22 @@ function triggerSubmit() {
year_of_study: form.value.year_of_study,
semester: form.value.semester === "Zimný" ? "WINTER" : "SUMMER",
position_description: form.value.description
- }
+ };
props.submit(new_internship);
}
+function companyListProps(company: CompanyData) {
+ return {
+ title: company.name,
+ subtitle: `IČO: ${company.ico}, Zodpovedný: ${company.contact.name}, ${!company.hiring ? "ne" : ""}prijímajú nových študentov`
+ };
+}
+
+function yearOfStudyValueHandler(item: { title: string, subtitle: string }) {
+ return parseInt(item.title) || 0;
+}
+
const { data, error } = await useSanctumFetch('/api/companies/simple');
@@ -105,16 +116,25 @@ const { data, error } = await useSanctumFetch('/api/companies/sim
+ :item-value="yearOfStudyValueHandler" :rules="[rules.required]">
-
+
-
+
+
+
+
+
+
+
+
+
@@ -130,4 +150,8 @@ form {
width: 80%;
margin: 0 auto;
}
+
+.alert {
+ margin-bottom: 10px;
+}
diff --git a/frontend/app/pages/dashboard/student/internship/create.vue b/frontend/app/pages/dashboard/student/internship/create.vue
index c0a5a4e..8aca6dd 100644
--- a/frontend/app/pages/dashboard/student/internship/create.vue
+++ b/frontend/app/pages/dashboard/student/internship/create.vue
@@ -1,5 +1,5 @@
@@ -22,7 +40,15 @@ const user = useSanctumUser();
-
+
+
+
+
+
+
+
@@ -33,4 +59,8 @@ const user = useSanctumUser();
padding-right: 10px;
padding-bottom: 10px;
}
+
+.alert {
+ margin-bottom: 10px;
+}
\ No newline at end of file
From e0335441fe9b519fd86d9f34cbc33eb9223caf4f Mon Sep 17 00:00:00 2001
From: br0kenpixel <23280129+br0kenpixel@users.noreply.github.com>
Date: Fri, 31 Oct 2025 14:21:34 +0100
Subject: [PATCH 10/10] fix: add missing semicolon in internship registration
navigation
---
frontend/app/pages/dashboard/student/internship/create.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/app/pages/dashboard/student/internship/create.vue b/frontend/app/pages/dashboard/student/internship/create.vue
index 8aca6dd..c58f787 100644
--- a/frontend/app/pages/dashboard/student/internship/create.vue
+++ b/frontend/app/pages/dashboard/student/internship/create.vue
@@ -24,7 +24,7 @@ async function handleInternshipRegistration(internship: NewInternship) {
body: internship
});
- navigateTo("/dashboard/student")
+ navigateTo("/dashboard/student");
} catch (e: any) {
error.value = e.data?.message as string;
} finally {