diff --git a/app/Contracts/Interfaces/AttendanceInterface.php b/app/Contracts/Interfaces/AttendanceInterface.php index d4749aaa..a4213ade 100644 --- a/app/Contracts/Interfaces/AttendanceInterface.php +++ b/app/Contracts/Interfaces/AttendanceInterface.php @@ -12,5 +12,5 @@ interface AttendanceInterface extends GetInterface, StoreInterface, UpdateInterface, ShowInterface, DeleteInterface, PaginateInterface, WhereSchoolInterface { - // + public function AttendanceChart(mixed $id, mixed $year, mixed $month) : mixed; } diff --git a/app/Contracts/Interfaces/SemesterInterface.php b/app/Contracts/Interfaces/SemesterInterface.php index eef54505..c1fd7d23 100644 --- a/app/Contracts/Interfaces/SemesterInterface.php +++ b/app/Contracts/Interfaces/SemesterInterface.php @@ -8,7 +8,9 @@ use App\Contracts\Interfaces\Eloquent\ShowInterface; use App\Contracts\Interfaces\Eloquent\StoreInterface; use App\Contracts\Interfaces\Eloquent\UpdateInterface; +use App\Contracts\Interfaces\Eloquent\WhereInterface; -interface SemesterInterface extends GetInterface, StoreInterface { - // +interface SemesterInterface extends GetInterface, StoreInterface +{ + public function whereSchool(mixed $id): mixed; } diff --git a/app/Contracts/Repositories/AttendanceRepository.php b/app/Contracts/Repositories/AttendanceRepository.php index cbaef19b..b17957d8 100644 --- a/app/Contracts/Repositories/AttendanceRepository.php +++ b/app/Contracts/Repositories/AttendanceRepository.php @@ -46,4 +46,13 @@ public function whereSchool(mixed $id): mixed { return $this->model->query()->whereRelation('classroomStudent.classroom.schoolYear.school', 'id', $id)->latest()->paginate(10); } + + public function AttendanceChart(mixed $id, mixed $year, mixed $month): mixed + { + return $this->model->query() + ->whereRelation('classroomStudent.classroom.schoolYear', 'school_id', $id) + ->whereYear('created_at', $year) + ->whereMonth('created_at', $month) + ->count(); + } } diff --git a/app/Contracts/Repositories/ClassroomRepository.php b/app/Contracts/Repositories/ClassroomRepository.php index 88b625f3..71387365 100644 --- a/app/Contracts/Repositories/ClassroomRepository.php +++ b/app/Contracts/Repositories/ClassroomRepository.php @@ -44,7 +44,7 @@ public function paginate() : mixed public function whereInSchoolYears($schoolYears) { - return $this->model->query()->whereIn('school_year_id', $schoolYears)->get(); + return $this->model->query()->where('school_year_id', $schoolYears)->get(); } public function countClass(mixed $id): mixed diff --git a/app/Contracts/Repositories/SemesterRepository.php b/app/Contracts/Repositories/SemesterRepository.php index b0ace60d..24f0cc8d 100644 --- a/app/Contracts/Repositories/SemesterRepository.php +++ b/app/Contracts/Repositories/SemesterRepository.php @@ -16,11 +16,16 @@ public function __construct(Semester $semester) public function get(): mixed { - return $this->model->query()->where('school_id', auth()->user()->school->id)->get(); + return $this->model->query()->where('school_id', auth()->user()->school->id)->orderBy('created_at', 'desc')->get(); } public function store(array $data): mixed { return $this->model->query()->create($data); } + + public function whereSchool(mixed $id): mixed + { + return $this->model->query()->where('school_id', $id)->latest()->firstOrFail(); + } } diff --git a/app/Http/Controllers/AttendanceMasterController.php b/app/Http/Controllers/AttendanceMasterController.php new file mode 100644 index 00000000..a80474c1 --- /dev/null +++ b/app/Http/Controllers/AttendanceMasterController.php @@ -0,0 +1,23 @@ +modelHasRfid = $modelHasRfid; + } + + public function index() { + return view('school.pages.test.attendance'); + } + + public function check(Request $request) { + + } +} diff --git a/app/Http/Controllers/MapleController.php b/app/Http/Controllers/MapleController.php index 39af830b..79822186 100644 --- a/app/Http/Controllers/MapleController.php +++ b/app/Http/Controllers/MapleController.php @@ -47,7 +47,7 @@ public function store(StoreMapleRequest $request) { $data = $this->service->store($request); $this->maple->store($data); - return redirect()->back()->with('success', 'Berhasil menambahkan mapel pelajaram'); + return redirect()->back()->with('success', 'Berhasil menambahkan mata pelajaran'); } /** @@ -73,7 +73,7 @@ public function update(UpdateMapleRequest $request, Maple $maple) { $data = $this->service->update($maple, $request); $this->maple->update($maple->id, $data); - return redirect()->back()->with('success', 'Berhasil memperbarui mapel pelajaram'); + return redirect()->back()->with('success', 'Berhasil memperbarui mata pelajaran'); } /** @@ -82,6 +82,6 @@ public function update(UpdateMapleRequest $request, Maple $maple) public function destroy(Maple $maple) { $this->maple->delete($maple->id); - return redirect()->back()->with('success', 'Berhasil menghapus mapel pelajaran'); + return redirect()->back()->with('success', 'Berhasil menghapus mata pelajaran'); } } diff --git a/app/Http/Controllers/SchoolController.php b/app/Http/Controllers/SchoolController.php index a33cedf4..b3a63973 100644 --- a/app/Http/Controllers/SchoolController.php +++ b/app/Http/Controllers/SchoolController.php @@ -114,7 +114,7 @@ public function update(UpdateSchoolRequest $request, School $school) { $data = $this->service->update($school, $request); $this->school->update($school->id, $data); - return to_route('school-admin.index')->with('success', 'Berhasil memperbarui sekolah'); + return to_route('settings-information.index')->with('success', 'Berhasil memperbarui sekolah'); } /** diff --git a/app/Http/Controllers/SchoolDashboardController.php b/app/Http/Controllers/SchoolDashboardController.php index 95083259..42d650b1 100644 --- a/app/Http/Controllers/SchoolDashboardController.php +++ b/app/Http/Controllers/SchoolDashboardController.php @@ -2,16 +2,19 @@ namespace App\Http\Controllers; +use App\Contracts\Interfaces\AttendanceInterface; use App\Contracts\Interfaces\ClassroomInterface; use App\Contracts\Interfaces\EmployeeInterface; use App\Contracts\Interfaces\MapleInterface; use App\Contracts\Interfaces\ModelHasRfidInterface; use App\Contracts\Interfaces\SchoolInterface; use App\Contracts\Interfaces\SchoolYearInterface; +use App\Contracts\Interfaces\SemesterInterface; use App\Contracts\Interfaces\StudentInterface; use App\Http\Requests\StoreModelHasRfidRequest; use App\Models\School; use App\Services\ModelHasRfidService; +use App\Services\SchoolChartService; use Illuminate\Http\Request; use PhpParser\Node\Expr\FuncCall; @@ -20,26 +23,34 @@ class SchoolDashboardController extends Controller private SchoolInterface $school; private SchoolYearInterface $schoolYear; private ModelHasRfidInterface $rfid; - - private EmployeeInterface $employee; - private StudentInterface $student; - private MapleInterface $maple; private ClassroomInterface $classroom; + private SemesterInterface $semester; + private AttendanceInterface $attendance; + + private SchoolChartService $schoolChart; - public function __construct(SchoolInterface $school, - SchoolYearInterface $schoolYear, ModelHasRfidInterface $rfid, ClassroomInterface $classroom) + public function __construct(SchoolInterface $school, SchoolYearInterface $schoolYear, + ModelHasRfidInterface $rfid, ClassroomInterface $classroom, SemesterInterface $semester, + SchoolChartService $schoolChart, AttendanceInterface $attendance) { $this->school = $school; $this->schoolYear = $schoolYear; $this->rfid = $rfid; $this->classroom = $classroom; + $this->semester = $semester; + $this->attendance = $attendance; + $this->schoolChart = $schoolChart; } public function index() { $school = $this->school->whereUserId(auth()->user()->id); $classrooms = $this->classroom->countClass(auth()->user()->school->id); - return view('school.pages.dashboard', compact('school', 'classrooms')); + $schoolYear = $this->schoolYear->active(auth()->user()->school->id); + $semester = $this->semester->whereSchool(auth()->user()->school->id); + $attendanceChart = $this->schoolChart->ChartAttendance($this->attendance); + // dd($attendanceChart); + return view('school.pages.dashboard', compact('school', 'classrooms', 'schoolYear', 'semester', 'attendanceChart')); } public function show() @@ -55,9 +66,4 @@ public function edit() $school = $this->school->showWithSlug(auth()->user()->slug); return view('school.pages.settings.update-information', compact('school')); } - - public function update() - { - // - } } diff --git a/app/Http/Requests/StoreSchoolRequest.php b/app/Http/Requests/StoreSchoolRequest.php index 8f55bbf6..6fd69761 100644 --- a/app/Http/Requests/StoreSchoolRequest.php +++ b/app/Http/Requests/StoreSchoolRequest.php @@ -67,7 +67,8 @@ public function messages(): array 'city.required' => 'Kabupaten atau kota wajib di isi', 'sub_district_id.required' => 'Kecamatan wajib di isi', 'type.required' => 'Tipe sekolah wajib di isi', - 'level.required' => 'Jenjang wajib di isi' + 'level.required' => 'Jenjang wajib di isi', + 'accreditation.required' => 'Akreditasi harus diisi', ]; } } diff --git a/app/Http/Requests/UpdateSchoolRequest.php b/app/Http/Requests/UpdateSchoolRequest.php index 5636626f..365831e2 100644 --- a/app/Http/Requests/UpdateSchoolRequest.php +++ b/app/Http/Requests/UpdateSchoolRequest.php @@ -22,18 +22,18 @@ public function authorize(): bool public function rules(): array { return [ - 'npsn' => 'required|min:8', - 'phone_number' => 'required|min:15', - 'image' => 'required', - 'pas_code' => 'required|min:10', + 'name' => 'required', + 'email' => 'required|email', + 'npsn' => 'required|max:8', + 'phone_number' => 'required|max:15', + 'image' => 'nullable|mimes:png,jpg,jpeg', + 'pas_code' => 'required|max:10', 'address' => 'required', 'head_school' => 'required', 'nip' => 'required', - 'website_school' => 'nullable', + 'website_school' => 'nullable|url', 'description' => 'nullable', - 'province' => 'required', - 'city' => 'required', - 'sub_district' => 'required', + 'accreditation' => 'required', ]; } @@ -45,19 +45,20 @@ public function rules(): array public function messages(): array { return [ + 'name.required' => 'Nama sekolah wajib diisi.', + 'email.required' => 'Email sekolah wajib diisi.', + 'email.email' => 'Email sekolah tidak valid.', 'npsn.required' => 'NPSN wajib diisi.', - 'npsn.min' => 'NPSN harus terdiri dari minimal 8 karakter.', + 'npsn.max' => 'NPSN harus terdiri dari maximal :max karakter.', 'phone_number.required' => 'Nomor telepon wajib diisi.', - 'phone_number.min' => 'Nomor telepon harus terdiri dari minimal 15 karakter.', - 'image.required' => 'Gambar wajib diunggah.', + 'phone_number.max' => 'Nomor telepon harus terdiri dari maximal :max karakter.', + 'image.mimes' => 'Gambar harus berekstensi png, jpg atau jpeg.', 'pas_code.required' => 'Kode PAS wajib diisi.', - 'pas_code.min' => 'Kode PAS harus terdiri dari minimal 10 karakter.', + 'pas_code.max' => 'Kode PAS harus terdiri dari maximal :max karakter.', 'address.required' => 'Alamat wajib diisi.', 'head_school.required' => 'Nama kepala sekolah wajib diisi.', 'nip.required' => 'NIP wajib diisi.', - 'province.required' => 'Profinsi wajib di isi', - 'city.required' => 'Kabupaten atau kota wajib di isi', - 'sub_district.required' => 'Kecamatan wajib di isi' + 'accreditation.required' => 'Akreditasi harus diisi', ]; } } diff --git a/app/Services/AttendanceService.php b/app/Services/AttendanceService.php new file mode 100644 index 00000000..34d99474 --- /dev/null +++ b/app/Services/AttendanceService.php @@ -0,0 +1,29 @@ +modelHasRfid = $modelHasRfid; + $this->student = $student; + $this->attendanceRule = $attendanceRule; + } + + public function store(StoreAttendanceRequest $request): array|bool + { + $data = $request->validated(); + return $data; + } +} diff --git a/app/Services/SchoolChartService.php b/app/Services/SchoolChartService.php new file mode 100644 index 00000000..fbe846e9 --- /dev/null +++ b/app/Services/SchoolChartService.php @@ -0,0 +1,39 @@ +attendance = $attendance; + } + + public function ChartAttendance(AttendanceInterface $attendance) + { + $Curentyear = Carbon::now()->year; + $Curentmonth = Carbon::now()->month; + + $grafikDataCollection = []; + + for($month = 1; $month <= 12; $month++){ + $date = Carbon::createFromDate($Curentyear, $month, 1); + $yearMonth = $date->isoFormat('MMMM'); + $attendance = $this->attendance->AttendanceChart(auth()->user()->school->id, $Curentyear, $month); + + $grafikDataCollection[] = [ + 'year' => $Curentyear, + 'month' => $yearMonth, + 'attendance' => $attendance + ]; + } + $data = array_values($grafikDataCollection); + + return $data; + } +} diff --git a/app/Services/SchoolService.php b/app/Services/SchoolService.php index e62be823..f9e04182 100644 --- a/app/Services/SchoolService.php +++ b/app/Services/SchoolService.php @@ -58,20 +58,15 @@ public function update(School $school, UpdateSchoolRequest $request): array|bool 'email' => $data['email'], 'password' => Hash::make($data['npsn']), ]; - $user = $this->user->update($school->user_id ,$dataUser); - $user->assignRole(RoleEnum::SCHOOL->value); - - $old_image = $school->image; - $image = ""; + $this->user->update($school->user_id, $dataUser); - if ($request->hasFile('image')) { - if (file_exists(public_path($old_image))) { - unlink(public_path($old_image)); - } - $image = $this->upload(UploadDiskEnum::LOGO->value, $request->image); + if ($request->hasFile('image') && $request->file('image')->isValid()) { + $this->remove($school->image); + $data['image'] = $request->file('image')->store(UploadDiskEnum::TEACHER->value, 'public'); + } else { + $data['image'] = $school->image; } - $data['image'] = $image ?: $old_image; return $data; } diff --git a/database/migrations/2024_07_15_133714_create_semesters_table.php b/database/migrations/2024_07_15_133714_create_semesters_table.php index 6b0277f2..e1d22fa3 100644 --- a/database/migrations/2024_07_15_133714_create_semesters_table.php +++ b/database/migrations/2024_07_15_133714_create_semesters_table.php @@ -1,12 +1,15 @@ id(); $table->string('type')->enum([SemesterEnum::GANJIL, SemesterEnum::GENAP]); - $table->foreignId('school_id')->constrained()->cascadeOnDelete()->cascadeOnUpdate(); + $this->addForeignId($table,'school_id'); $table->timestamps(); }); } diff --git a/database/seeders/SchoolYearSeeder.php b/database/seeders/SchoolYearSeeder.php index a48964ac..90361984 100644 --- a/database/seeders/SchoolYearSeeder.php +++ b/database/seeders/SchoolYearSeeder.php @@ -24,7 +24,7 @@ public function run(): void ], [ 'school_year' => '2023/2024', - 'active' => '1', + 'active' => '0', ], [ 'school_year' => '2024/2025', diff --git a/public/admin_assets/dist/images/ilustrations/presensi.png b/public/admin_assets/dist/images/ilustrations/presensi.png new file mode 100644 index 00000000..bb3c219a Binary files /dev/null and b/public/admin_assets/dist/images/ilustrations/presensi.png differ diff --git a/public/admin_assets/dist/images/ilustrations/sinkronisasi.png b/public/admin_assets/dist/images/ilustrations/sinkronisasi.png new file mode 100644 index 00000000..c59a7ea4 Binary files /dev/null and b/public/admin_assets/dist/images/ilustrations/sinkronisasi.png differ diff --git a/public/admin_assets/dist/images/ilustrations/siswa.png b/public/admin_assets/dist/images/ilustrations/siswa.png new file mode 100644 index 00000000..47cd9c60 Binary files /dev/null and b/public/admin_assets/dist/images/ilustrations/siswa.png differ diff --git a/public/admin_assets/dist/images/ilustrations/today.png b/public/admin_assets/dist/images/ilustrations/today.png new file mode 100644 index 00000000..c8c5b23e Binary files /dev/null and b/public/admin_assets/dist/images/ilustrations/today.png differ diff --git a/resources/views/school/pages/dashboard.blade.php b/resources/views/school/pages/dashboard.blade.php index 447fbbb5..8c800375 100644 --- a/resources/views/school/pages/dashboard.blade.php +++ b/resources/views/school/pages/dashboard.blade.php @@ -260,7 +260,7 @@ class="text-warning">
Tahun Ajaran Saat Ini
- 2023/2024 + {{ $schoolYear->school_year }}
@@ -268,7 +268,7 @@ class="text-warning">
Semester Saat Ini
- Ganjil + {{ $semester->type == 'ganjil' ? 'Ganjil' : 'Genap'}}
@@ -341,18 +341,76 @@ class="text-warning"> + + {{-- + --}} +@endsection \ No newline at end of file diff --git a/resources/views/school/pages/student/index.blade.php b/resources/views/school/pages/student/index.blade.php index 977a64c2..2a477131 100644 --- a/resources/views/school/pages/student/index.blade.php +++ b/resources/views/school/pages/student/index.blade.php @@ -233,7 +233,7 @@ {{ $student->user->name }} - {{ $student->classroomStudents[0] ? $student->classroomStudents[0]->classroom->name : 'Kelas tidak ada' }} + {{ count($student->classroomStudents) > 0 ? $student->classroomStudents[0]->classroom->name : 'Kelas tidak ada' }} {{ $student->gender == 'famale' ? 'Perempuan' : 'Laki-laki' }} {{ $student->nisn }} {{ $student->modelHasRfid ? $student->modelHasRfid->rfid : '' }} diff --git a/resources/views/school/pages/test/menu.blade.php b/resources/views/school/pages/test/menu.blade.php new file mode 100644 index 00000000..383d435a --- /dev/null +++ b/resources/views/school/pages/test/menu.blade.php @@ -0,0 +1,122 @@ + + + + + + + + Absensi | Menu + + + + + + + +
+
+ +
+
+ + + + + + + diff --git a/routes/role/school.php b/routes/role/school.php index f3dde40a..edcc0f70 100644 --- a/routes/role/school.php +++ b/routes/role/school.php @@ -1,6 +1,7 @@ group(function() { +Route::prefix('school')->group(function () { Route::get('', [SchoolDashboardController::class, 'index'])->name('school.index'); // pegawai @@ -59,7 +61,7 @@ // absen // Route::get('clock-settings', [AttendanceRuleController::class, 'index'])->name('clock-settings.index'); - Route::get('clock-settings', function(){ + Route::get('clock-settings', function () { return view('school.pages.attendace.copy-clock-settings'); })->name('clock-settings.index'); Route::get('get-clock-settings', [AttendanceRuleController::class, 'index'])->name('clock-settings.get'); @@ -67,16 +69,16 @@ Route::get('presence', [AttendanceController::class, 'index'])->name('presence.index'); - Route::get('presence-student', function(){ + Route::get('presence-student', function () { return view('school.pages.attendace.student'); })->name('presence-student.index'); //alumni - Route::get('class-alumni', function(){ + Route::get('class-alumni', function () { return view('school.pages.alumni.class'); })->name('class-alumni.index'); - Route::get('alumni', function(){ + Route::get('alumni', function () { return view('school.pages.alumni.index'); })->name('alumni.index'); @@ -93,7 +95,7 @@ Route::delete('delete-class/{classroom}', [ClassroomController::class, 'destroy'])->name('class.delete'); // detail kelas - Route::get('detail-class', function(){ + Route::get('detail-class', function () { return view('school.pages.class.detail-class'); })->name('detail-class.index'); @@ -113,7 +115,7 @@ Route::get('information', [SchoolDashboardController::class, 'show'])->name('settings-information.index'); Route::post('information/add-masterKey', [ModelHasRfidController::class, 'storeMaster'])->name('master-key.store'); Route::get('information/edit', [SchoolDashboardController::class, 'edit'])->name('settings-information.edit'); - Route::put('information/update', [SchoolDashboardController::class, 'update'])->name('settings-information.update'); + Route::put('information/update/{school}', [SchoolController::class, 'update'])->name('settings-information.update'); // rfid Route::get('rfid', [ModelHasRfidController::class, 'index'])->name('rfid-school.index'); @@ -136,7 +138,7 @@ // Route::get('lesson-hours', [LessonHourController::class, 'index'])->name('lesson-hours.index'); Route::resource('lesson-hours', LessonHourController::class); //semeter - Route::prefix('semesters')->name('semesters.')->group(function() { + Route::prefix('semesters')->name('semesters.')->group(function () { Route::get('/', [SemesterController::class, 'index'])->name('index'); Route::post('/', [SemesterController::class, 'store'])->name('store'); }); @@ -154,6 +156,7 @@ Route::put('school/{classroom}', [ClassroomStudentController::class, 'update'])->name('classroom.update'); //tes absensi -Route::get('attendance-test', function(){ - return view('school.pages.test.attendance'); -})->name('attendance-test.index'); +Route::get('menu-test', function () { + return view('school.pages.test.menu'); +})->name('menu-test.index'); +Route::get('attendance-test', [AttendanceMasterController::class, 'index'])->name('attendance-test.index'); \ No newline at end of file