Skip to content

Fix/validation errors admin fragment#51

Open
siddhigupta075 wants to merge 5 commits intoiiitl:masterfrom
siddhigupta075:fix/validation-errors-admin-fragment
Open

Fix/validation errors admin fragment#51
siddhigupta075 wants to merge 5 commits intoiiitl:masterfrom
siddhigupta075:fix/validation-errors-admin-fragment

Conversation

@siddhigupta075
Copy link
Copy Markdown
Contributor

@siddhigupta075 siddhigupta075 commented Apr 13, 2026

Resolves #49

Description

This PR fixes validation issues in AdminFragment.

Earlier, validation was done using a when block, so only the first error was shown.
Also, old error messages were not cleared, which caused incorrect errors to remain visible even after fixing inputs.

Now:

  • All previous errors are cleared before validation
  • Each field is validated properly
  • Multiple errors can be shown at the same time if needed

This improves user experience and makes validation behave correctly.

Checklist

  • I have read all the contributor guidelines for the repo.

Summary by CodeRabbit

  • New Features

    • Added email and designation validation with inline error messages.
    • Enhanced add action feedback: button shows "Adding..." and shows result toasts.
  • Bug Fixes / Stability

    • Improved UI lifecycle handling to prevent stale view issues.
    • Better error handling when adding committee members to avoid silent failures.
  • Style

    • Redesigned admin screen layout, spacing and input/button styling.
    • New gradients, backgrounds and updated icon tinting; night theme parent updated.
  • Refactor

    • More robust dropdown handling and simplified settings timing logic.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 13, 2026

Walkthrough

Admin page UI and behavior updated: view binding made nullable and cleared in onDestroyView; email and designation validation added; add operation disables button and shows "Adding..." while calling ViewModel which returns success/failure; multiple drawable and layout styling changes added.

Changes

Cohort / File(s) Summary
Admin Fragment logic
app/src/main/java/com/theayushyadav11/MessEase/ui/NavigationDrawers/Fragments/AdminFragment.kt
Refactored to nullable _binding with cleanup in onDestroyView(). Added form validation (validateAndAdd()), trimmed inputs, error handling for email/designation, button disable/"Adding..." state, add(email, designation) calls ViewModel and handles result, clears fields on success. Spinner adapter assignment guarded for null context.
ViewModel Firestore handling
app/src/main/java/com/theayushyadav11/MessEase/ui/NavigationDrawers/ViewModels/AdminViewModel.kt
addToMessCommittee(...) now attaches an addOnFailureListener to the Firestore update(...) call and returns error message via onResult on failure.
Layout — Admin UI
app/src/main/res/layout/fragment_admin.xml
Significant layout adjustments: removed root id, added subtitle TextView, changed paddings/margins, restyled header, MaterialCardView (corner radius, elevation, stroke), form container now uses bg_card_glass_inner, input fields standardized to 56dp height and simplified styling, button restyled and given icon and updated constraints.
Drawable resources (new)
app/src/main/res/drawable/bg_card_glass_inner.xml, app/src/main/res/drawable/bg_gradient_full.xml, app/src/main/res/drawable/bg_icon_soft.xml
Added three new shape/gradient drawables: inner glass card gradient, full orange gradient background, and semi-transparent rounded icon background.
Drawable resources (tint updates)
app/src/main/res/drawable/baseline_attach_email_24.xml, app/src/main/res/drawable/baseline_person_24.xml
Replaced hardcoded tint #A19C9C with @color/food; added app namespace in email icon vector.
Settings refactor
app/src/main/java/com/theayushyadav11/MessEase/ui/more/SettingsActivity.kt
Introduced mealKeys list and replaced repetitive get/save calls with indexed loops mapping mealKeys to times and saving via forEachIndexed.
Minor UI/theme tweaks
app/src/main/res/layout/fragment_review.xml, app/src/main/res/values-night/themes.xml
Toolbar title color switched to theme attribute ?attr/colorOnPrimary. Night theme parent changed to Theme.MaterialComponents.DayNight.NoActionBar.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AdminFragment as Fragment
    participant AdminVM as ViewModel
    participant Firestore

    User->>Fragment: fills email + designation, taps Add
    Fragment->>Fragment: validateAndAdd() (trim, validate)
    alt valid inputs
        Fragment->>Fragment: disable button, set text "Adding..."
        Fragment->>AdminVM: addToMessCommittee(email, designation)
        AdminVM->>Firestore: update(...) (async)
        Firestore-->>AdminVM: success / failure
        AdminVM-->>Fragment: onResult(success|error)
        Fragment->>Fragment: re-enable button, restore text
        alt success
            Fragment->>Fragment: clear input fields, show success toast
        else error
            Fragment->>Fragment: show toast with error
        end
    else invalid
        Fragment->>Fragment: show inline field errors
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

accepted-45

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing validation errors in AdminFragment by implementing proper validation logic with multiple simultaneous error messages.
Linked Issues check ✅ Passed All coding objectives from issue #49 are met: inline validation for email and designation fields, error message handling, disabled/loading state during submission, field clearing after success, and ViewBinding memory leak fix.
Out of Scope Changes check ✅ Passed All changes are directly related to issue #49 objectives. The PR includes UI refinements (drawable resources, layout styling), form validation, button state management, ViewBinding improvements, and theme updates—all within scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@app/src/main/java/com/theayushyadav11/MessEase/ui/NavigationDrawers/Fragments/AdminFragment.kt`:
- Around line 86-88: The code is clearing the input fields unconditionally after
any toast; change AdminFragment's handler that currently calls
mess.toast(result) followed by binding.etEmail.text?.clear() and
binding.spinnerAutoComplete.text?.clear() so it only clears when the ViewModel
indicates a real success (e.g., the success message string or a success flag
from AdminViewModel). Locate the callback/observer in AdminFragment that
receives the result from AdminViewModel (the place that calls
mess.toast(result)) and add a conditional: if result indicates success (or check
the success boolean from the ViewModel), then clear binding.etEmail and
binding.spinnerAutoComplete; otherwise leave user input intact.
- Around line 73-84: The UI cleanup and button state reset must run on every
completion path: move the progress dismiss call (mess.pbDismiss()) so it
executes before the `_binding` null-check in the viewModel.addToMessCommittee
callback and ensure you always re-enable `binding.btnAdd` and reset its text
even if `_binding` is null; additionally update
`AdminViewModel.addToMessCommittee` so it invokes the provided completion lambda
(onResult) for both success and failure/error listeners (not just success) so
the caller always gets notified to unwind the loading UI.
- Around line 93-99: The callback passed to Mess.getLists(...) can run after the
fragment view is destroyed; guard it by checking fragment and view state before
using requireContext() or binding: inside the lambda, replace direct calls with
a safe check like if (!isAdded || binding == null || context == null) return@...
(or use context?.let and val b = binding ?: return@...) and only then create the
ArrayAdapter and call binding.spinnerAutoComplete.setAdapter(adapter); reference
Mess.getLists, AdminFragment (the surrounding method), and
binding.spinnerAutoComplete when applying the guard.

In `@app/src/main/res/drawable/baseline_attach_email_24.xml`:
- Around line 2-5: Remove any app:tint attributes on <path> elements (attribute
name: app:tint) and instead use android:fillColor on those <path> tags if they
need specific colors; leave the root vector's android:tint in place to tint the
whole drawable. Also remove the xmlns:app namespace declaration if no other app:
attributes remain. Apply the same change to the other occurrences noted (the
other <path> entries).

In `@app/src/main/res/layout/fragment_admin.xml`:
- Around line 51-75: The divider view is currently constrained to
app:layout_constraintTop_toBottomOf="@id/ivHeaderIcon" which can cause overlap
when the title/subtitle wrap; change the divider's top constraint to
app:layout_constraintTop_toBottomOf="@id/subtitle" (reference the divider view
id "divider" and subtitle id "subtitle") so the divider always sits below the
subtitle; keep existing horizontal constraints and margins as-is to preserve
spacing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 69cd8141-c4c8-435a-842b-a7982d392e44

📥 Commits

Reviewing files that changed from the base of the PR and between b8a8e9f and 07fbd18.

📒 Files selected for processing (7)
  • app/src/main/java/com/theayushyadav11/MessEase/ui/NavigationDrawers/Fragments/AdminFragment.kt
  • app/src/main/res/drawable/baseline_attach_email_24.xml
  • app/src/main/res/drawable/baseline_person_24.xml
  • app/src/main/res/drawable/bg_card_glass_inner.xml
  • app/src/main/res/drawable/bg_gradient_full.xml
  • app/src/main/res/drawable/bg_icon_soft.xml
  • app/src/main/res/layout/fragment_admin.xml

Comment thread app/src/main/res/drawable/baseline_attach_email_24.xml
Comment thread app/src/main/res/layout/fragment_admin.xml
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src/main/java/com/theayushyadav11/MessEase/ui/NavigationDrawers/ViewModels/AdminViewModel.kt (1)

15-33: ⚠️ Potential issue | 🟠 Major

Add error handling for the Firestore lookup query to prevent caller from hanging.

The whereEqualTo(EMAIL, email).get() call on line 6 only has addOnSuccessListener. If the query fails (network error, permission denied), onResult is never called and the caller can remain stuck in a submitting state indefinitely.

Suggested patch
-        firestoreReference.collection(USERS).whereEqualTo(EMAIL, email).get().addOnSuccessListener {
+        firestoreReference.collection(USERS).whereEqualTo(EMAIL, email).get()
+            .addOnSuccessListener {
             if (it.isEmpty) {
                 onResult("User not found")
             } else {
                 val id = it.documents[0].id
                 val updates = mapOf(
                     DESIGNATION to designation,
                     IS_MEMBER to true
                 )
 
                 firestoreReference.collection(USERS).document(id).update(updates)
                     .addOnSuccessListener {
                         onResult("User added to committee")
                     }
                     .addOnFailureListener {e ->
                         onResult(e.message ?: "Error adding user to committee")
                     }
             }
-        }
+        }
+            .addOnFailureListener { e ->
+                onResult(e.message ?: "Error finding user")
+            }
🤖 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/ViewModels/AdminViewModel.kt`
around lines 15 - 33, The Firestore lookup using
firestoreReference.collection(USERS).whereEqualTo(EMAIL, email).get() only
attaches addOnSuccessListener so onResult is never called on query failure; add
an addOnFailureListener (or addOnCompleteListener with success/failure handling)
to the initial get() call to invoke onResult with a meaningful error string
(e.g., e.message ?: "Error querying user") so the caller is always notified;
update the block around whereEqualTo/ get() to attach the failure handler and
ensure any exceptions from document update
(firestoreReference.collection(USERS).document(id).update) are already covered
by its addOnFailureListener.
🧹 Nitpick comments (1)
app/src/main/java/com/theayushyadav11/MessEase/ui/more/SettingsActivity.kt (1)

28-31: Prefer zipping keys/defaults instead of index-based access.

Line 30 depends on positional indexing across two lists. It works now, but zip avoids accidental index drift and is safer to maintain.

♻️ Suggested refactor
-        val defaultTimes = listOf("7:30", "12:0", "16:30", "19:0")
-        val times = mealKeys.mapIndexed { index, key ->
-            mess.get(key, defaultTimes[index])
-        }
+        val defaultTimes = listOf("7:30", "12:0", "16:30", "19:0")
+        val times = mealKeys.zip(defaultTimes).map { (key, defaultTime) ->
+            mess.get(key, defaultTime)
+        }
🤖 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/more/SettingsActivity.kt`
around lines 28 - 31, The code uses mapIndexed with positional indexing
(mealKeys.mapIndexed { index, key -> mess.get(key, defaultTimes[index]) }) which
can break if lists diverge; replace that with zipping mealKeys with defaultTimes
and mapping the pairs, e.g. zip mealKeys and defaultTimes then for each (key,
default) call mess.get(key, default) so the mapping of keys to defaults is
explicit and safe (refer to the variables mealKeys, defaultTimes and the
mess.get call).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In
`@app/src/main/java/com/theayushyadav11/MessEase/ui/NavigationDrawers/ViewModels/AdminViewModel.kt`:
- Around line 15-33: The Firestore lookup using
firestoreReference.collection(USERS).whereEqualTo(EMAIL, email).get() only
attaches addOnSuccessListener so onResult is never called on query failure; add
an addOnFailureListener (or addOnCompleteListener with success/failure handling)
to the initial get() call to invoke onResult with a meaningful error string
(e.g., e.message ?: "Error querying user") so the caller is always notified;
update the block around whereEqualTo/ get() to attach the failure handler and
ensure any exceptions from document update
(firestoreReference.collection(USERS).document(id).update) are already covered
by its addOnFailureListener.

---

Nitpick comments:
In `@app/src/main/java/com/theayushyadav11/MessEase/ui/more/SettingsActivity.kt`:
- Around line 28-31: The code uses mapIndexed with positional indexing
(mealKeys.mapIndexed { index, key -> mess.get(key, defaultTimes[index]) }) which
can break if lists diverge; replace that with zipping mealKeys with defaultTimes
and mapping the pairs, e.g. zip mealKeys and defaultTimes then for each (key,
default) call mess.get(key, default) so the mapping of keys to defaults is
explicit and safe (refer to the variables mealKeys, defaultTimes and the
mess.get call).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 756c9bd5-354e-431b-8fa9-8139baa1c7af

📥 Commits

Reviewing files that changed from the base of the PR and between 07fbd18 and 95ea2fe.

📒 Files selected for processing (6)
  • app/src/main/java/com/theayushyadav11/MessEase/ui/NavigationDrawers/Fragments/AdminFragment.kt
  • app/src/main/java/com/theayushyadav11/MessEase/ui/NavigationDrawers/ViewModels/AdminViewModel.kt
  • app/src/main/java/com/theayushyadav11/MessEase/ui/more/SettingsActivity.kt
  • app/src/main/res/drawable/baseline_attach_email_24.xml
  • app/src/main/res/layout/fragment_review.xml
  • app/src/main/res/values-night/themes.xml
✅ Files skipped from review due to trivial changes (3)
  • app/src/main/res/layout/fragment_review.xml
  • app/src/main/res/drawable/baseline_attach_email_24.xml
  • app/src/main/res/values-night/themes.xml
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/main/java/com/theayushyadav11/MessEase/ui/NavigationDrawers/Fragments/AdminFragment.kt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants