9.8 KiB
📱 Ringkasan Implementasi Fitur Mata Kuliah dan Absen Kehadiran
✅ Fitur yang Telah Ditambahkan
1. Daftar Mata Kuliah
- Menampilkan semua mata kuliah yang tersedia
- Informasi lengkap: kode, nama, dosen, jadwal, ruang, SKS
- Dapat memilih mata kuliah untuk absensi
- Menyimpan pilihan mata kuliah terakhir
2. Absensi dengan Mata Kuliah
- User dapat memilih mata kuliah sebelum absensi
- Data kehadiran disimpan dengan informasi mata kuliah lengkap
- Dikirim ke N8n webhook dengan format JSON yang lebih lengkap
3. Riwayat Kehadiran
- Melihat riwayat absensi per mata kuliah
- Tanggal, waktu, dan status kehadiran
- Dapat difilter berdasarkan status (hadir, terlambat, tidak hadir, dll)
4. Laporan Kehadiran
- Statistik kehadiran per mata kuliah
- Persentase kehadiran dengan visual indicator (hijau/orange/merah)
- Total sesi, hadir, terlambat, tidak hadir, izin/sakit
- Automatic calculation dari history kehadiran
📁 File-File yang Ditambahkan
Models Layer
models/CourseModels.kt- Data class untuk Course, Attendance, AttendanceStatus, AttendanceReport
Configuration Layer
config/CourseConfig.kt- Konfigurasi mata kuliah dan threshold kehadiran
Service Layer
utils/CourseService.kt- Service untuk CRUD operasi mata kuliah dan kehadiranutils/AttendanceUtils.kt- Utility function untuk operasi kehadiran
UI Components Layer
ui/components/CourseComponents.kt- Reusable components untuk tampilan mata kuliah dan kehadiran
Screen/UI Layer
ui/screens/CourseScreen.kt- Screens untuk menampilkan daftar dan detail mata kuliah
🔄 Alur Data Flow
User Interface (MainActivity.kt)
↓
CourseService (Manage data)
↓
SharedPreferences (Local Storage)
↓
N8nService (Send to server)
↓
N8n Webhook → Google Sheets
📊 Data Struktur
Course Model
data class Course(
val courseId: String, // ID unik mata kuliah
val courseCode: String, // Kode mata kuliah (PBO2024)
val courseName: String, // Nama mata kuliah
val lecturer: String, // Nama dosen
val credits: Int, // Jumlah SKS
val schedule: String, // Jadwal (Senin 08:00-09:30)
val room: String, // Ruang kelas (A-101)
val semester: Int, // Semester
val isActive: Boolean // Status aktif
)
🎯 Perubahan di MainActivity.kt
Sebelum
fun AbsensiScreen(
modifier: Modifier = Modifier,
activity: ComponentActivity
) {
var state by remember { mutableStateOf(AttendanceState()) }
val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
val n8nService = remember { N8nService(activity) }
// Hanya absensi tanpa mata kuliah
n8nService.submitAttendance(...)
}
Sesudah
fun AbsensiScreen(
modifier: Modifier = Modifier,
activity: ComponentActivity
) {
var state by remember { mutableStateOf(AttendanceState()) }
var courses by remember { mutableStateOf<List<Course>>(emptyList()) }
var selectedCourse by remember { mutableStateOf<Course?>(null) }
val courseService = remember { CourseService(context) }
// Initialize courses
LaunchedEffect(Unit) {
courseService.initializeSampleData()
courses = courseService.getCourses()
selectedCourse = courseService.getSelectedCourse() ?: courses.firstOrNull()
}
// Absensi dengan pilihan mata kuliah
n8nService.submitAttendanceWithCourse(
courseId = selectedCourse!!.courseId,
courseCode = selectedCourse!!.courseCode,
courseName = selectedCourse!!.courseName,
...
)
// Simpan ke database lokal
courseService.saveAttendance(attendance)
}
🔌 Perubahan di N8nService.kt
Method Baru
fun submitAttendanceWithCourse(
npm: String,
nama: String,
courseId: String,
courseCode: String,
courseName: String,
latitude: Double,
longitude: Double,
foto: Bitmap,
isTest: Boolean = false,
callback: SubmitCallback? = null
) {
// Send to N8n dengan informasi mata kuliah
val json = JSONObject().apply {
put("npm", npm)
put("nama", nama)
put("courseId", courseId)
put("courseCode", courseCode)
put("courseName", courseName)
put("latitude", latitude)
put("longitude", longitude)
put("timestamp", System.currentTimeMillis())
put("foto_base64", bitmapToBase64(foto))
}
}
💾 Penyimpanan Data
Data disimpan di SharedPreferences dengan struktur:
SharedPreferences Database: "course_attendance_db"
├── courses_list (JSON)
│ └── [Course, Course, Course, ...]
├── attendance_list (JSON)
│ └── [Attendance, Attendance, Attendance, ...]
└── selected_course (JSON)
└── Current selected Course
🚀 Cara Menggunakan
1. Initialize CourseService
val courseService = CourseService(context)
courseService.initializeSampleData()
2. Dapatkan Daftar Mata Kuliah
val courses = courseService.getCourses()
courses.forEach { course ->
println("${course.courseCode} - ${course.courseName}")
}
3. Pilih Mata Kuliah
val selectedCourse = courses.first()
courseService.setSelectedCourse(selectedCourse)
4. Simpan Kehadiran
val attendance = Attendance(
npm = "202310715082",
nama = "Fazri Abdurrahman",
courseId = "COURSE_001",
courseCode = "PBO2024",
courseName = "Pemrograman Berorientasi Objek",
latitude = -7.000123,
longitude = 110.400456,
timestamp = System.currentTimeMillis(),
date = courseService.getCurrentDate(),
time = courseService.formatTime(System.currentTimeMillis()),
status = AttendanceStatus.PRESENT,
isValid = true
)
courseService.saveAttendance(attendance)
5. Buat Laporan Kehadiran
val report = courseService.generateAttendanceReport("COURSE_001")
println("Persentase: ${report.attendancePercentage}%")
println("Hadir: ${report.presentCount}/${report.totalSessions}")
📱 UI Components yang Baru
CourseCard
Menampilkan informasi singkat mata kuliah dengan design yang menarik
CourseListSection
List of courses dengan scroll support dan loading state
AttendanceReportCard
Menampilkan statistik kehadiran dengan progress visual
AttendanceDetailCard
Menampilkan detail satu record kehadiran
AttendanceHistoryList
List riwayat kehadiran dengan infinite scroll
🔧 Konfigurasi
Tambah Mata Kuliah Baru
Edit CourseConfig.kt:
Course(
courseId = "COURSE_006",
courseCode = "NEWCODE2024",
courseName = "Nama Mata Kuliah Baru",
lecturer = "Nama Dosen",
credits = 3,
schedule = "Hari HH:MM-HH:MM",
room = "Ruang Kelas",
semester = 4,
isActive = true
)
Ubah Threshold Kehadiran
Edit CourseConfig.kt:
const val MINIMUM_ATTENDANCE_PERCENTAGE = 80.0 // Minimum 80%
const val MAX_EXCUSED_ABSENCES = 3 // Maksimal 3 izin
const val MAX_SICK_LEAVE = 2 // Maksimal 2 sakit
🧪 Testing
Test Scenario 1: Daftar Mata Kuliah
- Buka app
- Lihat daftar mata kuliah di section atas
- Verifikasi ada 5 mata kuliah default
Test Scenario 2: Pilih Mata Kuliah
- Klik tombol "Pilih Mata Kuliah"
- Dialog muncul dengan daftar mata kuliah
- Pilih salah satu
- Verifikasi mata kuliah terpilih ditampilkan
Test Scenario 3: Absensi Lengkap
- Pilih mata kuliah
- Ambil foto
- Tunggu lokasi terdeteksi
- Klik "Kirim Absensi"
- Verifikasi pesan sukses dan data tersimpan
Test Scenario 4: Lihat Riwayat
- Setelah absensi berhasil
- Buka detail mata kuliah
- Lihat riwayat kehadiran
- Verifikasi ada record kehadiran baru
Test Scenario 5: Laporan Kehadiran
- Buka detail mata kuliah
- Lihat statistik kehadiran di atas
- Verifikasi persentase dihitung dengan benar
📦 Dependencies Baru
Tambahkan di app/build.gradle.kts:
implementation("com.google.code.gson:gson:2.10.1")
🐛 Troubleshooting
Issue: "Tidak ada mata kuliah"
Solusi:
// Pastikan initialization di startup
courseService.initializeSampleData()
Issue: Data tidak tersimpan
Solusi:
- Cek SharedPreferences di Device Explorer
- Verifikasi format data JSON
- Cek permissions untuk write
Issue: Kehadiran tidak terkirim ke N8n
Solusi:
- Pastikan network connection aktif
- Verifikasi webhook URL di AttendanceConfig
- Cek logcat untuk error details
Issue: Laporan kehadiran tidak update
Solusi:
// Force refresh
val report = courseService.generateAttendanceReport(courseId)
📈 Fitur yang Mungkin Ditambahkan di Masa Depan
- Filter attendance berdasarkan rentang tanggal
- Export laporan ke PDF/Excel
- Multi-semester support
- Notification untuk kehadiran di bawah threshold
- Analytics dashboard
- Sync dengan server API
- Offline mode dengan sync otomatis
- QR code untuk quick attendance
📝 Catatan Penting
- Data Privacy: Semua data sensitif dikirim via HTTPS
- Local Storage: Menggunakan SharedPreferences (aman untuk level ini)
- Photo Handling: Foto dikonversi ke Base64 hanya saat pengiriman
- Database: Menggunakan Gson untuk serialisasi/deserialisasi JSON
🎯 Hasil Akhir
✅ Fitur Mata Kuliah - Daftar, pilih, dan kelola mata kuliah ✅ Fitur Absensi - Absensi dengan pilihan mata kuliah lengkap ✅ Fitur Riwayat - Lihat history kehadiran per mata kuliah ✅ Fitur Laporan - Statistik dan analisis kehadiran ✅ Integration - Terintegrasi dengan N8n webhook ✅ Storage - Penyimpanan lokal dengan SharedPreferences
Status: ✅ SELESAI - Semua fitur siap digunakan Last Updated: 14 Januari 2026 Version: 1.0