Jetpack Compose How to Update UI whenever new Data is input

46 Views Asked by At

I have a project where there is a feature that will allow the user/admin to add a new document and contact in firestore, a edit feature and a delete feature.

this is the Firestore query ` data class FirefighterAdmin(val documentId: String, val contactNumber: String)

private fun getEmergencyPhoneNumber(finalMunicipalityForm: String): List { val db = Firebase.firestore val TAG = "EmergencyPhoneNumber"

Log.d(TAG, "Retrieving emergency phone numbers for municipality: $finalMunicipalityForm")

var firefighters = mutableListOf<FirefighterAdmin>()

db.collection("Emergency Contacts")
    .document("$finalMunicipalityForm")
    .collection("Firefighters")
    .get()
    .addOnSuccessListener { querySnapshot ->
        Log.d(TAG, "Successfully retrieved query snapshot for firefighters")

        for (document in querySnapshot.documents) {
            Log.d(TAG, "Processing document: ${document.id}")

            val documentId = document.id
            val contactNumber = document.getString("contacts") ?: ""
            Log.d(TAG, "Extracted contact number: $contactNumber")

            firefighters.add(FirefighterAdmin(documentId, contactNumber))
        }

        Log.d(TAG, "Retrieved firefighters: $firefighters")

        // Update the state variable with the retrieved firefighters
        firefighters.let { updatedFirefighters ->
            firefighters = updatedFirefighters
        }
    }
    .addOnFailureListener { exception ->
        Log.e(TAG, "Error retrieving emergency phone numbers: ${exception.message}", exception)
    }

return firefighters

} `

and this is the my lazy column

` Box( modifier = Modifier .fillMaxWidth() .fillMaxHeight(.8f) .background(containerColor) // Set the background color as needed ) { var contactNumber = "" var documentId =""

                        LazyColumn(
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(horizontal = 16.dp)
                        ) {
                            item {
                                if (firefighters != null) {
                                    for (firefighter in firefighters!!) {

                                        contactNumber = firefighter.contactNumber
                                        documentId = firefighter.documentId

                                        val editedContactNumber =
                                            remember { mutableStateOf(contactNumber) }


                                        Spacer(modifier = Modifier.height(5.dp))
                                        Column {
                                            Text(
                                                text = "$documentId",
                                                color = Color.Black,
                                                style = LocalTextStyle.current,
                                                modifier = Modifier
                                                    .paddingFromBaseline(
                                                        10.dp,
                                                        0.dp
                                                    ) // Adjust vertical spacing as needed
                                            )


                                            Row(
                                                modifier = Modifier
                                                    .fillMaxWidth()
                                                    .height(50.dp)
                                                    .padding(5.dp),
                                                horizontalArrangement = Arrangement.SpaceBetween
                                            ) {
                                                var isEditing by remember { mutableStateOf(false) }

                                                Box(
                                                    modifier = Modifier
                                                        .size(width = 150.dp, height = 40.dp)
                                                        .border(2.dp, Color.Black)
                                                        .background(Color.White),
                                                    contentAlignment = Alignment.Center
                                                ) {
                                                    if (isEditing) {
                                                        TextField(
                                                            value = if (isEditing) editedContactNumber.value else "", // Show editedContactNumber if editing, otherwise show an empty string
                                                            onValueChange = { newValue ->
                                                                // Check if the input is not empty and contains only numeric characters
                                                                if (newValue.isNotEmpty() && newValue.all { char -> char.isDigit() }) {
                                                                    // Check if the length is less than or equal to 11 digits
                                                                    if (newValue.length <= 11) {
                                                                        editedContactNumber.value =
                                                                            newValue
                                                                        contactNumber =
                                                                            editedContactNumber.value
                                                                    } else {
                                                                        Log.d(
                                                                            "editedContactNumber",
                                                                            "editedContactNumber: Number Input is not Valid "
                                                                        )
                                                                    }
                                                                } else {
                                                                    Log.d(
                                                                        "EditInput",
                                                                        "Empty Field"
                                                                    )
                                                                }
                                                                // You can provide feedback to the user or handle other cases as needed
                                                            },
                                                            textStyle = LocalTextStyle.current.copy(
                                                                color = Color.Black,
                                                                fontSize = 14.sp
                                                            ),
                                                            keyboardOptions = KeyboardOptions.Default.copy(
                                                                keyboardType = KeyboardType.Number
                                                            ),

                                                            )


                                                    } else {
                                                        Text(
                                                            text = editedContactNumber.value,
                                                            color = Color.Black,
                                                            style = LocalTextStyle.current
                                                        )
                                                    }
                                                }

                                                Icon(
                                                    imageVector = if (isEditing) Icons.Default.Check else Icons.Default.Edit,
                                                    contentDescription = null,
                                                    tint = Color.Black,
                                                    modifier = Modifier
                                                        .size(24.dp)
                                                        .align(Alignment.Bottom)
                                                        .padding(bottom = 1.dp)
                                                        .clickable {

                                                            isEditing = !isEditing

                                                            if (!isEditing) {
                                                                if (editedContactNumber.value.length == 11) {
                                                                    // Update the contact number in Firestore
                                                                    if (finalMunicipalityForm != null) {
                                                                        val db =
                                                                            Firebase.firestore
                                                                        db
                                                                            .collection("Emergency Contacts")
                                                                            .document("$finalMunicipalityForm")
                                                                            .collection("Firefighters")
                                                                            .document(documentId)
                                                                            .update(
                                                                                "contacts",
                                                                                editedContactNumber.value
                                                                            )
                                                                            .addOnSuccessListener {
                                                                                Log.d(
                                                                                    "EditNumber",
                                                                                    "Number updated successfully : $editedContactNumber.value"
                                                                                )
                                                                                isEditing =
                                                                                    false
                                                                                Toast.makeText(context, "Number Updated", Toast.LENGTH_SHORT).show()

                                                                            }
                                                                            .addOnFailureListener { e ->
                                                                                Log.e(
                                                                                    "EditNumber",
                                                                                    "Error updating number",
                                                                                    e
                                                                                )
                                                                            }
                                                                    } else {
                                                                        Toast.makeText(context, "Please enter 11-digit only", Toast.LENGTH_SHORT).show()
                                                                    }
                                                                } else {
                                                                    // Display error message
                                                                    errorState =
                                                                        "Invalid phone number. Please enter a 11-digit number."
                                                                }

                                                            }
                                                        }
                                                )

                                                Icon(
                                                    imageVector = Icons.Default.Delete,
                                                    contentDescription = null,
                                                    tint = Color.Black,
                                                    modifier = Modifier
                                                        .size(24.dp)
                                                        .align(Alignment.Bottom)
                                                        .padding(bottom = 1.dp)
                                                        .clickable {

                                                            // Delete the contact number from Firestore
                                                            if (finalMunicipalityForm != null) {
                                                                val db = Firebase.firestore
                                                                db
                                                                    .collection("Emergency Contacts")
                                                                    .document("$finalMunicipalityForm")
                                                                    .collection("Firefighters")
                                                                    .document(documentId)
                                                                    .delete()
                                                                    .addOnSuccessListener {
                                                                        Log.d(
                                                                            "DeleteNumber",
                                                                            "Number deleted successfully"
                                                                        )
                                                                        isEditing = false
                                                                        Toast.makeText(context, "Number Deleted Successfully", Toast.LENGTH_SHORT).show()
                                                                    }
                                                                    .addOnFailureListener { e ->
                                                                        Log.e(
                                                                            "DeleteNumber",
                                                                            "Error deleting number",
                                                                            e
                                                                        )
                                                                    }
                                                            } else {
                                                       //         context.showToast("Error")
                                                            }
                                                        }
                                                )

                                                Icon(
                                                    imageVector = Icons.Default.LocationOn,
                                                    contentDescription = null,
                                                    tint = Color.Black,
                                                    modifier = Modifier
                                                        .size(40.dp)
                                                        .clickable {
                                                            userLocation?.let { location ->
                                                                // Call a function to handle sending SMS with location and phone number
                                                                sendLocationSMS(
                                                                    context = context,
                                                                    location = location,
                                                                    phoneNumber = contactNumber
                                                                )
                                                            } ?: run {
                                                                Log.w(
                                                                    "Clickable",
                                                                    "User location is null"
                                                                )
                                                            }
                                                        }
                                                )

                                                Spacer(modifier = Modifier.width(2.dp))

                                                Icon(
                                                    imageVector = Icons.Default.Phone,
                                                    contentDescription = null,
                                                    tint = Color.Black,
                                                    modifier = Modifier
                                                        .size(40.dp)
                                                        .clickable {
                                                            // Launch the dialer here
                                                            val dialIntent = Intent(
                                                                Intent.ACTION_DIAL,
                                                                Uri.parse("tel:$contactNumber")
                                                            )
                                                            dialerLauncher.launch(dialIntent)
                                                        }
                                                )
                                            }

                                            Spacer(
                                                modifier = Modifier
                                                    .height(1.dp)
                                                    .fillMaxWidth()
                                                    .background(Color.Black)
                                            )

                                            Spacer(modifier = Modifier.height(5.dp))


                                        }
                                    }
                                } // here

                                Column {
                                    val mutableNewDocumentId = remember { mutableStateOf("") }
                                    val mutableNewContactNumber = remember { mutableStateOf("") }

                                    Text(
                                        text = "Document ID",
                                        style = MaterialTheme.typography.labelSmall,
                                        color = Color.Black,
                                        modifier = Modifier.padding(horizontal = 10.dp)
                                    )

                                    TextField(
                                        value = mutableNewDocumentId.value,
                                        onValueChange = { newValue ->
                                            mutableNewDocumentId.value = newValue
                                        },
                                        textStyle = LocalTextStyle.current.copy(
                                            color = Color.Black,
                                            fontSize = 8.sp
                                        ),
                                        modifier = Modifier
                                            .border(2.dp, Color.Black) // Add a border
                                            .size(width = 150.dp, height = 40.dp)

                                    )

                                    Spacer(modifier = Modifier.height(10.dp))

                                    Text(
                                        text = "Contact Number",
                                        style = MaterialTheme.typography.labelSmall,
                                        color = Color.Black,
                                        modifier = Modifier.padding(horizontal = 10.dp)
                                    )

                                    val pattern = Regex("[0-9]+")

                                    TextField(
                                        value = mutableNewContactNumber.value,
                                        onValueChange = { newValue ->
                                            if (newValue.length <= 11 && pattern.matches(newValue)) {
                                                mutableNewContactNumber.value = newValue
                                            }
                                        },
                                        keyboardOptions = KeyboardOptions.Default.copy(
                                            keyboardType = KeyboardType.Number
                                        ),
                                        textStyle = LocalTextStyle.current.copy(
                                            color = Color.Black,
                                            fontSize = 8.sp
                                        ),
                                        modifier = Modifier
                                            .border(2.dp, Color.Black) // Add a border
                                            .size(width = 150.dp, height = 40.dp)

                                    )

                                    Button(
                                        onClick = {
                                            val pattern = Regex("[0-9]+")
                                            // Add to Firestore
                                            if (mutableNewDocumentId.value.isNotEmpty() && mutableNewContactNumber.value.isNotEmpty()) {
                                                if (mutableNewContactNumber.value.length == 11 && pattern.matches(mutableNewContactNumber.value)) {
                                                    val db = Firebase.firestore
                                                    db
                                                        .collection("Emergency Contacts")
                                                        .document("$finalMunicipalityForm")
                                                        .collection("Firefighters")
                                                        .document(mutableNewDocumentId.value)
                                                        .set(
                                                            hashMapOf(
                                                                "contacts" to mutableNewContactNumber.value
                                                            )
                                                        )
                                                        .addOnSuccessListener {
                                                            Log.d("AddField", "New firefighter added successfully")
                                                            Toast.makeText(context, "New firefighter added successfully", Toast.LENGTH_SHORT).show()
                                                            mutableNewDocumentId.value = ""
                                                            mutableNewContactNumber.value = ""
                                                        }
                                                        .addOnFailureListener { e ->
                                                            Log.e("AddField", "Error adding firefighter", e)
                                                            Toast.makeText(context, "Error adding firefighter", Toast.LENGTH_SHORT).show()

                                                        }
                                                } else {
                                                    Log.d("AddField", "Invalid phone number. Please enter a 11-digit number.")
                                                }
                                            } else {
                                                Log.d("AddField", "Empty fields. Please enter both document ID and contact number.")
                                            }
                                        },
                                        shape = RoundedCornerShape(10.dp),

                                        content = {
                                            Icon(
                                                imageVector = Icons.Default.Check,
                                                contentDescription = null,
                                                tint = Color.White,
                                                modifier = Modifier.size(30.dp)
                                            )
                                        },
                                        modifier = Modifier
                                            .align(Alignment.End) // Align the button to the right
                                            .padding(horizontal = 25.dp) // Add some horizontal padding
                                    )


                                }

                            }
                        }`

I am trying to update my UI whenever there is a new data or updated data or deleted data being process.

0

There are 0 best solutions below