# Fitur Absensi Guru di Dashboard dengan Deteksi Terlambat

## Ringkasan
Implementasi fitur lengkap untuk menampilkan informasi guru, status absensi hari ini, dan riwayat absensi 7 hari terakhir di dashboard. Termasuk deteksi otomatis keterlambatan berdasarkan jam masuk.

## Fitur yang Diimplementasikan

### 1. **Informasi Guru di Dashboard**
Menampilkan card informasi guru yang login dengan data:
- **NIP**: Nomor Induk Pegawai
- **Mapel**: Daftar mata pelajaran yang diampu (dari relasi many-to-many)
- **Status Hari Ini**: Badge status absensi (Hadir, Terlambat, Izin, Sakit, Alpha, atau Belum Absen)

### 2. **Riwayat Absensi 7 Hari Terakhir**
Menampilkan tabel riwayat absensi dengan informasi:
- Tanggal dan hari
- Jam masuk
- Jam pulang
- Status (dengan badge berwarna)
- Keterangan

### 3. **Deteksi Terlambat Otomatis**
Sistem otomatis mendeteksi keterlambatan berdasarkan:
- Batas waktu masuk default: **08:00:00**
- Dapat dikonfigurasi dari tabel `pengaturans` (field `jam_masuk`)
- Jika guru absen setelah batas waktu, status otomatis berubah dari 'hadir' menjadi 'terlambat'

## File yang Dimodifikasi

### 1. **DashboardController** (`app/Http/Controllers/Simaju/DashboardController.php`)

```php
public function index()
{
    // Get current guru data if user is a guru
    $currentGuru = null;
    $riwayatAbsensi = collect();
    $absensiHariIni = null;
    
    if (auth()->user()->role === 'wali_kelas' && auth()->user()->guru) {
        $currentGuru = auth()->user()->guru()->with('mataPelajarans')->first();
        
        // Get riwayat absensi for this guru (last 7 days)
        $riwayatAbsensi = \App\Models\AbsensiGuru::where('guru_id', $currentGuru->id)
            ->orderBy('tanggal', 'desc')
            ->orderBy('created_at', 'desc')
            ->take(7)
            ->get();
        
        // Check if already absent today
        $absensiHariIni = \App\Models\AbsensiGuru::where('guru_id', $currentGuru->id)
            ->whereDate('tanggal', today())
            ->first();
    }
    
    // ... rest of the code
    
    return view('simaju.dashboard', compact(..., 'currentGuru', 'riwayatAbsensi', 'absensiHariIni'));
}
```

**Perubahan:**
- Menambahkan query untuk mengambil data guru dengan relasi `mataPelajarans`
- Mengambil riwayat absensi 7 hari terakhir
- Mengecek status absensi hari ini
- Mengirim 3 variable baru ke view: `$currentGuru`, `$riwayatAbsensi`, `$absensiHariIni`

### 2. **Dashboard View** (`resources/views/simaju/dashboard.blade.php`)

#### Card Informasi Guru
```blade
@if(auth()->user()->role === 'wali_kelas' && $currentGuru)
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 mb-6">
    <h2 class="text-xl font-bold text-gray-800 mb-4">
        <i class="fas fa-user-tie text-indigo-600"></i>
        Informasi Guru
    </h2>
    <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
        <!-- NIP -->
        <div class="bg-gray-50 rounded-lg p-4">
            <p class="text-xs text-gray-500 mb-1">NIP</p>
            <p class="font-semibold text-gray-800">{{ $currentGuru->nip ?? '-' }}</p>
        </div>
        
        <!-- Mapel -->
        <div class="bg-gray-50 rounded-lg p-4">
            <p class="text-xs text-gray-500 mb-1">Mapel</p>
            <p class="font-semibold text-gray-800">
                @if($currentGuru->mataPelajarans && $currentGuru->mataPelajarans->count() > 0)
                    {{ $currentGuru->mataPelajarans->pluck('nama_mapel')->join(', ') }}
                @else
                    <span class="text-gray-400">-</span>
                @endif
            </p>
        </div>
        
        <!-- Status Hari Ini -->
        <div class="bg-gray-50 rounded-lg p-4">
            <p class="text-xs text-gray-500 mb-1">Status Hari Ini</p>
            <p class="font-semibold">
                @if($absensiHariIni)
                    <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium {{ $absensiHariIni->status_masuk_badge_class }}">
                        @if($absensiHariIni->status_masuk === 'hadir')
                            <i class="fas fa-check-circle mr-1"></i>
                        @elseif($absensiHariIni->status_masuk === 'terlambat')
                            <i class="fas fa-clock mr-1"></i>
                        @elseif($absensiHariIni->status_masuk === 'izin')
                            <i class="fas fa-info-circle mr-1"></i>
                        @elseif($absensiHariIni->status_masuk === 'sakit')
                            <i class="fas fa-hospital mr-1"></i>
                        @else
                            <i class="fas fa-times-circle mr-1"></i>
                        @endif
                        {{ $absensiHariIni->status_masuk_label }}
                    </span>
                @else
                    <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-600">
                        <i class="fas fa-question-circle mr-1"></i>
                        Belum Absen
                    </span>
                @endif
            </p>
        </div>
    </div>
</div>
```

#### Tabel Riwayat Absensi
```blade
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 mb-6">
    <h2 class="text-xl font-bold text-gray-800 mb-4">
        <i class="fas fa-history text-indigo-600"></i>
        Riwayat 7 Hari Terakhir
    </h2>
    <div class="overflow-x-auto">
        <table class="min-w-full divide-y divide-gray-200">
            <thead class="bg-gray-50">
                <tr>
                    <th>Tanggal</th>
                    <th>Jam Masuk</th>
                    <th>Jam Pulang</th>
                    <th>Status</th>
                    <th>Keterangan</th>
                </tr>
            </thead>
            <tbody>
                @forelse($riwayatAbsensi as $absensi)
                <tr>
                    <td>{{ $absensi->tanggal->format('d M Y') }}</td>
                    <td>{{ $absensi->jam_masuk ?? '-' }}</td>
                    <td>{{ $absensi->jam_pulang ?? '-' }}</td>
                    <td>
                        <span class="{{ $absensi->status_masuk_badge_class }}">
                            {{ $absensi->status_masuk_label }}
                        </span>
                    </td>
                    <td>{{ $absensi->keterangan ?? '-' }}</td>
                </tr>
                @empty
                <tr>
                    <td colspan="5" class="text-center">Belum ada riwayat absensi</td>
                </tr>
                @endforelse
            </tbody>
        </table>
    </div>
</div>
@endif
```

### 3. **AbsensiGuruController** (`app/Http/Controllers/Simaju/AbsensiGuruController.php`)

#### Logika Deteksi Terlambat pada Method `store()`

```php
// Auto detect late arrival (terlambat) based on time
$jamMasuk = $validated['jam_masuk'] ?? Carbon::now('Asia/Makassar')->format('H:i:s');
$statusMasuk = $validated['status_masuk'];

// If status is 'hadir', check if it should be 'terlambat'
if ($statusMasuk === 'hadir') {
    $batasJamMasuk = '08:00:00'; // Default 08:00 AM
    
    // Get from settings if available
    $pengaturan = Pengaturan::first();
    if ($pengaturan && !empty($pengaturan->jam_masuk)) {
        $batasJamMasuk = $pengaturan->jam_masuk;
    }
    
    // Compare times
    if ($jamMasuk > $batasJamMasuk) {
        $statusMasuk = 'terlambat';
    }
}

AbsensiGuru::create([
    'guru_id' => $validated['guru_id'],
    'tanggal' => $validated['tanggal'],
    'jam_masuk' => $jamMasuk,
    'status_masuk' => $statusMasuk,  // Auto-adjusted status
    // ... rest of fields
]);
```

**Cara Kerja:**
1. Sistem mengambil jam masuk dari request atau waktu saat ini
2. Jika status yang dipilih adalah 'hadir', sistem akan mengecek jam masuk
3. Membandingkan dengan batas jam masuk (default 08:00:00 atau dari setting)
4. Jika lewat batas waktu, status otomatis diubah menjadi 'terlambat'
5. Data disimpan dengan status yang sudah disesuaikan

## Konfigurasi Batas Waktu Masuk

### Melalui Database (Recommended)
Tambahkan field `jam_masuk` di tabel `pengaturans`:

```sql
ALTER TABLE pengaturans ADD COLUMN jam_masuk TIME DEFAULT '08:00:00';
```

Atau update melalui aplikasi:
```php
$pengaturan = Pengaturan::first();
$pengaturan->jam_masuk = '07:30:00';  // Set batas masuk jam 07:30
$pengaturan->save();
```

### Default Value
Jika tidak ada konfigurasi di database, sistem akan menggunakan default:
- **Batas Jam Masuk**: 08:00:00

## Status Badge Colors

Status absensi menggunakan warna yang berbeda untuk memudahkan identifikasi:

| Status | Badge Class | Warna |
|--------|------------|-------|
| Hadir | `bg-green-100 text-green-800` | Hijau |
| Terlambat | `bg-yellow-100 text-yellow-800` | Kuning |
| Izin | `bg-blue-100 text-blue-800` | Biru |
| Sakit | `bg-purple-100 text-purple-800` | Ungu |
| Alpha | `bg-red-100 text-red-800` | Merah |

## Cara Penggunaan

### 1. Untuk Guru (Wali Kelas)
1. Login sebagai guru dengan role `wali_kelas`
2. Otomatis akan melihat card "Informasi Guru" di dashboard
3. Status hari ini akan menampilkan apakah sudah absen atau belum
4. Riwayat 7 hari terakhir ditampilkan di bawahnya

### 2. Melakukan Absensi
1. Akses halaman absensi guru
2. Isi form absensi (foto, lokasi, keterangan)
3. Pilih status 'hadir' saat submit
4. **Sistem otomatis akan mendeteksi keterlambatan:**
   - Jika absen sebelum jam 08:00 → Status: **Hadir**
   - Jika absen setelah jam 08:00 → Status: **Terlambat**

### 3. Untuk Admin
1. Admin dapat melihat semua data absensi di menu "Absensi Guru"
2. Admin dapat melihat rekapitulasi lengkap per bulan
3. Admin dapat export ke PDF
4. Admin dapat mengatur batas waktu masuk di Profil Sekolah

## Rekapitulasi Absensi

Semua data absensi (termasuk yang terlambat) akan masuk ke:
1. **Halaman Index Absensi Guru** - Daftar semua absensi
2. **Halaman Rekap** - Rekapitulasi per bulan dengan statistik
3. **Export PDF** - Laporan lengkap yang bisa di-download
4. **Dashboard** - Riwayat 7 hari terakhir untuk guru

## Testing

### Test Deteksi Terlambat
1. Set waktu sistem sebelum jam 08:00
2. Lakukan absensi dengan status 'hadir'
3. Verifikasi status tersimpan sebagai 'hadir'

4. Set waktu sistem setelah jam 08:00
5. Lakukan absensi dengan status 'hadir'
6. Verifikasi status otomatis berubah menjadi 'terlambat'

### Test Dashboard
1. Login sebagai guru (role: wali_kelas)
2. Pastikan card "Informasi Guru" muncul
3. Pastikan NIP dan Mapel ditampilkan
4. Pastikan status hari ini akurat
5. Pastikan riwayat 7 hari terakhir lengkap

## Troubleshooting

### Mapel Tidak Muncul
**Penyebab**: Relasi `mataPelajarans` tidak tersedia
**Solusi**: 
1. Pastikan tabel `guru_mapels` (pivot table) sudah terisi
2. Pastikan relasi many-to-many sudah benar di model `Guru`

### Status Tidak Berubah Terlambat
**Penyebab**: Jam masuk sudah dikirim dari client dengan status tertentu
**Solusi**:
1. Pastikan client mengirim status 'hadir' (bukan 'terlambat')
2. Sistem akan auto-detect berdasarkan jam
3. Atau ubah logic di client untuk tidak mengirim status

### Riwayat Tidak Muncul
**Penyebab**: User bukan guru atau tidak ada data
**Solusi**:
1. Pastikan user memiliki role 'wali_kelas'
2. Pastikan ada relasi `guru` di user
3. Pastikan ada data absensi di database

## Keamanan

1. **Akses Dashboard**: Hanya guru dengan role `wali_kelas` yang bisa melihat card informasi dan riwayat
2. **Akses Rekap**: Hanya admin yang bisa mengakses halaman rekapitulasi lengkap
3. **Validasi Data**: Semua input divalidasi sebelum disimpan
4. **SQL Injection**: Menggunakan Eloquent ORM untuk mencegah SQL injection

## Update Selanjutnya (Optional)

1. **Notifikasi Real-time**: Push notification saat guru terlambat
2. **Grafik Statistik**: Visualisasi kehadiran per bulan
3. **Export Excel**: Selain PDF, tambahkan export ke Excel
4. **Filter Lanjutan**: Filter berdasarkan status, tanggal range, dll
5. **Mobile App Integration**: API untuk aplikasi mobile

---

**Tanggal Implementasi**: 6 Agustus 2026
**Developer**: AI Assistant
**Status**: ✅ Completed & Tested
