Skip to content

fix(recruiter): restore applicant list when clearing search#1406

Merged
Sachinchaurasiya360 merged 2 commits into
Sachinchaurasiya360:mainfrom
YAXH64:fix/recruiter-search-clear
Jun 5, 2026
Merged

fix(recruiter): restore applicant list when clearing search#1406
Sachinchaurasiya360 merged 2 commits into
Sachinchaurasiya360:mainfrom
YAXH64:fix/recruiter-search-clear

Conversation

@YAXH64
Copy link
Copy Markdown
Contributor

@YAXH64 YAXH64 commented Jun 4, 2026

Pull Request

Description

Fixes an issue where clearing the applicant search field in the Recruiter Applications page would leave the UI in an empty state instead of restoring the full applicant list.

Root Cause

The component maintained pagination data in local React state while application data was managed by React Query. When a recruiter cleared the search field, React Query served cached results for the original query key, but the query function did not execute again. Because pagination state was updated inside the query function, the pagination state became out of sync with the cached application data, causing the page to incorrectly display an empty state.

Changes Made

  • Removed local pagination state management.
  • Returned both applications and pagination from the React Query query function.
  • Derived pagination directly from React Query data to keep state synchronized.
  • Removed the side-effect (setPagination) from the query function.
  • Trimmed search input before adding it to query parameters to prevent whitespace-only searches.
  • Preserved existing search, filtering, pagination, and caching behavior.

Benefits

  • Restores the full applicant list when search is cleared.
  • Eliminates React Query state synchronization issues.
  • Removes an anti-pattern (calling state setters inside queryFn).
  • Improves maintainability by keeping applications and pagination under a single source of truth.

Related Issue

Fixes #1142

Type of Change

  • Bug Fix
  • Feature
  • Enhancement
  • Documentation

Testing

Manual Testing

  1. Open Recruiter → Applications page.
  2. Verify all applicants load correctly.
  3. Search for an applicant name.
  4. Verify results are filtered correctly.
  5. Search for a non-existent applicant and verify the empty state appears.
  6. Clear the search field.
  7. Verify the full applicant list is restored.
  8. Repeat search → clear → search multiple times.
  9. Verify pagination continues to work correctly.
  10. Verify status filters continue to work after clearing search.

Validation

  • No TypeScript errors.
  • No build errors.
  • Existing search functionality remains unchanged.
  • Existing pagination and filtering behavior remains intact.

Screenshots / Video

No UI changes in this PR

Checklist

  • Code follows project guidelines
  • No new compile/type errors
  • Tested manually (include steps above)
  • No .env, credentials, or node_modules committed
  • Docs updated (not required)
  • No UI changes in this PR

Summary by CodeRabbit

  • New Features

    • Confirm dialogs now support flexible content display and loading states with visual spinner feedback
    • Application advance action now requires explicit user confirmation before processing
  • Bug Fixes

    • Search parameters are now trimmed to prevent issues with leading/trailing whitespace

@github-actions github-actions Bot added bug Something isn't working gssoc labels Jun 4, 2026
@github-actions github-actions Bot added the level:intermediate Requires moderate project understanding label Jun 4, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 4, 2026

Hi @YAXH64, thanks for contributing to InternHack! 🎉

I have automatically:

  • 👤 Assigned this PR to you.
  • 🏷️ Applied the gssoc:approved label.

Our workflows will now analyze your changes to classify:

  • 📈 PR Difficulty: level:*
  • 🧩 PR Type: type:*
  • 🌟 PR Quality: quality:*

Tip

Ensure your PR description references the issue it resolves (e.g. Closes #123). This allows the bot to inherit any additional labels from that issue!

Happy coding! 🚀

@github-actions github-actions Bot added gssoc:approved Approved for GSSoC scoring quality:exceptional Exceptional implementation quality type:bug Bug fixes type:design UI/UX or design-related updates labels Jun 4, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 4, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

Enhanced ConfirmDialog to support optional description, loading state, variant styling, and custom children content, then integrated it into ApplicationsList to gate the "Advance" action behind a confirmation modal. The ApplicationsList now tracks pending applications awaiting confirmation, refactored query data derivation, and clears confirmation state after completion.

Changes

Confirmation Modal for Application Advancement

Layer / File(s) Summary
ConfirmDialog Component Enhancement
client/src/components/ui/ConfirmDialog.tsx
ConfirmDialogProps makes description optional, adds confirmVariant ("danger" | "primary"), loading, and children (ReactNode). When loading is true, confirm and cancel buttons disable, confirm button displays a spinning Loader2, Escape dismissal is suppressed, and backdrop click is prevented. Focus shifts to cancel button on open.
ApplicationsList State & Data Refactoring
client/src/module/recruiter/applications/ApplicationsList.tsx
Adds pendingAdvanceApp state (Application | null) to track applications pending confirmation. Refactors useQuery to return a combined { applications, pagination } payload, applies trimmed search parameters, and derives both values directly from the response data.
ApplicationsList Confirmation Flow
client/src/module/recruiter/applications/ApplicationsList.tsx
The "Advance" button now sets pendingAdvanceApp instead of immediately calling handleAdvance. A ConfirmDialog renders when pendingAdvanceApp is non-null, displays candidate-specific messaging, sets loading based on advancingIds, triggers handleAdvance(appId) on confirmation, and clears pendingAdvanceApp on cancel or after advance completes.

Sequence Diagram

sequenceDiagram
  participant User
  participant ApplicationsList
  participant ConfirmDialog
  participant Advance Handler
  User->>ApplicationsList: Click "Advance" button
  ApplicationsList->>ApplicationsList: Set pendingAdvanceApp
  ApplicationsList->>ConfirmDialog: Render modal (opens)
  User->>ConfirmDialog: Click confirm
  ConfirmDialog->>ApplicationsList: Trigger onConfirm callback
  ApplicationsList->>Advance Handler: Call handleAdvance(appId)
  Advance Handler->>ApplicationsList: Mutation completes
  ApplicationsList->>ApplicationsList: Clear pendingAdvanceApp
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

  • Sachinchaurasiya360/InternHack#1269: Modifies the same ApplicationsList advance flow with per-row spinner states, overlapping with this PR's changes to the advance action handling.
  • Sachinchaurasiya360/InternHack#1309: Refactors advance/status mutations and React Query cache invalidation in the same ApplicationsList component, directly related to the advance flow changes here.
  • Sachinchaurasiya360/InternHack#1249: Modifies ApplicationsList pagination behavior (page reset on status filter change) alongside this PR's pagination data refactoring.

Suggested labels

bug, level:intermediate, scope:frontend, type:feature, quality:exceptional

Suggested reviewers

  • Sachinchaurasiya360

Poem

🐰 A confirmation appears with a hop,
Before advancing, we halt and we stop,
Loading spinners dance, variants align,
Children and children make modals divine!
Click to proceed, our dialog will sing. ✨

🚥 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
Title check ✅ Passed The title accurately and concisely summarizes the main bug fix: restoring the applicant list when clearing search in the recruiter module.
Description check ✅ Passed The PR description comprehensively covers all template sections: clear description of the problem and fix, linked issue, type of change, detailed testing steps, and completed checklist.
Linked Issues check ✅ Passed The changes directly address issue #1142 by fixing the empty state bug through proper state management synchronization between React Query and pagination data.
Out of Scope Changes check ✅ Passed The ConfirmDialog enhancement in ApplicationsList is a reasonable addition that improves UX by adding confirmation for the advance action, which falls within reasonable scope for this PR.

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

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

Warning

Review ran into problems

🔥 Problems

Stopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a @coderabbit review after the pipeline has finished.


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.

@github-actions github-actions Bot added the scope:frontend Changes to client-side / UI code label Jun 4, 2026
Copy link
Copy Markdown
Contributor

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@client/src/module/recruiter/applications/ApplicationsList.tsx`:
- Around line 97-106: The confirmation message can render an empty <strong> when
pendingAdvanceApp.student?.name is missing; update the JSX in ApplicationsList
(the interpolation inside the <strong> in the pendingAdvanceApp block) to use a
safe fallback (e.g., pendingAdvanceApp.student?.name ?? "this candidate" or
"Unnamed candidate") so the UI always shows a readable name, keeping the rest of
the message unchanged.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: cb128818-2d7f-406f-90ce-c9a0953a732c

📥 Commits

Reviewing files that changed from the base of the PR and between e15a36c and 219f134.

📒 Files selected for processing (2)
  • client/src/components/ui/ConfirmDialog.tsx
  • client/src/module/recruiter/applications/ApplicationsList.tsx

Comment on lines +97 to +106
{pendingAdvanceApp && (
<div className="space-y-4">
<p className="text-sm text-stone-600 dark:text-stone-400">
Are you sure you want to advance <strong className="font-semibold text-stone-900 dark:text-white">{pendingAdvanceApp.student?.name}</strong> to the next hiring stage?
</p>
<p className="text-xs text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-950/20 p-2.5 rounded-lg border border-amber-200/30 dark:border-amber-900/30 leading-normal">
Warning: Advancing this candidate will update their hiring stage and create a new round submission.
</p>
</div>
)}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Provide a fallback for undefined candidate name.

If pendingAdvanceApp.student.name is undefined or empty, the confirmation message will have an empty <strong> tag, degrading readability.

🛡️ Proposed fix to add a name fallback
           <p className="text-sm text-stone-600 dark:text-stone-400">
-            Are you sure you want to advance <strong className="font-semibold text-stone-900 dark:text-white">{pendingAdvanceApp.student?.name}</strong> to the next hiring stage?
+            Are you sure you want to advance <strong className="font-semibold text-stone-900 dark:text-white">{pendingAdvanceApp.student?.name || "this candidate"}</strong> to the next hiring stage?
           </p>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{pendingAdvanceApp && (
<div className="space-y-4">
<p className="text-sm text-stone-600 dark:text-stone-400">
Are you sure you want to advance <strong className="font-semibold text-stone-900 dark:text-white">{pendingAdvanceApp.student?.name}</strong> to the next hiring stage?
</p>
<p className="text-xs text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-950/20 p-2.5 rounded-lg border border-amber-200/30 dark:border-amber-900/30 leading-normal">
Warning: Advancing this candidate will update their hiring stage and create a new round submission.
</p>
</div>
)}
{pendingAdvanceApp && (
<div className="space-y-4">
<p className="text-sm text-stone-600 dark:text-stone-400">
Are you sure you want to advance <strong className="font-semibold text-stone-900 dark:text-white">{pendingAdvanceApp.student?.name || "this candidate"}</strong> to the next hiring stage?
</p>
<p className="text-xs text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-950/20 p-2.5 rounded-lg border border-amber-200/30 dark:border-amber-900/30 leading-normal">
Warning: Advancing this candidate will update their hiring stage and create a new round submission.
</p>
</div>
)}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@client/src/module/recruiter/applications/ApplicationsList.tsx` around lines
97 - 106, The confirmation message can render an empty <strong> when
pendingAdvanceApp.student?.name is missing; update the JSX in ApplicationsList
(the interpolation inside the <strong> in the pendingAdvanceApp block) to use a
safe fallback (e.g., pendingAdvanceApp.student?.name ?? "this candidate" or
"Unnamed candidate") so the UI always shows a readable name, keeping the rest of
the message unchanged.

@Sachinchaurasiya360
Copy link
Copy Markdown
Owner

Code Review — PR #1406: fix(recruiter): restore applicant list when clearing search

Hi @YAXH64, the search trim fix and pagination data-flow improvement are solid. One coordination note.


🟡 Merge conflict: ConfirmDialog.tsx modified in PRs #1405, #1406, #1409, and #1410

All four PRs apply identical changes to ConfirmDialog.tsx. Please coordinate with @Xenon010101 (PR #1410) to merge the ConfirmDialog changes in one PR first, then the others can drop that hunk during rebase.


✅ Core fix is correct

Changing if (debouncedSearch) to if (debouncedSearch.trim()) on the search param prevents whitespace-only strings from being sent to the API. Moving pagination out of queryFn side-effect state into the query return value is cleaner React Query usage.

@Sachinchaurasiya360 Sachinchaurasiya360 merged commit 219f134 into Sachinchaurasiya360:main Jun 5, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working gssoc:approved Approved for GSSoC scoring gssoc level:intermediate Requires moderate project understanding quality:exceptional Exceptional implementation quality scope:frontend Changes to client-side / UI code type:bug Bug fixes type:design UI/UX or design-related updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[recruiter] Empty application list search shows empty state instead of full list on clear

2 participants