diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2e0d78f..6e146bf 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -22,6 +22,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/java/id/ac/ubharajaya/panicbutton/JalurEvakuasiActivity.kt b/app/src/main/java/id/ac/ubharajaya/panicbutton/JalurEvakuasiActivity.kt new file mode 100644 index 0000000..82352d3 --- /dev/null +++ b/app/src/main/java/id/ac/ubharajaya/panicbutton/JalurEvakuasiActivity.kt @@ -0,0 +1,47 @@ +package id.ac.ubharajaya.panicbutton + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.* +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp + +class JalurEvakuasiActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContent { + JalurEvakuasiScreen(onClose = { finish() }) + } + } +} + +@Composable +fun JalurEvakuasiScreen(onClose: () -> Unit) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + + Image( + painter = painterResource(id = R.drawable.evakuasiselatan), + contentDescription = "Jalur Evakuasi", + modifier = Modifier.fillMaxWidth() + ) + + Spacer(modifier = Modifier.height(20.dp)) + + Button(onClick = onClose) { + Text("Close") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/id/ac/ubharajaya/panicbutton/MainActivity.kt b/app/src/main/java/id/ac/ubharajaya/panicbutton/MainActivity.kt index ec5244b..2a854a5 100644 --- a/app/src/main/java/id/ac/ubharajaya/panicbutton/MainActivity.kt +++ b/app/src/main/java/id/ac/ubharajaya/panicbutton/MainActivity.kt @@ -1,15 +1,25 @@ package id.ac.ubharajaya.panicbutton +import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* -import androidx.compose.material3.Button -import androidx.compose.material3.Text +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.Request @@ -19,64 +29,189 @@ class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { - MyApp() + MyApp( + onClose = { finish() }, + onOpenEvacuation = { + startActivity(Intent(this, JalurEvakuasiActivity::class.java)) + } + ) } } } +// Emoji untuk tiap kondisi +fun getEmoji(condition: String): String { + return when (condition) { + "Kebakaran" -> "🐦‍🔥" + "Banjir" -> "😒" + "Tsunami" -> "🐳" + "Gunung Meletus" -> "🤯" + "Gempa Bumi" -> "😫" + "Huru Hara/Demonstrasi" -> "😮" + "Binatang Buas" -> "💀" + "Radiasi Nuklir" -> "😶‍🌫️" + "Biohazard" -> "🥶" + else -> "" + } +} @Composable -fun MyApp() { - // State untuk menampilkan hasil request +fun MyApp(onClose: () -> Unit, onOpenEvacuation: () -> Unit) { + val focusManager = LocalFocusManager.current var message by remember { mutableStateOf("Klik tombol untuk mengirim notifikasi") } + var selectedConditions by remember { mutableStateOf(mutableSetOf()) } + var additionalNotes by remember { mutableStateOf(TextFieldValue("")) } - - // UI Column( modifier = Modifier .fillMaxSize() .padding(16.dp), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.Start ) { - Text(text = message, Modifier.padding(bottom = 16.dp)) - Button(onClick = { - // Kirim HTTP request saat tombol ditekan - sendNotification { response -> - message = response + // Judul + Text( + text = "Terjadi Kondisi Darurat:", + fontSize = 26.sp, + fontWeight = FontWeight.Bold, + color = Color.Red, + modifier = Modifier.padding(bottom = 16.dp) + ) + + // Daftar kondisi + listOf( + "Kebakaran", + "Banjir", + "Tsunami", + "Gunung Meletus", + "Gempa Bumi", + "Huru Hara/Demonstrasi", + "Binatang Buas", + "Radiasi Nuklir", + "Biohazard", + "Lainnya" + ).forEach { condition -> + val emoji = getEmoji(condition) + + Row( + modifier = Modifier + .fillMaxWidth() + .clickable { + focusManager.clearFocus() + selectedConditions = selectedConditions.toMutableSet().apply { + if (contains(condition)) remove(condition) else add(condition) + } + } + .padding(vertical = 4.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Checkbox( + checked = selectedConditions.contains(condition), + onCheckedChange = { isChecked -> + focusManager.clearFocus() + selectedConditions = selectedConditions.toMutableSet().apply { + if (isChecked) add(condition) else remove(condition) + } + } + ) + Text( + text = "$emoji $condition", + modifier = Modifier.padding(start = 8.dp) + ) } - }) { - Text(text = "Kirim Alert") } + + // Catatan tambahan + Spacer(modifier = Modifier.height(16.dp)) + Text(text = "Catatan tambahan:", fontWeight = FontWeight.Bold) + + BasicTextField( + value = additionalNotes, + onValueChange = { additionalNotes = it }, + modifier = Modifier + .fillMaxWidth() + .height(100.dp) + .padding(8.dp) + .border(1.dp, Color.Gray), + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done) + ) + + // ================================================ + // Tombol Kirim + Lihat Jalur Evakuasi (Berdampingan) + // ================================================ + Spacer(modifier = Modifier.height(16.dp)) + + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + + // Tombol Kirim Laporan + Button( + onClick = { + val notes = additionalNotes.text + val conditions = selectedConditions.joinToString(", ") { + "${getEmoji(it)} $it" + } + val report = "Kondisi: $conditions\nCatatan: $notes" + + sendNotification(report) { response -> + message = response + } + }, + modifier = Modifier.weight(1f), + colors = ButtonDefaults.buttonColors(containerColor = Color.Black) + ) { + Text(text = "Kirim Laporan", color = Color.Yellow) + } + + Spacer(modifier = Modifier.width(12.dp)) + + // Tombol Jalur Evakuasi + Button( + onClick = onOpenEvacuation, + modifier = Modifier.weight(1f), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF0080FF)) + ) { + Text(text = "Lihat Jalur Evakuasi", color = Color.White) + } + } + + Spacer(modifier = Modifier.height(16.dp)) + Text( + text = "“JANGAN PANIK! SEGERA EVAKUASI\nDIRI ANDA KE TITIK KUMPUL”", + color = Color.Red, + fontSize = 15.sp + ) + + Spacer(modifier = Modifier.height(20.dp)) + + // Tombol Tutup (opsional) + Button(onClick = onClose) { + Text("Tutup") + } + + Spacer(modifier = Modifier.height(16.dp)) + Text(text = message) } } - -// Fungsi untuk mengirimkan HTTP request -fun sendNotification(onResult: (String) -> Unit) { +// =============================================================== +// Fungsi Kirim Notifikasi ke Server ntfy.ubharajaya.ac.id +// =============================================================== +fun sendNotification(report: String, onResult: (String) -> Unit) { val client = OkHttpClient() - val url = "https://ntfy.ubharajaya.ac.id/panic-button" // Ganti dengan topik Anda - - - - - val requestBody = RequestBody.create( - "text/plain".toMediaType(), // Mengirim plain text - "Notifikasi dari Satrio Putra Wardani 202310715307" // Pesan yang akan tampil - ) + val url = "https://ntfy.ubharajaya.ac.id/panic-button" + val requestBody = RequestBody.create("text/plain".toMediaType(), report) val request = Request.Builder() .url(url) .addHeader("Title", "Alert") .addHeader("Priority", "urgent") - .addHeader("Tags", "alert warning,rotating_light") .post(requestBody) .build() - - - // Eksekusi request di thread terpisah Thread { try { val response = client.newCall(request).execute() diff --git a/app/src/main/res/drawable/evakuasiselatan.jpg b/app/src/main/res/drawable/evakuasiselatan.jpg new file mode 100644 index 0000000..1d24604 Binary files /dev/null and b/app/src/main/res/drawable/evakuasiselatan.jpg differ