Skip to content

Commit

Permalink
#11 - courses in semester (#56)
Browse files Browse the repository at this point in the history
* #11 - wip: added models, migrations and first views

* #11 - wip: course in semestr crud, student groups crud

* #11 - wip: added adding students to group

* #11 - fixes

* #11 - added tests

* #11 - wip: some fixes and updates

* #11 - cr fixes

* Apply suggestions from code review

Co-authored-by: Krzysztof Rewak <krzysztof.rewak@blumilk.pl>

* #11 - cr fixes

---------

Co-authored-by: Krzysztof Rewak <krzysztof.rewak@blumilk.pl>
  • Loading branch information
kamilpiech97 and krzysztofrewak authored Oct 9, 2023
1 parent 65a28f9 commit 0e78000
Show file tree
Hide file tree
Showing 26 changed files with 1,380 additions and 3 deletions.
87 changes: 87 additions & 0 deletions app/Http/Controllers/Dashboard/CourseSemesterController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\Dashboard;

use App\Enums\StudyForm;
use App\Http\Controllers\Controller;
use App\Http\Requests\CourseSemesterRequest;
use App\Http\Resources\CourseSemesterResource;
use App\Http\Resources\GroupResource;
use App\Models\Course;
use App\Models\CourseSemester;
use App\Models\Semester;
use Illuminate\Http\RedirectResponse;
use Inertia\Response;
use Spatie\LaravelOptions\Options;

class CourseSemesterController extends Controller
{
public function index(): Response
{
$courses = CourseSemester::query()
->withCount("groups")
->orderBy("created_at")
->get();

return inertia("Dashboard/CourseSemester/Index", [
"courses" => CourseSemesterResource::collection($courses),
"total" => Course::query()->count(),
"lastUpdate" => CourseSemester::query()->orderByDesc("updated_at")->first()?->updated_at->diffForHumans(),
]);
}

public function create(): Response
{
return inertia("Dashboard/CourseSemester/Create", [
"courses" => Course::all(["id", "name"]),
"semesters" => Semester::all(["id", "name"]),
]);
}

public function store(CourseSemesterRequest $request): RedirectResponse
{
CourseSemester::query()->create($request->getData());

return redirect()
->route("course.semester.index")
->with("success", "Dodano kurs");
}

public function show(CourseSemester $course): Response
{
return inertia("Dashboard/CourseSemester/Show", [
"course" => new CourseSemesterResource($course->load("groups")),
"groups" => GroupResource::collection($course->groups),
"studyForms" => Options::forEnum(StudyForm::class)->toArray(),
]);
}

public function edit(CourseSemester $course): Response
{
return inertia("Dashboard/CourseSemester/Edit", [
"course" => $course,
"studyForms" => Options::forEnum(StudyForm::class)->toArray(),
"courses" => Course::all(["id", "name"]),
"semesters" => Semester::all(["id", "name"]),
]);
}

public function update(CourseSemesterRequest $request, CourseSemester $course): RedirectResponse
{
$course->update($request->getData());

return redirect()
->route("course.semester.index")
->with("success", "Zaktualizowano kurs");
}

public function destroy(CourseSemester $course): RedirectResponse
{
$course->delete();

return redirect()->back()
->with("success", "Usunięto kurs");
}
}
39 changes: 39 additions & 0 deletions app/Http/Controllers/Dashboard/GroupController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\Dashboard;

use App\Http\Controllers\Controller;
use App\Http\Requests\GroupRequest;
use App\Models\CourseSemester;
use App\Models\Group;
use Illuminate\Http\RedirectResponse;

class GroupController extends Controller
{
public function store(GroupRequest $request, CourseSemester $course): RedirectResponse
{
$course->groups()->create($request->validated());

return redirect()->back()
->with("success", "Dodano grupę");
}

public function update(GroupRequest $request, CourseSemester $course, Group $group): RedirectResponse
{
$group->update($request->validated());

return redirect()->back()
->with("success", "Zaktualizowano grupę");
}

public function destroy(CourseSemester $course, Group $group): RedirectResponse
{
$group->students()->detach($group->students);
$group->delete();

return redirect()->back()
->with("success", "Usunięto grupę");
}
}
61 changes: 61 additions & 0 deletions app/Http/Controllers/Dashboard/GroupStudentController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\Dashboard;

use App\Http\Controllers\Controller;
use App\Http\Resources\CourseSemesterResource;
use App\Models\CourseSemester;
use App\Models\Group;
use App\Models\Student;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Response;

class GroupStudentController extends Controller
{
public function index(Request $request, CourseSemester $course, Group $group): Response
{
$searchText = $request->query("search");
$students = $group->students()
->paginate()
->withQueryString();
$availableStudents = $searchText
? Student::query()
->whereNotIn("id", $group->students->pluck("id"))
->where(
fn(Builder $query): Builder => $query
->where("first_name", "ILIKE", "%$searchText%")
->orWhere("surname", "ILIKE", "%$searchText%")
->orWhere("index_number", "LIKE", "%$searchText%"),
)->get()
: [];

return inertia("Dashboard/CourseSemester/Student/Index", [
"course" => new CourseSemesterResource($course),
"group" => $group,
"students" => $students,
"availableStudents" => $availableStudents,
"search" => $searchText,
"total" => $group->students->count(),
]);
}

public function store(Request $request, CourseSemester $course, Group $group): RedirectResponse
{
$group->students()->sync(ids: $request->get("student"), detaching: false);

return redirect()->back()
->with("success", "Dodano studenta");
}

public function destroy(CourseSemester $course, Group $group, Student $student): RedirectResponse
{
$group->students()->detach($student);

return redirect()->back()
->with("success", "Usunięto grupę");
}
}
2 changes: 1 addition & 1 deletion app/Http/Controllers/Dashboard/StudentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function index(Request $request): Response
->when(
$searchText !== null,
fn(Builder $query): Builder => $query
->where("name", "ILIKE", "%$searchText%")
->where("first_name", "ILIKE", "%$searchText%")
->orWhere("surname", "ILIKE", "%$searchText%")
->orWhere("index_number", "LIKE", "%$searchText%"),
)
Expand Down
26 changes: 26 additions & 0 deletions app/Http/Requests/CourseSemesterRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CourseSemesterRequest extends FormRequest
{
public function rules(): array
{
return [
"course" => ["required", "exists:courses,id"],
"semester" => ["required", "exists:semesters,id"],
];
}

public function getData(): array
{
return [
"course_id" => $this->get("course"),
"semester_id" => $this->get("semester"),
];
}
}
20 changes: 20 additions & 0 deletions app/Http/Requests/GroupRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace App\Http\Requests;

use App\Enums\StudyForm;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\Enum;

class GroupRequest extends FormRequest
{
public function rules(): array
{
return [
"name" => ["required", "max:255"],
"form" => ["required", new Enum(StudyForm::class)],
];
}
}
25 changes: 25 additions & 0 deletions app/Http/Resources/CourseSemesterResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace App\Http\Resources;

use App\Models\CourseSemester;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class CourseSemesterResource extends JsonResource
{
public function toArray(Request $request): array
{
/** @var CourseSemester $course */
$course = $this;

return [
"id" => $course->id,
"course" => $course->course->name,
"semester" => $course->semester->name,
"groupsCount" => $course->groups_count ?? $course->groups->count(),
];
}
}
26 changes: 26 additions & 0 deletions app/Http/Resources/GroupResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace App\Http\Resources;

use App\Enums\StudyForm;
use App\Models\Group;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class GroupResource extends JsonResource
{
public function toArray(Request $request): array
{
/** @var Group $group */
$group = $this;

return [
"id" => $group->id,
"name" => $group->name,
"formAbbreviation" => StudyForm::abbreviationLabels()[$group->form->value],
"form" => $group->form->value,
];
}
}
52 changes: 52 additions & 0 deletions app/Models/CourseSemester.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Ramsey\Collection\Collection;

/**
* @property string $id
* @property string $name
* @property string $course_id
* @property string $semester_id
* @property Course $course
* @property Semester $semester
* @property Collection<Group> $groups
* @property Carbon $created_at
* @property Carbon $updated_at
*/
class CourseSemester extends Model
{
use HasFactory;
use HasUlids;

protected $table = "course_semester";
protected $fillable = [
"name",
"course_id",
"semester_id",
];

public function course(): BelongsTo
{
return $this->belongsTo(Course::class);
}

public function semester(): BelongsTo
{
return $this->belongsTo(Semester::class);
}

public function groups(): HasMany
{
return $this->hasMany(Group::class);
}
}
46 changes: 46 additions & 0 deletions app/Models/Group.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace App\Models;

use App\Enums\StudyForm;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

/**
* @property string $id
* @property string $name
* @property string $course_semester_id
* @property StudyForm $form
* @property Carbon $created_at
* @property Carbon $updated_at
*/
class Group extends Model
{
use HasFactory;
use HasUlids;

protected $fillable = [
"name",
"course_semester_id",
"form",
];
protected $casts = [
"form" => StudyForm::class,
];

public function course(): BelongsTo
{
return $this->belongsTo(CourseSemester::class);
}

public function students(): BelongsToMany
{
return $this->belongsToMany(Student::class, "student_group");
}
}
Loading

0 comments on commit 0e78000

Please sign in to comment.