diff --git a/.env.example b/.env.example index 71ef872..edca79d 100644 --- a/.env.example +++ b/.env.example @@ -35,3 +35,10 @@ VITE_REVERB_APP_KEY="${REVERB_APP_KEY}" # ===== Firebase Cloud Messaging (push notification aplikasi wali) ===== FCM_SERVICE_ACCOUNT= FCM_PROJECT_ID= + +# ===== Koneksi database e-jurnal (untuk jadwal pelajaran wali) ===== +DB_EJURNAL_HOST=127.0.0.1 +DB_EJURNAL_PORT=3306 +DB_EJURNAL_DATABASE=e_jurnal +DB_EJURNAL_USERNAME=ejurnal +DB_EJURNAL_PASSWORD=P4ssw0rd diff --git a/app/Http/Controllers/Api/ParentStudentController.php b/app/Http/Controllers/Api/ParentStudentController.php index 43e2aac..3d19da6 100644 --- a/app/Http/Controllers/Api/ParentStudentController.php +++ b/app/Http/Controllers/Api/ParentStudentController.php @@ -10,6 +10,7 @@ use App\Models\Violation; use App\Support\PhoneHelper; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; use Illuminate\Validation\Rule; class ParentStudentController extends Controller @@ -24,6 +25,62 @@ class ParentStudentController extends Controller return response()->json(['students' => $payload]); } + /** + * Jadwal pelajaran mingguan kelas siswa (diambil dari database e-jurnal). + */ + public function schedule(Request $request, Student $student): JsonResponse + { + // Hanya wali dengan tautan aktif yang boleh melihat + $hasLink = ParentStudent::where('user_id', $request->user()->id) + ->where('student_id', $student->id) + ->where('status', 'active') + ->exists(); + + abort_unless($hasLink, 403, 'Putra/putri belum tertaut aktif.'); + + try { + $db = DB::connection('ejurnal'); + $yearId = $db->table('academic_years')->where('is_active', 1)->value('id'); + $semesterId = $db->table('semesters')->where('is_active', 1)->value('id'); + + $rows = $db->table('schedules as s') + ->join('classes as c', 'c.id', '=', 's.class_id') + ->join('subjects as sub', 'sub.id', '=', 's.subject_id') + ->where('c.name', $student->class_name) + ->where('s.academic_year_id', $yearId) + ->where('s.semester_id', $semesterId) + ->where('s.is_active', 1) + ->orderBy('s.day_of_week') + ->orderBy('s.start_time') + ->get(['s.day_of_week', 's.start_time', 's.end_time', 'sub.name as subject']); + + $days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday']; + $grouped = []; + foreach ($days as $day) { + $items = $rows->where('day_of_week', $day)->values()->map(fn ($r) => [ + 'start' => substr($r->start_time, 0, 5), + 'end' => substr($r->end_time, 0, 5), + 'subject' => $r->subject, + ]); + if ($items->isNotEmpty()) { + $grouped[] = [ + 'day' => $day, + 'items' => $items, + ]; + } + } + + return response()->json([ + 'class_name' => $student->class_name, + 'schedule' => $grouped, + ]); + } catch (\Throwable $e) { + \Illuminate\Support\Facades\Log::error('Jadwal gagal dimuat: '.$e->getMessage()); + + return response()->json(['message' => 'Jadwal belum tersedia untuk kelas ini.'], 404); + } + } + /** * Tautkan anak tambahan (kakak/adik) ke akun wali. */ diff --git a/config/database.php b/config/database.php index abbb88e..21f7949 100644 --- a/config/database.php +++ b/config/database.php @@ -64,6 +64,20 @@ return [ ]) : [], ], + 'ejurnal' => [ + 'driver' => 'mysql', + 'host' => env('DB_EJURNAL_HOST', '127.0.0.1'), + 'port' => env('DB_EJURNAL_PORT', '3306'), + 'database' => env('DB_EJURNAL_DATABASE', 'e_jurnal'), + 'username' => env('DB_EJURNAL_USERNAME', 'ejurnal'), + 'password' => env('DB_EJURNAL_PASSWORD', ''), + 'charset' => 'utf8mb4', + 'collation' => 'utf8mb4_unicode_ci', + 'prefix' => '', + 'strict' => false, + 'engine' => null, + ], + 'mariadb' => [ 'driver' => 'mariadb', 'url' => env('DB_URL'), diff --git a/routes/api.php b/routes/api.php index 46ab91e..dde18c1 100644 --- a/routes/api.php +++ b/routes/api.php @@ -35,6 +35,7 @@ Route::middleware('auth:sanctum')->prefix('parent')->group(function () { Route::post('/students/link', [ParentStudentController::class, 'link'])->middleware('throttle:5,10')->name('api.parent.students.link'); Route::get('/students/{student}/violations', [ParentStudentController::class, 'violations'])->name('api.parent.students.violations'); Route::get('/students/{student}/sp-letters', [ParentStudentController::class, 'spLetters'])->name('api.parent.students.sp-letters'); + Route::get('/students/{student}/schedule', [ParentStudentController::class, 'schedule'])->name('api.parent.students.schedule'); // Notifikasi & perangkat Route::get('/notifications', [ParentNotificationController::class, 'index'])->name('api.parent.notifications');