Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,60 +13,95 @@ import com.theayushyadav11.MessEase.utils.Constants.Companion.DESIGNATION
import com.theayushyadav11.MessEase.utils.Mess

class AdminFragment : Fragment() {
private lateinit var binding: FragmentAdminBinding
private lateinit var mess: Mess

private var _binding: FragmentAdminBinding? = null
private val binding get() = _binding!!

private lateinit var mess: Mess
private val viewModel: AdminViewModel by viewModels()

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
binding = FragmentAdminBinding.inflate(layoutInflater, container, false)
_binding = FragmentAdminBinding.inflate(inflater, container, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initialise()
listeners()
}

private fun initialise() {
mess = Mess(requireContext())
setAdapter()
}

private fun listeners() {
binding.btnAdd.setOnClickListener {
add()
validateAndAdd()
}
}

private fun initialise() {
mess = Mess(requireContext())
setAdapter()
}
private fun validateAndAdd() {
val email = binding.etEmail.text.toString().trim()
val designation = binding.spinnerAutoComplete.text.toString().trim()

when {
email.isEmpty() -> {
binding.tilEmail.error = "Email required"
}

fun add() {
if (binding.etEmail.text.toString().isNotEmpty()) {
mess.addPb("Adding to Mess Committee")
viewModel.addToMessCommittee(
binding.etEmail.text.toString(),
binding.spinnerAutoComplete.text.toString()
)
{
mess.pbDismiss()
mess.toast(it)
!android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches() -> {
binding.tilEmail.error = "Invalid email"
}
} else {
mess.toast("Please enter email")

designation.isEmpty() -> {
binding.tilspin.error = "Select designation"
}
Comment on lines +50 to +61
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Clear field errors before validation branches to avoid stale messages.

If one field becomes valid and another fails, the old error can remain visible.

Small validation cleanup
 private fun validateAndAdd() {
     val email = binding.etEmail.text.toString().trim()
     val designation = binding.spinnerAutoComplete.text.toString().trim()

+    binding.tilEmail.error = null
+    binding.tilspin.error = null
+
     when {
         email.isEmpty() -> {
             binding.tilEmail.error = "Email required"
         }
         !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches() -> {
             binding.tilEmail.error = "Invalid email"
         }
         designation.isEmpty() -> {
             binding.tilspin.error = "Select designation"
         }
         else -> {
-            binding.tilEmail.error = null
-            binding.tilspin.error = null
             add(email, designation)
         }
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/theayushyadav11/MessEase/ui/NavigationDrawers/Fragments/AdminFragment.kt`
around lines 50 - 61, Before running the validation when-block in AdminFragment
(the block checking email and designation using android.util.Patterns), clear
any existing error messages on the involved TextInputLayouts first; e.g., set
binding.tilEmail.error = null and binding.tilspin.error = null (and any other
tilX used for inputs) immediately before the when { ... } so stale errors are
removed and only current validation failures are shown.


else -> {
binding.tilEmail.error = null
binding.tilspin.error = null
add(email, designation)
}
}
}

private fun add(email: String, designation: String) {
// Disable button to avoid spam clicking
binding.btnAdd.isEnabled = false
binding.btnAdd.text = "Adding..."

mess.addPb("Adding to Mess Committee")

viewModel.addToMessCommittee(email, designation) {
mess.pbDismiss()

binding.btnAdd.isEnabled = true
binding.btnAdd.text = "Add to Committee"

mess.toast(it)

// Clear fields after success
binding.etEmail.text?.clear()
binding.spinnerAutoComplete.text?.clear()
}
Comment on lines +78 to 89
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard async callbacks against Fragment view destruction.

These callbacks use binding/requireContext() after async work. If the view is destroyed first, this can crash.

Safer callback handling
 private fun add(email: String, designation: String) {
     binding.btnAdd.isEnabled = false
     binding.btnAdd.text = "Adding..."
     mess.addPb("Adding to Mess Committee")

     viewModel.addToMessCommittee(email, designation) {
+        val b = _binding ?: return@addToMessCommittee
         mess.pbDismiss()
-        binding.btnAdd.isEnabled = true
-        binding.btnAdd.text = "Add to Committee"
+        b.btnAdd.isEnabled = true
+        b.btnAdd.text = "Add to Committee"
         mess.toast(it)
-        binding.etEmail.text?.clear()
-        binding.spinnerAutoComplete.text?.clear()
+        b.etEmail.text?.clear()
+        b.spinnerAutoComplete.text?.clear()
     }
 }

 private fun setAdapter() {
     mess.getLists("${DESIGNATION}s") {
+        val b = _binding ?: return@getLists
+        val ctx = context ?: return@getLists
         val adapter = ArrayAdapter(
-            requireContext(),
+            ctx,
             android.R.layout.simple_dropdown_item_1line,
             it
         )
-        binding.spinnerAutoComplete.setAdapter(adapter)
+        b.spinnerAutoComplete.setAdapter(adapter)
     }
 }

Also applies to: 94-100

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/theayushyadav11/MessEase/ui/NavigationDrawers/Fragments/AdminFragment.kt`
around lines 78 - 89, The async callbacks passed to viewModel.addToMessCommittee
(and the similar callback at lines 94-100) access binding and requireContext()
after async work, which can crash if the Fragment view is destroyed; update the
callback bodies to first check the Fragment/view lifecycle (e.g.,
viewLifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) or
isAdded() && view != null) before touching binding or calling requireContext(),
and bail out silently if the view is gone—ensure all UI updates
(mess.pbDismiss(), binding.btnAdd.*, mess.toast(...), clearing fields) are
guarded by that check or run via view?.let { ... } so no UI is accessed after
destruction.

}

private fun setAdapter() {
mess.getLists("${DESIGNATION}s") {
val spinner = binding.spinnerAutoComplete
val spinnerItems = it
val adapter =
ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, spinnerItems)
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.setAdapter(adapter)
val adapter = ArrayAdapter(
requireContext(),
android.R.layout.simple_dropdown_item_1line,
it
)
binding.spinnerAutoComplete.setAdapter(adapter)
}
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
4 changes: 3 additions & 1 deletion app/src/main/res/drawable/baseline_attach_email_24.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:width="24dp"
android:height="24dp"
android:tint="#A19C9C"
android:tint="@color/food"
android:viewportWidth="24"
android:viewportHeight="24">

Expand All @@ -11,6 +12,7 @@

<path
android:fillColor="@android:color/white"
app:tint="@color/food"
android:pathData="M21,14v4c0,1.1 -0.9,2 -2,2s-2,-0.9 -2,-2v-4.5c0,-0.28 0.22,-0.5 0.5,-0.5s0.5,0.22 0.5,0.5V18h2v-4.5c0,-1.38 -1.12,-2.5 -2.5,-2.5S15,12.12 15,13.5V18c0,2.21 1.79,4 4,4s4,-1.79 4,-4v-4H21z" />

</vector>
2 changes: 1 addition & 1 deletion app/src/main/res/drawable/baseline_person_24.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#A19C9C"
android:tint="@color/food"
android:viewportWidth="24"
android:viewportHeight="24">

Expand Down
8 changes: 8 additions & 0 deletions app/src/main/res/drawable/bg_card_glass_inner.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#FFFFFF"
android:endColor="#F5F5F5"
android:angle="270"/>
<corners android:radius="22dp"/>
</shape>
7 changes: 7 additions & 0 deletions app/src/main/res/drawable/bg_gradient_full.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape>
<gradient xmlns:android="http://schemas.android.com/apk/res/android"
android:startColor="#FF6F00"
android:endColor="#FFB74D"
android:angle="270"/>
</shape>
6 changes: 6 additions & 0 deletions app/src/main/res/drawable/bg_icon_soft.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- res/drawable/bg_icon_soft.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#22FFFFFF"/>
<corners android:radius="50dp"/>
</shape>
Loading