diff --git a/app/Actions/ActivateSemesterAction.php b/app/Actions/ActivateSemesterAction.php index d4a1afb..bceffd5 100644 --- a/app/Actions/ActivateSemesterAction.php +++ b/app/Actions/ActivateSemesterAction.php @@ -24,6 +24,10 @@ public function execute(Semester $semester): void $semester->update(["active" => !$semester->active]); + if ($semester->active) { + Semester::query()->whereNot("id", $semester->id)->update(["active" => false]); + } + $this->db->commit(); } catch (Exception $exception) { $this->db->rollBack(); diff --git a/app/DTOs/CoursePublicData.php b/app/DTOs/CoursePublicData.php index f689701..c702a42 100644 --- a/app/DTOs/CoursePublicData.php +++ b/app/DTOs/CoursePublicData.php @@ -8,6 +8,7 @@ use Keating\Enums\ClassType; use Keating\Enums\SemesterName; use Keating\Models\Course; +use Keating\Models\CourseSemester; readonly class CoursePublicData { @@ -40,7 +41,11 @@ public static function fromModel(Course $course, ?Collection $activeSemesters = typeAbbreviation: ClassType::abbreviationLabels()[$course->type], field: $course->field->name, fieldAbbreviation: $course->field->abbreviation, - active: $activeSemesters && ($activeSemesters->contains($course->getRomanizedSemester()) || $activeSemesters->contains($course->semester)), + active: CourseSemester::query() + ->join("semesters", "course_semester.semester_id", "=", "semesters.id") + ->where("semesters.active", true) + ->where("course_semester.course_id", $course->id) + ->count() > 0, ); } } diff --git a/app/DTOs/CourseSemesterData.php b/app/DTOs/CourseSemesterData.php index f9cf7f2..5297d42 100644 --- a/app/DTOs/CourseSemesterData.php +++ b/app/DTOs/CourseSemesterData.php @@ -11,6 +11,7 @@ public function __construct( public string $id, public string $course, + public string $courseId, public string $semester, public string $semesterId, public int $groupsCount, @@ -21,6 +22,7 @@ public static function fromModel(CourseSemester $course): self return new self( id: $course->id, course: $course->course->name, + courseId: $course->course->id, semester: $course->semester->name, semesterId: $course->semester->id, groupsCount: $course->groups_count ?? $course->groups->count(), diff --git a/app/Http/Controllers/Dashboard/CourseSemesterController.php b/app/Http/Controllers/Dashboard/CourseSemesterController.php index 7ddfff9..13a8254 100644 --- a/app/Http/Controllers/Dashboard/CourseSemesterController.php +++ b/app/Http/Controllers/Dashboard/CourseSemesterController.php @@ -4,6 +4,7 @@ namespace Keating\Http\Controllers\Dashboard; +use Exception; use Illuminate\Http\RedirectResponse; use Inertia\Response; use Keating\DTOs\CourseSemesterData; @@ -20,7 +21,12 @@ class CourseSemesterController public function index(): Response { $courses = CourseSemester::query() + ->join("semesters", "semesters.id", "=", "course_semester.semester_id") + ->join("courses", "courses.id", "=", "course_semester.course_id") ->withCount("groups") + ->orderByDesc("semesters.active") + ->orderByDesc("semesters.id") + ->orderBy("courses.semester") ->orderBy("created_at") ->get(); @@ -49,22 +55,17 @@ public function store(CourseSemesterRequest $request): RedirectResponse ->with("success", "Dodano kurs"); } - public function show(CourseSemester $course): Response - { - return inertia("Dashboard/CourseSemester/Show", [ - "course" => CourseSemesterData::fromModel($course), - "groups" => $course->groups->map(fn($group): GroupData => GroupData::fromModel($group)), - "studyForms" => Options::forEnum(StudyForm::class)->toArray(), - ]); - } - + /** + * @throws Exception + */ public function edit(CourseSemester $course): Response { return inertia("Dashboard/CourseSemester/Edit", [ - "course" => $course, + "course" => CourseSemesterData::fromModel($course), + "courses" => Course::query()->get(["id", "name"]), + "semesters" => Semester::query()->orderByDesc("id")->get(["id", "name"]), + "groups" => $course->groups->map(fn($group): GroupData => GroupData::fromModel($group)), "studyForms" => Options::forEnum(StudyForm::class)->toArray(), - "courses" => Course::all(["id", "name"]), - "semesters" => Semester::all(["id", "name"]), ]); } diff --git a/app/Http/Controllers/Dashboard/SemesterController.php b/app/Http/Controllers/Dashboard/SemesterController.php index aaab465..222774a 100644 --- a/app/Http/Controllers/Dashboard/SemesterController.php +++ b/app/Http/Controllers/Dashboard/SemesterController.php @@ -16,7 +16,9 @@ class SemesterController public function index(): Response { $semesters = Semester::query() + ->orderByDesc("active") ->orderByDesc("created_at") + ->orderByDesc("id") ->get(); return inertia("Dashboard/Semester/Index", [ @@ -71,7 +73,7 @@ public function toggleActive(Semester $semester, ActivateSemesterAction $activat return redirect()->back() ->with("success", "Semestr aktywny"); - } catch (Exception $e) { + } catch (Exception) { return redirect()->back() ->with("error", "Wystąpił nieoczekiwany problem"); } diff --git a/app/Http/Controllers/Public/CourseController.php b/app/Http/Controllers/Public/CourseController.php index db60712..c003455 100644 --- a/app/Http/Controllers/Public/CourseController.php +++ b/app/Http/Controllers/Public/CourseController.php @@ -7,20 +7,15 @@ use Inertia\Response; use Keating\DTOs\CoursePublicData; use Keating\Models\Course; -use Keating\Models\Semester; class CourseController { public function index(): Response { - $activeSemesters = Semester::query() - ->where("active", true) - ->pluck("name"); - $courses = Course::query() ->with("field") ->get() - ->map(fn(Course $course): CoursePublicData => CoursePublicData::fromModel($course, $activeSemesters)) + ->map(fn(Course $course): CoursePublicData => CoursePublicData::fromModel($course)) ->sortBy("semester") ->sortByDesc("active"); diff --git a/app/Http/Controllers/Public/GradeController.php b/app/Http/Controllers/Public/GradeController.php index 921a63b..fb8916c 100644 --- a/app/Http/Controllers/Public/GradeController.php +++ b/app/Http/Controllers/Public/GradeController.php @@ -47,19 +47,18 @@ public function __invoke(Request $request, ?Semester $semester = null, ?CourseSe ->where("active", true) ->orderBy("priority") ->get(); + $students = $group->students() ->whereNot("index_number", $index) ->inRandomOrder() - ->take(8) ->get() - ->push($studentByIndex) - ->sortBy("index_number") + ->prepend($studentByIndex) ->map(fn(Student $student): StudentData => StudentData::fromModels($student, $studentByIndex, $gradeColumns)); } } return inertia("Public/Grade", [ - "semesters" => Semester::query()->get(["name", "id"]), + "semesters" => Semester::query()->orderByDesc("id")->get(["name", "id"]), "semester" => $semester, "courses" => $courses, "course" => $course, diff --git a/app/Models/Field.php b/app/Models/Field.php index 7cf2e68..45ba2a0 100644 --- a/app/Models/Field.php +++ b/app/Models/Field.php @@ -22,6 +22,7 @@ class Field extends Model use HasUlids; protected $fillable = [ + "id", "name", "abbreviation", ]; diff --git a/database/factories/GroupFactory.php b/database/factories/GroupFactory.php index e6204c1..ea6597b 100644 --- a/database/factories/GroupFactory.php +++ b/database/factories/GroupFactory.php @@ -13,7 +13,7 @@ class GroupFactory extends Factory public function definition(): array { return [ - "name" => fake()->asciify("******"), + "name" => fake()->numerify("s#INF#"), "course_semester_id" => CourseSemester::factory(), "form" => StudyForm::Stationary->value, ]; diff --git a/database/factories/SemesterFactory.php b/database/factories/SemesterFactory.php index 7929ba2..00b0e42 100644 --- a/database/factories/SemesterFactory.php +++ b/database/factories/SemesterFactory.php @@ -11,7 +11,7 @@ class SemesterFactory extends Factory public function definition(): array { return [ - "name" => fake()->numberBetween(1, 7), + "name" => fake()->randomElement(["zimowy", "letni"]) . " " . fake()->year(), "active" => fake()->boolean, ]; } diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 4b5de92..598ae00 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -5,12 +5,16 @@ namespace Database\Seeders; use Illuminate\Database\Seeder; +use Keating\Enums\SemesterName; +use Keating\Models\Course; use Keating\Models\CourseSemester; +use Keating\Models\Field; use Keating\Models\Grade; use Keating\Models\GradeColumn; use Keating\Models\Group; use Keating\Models\Section; use Keating\Models\SectionSettings; +use Keating\Models\Semester; use Keating\Models\Setting; use Keating\Models\Student; use Keating\Models\User; @@ -20,6 +24,7 @@ class DatabaseSeeder extends Seeder public function run(): void { User::factory()->create(["email" => "admin@example.com"]); + Setting::factory()->create(); Section::factory(4)->counter()->create(); Section::factory(3)->about()->create(); @@ -29,12 +34,63 @@ public function run(): void "counters_enabled" => true, "contact_enabled" => true, ]); - $this->seedGrades(); + + $this->seedRealData(); } - protected function seedGrades(): void + protected function seedRealData(): void { - $courses = CourseSemester::factory(5)->create(); + $semesters = Semester::factory()->count(5)->sequence( + ["name" => "zimowy 2022/23", "active" => false], + ["name" => "letni 2022/23", "active" => false], + ["name" => "zimowy 2023/24", "active" => false], + ["name" => "letni 2023/24", "active" => false], + ["name" => "zimowy 2024/25", "active" => true], + )->create(); + + $fields = Field::factory()->count(3)->sequence( + ["name" => "Informatyka", "abbreviation" => "INF"], + ["name" => "Informatyka, specjalność Programowanie", "abbreviation" => "INF/PAM"], + ["name" => "Informatyka, specjalność Grafika", "abbreviation" => "INF/GK"], + )->create(); + + $courses = Course::factory()->count(3)->sequence( + [ + "name" => "Programowanie obiektowe", + "abbreviation" => "PO", + "semester" => 3, + "type" => "laboratory", + "field_id" => $fields[1]->id, + "semester_name" => SemesterName::Winter->value, + ], + [ + "name" => "Programowanie systemów internetowych", + "abbreviation" => "PSI", + "semester" => 4, + "type" => "lecture", + "field_id" => $fields[2]->id, + "semester_name" => SemesterName::Summer->value, + ], + [ + "name" => "Programowanie systemów internetowych", + "abbreviation" => "PSI", + "semester" => 4, + "type" => "project", + "field_id" => $fields[2]->id, + "semester_name" => SemesterName::Summer->value, + ], + )->create(); + + $courses = CourseSemester::factory(7)->sequence( + ["course_id" => $courses[0]->id, "semester_id" => $semesters[4]->id], + ["course_id" => $courses[1]->id, "semester_id" => $semesters[3]->id], + ["course_id" => $courses[2]->id, "semester_id" => $semesters[3]->id], + ["course_id" => $courses[0]->id, "semester_id" => $semesters[2]->id], + ["course_id" => $courses[1]->id, "semester_id" => $semesters[1]->id], + ["course_id" => $courses[2]->id, "semester_id" => $semesters[1]->id], + ["course_id" => $courses[0]->id, "semester_id" => $semesters[0]->id], + )->create(); + $students = Student::factory(100)->create(); foreach ($courses as $course) { diff --git a/database/seeders/DemoSeeder.php b/database/seeders/DemoSeeder.php deleted file mode 100644 index d7a6b55..0000000 --- a/database/seeders/DemoSeeder.php +++ /dev/null @@ -1,16 +0,0 @@ -create(); - } -} diff --git a/resources/js/Components/SectionHeader.vue b/resources/js/Components/SectionHeader.vue index a781ae1..265d237 100644 --- a/resources/js/Components/SectionHeader.vue +++ b/resources/js/Components/SectionHeader.vue @@ -3,7 +3,7 @@

-

+

diff --git a/resources/js/Layouts/PublicLayout.vue b/resources/js/Layouts/PublicLayout.vue index 82a8b34..06cdabf 100644 --- a/resources/js/Layouts/PublicLayout.vue +++ b/resources/js/Layouts/PublicLayout.vue @@ -80,7 +80,7 @@ const mobileMenuOpen = ref(false)

- 2023 + 2024 keating management system developed at Blumilk diff --git a/resources/js/Pages/Dashboard/ContactInfo/Edit.vue b/resources/js/Pages/Dashboard/ContactInfo/Edit.vue index fbf425d..2a85522 100644 --- a/resources/js/Pages/Dashboard/ContactInfo/Edit.vue +++ b/resources/js/Pages/Dashboard/ContactInfo/Edit.vue @@ -47,7 +47,7 @@ function updateContactInfo() { Id - + diff --git a/resources/js/Pages/Dashboard/ContactInfo/Index.vue b/resources/js/Pages/Dashboard/ContactInfo/Index.vue index d13608e..dd701d0 100644 --- a/resources/js/Pages/Dashboard/ContactInfo/Index.vue +++ b/resources/js/Pages/Dashboard/ContactInfo/Index.vue @@ -9,7 +9,6 @@ import Button from '@/Shared/Components/Buttons/Button.vue' import EmptyState from '@/Shared/Components/EmptyState/EmptyState.vue' import RemoveModal from '@/Shared/Modals/RemoveModal.vue' import { ref } from 'vue' -import { PencilSquareIcon, XCircleIcon } from '@heroicons/vue/24/outline' import ManagementHeader from '@/Shared/Components/ManagementHeader.vue' import ManagementHeaderItem from '@/Shared/Components/ManagementHeaderItem.vue' import StyledLink from '@/Shared/Components/StyledLink.vue' @@ -74,10 +73,10 @@ const contactInfoToDeleteId = ref(0) - + edytuj diff --git a/resources/js/Pages/Dashboard/Course/Edit.vue b/resources/js/Pages/Dashboard/Course/Edit.vue index 82ace59..fc3e09a 100644 --- a/resources/js/Pages/Dashboard/Course/Edit.vue +++ b/resources/js/Pages/Dashboard/Course/Edit.vue @@ -12,7 +12,6 @@ import ManagementHeader from '@/Shared/Components/ManagementHeader.vue' import ManagementHeaderItem from '@/Shared/Components/ManagementHeaderItem.vue' import TextAreaEditor from '../../../Shared/Forms/TextAreaEditor.vue' - const props = defineProps({ course: Object, classTypes: Array, @@ -20,7 +19,6 @@ const props = defineProps({ semesterNames: Array, }) - const form = useForm({ name: props.course.name, slug: props.course.slug, @@ -58,7 +56,7 @@ function updateCourse() { Id - + diff --git a/resources/js/Pages/Dashboard/Course/Index.vue b/resources/js/Pages/Dashboard/Course/Index.vue index c0bc8a0..3e6276e 100644 --- a/resources/js/Pages/Dashboard/Course/Index.vue +++ b/resources/js/Pages/Dashboard/Course/Index.vue @@ -10,7 +10,6 @@ import RemoveModal from '@/Shared/Modals/RemoveModal.vue' import { ref } from 'vue' import ManagementHeader from '@/Shared/Components/ManagementHeader.vue' import ManagementHeaderItem from '@/Shared/Components/ManagementHeaderItem.vue' -import { PencilSquareIcon, XCircleIcon } from '@heroicons/vue/24/outline' import StyledLink from '@/Shared/Components/StyledLink.vue' defineProps({ @@ -40,7 +39,7 @@ const courseToDeleteId = ref(0) @@ -84,10 +83,10 @@ const courseToDeleteId = ref(0) - + edytuj diff --git a/resources/js/Pages/Dashboard/CourseSemester/Edit.vue b/resources/js/Pages/Dashboard/CourseSemester/Edit.vue index f8a13aa..7285187 100644 --- a/resources/js/Pages/Dashboard/CourseSemester/Edit.vue +++ b/resources/js/Pages/Dashboard/CourseSemester/Edit.vue @@ -1,31 +1,73 @@ @@ -34,40 +76,37 @@ function updateCourse() {

-
+ +
Id - + Kurs - + Semestr - +
@@ -77,6 +116,112 @@ function updateCourse() {
+ + + + + + + + + +
+
+
+
+ + + Id + + + + + + Nazwa + + + + + + + Tryb studiów + + + + +
+ + Zapisz + +
+
+
+
+
+
+
+ {{ group.name }} +
+
+ + oceny + + + studenci + + + +
+
+
+
+ + diff --git a/resources/js/Pages/Dashboard/CourseSemester/Grade/Index.vue b/resources/js/Pages/Dashboard/CourseSemester/Grade/Index.vue index de388e7..54e3ff1 100644 --- a/resources/js/Pages/Dashboard/CourseSemester/Grade/Index.vue +++ b/resources/js/Pages/Dashboard/CourseSemester/Grade/Index.vue @@ -127,7 +127,7 @@ watch(searchForm, debounce(() => { diff --git a/resources/js/Pages/Dashboard/CourseSemester/Index.vue b/resources/js/Pages/Dashboard/CourseSemester/Index.vue index f9317be..f057592 100644 --- a/resources/js/Pages/Dashboard/CourseSemester/Index.vue +++ b/resources/js/Pages/Dashboard/CourseSemester/Index.vue @@ -10,7 +10,6 @@ import RemoveModal from '@/Shared/Modals/RemoveModal.vue' import { ref } from 'vue' import ManagementHeader from '@/Shared/Components/ManagementHeader.vue' import ManagementHeaderItem from '@/Shared/Components/ManagementHeaderItem.vue' -import { PencilSquareIcon, XCircleIcon, EyeIcon } from '@heroicons/vue/24/outline' import StyledLink from '@/Shared/Components/StyledLink.vue' defineProps({ @@ -41,7 +40,7 @@ const courseToDeleteId = ref(0) @@ -86,13 +85,10 @@ const courseToDeleteId = ref(0) - - - - + zarządzaj diff --git a/resources/js/Pages/Dashboard/CourseSemester/Show.vue b/resources/js/Pages/Dashboard/CourseSemester/Show.vue deleted file mode 100644 index 8b617ee..0000000 --- a/resources/js/Pages/Dashboard/CourseSemester/Show.vue +++ /dev/null @@ -1,217 +0,0 @@ - - - diff --git a/resources/js/Pages/Dashboard/CourseSemester/Student/Index.vue b/resources/js/Pages/Dashboard/CourseSemester/Student/Index.vue index c70dde8..a9e5a56 100644 --- a/resources/js/Pages/Dashboard/CourseSemester/Student/Index.vue +++ b/resources/js/Pages/Dashboard/CourseSemester/Student/Index.vue @@ -13,7 +13,7 @@ import { Inertia } from '@inertiajs/inertia' import { debounce } from 'lodash' import TextInput from '@/Shared/Forms/TextInput.vue' import { useForm } from '@inertiajs/inertia-vue3' -import { XCircleIcon, PlusIcon } from '@heroicons/vue/24/outline' +import { PlusIcon } from '@heroicons/vue/24/outline' import ManagementHeader from '@/Shared/Components/ManagementHeader.vue' import ManagementHeaderItem from '@/Shared/Components/ManagementHeaderItem.vue' @@ -55,8 +55,10 @@ watch(form, debounce(() => {
- +
-
+
- {{ student.first_name }} {{ student.surname }}
- {{ student.index_number }} + {{ student.first_name }} {{ student.surname }}
{{ student.index_number }}
diff --git a/resources/js/Pages/Dashboard/FAQ/Edit.vue b/resources/js/Pages/Dashboard/FAQ/Edit.vue index d202df9..993a8a5 100644 --- a/resources/js/Pages/Dashboard/FAQ/Edit.vue +++ b/resources/js/Pages/Dashboard/FAQ/Edit.vue @@ -46,7 +46,7 @@ function editFAQ() { Id - + diff --git a/resources/js/Pages/Dashboard/FAQ/Index.vue b/resources/js/Pages/Dashboard/FAQ/Index.vue index 3d4807b..0e4c11b 100644 --- a/resources/js/Pages/Dashboard/FAQ/Index.vue +++ b/resources/js/Pages/Dashboard/FAQ/Index.vue @@ -10,7 +10,6 @@ import RemoveModal from '@/Shared/Modals/RemoveModal.vue' import { ref } from 'vue' import ManagementHeader from '@/Shared/Components/ManagementHeader.vue' import ManagementHeaderItem from '@/Shared/Components/ManagementHeaderItem.vue' -import { PencilSquareIcon, XCircleIcon } from '@heroicons/vue/24/outline' import StyledLink from '@/Shared/Components/StyledLink.vue' defineProps({ @@ -66,10 +65,10 @@ const faqToDeleteId = ref(0) - + edytuj diff --git a/resources/js/Pages/Dashboard/Field/Index.vue b/resources/js/Pages/Dashboard/Field/Index.vue index 674eca1..625d316 100644 --- a/resources/js/Pages/Dashboard/Field/Index.vue +++ b/resources/js/Pages/Dashboard/Field/Index.vue @@ -10,7 +10,6 @@ import RemoveModal from '@/Shared/Modals/RemoveModal.vue' import { ref } from 'vue' import ManagementHeader from '@/Shared/Components/ManagementHeader.vue' import ManagementHeaderItem from '@/Shared/Components/ManagementHeaderItem.vue' -import { PencilSquareIcon, XCircleIcon } from '@heroicons/vue/24/outline' import StyledLink from '@/Shared/Components/StyledLink.vue' defineProps({ @@ -40,7 +39,7 @@ const fieldToDeleteId = ref(0) @@ -72,10 +71,10 @@ const fieldToDeleteId = ref(0) - + edytuj diff --git a/resources/js/Pages/Dashboard/News/Index.vue b/resources/js/Pages/Dashboard/News/Index.vue index 4b62f01..67460a8 100644 --- a/resources/js/Pages/Dashboard/News/Index.vue +++ b/resources/js/Pages/Dashboard/News/Index.vue @@ -13,7 +13,6 @@ import { Inertia } from '@inertiajs/inertia' import { debounce } from 'lodash' import TextInput from '@/Shared/Forms/TextInput.vue' import { useForm } from '@inertiajs/inertia-vue3' -import { PencilSquareIcon, XCircleIcon } from '@heroicons/vue/24/outline' import ManagementHeader from '@/Shared/Components/ManagementHeader.vue' import ManagementHeaderItem from '@/Shared/Components/ManagementHeaderItem.vue' import StyledLink from '@/Shared/Components/StyledLink.vue' @@ -98,10 +97,10 @@ watch(form, debounce(() => { - + edytuj diff --git a/resources/js/Pages/Dashboard/Section/Show.vue b/resources/js/Pages/Dashboard/Section/Show.vue index d24fee6..8ca70b6 100644 --- a/resources/js/Pages/Dashboard/Section/Show.vue +++ b/resources/js/Pages/Dashboard/Section/Show.vue @@ -8,7 +8,6 @@ import FormError from '@/Shared/Forms/FormError.vue' import { useForm } from '@inertiajs/inertia-vue3' import ManagementHeader from '@/Shared/Components/ManagementHeader.vue' import ManagementHeaderItem from '@/Shared/Components/ManagementHeaderItem.vue' -import { PencilSquareIcon, XCircleIcon } from '@heroicons/vue/24/outline' import EmptyState from '@/Shared/Components/EmptyState/EmptyState.vue' import TableCell from '@/Shared/Components/Table/TableCell.vue' import TableRow from '@/Shared/Components/Table/TableRow.vue' @@ -210,10 +209,10 @@ function updateSectionSettings() { @@ -251,10 +250,10 @@ function updateSectionSettings() { diff --git a/resources/js/Pages/Dashboard/Semester/Index.vue b/resources/js/Pages/Dashboard/Semester/Index.vue index 72bcc8e..d769487 100644 --- a/resources/js/Pages/Dashboard/Semester/Index.vue +++ b/resources/js/Pages/Dashboard/Semester/Index.vue @@ -11,7 +11,6 @@ import { ref } from 'vue' import { Method } from '@inertiajs/inertia' import ManagementHeader from '@/Shared/Components/ManagementHeader.vue' import ManagementHeaderItem from '@/Shared/Components/ManagementHeaderItem.vue' -import { PencilSquareIcon, XCircleIcon, CheckIcon } from '@heroicons/vue/24/outline' import StyledLink from '@/Shared/Components/StyledLink.vue' defineProps({ @@ -41,11 +40,12 @@ const semesterToDeleteId = ref(0) +