diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..218ffe6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,71 @@ +# Changelog + +Semua perubahan penting pada proyek Aplikasi Absensi Akademik didokumentasikan dalam file ini. + +## [Unreleased] - Versi Terbaru (Redesign & Backend Integration) + +Perubahan besar-besaran dilakukan pada arsitektur aplikasi, beralih dari aplikasi *single-screen* sederhana menjadi aplikasi manajemen akademik yang komprehensif dengan autentikasi dan validasi keamanan. + +### ✨ Fitur Baru (Added) +- **Sistem Autentikasi**: + - Menambahkan layar **Login** dan **Register**. + - Integrasi **JWT Authentication** (penyimpanan token via `SharedPreferences`). + - Manajemen sesi pengguna (Auto-login jika token tersimpan). +- **Manajemen Jadwal & Mata Kuliah**: + - Menambahkan fitur pengambilan data **Jadwal Kuliah** hari ini dari database. + - Dropdown pemilihan mata kuliah saat melakukan absensi. +- **Validasi Keamanan Tingkat Lanjut**: + - **Geofencing**: Validasi lokasi dalam radius 500m dari koordinat kampus. + - **Anti-Fake GPS**: Logika deteksi aplikasi *Mock Location* untuk mencegah kecurangan. + - **Face Detection**: Integrasi **CameraX + ML Kit** (tersirat dalam logika kamera baru) untuk mewajibkan deteksi wajah saat status "HADIR". +- **Fitur Kamera Kustom**: + - Mengganti intent kamera bawaan (`MediaStore`) dengan **CameraX** tertanam dalam UI. + - Fitur overlay kamera untuk panduan posisi wajah/dokumen. + - Dukungan kamera depan (selfie) dan belakang (dokumen). +- **Riwayat & Profil**: + - Menambahkan tab **Riwayat Absensi** untuk melihat log kehadiran dan bukti foto. + - Menambahkan tab **Profil** yang menampilkan data mahasiswa dan fitur Logout. +- **Multi-Status Absensi**: + - Dukungan untuk status **HADIR**, **SAKIT**, dan **IZIN**. + - Logika validasi berbeda untuk setiap status (Sakit/Izin tidak butuh radius lokasi). + +### 🎨 Antarmuka & UX (Changed) +- **UI Overhaul (Material3)**: + - Redesign total menggunakan **Jetpack Compose Material3**. + - Penerapan tema identitas kampus (**Gold & Maroon**). + - Penggunaan komponen UI modern: `Card`, `NavigationBar` (Bottom Nav), `Gradient Button`. +- **Navigasi**: + - Implementasi **Bottom Navigation Bar** dengan 4 menu utama (Absensi, Kelas, Riwayat, Profil). + - Transisi antar layar (Login <-> Main <-> Register). +- **Feedback User**: + - Loading indicator saat proses API berjalan. + - Dialog error dan sukses yang lebih informatif dibandingkan `Toast` sederhana. + +### βš™οΈ Teknis & Backend (Changed) +- **Migrasi API**: + - **Sebelumnya**: Mengirim data hardcoded langsung ke Webhook N8N via `HttpURLConnection`. + - **Sekarang**: Berkomunikasi dengan **Backend Python Flask** (`/api/auth`, `/api/absensi`, `/api/jadwal`). Backend yang kemudian meneruskan data ke N8N. +- **Struktur Kode**: + - Refactoring dari *Single Activity Monolith* menjadi struktur modular. + - Pemisahan logic ke dalam: + - `AppConstants` (Konfigurasi URL & Koordinat). + - `UserPreferences` (Manajemen sesi lokal). + - `Data Classes` (Mahasiswa, Jadwal, Riwayat). + - Helper functions (Bitmap Converter, Distance Calculation). + +### πŸ”₯ Dihapus (Removed) +- Menghapus pengiriman data hardcoded (NPM "12345") pada fungsi `kirimKeN8n`. +- Menghapus penggunaan `MediaStore.ACTION_IMAGE_CAPTURE` (Intent kamera eksternal). +- Menghapus tampilan *single-screen* sederhana tanpa navigasi. + +--- + +## [Legacy] - Versi Awal (Sebelum Redesign) + +Versi purwarupa (prototype) untuk pengujian fungsionalitas dasar. + +### Fitur +- Pengambilan titik koordinat GPS sederhana (`FusedLocationProvider`). +- Pengambilan foto menggunakan aplikasi kamera bawaan HP (`Intent`). +- Pengiriman data dummy langsung ke Webhook N8N. +- Tampilan UI dasar menggunakan `Column` dan `Button` standar. \ No newline at end of file diff --git a/README.md b/README.md index a07d04a..905bc20 100644 --- a/README.md +++ b/README.md @@ -1,95 +1,101 @@ -# πŸ“± Aplikasi Absensi Akademik Berbasis Koordinat dan Foto (Mobile) +# πŸ“± Aplikasi Absensi Akademik UBHARA Jaya (Mobile & Backend) + +[πŸ“‹ Changelog](./CHANGELOG.md) ## πŸ“Œ Deskripsi Proyek -Proyek ini merupakan **Tugas Project Akhir Mata Kuliah Pemrograman Mobile** yang bertujuan untuk membangun **aplikasi akademik berbasis mobile** dengan fokus pada **fitur absensi menggunakan data koordinat (GPS) dan pengambilan foto mahasiswa**. +Proyek ini merupakan **Tugas Project Akhir Mata Kuliah Pemrograman Mobile** yang mengimplementasikan sistem absensi akademik berbasis **Client-Server**. Aplikasi mobile dibangun menggunakan **Kotlin (Jetpack Compose)**, sedangkan sisi server menggunakan **Python Flask** dengan database **MySQL**. -Aplikasi ini dirancang untuk meningkatkan **validitas kehadiran mahasiswa**, dengan memastikan bahwa absensi hanya dapat dilakukan apabila mahasiswa: -1. Berada pada **lokasi yang telah ditentukan**, dan -2. Melakukan **pengambilan foto (selfie) secara langsung saat absensi** +Sistem ini dirancang dengan validasi ketat menggunakan **Geofencing (GPS)** dan **Deteksi Wajah (Face Detection)** untuk status kehadiran "Hadir", serta mendukung pengiriman bukti dokumen untuk status "Sakit/Izin". Seluruh data terintegrasi secara real-time ke **N8N Webhook** untuk pelaporan otomatis. --- ## 🎯 Tujuan Proyek -- Mengimplementasikan **Location-Based Service (LBS)** pada aplikasi mobile -- Mengintegrasikan **kamera perangkat** untuk dokumentasi absensi -- Mencegah kecurangan absensi (titip absen) -- Mengembangkan aplikasi mobile akademik berbasis Android -- Melatih kemampuan perancangan dan implementasi aplikasi mobile +- Mengimplementasikan arsitektur **REST API** antara Android dan Python Flask. +- Menerapkan **Face Detection** menggunakan CameraX untuk memvalidasi kehadiran fisik mahasiswa. +- Mencegah kecurangan absensi dengan fitur deteksi **Fake GPS**. +- Mengelola status kehadiran otomatis (**Auto-Alfa**) pada server jika mahasiswa lupa absen. +- Melatih kemampuan Fullstack Mobile Development (Backend, Database, & Mobile UI). --- ## πŸš€ Fitur Utama -- πŸ” **Login Pengguna (Mahasiswa)** -- πŸ“ **Pengambilan Koordinat Lokasi (Latitude & Longitude)** -- 🏫 **Validasi Lokasi Absensi (Radius Area)** -- πŸ“Έ **Pengambilan Foto Mahasiswa Saat Absensi** -- πŸ•’ **Pencatatan Waktu Absensi** -- πŸ“„ **Riwayat Kehadiran Mahasiswa** -- ⚠️ **Notifikasi Absensi Ditolak jika Tidak Valid** + +### πŸ“± Sisi Mobile (Android - Jetpack Compose) +- **Modern UI**: Antarmuka modern menggunakan **Material3** & **Jetpack Compose**. +- **Smart Attendance**: + - **Hadir**: Wajib berada di radius kampus & Wajib deteksi wajah (Real-time). + - **Sakit/Izin**: Wajib upload foto surat dokter/bukti (Tanpa validasi radius). +- **Anti-Fraud**: Sistem mendeteksi dan menolak jika pengguna mengaktifkan **Fake GPS/Mock Location**. +- **Riwayat & Bukti**: Mahasiswa dapat melihat riwayat kehadiran beserta foto bukti yang tersimpan di server. +- **Profil Mahasiswa**: Menampilkan data akademik dan fitur logout. + +### πŸ’» Sisi Backend (Python Flask) +- **JWT Authentication**: Keamanan berbasis token untuk setiap request. +- **Auto-Alfa Trigger**: Sistem otomatis menandai "TIDAK HADIR" jika jam kuliah berakhir dan mahasiswa belum absen. +- **N8N Integration**: Data absensi yang valid dikirim otomatis ke webhook N8N untuk notifikasi/reporting. +- **Image Handling**: Kompresi foto (Base64) otomatis untuk efisiensi penyimpanan database. --- -## πŸ—ΊοΈ Mekanisme Absensi Berbasis Lokasi dan Foto -1. Mahasiswa melakukan **login** -2. Memilih menu **Absensi** -3. Sistem meminta: - - Izin **akses lokasi** - - Izin **akses kamera** -4. Aplikasi mengambil: - - πŸ“ **Koordinat lokasi mahasiswa** - - πŸ“Έ **Foto mahasiswa secara real-time** -5. Sistem melakukan validasi: - - Lokasi berada dalam **radius absensi** - - Foto berhasil diambil -6. Jika valid β†’ **Absensi berhasil** -7. Jika tidak valid β†’ **Absensi ditolak** +## πŸ—ΊοΈ Mekanisme Absensi ---- +### 1. Absensi Status "HADIR" +1. Mahasiswa memilih Jadwal Kelas yang aktif. +2. Sistem mengecek **GPS**: + - Apakah di dalam radius **500m** dari kampus? + - Apakah terdeteksi aplikasi **Fake GPS**? +3. Sistem membuka **Kamera Deteksi Wajah**: + - Tombol shutter hanya aktif jika wajah terdeteksi. +4. Data (Lokasi + Foto Wajah) dikirim ke server. -## πŸ“Έ Pengambilan Foto Saat Absensi -- Foto diambil menggunakan **kamera depan (selfie)** -- Foto hanya dapat diambil **saat proses absensi** -- Foto disimpan sebagai **bukti kehadiran** -- Foto dapat digunakan untuk: - - Verifikasi manual oleh dosen - - Dokumentasi akademik +### 2. Absensi Status "SAKIT / IZIN" +1. Mahasiswa memilih status Sakit atau Izin. +2. Validasi lokasi dilewati (bisa absen dari rumah/RS). +3. Sistem membuka **Kamera Dokumen** (Tanpa deteksi wajah). +4. Mahasiswa memfoto surat keterangan. +5. Data dikirim ke server. + +### 3. Logika Auto-Alfa (Server) +- Setiap kali jadwal dimuat, server mengecek jadwal yang `jam_selesai < jam_sekarang`. +- Jika mahasiswa belum ada record absensi pada jam tersebut, server otomatis menginput status **"TIDAK HADIR"**. --- ## πŸ› οΈ Teknologi yang Digunakan -- **Platform** : Android -- **Bahasa Pemrograman** : Kotlin / Java -- **Location Service** : - - Google Maps API - - Fused Location Provider -- **Camera API** : CameraX / Camera2 -- **Database** : Firebase / SQLite / MySQL -- **Storage** : Firebase Storage / Local Storage -- **IDE** : Android Studio +- **Mobile Platform**: Android (Kotlin) +- **UI Framework**: Jetpack Compose +- **Camera Engine**: CameraX + ML Kit (Face Analysis) +- **Backend Framework**: Python Flask +- **Database**: MySQL +- **Integrasi**: N8N Webhook +- **Protocol**: HTTP/REST (JSON) --- ## πŸ” Izin Aplikasi (Permissions) Aplikasi memerlukan izin berikut: -- `ACCESS_FINE_LOCATION` -- `ACCESS_COARSE_LOCATION` -- `CAMERA` -- `INTERNET` -- `WRITE_EXTERNAL_STORAGE` (jika diperlukan) +- `INTERNET`: Koneksi ke Server API. +- `ACCESS_FINE_LOCATION`: Validasi koordinat presisi tinggi. +- `ACCESS_COARSE_LOCATION`: Validasi koordinat jaringan. +- `CAMERA`: Pengambilan foto bukti kehadiran & deteksi wajah. --- ## πŸ“‚ Mockup ![mockup](Mockup.png) -## Catatan: -- Kembangkan project dari starter yang sudah disediakan, tidak membuat dari awal. -- Untuk koordinat bisa ditambah/kurangi angka tertentu agar tidak memunculkan koordinat rumah masing-masing, data awal tetap dari GPS. - -## Pengecekan: -- https://ntfy.ubharajaya.ac.id/EAS -- https://docs.google.com/spreadsheets/d/1jH15MfnNgpPGuGeid0hYfY7fFUHCEFbCmg8afTyyLZs/edit?gid=0#gid=0 +## Catatan Konfigurasi: +- **Server**: Pastikan `app.py` berjalan (`python app.py`) pada jaringan yang sama dengan HP. +- **Endpoint**: Sesuaikan `BASE_URL` pada file `MainActivity.kt` (Object `AppConstants`) dengan IP Laptop Anda. + ```kotlin + const val BASE_URL = "[http://192.168.](http://192.168.)x.x:5000" + ``` +- **Fake GPS**: Pastikan mematikan aplikasi Mock Location saat pengujian fitur Hadir. -## Webhook: -- test: https://n8n.lab.ubharajaya.ac.id/webhook-test/23c6993d-1792-48fb-ad1c-ffc78a3e6254 -- production: https://n8n.lab.ubharajaya.ac.id/webhook/23c6993d-1792-48fb-ad1c-ffc78a3e6254 \ No newline at end of file +## Pengecekan & Monitoring: +- **Monitoring**: https://ntfy.ubharajaya.ac.id/EAS +- **Data Spreadsheet**: https://docs.google.com/spreadsheets/d/1jH15MfnNgpPGuGeid0hYfY7fFUHCEFbCmg8afTyyLZs/edit?gid=0#gid=0 + +## Webhook N8N: +- **Test**: https://n8n.lab.ubharajaya.ac.id/webhook-test/23c6993d-1792-48fb-ad1c-ffc78a3e6254 +- **Production**: https://n8n.lab.ubharajaya.ac.id/webhook/23c6993d-1792-48fb-ad1c-ffc78a3e6254 \ No newline at end of file diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..dd501ed Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher.xml b/app/src/main/res/mipmap-anydpi/ic_launcher.xml deleted file mode 100644 index 6f3b755..0000000 --- a/app/src/main/res/mipmap-anydpi/ic_launcher.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml deleted file mode 100644 index 6f3b755..0000000 --- a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp index c209e78..75730f7 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..117515b Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp index b2dfe3d..79d1c7b 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp index 4f0f1d6..5eff16a 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..5bd5f80 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp index 62b611d..10cea98 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp index 948a307..3390eb3 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..5cc7f71 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp index 1b9a695..1447591 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp index 28d4b77..8dc1fc9 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..671310e Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp index 9287f50..e7d58d2 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp index aa7d642..800a458 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..fe7650f Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp index 9126ae3..7802ac7 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..c5d5899 --- /dev/null +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #FFFFFF + \ No newline at end of file