feat: Add search, sort, and filter to Application Page - #36
Conversation
Kushal425
commented
Sep 15, 2025
- Add real-time search by company, job title, status
- Add sorting by date, company, status priority
- Add filters for status, location type, employment type
- Enhance UI with status badges and responsive design
- Add keyboard shortcuts (⌘+K search, ⌘+N new)
- Improve accessibility with ARIA labels
- Add real-time search by company, job title, status - Add sorting by date, company, status priority - Add filters for status, location type, employment type - Enhance UI with status badges and responsive design - Add keyboard shortcuts (⌘+K search, ⌘+N new) - Improve accessibility with ARIA labels
There was a problem hiding this comment.
Pull Request Overview
This PR adds comprehensive search, sort, and filter functionality to the Application Page to help users organize and find job applications efficiently. The changes enhance user experience with real-time search, multiple sort options, status-based filtering, and keyboard shortcuts.
Key changes include:
- Implemented real-time search across company, job title, status, and notes
- Added sorting by date, company, status priority, and job title with ascending/descending options
- Created filtering system for application status, location type (remote/hybrid/onsite), and employment type (full-time/part-time/internship)
- Enhanced UI with status badges, responsive design, and keyboard shortcuts (⌘+K search, ⌘+N new application)
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
frontend/applyday/src/utils/applicationUtils.js |
New utility module with search, filter, and sort functions |
frontend/applyday/src/pages/Application.jsx |
Integrated search/filter controls and keyboard shortcuts |
frontend/applyday/src/components/ApplicationItem.jsx |
Enhanced application display with status badges and improved layout |
frontend/applyday/src/components/ApplicationControls.jsx |
New component providing search bar, sort dropdown, and filter panel |
SEARCH_SORT_FILTER_FEATURES.md |
Documentation of new features and implementation details |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
|
|
||
| if (selectedLocationTypes.includes('remote') && hasRemote) return true; | ||
| if (selectedLocationTypes.includes('onsite') && !hasRemote) return true; | ||
| if (selectedLocationTypes.includes('hybrid')) return true; // Default assumption |
There was a problem hiding this comment.
The hybrid location type filter always returns true regardless of actual job characteristics. This creates inaccurate filtering behavior where all applications will match the hybrid filter. Consider implementing proper detection logic or removing this default assumption.
| if (selectedLocationTypes.includes('remote') && hasRemote) return true; | |
| if (selectedLocationTypes.includes('onsite') && !hasRemote) return true; | |
| if (selectedLocationTypes.includes('hybrid')) return true; // Default assumption | |
| // Attempt to detect hybrid jobs by checking for "hybrid" keyword | |
| const hasHybrid = app.job_title?.toLowerCase().includes('hybrid') || | |
| app.stage_notes?.toLowerCase().includes('hybrid') || | |
| app.company?.toLowerCase().includes('hybrid'); | |
| if (selectedLocationTypes.includes('remote') && hasRemote) return true; | |
| if (selectedLocationTypes.includes('onsite') && !hasRemote && !hasHybrid) return true; | |
| if (selectedLocationTypes.includes('hybrid') && hasHybrid) return true; |
| notes.includes('full-time') || notes.includes('full time') || | ||
| (!hasInternship && !hasPartTime); // Default to full-time |
There was a problem hiding this comment.
The full-time detection logic defaults to true when neither internship nor part-time keywords are found. This assumption may not always be accurate and could lead to incorrect filtering results. Consider requiring explicit full-time indicators or implementing a more robust detection mechanism.
| notes.includes('full-time') || notes.includes('full time') || | |
| (!hasInternship && !hasPartTime); // Default to full-time | |
| notes.includes('full-time') || notes.includes('full time'); |
| document.body.style.overflow = 'unset'; | ||
| }; | ||
| }, [showCreateForm, showEditForm]); | ||
| }, [showCreateForm, showEditForm, handleClearFilters]); |
There was a problem hiding this comment.
The useEffect dependency array includes handleClearFilters which is not memoized with useCallback, causing the effect to run on every render. This will cause unnecessary event listener cleanup and re-registration. Either memoize handleClearFilters with useCallback or remove it from the dependency array since it doesn't use any state variables.
| const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); | ||
|
|
||
| if (diffDays === 1) return 'Today'; | ||
| if (diffDays === 2) return 'Yesterday'; | ||
| if (diffDays <= 7) return `${diffDays - 1} days ago`; | ||
| if (diffDays <= 30) return `${Math.ceil((diffDays - 1) / 7)} weeks ago`; |
There was a problem hiding this comment.
The date comparison logic is incorrect. When diffDays === 1, it means the difference is 1 day, not that it's today. Similarly, diffDays === 2 means 2 days difference, not yesterday. The logic should be diffDays < 1 for 'Today' and diffDays >= 1 && diffDays < 2 for 'Yesterday'.
| const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); | |
| if (diffDays === 1) return 'Today'; | |
| if (diffDays === 2) return 'Yesterday'; | |
| if (diffDays <= 7) return `${diffDays - 1} days ago`; | |
| if (diffDays <= 30) return `${Math.ceil((diffDays - 1) / 7)} weeks ago`; | |
| const diffDays = diffTime / (1000 * 60 * 60 * 24); | |
| if (diffDays < 1) return 'Today'; | |
| if (diffDays >= 1 && diffDays < 2) return 'Yesterday'; | |
| if (diffDays < 7) return `${Math.floor(diffDays)} days ago`; | |
| if (diffDays < 30) return `${Math.ceil(diffDays / 7)} weeks ago`; |
There was a problem hiding this comment.
Great work on this PR! 🎉
The functionality is very well implemented and the code is clean and easy to follow. I also appreciate the fact that you wrote a complete piece of documentation to support it—thank you so much for your contribution!
On top of that, the red-dot notification for resume management was a delightful surprise. It adds a thoughtful, human-centric touch to the user experience.
|
Thank you for your acknowledgment, as a beginner i would love to get some tips from you on open-source and development. |