feat(ui): checklist report types with emoji icons; improved card styling and 3D panic button
This commit is contained in:
parent
97d37a43ad
commit
f0d6074b55
3
.idea/copilot.data.migration.agent.xml
generated
3
.idea/copilot.data.migration.agent.xml
generated
@ -13,6 +13,9 @@
|
||||
<option value="f607f271-4885-4c4e-91da-e2caf2abd67a" />
|
||||
<option value="39a0d9c4-a68f-4050-bb14-eda17dc695db" />
|
||||
<option value="94d90579-6a6d-44a9-8b93-de694c0c38ef" />
|
||||
<option value="fe272d92-3acf-42e8-bd88-66dc00800c3f" />
|
||||
<option value="ea6afe5a-c296-461b-a4a7-49209b3d7937" />
|
||||
<option value="2b41e5bf-4d90-46d8-8fc8-7b41c3f788e1" />
|
||||
</set>
|
||||
</value>
|
||||
</entry>
|
||||
|
||||
18
.idea/copilotDiffState.xml
generated
Normal file
18
.idea/copilotDiffState.xml
generated
Normal file
File diff suppressed because one or more lines are too long
@ -46,54 +46,89 @@ fun MyApp() {
|
||||
// dialogMessage akan menampung hasil callback dari sendNotification; null = tidak tampil
|
||||
var dialogMessage by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
// Report options (checkbox-style)
|
||||
val reportOptions = listOf("Kebakaran", "Banjir", "Gempa Bumi", "Huru Hara/Demostrasi", "Lainnya")
|
||||
val checkedMap = remember { mutableStateMapOf<String, Boolean>().apply { reportOptions.forEach { put(it, false) } } }
|
||||
// theme color for panic
|
||||
val panicColor = Color(0xFFB71C1C)
|
||||
|
||||
// Report options (checkbox-style) with icons (emoji from ntfy emoji list)
|
||||
val reportOptions = listOf(
|
||||
"Kebakaran" to "🔥",
|
||||
"Banjir" to "🌊",
|
||||
"Gempa Bumi" to "🌍",
|
||||
"Huru Hara/Demostrasi" to "📣",
|
||||
"Lainnya" to "📝"
|
||||
)
|
||||
val checkedMap = remember { mutableStateMapOf<String, Boolean>().apply { reportOptions.forEach { put(it.first, false) } } }
|
||||
var otherNote by remember { mutableStateOf("") }
|
||||
|
||||
// UI
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
.padding(18.dp),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
// Checklist area similar to the wireframe
|
||||
// Checklist area styled as card
|
||||
Surface(
|
||||
tonalElevation = 2.dp,
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
color = Color(0xFFFFEBEE), // soft red/pink background to match panic theme
|
||||
tonalElevation = 4.dp,
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp)
|
||||
.fillMaxWidth(0.92f)
|
||||
.padding(horizontal = 12.dp)
|
||||
) {
|
||||
Column(modifier = Modifier.padding(12.dp)) {
|
||||
Text(text = "Terjadi Kondisi Darurat", fontWeight = FontWeight.SemiBold)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Column(modifier = Modifier.padding(14.dp)) {
|
||||
Text(
|
||||
text = "Terjadi Kondisi Darurat",
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 18.sp,
|
||||
color = panicColor
|
||||
)
|
||||
|
||||
// Each option as a row with checkbox
|
||||
reportOptions.forEach { option ->
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
|
||||
// Each option as a row with icon, label and checkbox aligned nicely
|
||||
reportOptions.forEach { (label, icon) ->
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 4.dp)
|
||||
.padding(vertical = 6.dp)
|
||||
.toggleable(
|
||||
value = checkedMap[option] ?: false,
|
||||
onValueChange = { checked -> checkedMap[option] = checked }
|
||||
value = checkedMap[label] ?: false,
|
||||
onValueChange = { checked -> checkedMap[label] = checked }
|
||||
)
|
||||
) {
|
||||
// icon circle
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = Modifier
|
||||
.size(34.dp)
|
||||
.background(color = Color.White.copy(alpha = 0.9f), shape = CircleShape)
|
||||
.shadow(1.dp, shape = CircleShape)
|
||||
) {
|
||||
Text(text = icon, fontSize = 18.sp)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(text = label, fontSize = 16.sp)
|
||||
}
|
||||
|
||||
Checkbox(
|
||||
checked = checkedMap[option] ?: false,
|
||||
onCheckedChange = { checked -> checkedMap[option] = checked }
|
||||
checked = checkedMap[label] ?: false,
|
||||
onCheckedChange = { checked -> checkedMap[label] = checked },
|
||||
colors = CheckboxDefaults.colors(
|
||||
checkedColor = panicColor,
|
||||
uncheckedColor = Color.DarkGray
|
||||
)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(text = option)
|
||||
}
|
||||
}
|
||||
|
||||
// Additional notes field — show always (wireframe shows a note field)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = otherNote,
|
||||
onValueChange = { otherNote = it },
|
||||
@ -101,7 +136,8 @@ fun MyApp() {
|
||||
placeholder = { Text("Catatan tambahan ...") },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 8.dp)
|
||||
.heightIn(min = 56.dp, max = 140.dp),
|
||||
maxLines = 4
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
@ -110,7 +146,7 @@ fun MyApp() {
|
||||
if ((checkedMap["Lainnya"] == true) && otherNote.isBlank()) {
|
||||
Text(
|
||||
text = "Catatan wajib jika Anda memilih 'Lainnya'",
|
||||
color = Color(0xFFB71C1C),
|
||||
color = panicColor,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
modifier = Modifier.padding(top = 6.dp)
|
||||
)
|
||||
@ -118,12 +154,12 @@ fun MyApp() {
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(18.dp))
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
|
||||
// Keep the existing nice PanicButton unchanged
|
||||
// Keep the existing nice PanicButton unchanged (slightly smaller spacing)
|
||||
PanicButton(onClick = {
|
||||
// Validation: at least one option selected
|
||||
val selected = reportOptions.filter { checkedMap[it] == true }
|
||||
val selected = reportOptions.map { it.first }.filter { checkedMap[it] == true }
|
||||
if (selected.isEmpty()) {
|
||||
dialogMessage = "Pilih minimal satu jenis laporan sebelum mengirim."
|
||||
return@PanicButton
|
||||
@ -139,15 +175,15 @@ fun MyApp() {
|
||||
append(selected.joinToString(", "))
|
||||
append("\n")
|
||||
append("Keterangan: ")
|
||||
if (selected.contains("Lainnya")) append(otherNote.trim()) else append("-")
|
||||
if (otherNote.isNotBlank()) append(otherNote.trim()) else append("-")
|
||||
append("\n")
|
||||
append("Pengirim: Satrio Putra Wardani 202310715307")
|
||||
append("Pengirim: Rakha adi saputro 202310715083")
|
||||
}
|
||||
|
||||
sendNotification(message) { response -> dialogMessage = response }
|
||||
})
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Spacer(modifier = Modifier.height(14.dp))
|
||||
|
||||
// dialog hasil
|
||||
if (dialogMessage != null) {
|
||||
@ -174,7 +210,7 @@ fun MyApp() {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(color = Color(0xFFB71C1C))
|
||||
.background(color = panicColor)
|
||||
.padding(vertical = 12.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
@ -206,7 +242,7 @@ fun MyApp() {
|
||||
) {
|
||||
Button(
|
||||
onClick = { dialogMessage = null },
|
||||
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFFB71C1C))
|
||||
colors = ButtonDefaults.buttonColors(containerColor = panicColor)
|
||||
) {
|
||||
Text(text = "OK", color = Color.White)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user