From ca6d6e2d333ef30df1cbb47e89ce6cf2f3af31d2 Mon Sep 17 00:00:00 2001 From: Indris Alpasela <202310715200@mhs.ubharajaya.ac.id> Date: Wed, 14 Jan 2026 21:20:01 +0700 Subject: [PATCH] EAS_202310715200_IndrisAlpasela --- .../ac/ubharajaya/sistemakademik/Absensi.kt | 30 +- .../sistemakademik/LoginActivity.kt | 2 +- .../ubharajaya/sistemakademik/MainActivity.kt | 546 +++++++++++++----- .../sistemakademik/SessionManager.kt | 42 +- ... Naufal Priatna => er.name Indris Alpasela | 0 5 files changed, 451 insertions(+), 169 deletions(-) rename er.name Faris Naufal Priatna => er.name Indris Alpasela (100%) diff --git a/app/src/main/java/id/ac/ubharajaya/sistemakademik/Absensi.kt b/app/src/main/java/id/ac/ubharajaya/sistemakademik/Absensi.kt index 13ef788..f913df0 100644 --- a/app/src/main/java/id/ac/ubharajaya/sistemakademik/Absensi.kt +++ b/app/src/main/java/id/ac/ubharajaya/sistemakademik/Absensi.kt @@ -5,9 +5,6 @@ import android.util.Base64 import org.json.JSONObject import java.io.ByteArrayOutputStream -/** - * Data class untuk menyimpan informasi absensi mahasiswa - */ data class Absensi( val npm: String, val nama: String, @@ -16,30 +13,21 @@ data class Absensi( val waktu: String, val foto: Bitmap ) { - /** - * Convert objek Absensi ini menjadi JSONObject - * Siap untuk dikirim ke server - */ fun toJson(): JSONObject { val json = JSONObject() json.put("npm", npm) json.put("nama", nama) json.put("latitude", latitude) json.put("longitude", longitude) - json.put("timestamp", System.currentTimeMillis()) json.put("waktu", waktu) - json.put("foto_base64", bitmapToBase64(foto)) + + // Convert Bitmap to Base64 + val byteArrayOutputStream = ByteArrayOutputStream() + foto.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayOutputStream) + val byteArray = byteArrayOutputStream.toByteArray() + val encodedImage = Base64.encodeToString(byteArray, Base64.DEFAULT) + json.put("foto", encodedImage) + return json } - - companion object { - /** - * Helper function untuk convert Bitmap ke Base64 - */ - fun bitmapToBase64(bitmap: Bitmap): String { - val outputStream = ByteArrayOutputStream() - bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream) - return Base64.encodeToString(outputStream.toByteArray(), Base64.NO_WRAP) - } - } -} +} \ No newline at end of file diff --git a/app/src/main/java/id/ac/ubharajaya/sistemakademik/LoginActivity.kt b/app/src/main/java/id/ac/ubharajaya/sistemakademik/LoginActivity.kt index b091c10..a4e3228 100644 --- a/app/src/main/java/id/ac/ubharajaya/sistemakademik/LoginActivity.kt +++ b/app/src/main/java/id/ac/ubharajaya/sistemakademik/LoginActivity.kt @@ -92,7 +92,7 @@ fun LoginScreen(modifier: Modifier = Modifier) { // Tombol Login Button( onClick = { - if (npm == "202310715123" && password == "123") { + if (npm == "202310715200" && password == "123") { val intent = Intent(context, MainActivity::class.java) context.startActivity(intent) } else { diff --git a/app/src/main/java/id/ac/ubharajaya/sistemakademik/MainActivity.kt b/app/src/main/java/id/ac/ubharajaya/sistemakademik/MainActivity.kt index 1417d18..c8ad2b4 100644 --- a/app/src/main/java/id/ac/ubharajaya/sistemakademik/MainActivity.kt +++ b/app/src/main/java/id/ac/ubharajaya/sistemakademik/MainActivity.kt @@ -14,21 +14,22 @@ import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.animation.* import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.* import androidx.compose.runtime.* +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat import com.google.android.gms.location.LocationServices @@ -38,7 +39,11 @@ import java.util.* import kotlin.concurrent.thread import java.net.HttpURLConnection import java.net.URL -import org.json.JSONObject + +// Warna Akademik Biru Konsisten +val AkademikBlue = Color(0xFF1565C0) +val AkademikLightBlue = Color(0xFFE3F2FD) +val AkademikDarkBlue = Color(0xFF0D47A1) // ================== UTILS ================== fun kirimKeN8n(context: ComponentActivity, absensi: Absensi) { @@ -55,14 +60,14 @@ fun kirimKeN8n(context: ComponentActivity, absensi: Absensi) { context.runOnUiThread { Toast.makeText( context, - if (responseCode == 200) "Absensi diterima server" else "Absensi ditolak server", + if (responseCode == 200) "Absensi berhasil dikirim" else "Absensi gagal dikirim", Toast.LENGTH_SHORT ).show() } conn.disconnect() } catch (_: Exception) { context.runOnUiThread { - Toast.makeText(context, "Gagal kirim ke server", Toast.LENGTH_SHORT).show() + Toast.makeText(context, "Gagal terhubung ke server", Toast.LENGTH_SHORT).show() } } } @@ -77,8 +82,11 @@ class MainActivity : ComponentActivity() { setContent { SistemAkademikTheme { - Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> - AbsensiScreen(modifier = Modifier.padding(innerPadding), activity = this) + Surface( + modifier = Modifier.fillMaxSize(), + color = AkademikLightBlue + ) { + AbsensiScreen(activity = this) } } } @@ -86,30 +94,23 @@ class MainActivity : ComponentActivity() { } // ================== COMPOSABLE UI ================== +@OptIn(ExperimentalMaterial3Api::class) @Composable -fun AbsensiScreen(modifier: Modifier = Modifier, activity: ComponentActivity) { +fun AbsensiScreen(activity: ComponentActivity) { val context = LocalContext.current val session = remember { SessionManager(context) } - var lokasi by remember { mutableStateOf("Koordinat: -") } + var lokasi by remember { mutableStateOf("Menunggu lokasi...") } var latitude by remember { mutableStateOf(null) } var longitude by remember { mutableStateOf(null) } var foto by remember { mutableStateOf(null) } var waktuAbsensi by remember { mutableStateOf(null) } + var isLoading by remember { mutableStateOf(false) } + var showLogoutDialog by remember { mutableStateOf(false) } val absensiList = remember { mutableStateListOf() } val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context) - // ================== STATE WARNA ================== - var primaryColor by remember { mutableStateOf(Color(0xFF6200EE)) } - var backgroundColor by remember { mutableStateOf(Color(0xFFF2F2F2)) } - - val colors = listOf( - Color.Red, Color.Green, Color.Blue, Color.Magenta, Color.Cyan, - Color.Yellow, Color.Gray, Color.DarkGray, Color.Black, Color(0xFFFF9800), - Color(0xFF9C27B0), Color(0xFF4CAF50), Color(0xFF03A9F4), Color(0xFFE91E63) - ) - // ===== Permission & Kamera ===== val locationPermissionLauncher = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) { granted -> @@ -122,7 +123,7 @@ fun AbsensiScreen(modifier: Modifier = Modifier, activity: ComponentActivity) { if (location != null) { latitude = location.latitude longitude = location.longitude - lokasi = "Lat: ${location.latitude}\nLon: ${location.longitude}" + lokasi = "${String.format("%.6f", location.latitude)}, ${String.format("%.6f", location.longitude)}" } else { lokasi = "Lokasi tidak tersedia" } @@ -130,7 +131,7 @@ fun AbsensiScreen(modifier: Modifier = Modifier, activity: ComponentActivity) { .addOnFailureListener { lokasi = "Gagal mengambil lokasi" } } } else { - Toast.makeText(context, "Izin lokasi ditolak", Toast.LENGTH_SHORT).show() + Toast.makeText(context, "Izin lokasi diperlukan", Toast.LENGTH_SHORT).show() } } @@ -156,7 +157,7 @@ fun AbsensiScreen(modifier: Modifier = Modifier, activity: ComponentActivity) { val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) cameraLauncher.launch(intent) } else { - Toast.makeText(context, "Izin kamera ditolak", Toast.LENGTH_SHORT).show() + Toast.makeText(context, "Izin kamera diperlukan", Toast.LENGTH_SHORT).show() } } @@ -164,121 +165,406 @@ fun AbsensiScreen(modifier: Modifier = Modifier, activity: ComponentActivity) { locationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION) } - // ================== UI ================== - Column( - modifier = modifier - .fillMaxSize() - .background(backgroundColor) - .padding(24.dp) - ) { - Text( - text = "Absensi Akademik", - style = MaterialTheme.typography.titleLarge, - color = primaryColor - ) - Spacer(modifier = Modifier.height(16.dp)) - - // PALETTE WARNA BULETAN - Text("Pilih Warna Tema:", style = MaterialTheme.typography.bodyMedium, color = primaryColor) - Spacer(modifier = Modifier.height(8.dp)) - Row(modifier = Modifier.horizontalScroll(rememberScrollState())) { - colors.forEach { color -> - Box( - modifier = Modifier - .size(40.dp) - .padding(4.dp) - .background(color, shape = CircleShape) - .clickable { - primaryColor = color - backgroundColor = color.copy(alpha = 0.1f) - } - ) - } - } - - Spacer(modifier = Modifier.height(16.dp)) - Text(text = lokasi, color = primaryColor) - Spacer(modifier = Modifier.height(16.dp)) - - Button( - onClick = { cameraPermissionLauncher.launch(Manifest.permission.CAMERA) }, - modifier = Modifier.fillMaxWidth(), - colors = ButtonDefaults.buttonColors(containerColor = primaryColor) - ) { Text("Ambil Foto") } - - Spacer(modifier = Modifier.height(12.dp)) - - Button( - onClick = { - if (latitude != null && longitude != null && foto != null) { - val waktu = SimpleDateFormat("dd MMM yyyy HH:mm:ss", Locale.getDefault()).format(System.currentTimeMillis()) - waktuAbsensi = waktu - - val absensi = Absensi( - npm = session.getUserNpm() ?: "Faris Naufal Priatna", - nama = session.getUserName() ?: "202310715123", - latitude = latitude!!, - longitude = longitude!!, - waktu = waktu, - foto = foto!! - ) - kirimKeN8n(activity, absensi) - absensiList.add(absensi) - } else { - Toast.makeText(context, "⚠️ Absensi ditolak: Silahkan Foto Dlu Kocak", Toast.LENGTH_SHORT).show() + // Logout Dialog + if (showLogoutDialog) { + AlertDialog( + onDismissRequest = { showLogoutDialog = false }, + title = { Text("Konfirmasi Keluar") }, + text = { Text("Apakah Anda yakin ingin keluar dari sistem?") }, + confirmButton = { + TextButton( + onClick = { + session.logout() + context.startActivity(Intent(context, LoginActivity::class.java)) + (context as ComponentActivity).finish() + } + ) { + Text("Ya", color = Color.Red, fontWeight = FontWeight.Bold) } }, - modifier = Modifier.fillMaxWidth(), - colors = ButtonDefaults.buttonColors(containerColor = primaryColor) - ) { Text("Kirim Absensi") } + dismissButton = { + TextButton(onClick = { showLogoutDialog = false }) { + Text("Batal", color = AkademikBlue) + } + } + ) + } - Spacer(modifier = Modifier.height(16.dp)) - waktuAbsensi?.let { Text("Waktu Absensi: $it", color = primaryColor) } - - Spacer(modifier = Modifier.height(16.dp)) - - // ================== LOGOUT BUTTON ================== - Button( - onClick = { - session.logout() - context.startActivity(Intent(context, LoginActivity::class.java)) - (context as ComponentActivity).finish() - }, - modifier = Modifier.fillMaxWidth(), - colors = ButtonDefaults.buttonColors(containerColor = Color.Red) - ) { - Text("Logout") + // ================== UI ================== + Scaffold( + topBar = { + TopAppBar( + title = { + Column { + Text( + "Sistem Absensi Mahasiswa", + style = MaterialTheme.typography.titleLarge, + fontWeight = FontWeight.Bold + ) + Text( + "Universitas Bhayangkara Jakarta Raya", + style = MaterialTheme.typography.bodySmall + ) + } + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = AkademikBlue, + titleContentColor = Color.White + ), + actions = { + TextButton(onClick = { showLogoutDialog = true }) { + Text("Keluar", color = Color.White, fontWeight = FontWeight.Bold) + } + } + ) } - - Spacer(modifier = Modifier.height(16.dp)) - Text("Riwayat Kehadiran", color = primaryColor) - Spacer(modifier = Modifier.height(12.dp)) - - if (absensiList.isEmpty()) Text("Belum ada absensi", color = primaryColor) - else LazyColumn { - items(absensiList) { item -> - Card( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 4.dp), - elevation = CardDefaults.cardElevation(defaultElevation = 4.dp) + ) { paddingValues -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .padding(16.dp) + ) { + // CARD PROFIL MAHASISWA + Card( + modifier = Modifier.fillMaxWidth(), + shape = RoundedCornerShape(12.dp), + colors = CardDefaults.cardColors( + containerColor = Color.White + ), + elevation = CardDefaults.cardElevation(defaultElevation = 3.dp) + ) { + Row( + modifier = Modifier.padding(20.dp), + verticalAlignment = Alignment.CenterVertically ) { - Column(modifier = Modifier.padding(12.dp)) { - Text("Nama: ${item.nama}", color = primaryColor) - Text("NPM: ${item.npm}", color = primaryColor) - Text("Waktu: ${item.waktu}", color = primaryColor) - Text("Lat: ${item.latitude}, Lon: ${item.longitude}", color = primaryColor) - Spacer(modifier = Modifier.height(8.dp)) - Image( - bitmap = item.foto.asImageBitmap(), - contentDescription = "Foto Absensi", + Surface( + modifier = Modifier.size(70.dp), + shape = RoundedCornerShape(12.dp), + color = AkademikLightBlue + ) { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + Text( + "IA", + style = MaterialTheme.typography.headlineMedium, + fontWeight = FontWeight.Bold, + color = AkademikBlue + ) + } + } + Spacer(modifier = Modifier.width(16.dp)) + Column { + Text( + text = session.getUserName() ?: "Indris Alpasela", + style = MaterialTheme.typography.titleLarge, + fontWeight = FontWeight.Bold, + color = AkademikDarkBlue + ) + Text( + text = "NPM: ${session.getUserNpm() ?: "202310715200"}", + style = MaterialTheme.typography.bodyLarge, + color = Color.Gray + ) + } + } + } + + Spacer(modifier = Modifier.height(16.dp)) + + // INFO CARD: LOKASI & WAKTU + Card( + modifier = Modifier.fillMaxWidth(), + shape = RoundedCornerShape(12.dp), + colors = CardDefaults.cardColors(containerColor = Color.White), + elevation = CardDefaults.cardElevation(defaultElevation = 3.dp) + ) { + Column(modifier = Modifier.padding(16.dp)) { + // Lokasi + Row(verticalAlignment = Alignment.Top) { + Text( + "📍", + style = MaterialTheme.typography.headlineSmall + ) + Spacer(modifier = Modifier.width(12.dp)) + Column { + Text( + "Lokasi Saat Ini", + style = MaterialTheme.typography.labelMedium, + color = Color.Gray + ) + Text( + lokasi, + style = MaterialTheme.typography.bodyLarge, + fontWeight = FontWeight.Medium + ) + } + } + + waktuAbsensi?.let { + Spacer(modifier = Modifier.height(16.dp)) + Divider() + Spacer(modifier = Modifier.height(16.dp)) + + // Waktu Absensi + Row(verticalAlignment = Alignment.Top) { + Text( + "🕐", + style = MaterialTheme.typography.headlineSmall + ) + Spacer(modifier = Modifier.width(12.dp)) + Column { + Text( + "Waktu Absensi Terakhir", + style = MaterialTheme.typography.labelMedium, + color = Color.Gray + ) + Text( + it, + style = MaterialTheme.typography.bodyLarge, + fontWeight = FontWeight.Medium + ) + } + } + } + } + } + + Spacer(modifier = Modifier.height(16.dp)) + + // PREVIEW FOTO + AnimatedVisibility(visible = foto != null) { + Column { + Card( + modifier = Modifier + .fillMaxWidth() + .height(240.dp), + shape = RoundedCornerShape(12.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 3.dp) + ) { + Box(modifier = Modifier.fillMaxSize()) { + foto?.let { + Image( + bitmap = it.asImageBitmap(), + contentDescription = "Preview Foto", + modifier = Modifier.fillMaxSize() + ) + } + Surface( + modifier = Modifier + .align(Alignment.TopEnd) + .padding(8.dp), + shape = RoundedCornerShape(8.dp), + color = Color.White.copy(alpha = 0.9f) + ) { + Text( + "Preview", + modifier = Modifier.padding(horizontal = 12.dp, vertical = 6.dp), + style = MaterialTheme.typography.labelMedium, + fontWeight = FontWeight.Bold, + color = AkademikBlue + ) + } + } + } + Spacer(modifier = Modifier.height(16.dp)) + } + } + + // TOMBOL AMBIL FOTO + Button( + onClick = { cameraPermissionLauncher.launch(Manifest.permission.CAMERA) }, + modifier = Modifier + .fillMaxWidth() + .height(60.dp), + colors = ButtonDefaults.buttonColors(containerColor = AkademikBlue), + shape = RoundedCornerShape(12.dp), + elevation = ButtonDefaults.buttonElevation(defaultElevation = 4.dp) + ) { + Text( + "📷", + style = MaterialTheme.typography.headlineMedium + ) + Spacer(modifier = Modifier.width(12.dp)) + Text( + "Ambil Foto", + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.Bold + ) + } + + Spacer(modifier = Modifier.height(12.dp)) + + // TOMBOL KIRIM ABSENSI + Button( + onClick = { + if (latitude != null && longitude != null && foto != null) { + isLoading = true + val waktu = SimpleDateFormat("dd MMMM yyyy, HH:mm:ss", Locale("id", "ID")).format(System.currentTimeMillis()) + waktuAbsensi = waktu + + val absensi = Absensi( + npm = session.getUserNpm() ?: "202310715200", + nama = session.getUserName() ?: "Indris Alpasela", + latitude = latitude!!, + longitude = longitude!!, + waktu = waktu, + foto = foto!! + ) + kirimKeN8n(activity, absensi) + absensiList.add(0, absensi) + isLoading = false + } else { + Toast.makeText( + context, + "Mohon ambil foto dan pastikan lokasi aktif", + Toast.LENGTH_LONG + ).show() + } + }, + modifier = Modifier + .fillMaxWidth() + .height(60.dp), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2E7D32)), + shape = RoundedCornerShape(12.dp), + enabled = !isLoading, + elevation = ButtonDefaults.buttonElevation(defaultElevation = 4.dp) + ) { + if (isLoading) { + CircularProgressIndicator( + color = Color.White, + modifier = Modifier.size(28.dp) + ) + } else { + Text( + "✉️", + style = MaterialTheme.typography.headlineMedium + ) + Spacer(modifier = Modifier.width(12.dp)) + Text( + "Kirim Absensi", + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.Bold + ) + } + } + + Spacer(modifier = Modifier.height(20.dp)) + + // RIWAYAT ABSENSI + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + "Riwayat Kehadiran", + style = MaterialTheme.typography.titleLarge, + fontWeight = FontWeight.Bold, + color = AkademikDarkBlue + ) + if (absensiList.isNotEmpty()) { + Surface( + shape = RoundedCornerShape(20.dp), + color = AkademikLightBlue + ) { + Text( + "${absensiList.size}", + modifier = Modifier.padding(horizontal = 12.dp, vertical = 6.dp), + style = MaterialTheme.typography.labelLarge, + fontWeight = FontWeight.Bold, + color = AkademikBlue + ) + } + } + } + Spacer(modifier = Modifier.height(12.dp)) + + if (absensiList.isEmpty()) { + Card( + modifier = Modifier.fillMaxWidth(), + colors = CardDefaults.cardColors(containerColor = Color.White), + shape = RoundedCornerShape(12.dp) + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(40.dp), + contentAlignment = Alignment.Center + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text( + "📋", + style = MaterialTheme.typography.displayMedium + ) + Spacer(modifier = Modifier.height(12.dp)) + Text( + "Belum ada riwayat kehadiran", + color = Color.Gray, + style = MaterialTheme.typography.bodyLarge + ) + } + } + } + } else { + LazyColumn { + items(absensiList) { item -> + Card( modifier = Modifier .fillMaxWidth() - .height(150.dp) - ) + .padding(vertical = 6.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 3.dp), + shape = RoundedCornerShape(12.dp), + colors = CardDefaults.cardColors(containerColor = Color.White) + ) { + Row( + modifier = Modifier.padding(16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + // Foto Kecil + Image( + bitmap = item.foto.asImageBitmap(), + contentDescription = "Foto Absensi", + modifier = Modifier + .size(80.dp) + .clip(RoundedCornerShape(8.dp)) + ) + + Spacer(modifier = Modifier.width(16.dp)) + + // Info + Column(modifier = Modifier.weight(1f)) { + Text( + item.nama, + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.Bold, + color = AkademikDarkBlue + ) + Text( + item.npm, + style = MaterialTheme.typography.bodyMedium, + color = Color.Gray + ) + Spacer(modifier = Modifier.height(6.dp)) + Text( + item.waktu, + style = MaterialTheme.typography.bodySmall, + color = Color.Gray + ) + } + + // Status + Text( + "✅", + style = MaterialTheme.typography.headlineMedium + ) + } + } } } } } } -} +} \ No newline at end of file diff --git a/app/src/main/java/id/ac/ubharajaya/sistemakademik/SessionManager.kt b/app/src/main/java/id/ac/ubharajaya/sistemakademik/SessionManager.kt index f09ab98..167cd5f 100644 --- a/app/src/main/java/id/ac/ubharajaya/sistemakademik/SessionManager.kt +++ b/app/src/main/java/id/ac/ubharajaya/sistemakademik/SessionManager.kt @@ -5,29 +5,37 @@ import android.content.SharedPreferences class SessionManager(context: Context) { private val prefs: SharedPreferences = - context.getSharedPreferences("user_session", Context.MODE_PRIVATE) + context.getSharedPreferences("AbsensiSession", Context.MODE_PRIVATE) companion object { - private const val KEY_IS_LOGGED_IN = "is_logged_in" - private const val KEY_NPM = "npm" - private const val KEY_NAME = "name" + private const val KEY_IS_LOGGED_IN = "isLoggedIn" + private const val KEY_USER_NAME = "userName" + private const val KEY_USER_NPM = "userNpm" } - fun saveLogin(npm: String, name: String) { - prefs.edit().apply { - putBoolean(KEY_IS_LOGGED_IN, true) - putString(KEY_NPM, npm) - putString(KEY_NAME, name) - apply() - } + fun saveLoginSession(nama: String, npm: String) { + val editor = prefs.edit() + editor.putBoolean(KEY_IS_LOGGED_IN, true) + editor.putString(KEY_USER_NAME, nama) + editor.putString(KEY_USER_NPM, npm) + editor.apply() } - fun isLoggedIn(): Boolean = prefs.getBoolean(KEY_IS_LOGGED_IN, false) + fun isLoggedIn(): Boolean { + return prefs.getBoolean(KEY_IS_LOGGED_IN, false) + } + + fun getUserName(): String? { + return prefs.getString(KEY_USER_NAME, null) + } + + fun getUserNpm(): String? { + return prefs.getString(KEY_USER_NPM, null) + } fun logout() { - prefs.edit().clear().apply() + val editor = prefs.edit() + editor.clear() + editor.apply() } - - fun getUserNpm(): String? = prefs.getString(KEY_NPM, null) - fun getUserName(): String? = prefs.getString(KEY_NAME, null) -} +} \ No newline at end of file diff --git a/er.name Faris Naufal Priatna b/er.name Indris Alpasela similarity index 100% rename from er.name Faris Naufal Priatna rename to er.name Indris Alpasela