Created API endpoints and React hooks for application cards#218
Created API endpoints and React hooks for application cards#218
Conversation
There was a problem hiding this comment.
Pull request overview
Adds backend count endpoints and frontend hooks to populate the Admin dashboard “application cards” with live counts instead of hardcoded values.
Changes:
- Added 4 backend
/applications/count/*endpoints and corresponding service methods for application status counts. - Added frontend
ApiClientmethods + React hooks to fetch those counts. - Added frontend and backend tests for the new count behavior.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/frontend/src/containers/AdminLanding.tsx | Replaces hardcoded dashboard tile values with live counts via new hooks |
| apps/frontend/src/containers/AdminLanding.spec.tsx | Adds a unit test verifying the dashboard renders counts from mocked hooks |
| apps/frontend/src/api/apiClient.ts | Adds count-fetching API methods and introduces use*Count hooks |
| apps/backend/src/applications/applications.service.ts | Adds repository count() queries for total/in-review/rejected/approved-or-active |
| apps/backend/src/applications/applications.controller.ts | Exposes new GET endpoints returning { count } payloads |
| apps/backend/src/applications/applications.controller.spec.ts | Adds controller tests for the new count endpoints |
| apps/backend/src/applications/application.service.spec.ts | Adds service tests for the new counting methods |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const [error, setError] = useState<Error | null>(null); | ||
|
|
||
| useEffect(() => { | ||
| let mounted = true; |
There was a problem hiding this comment.
useCount never sets isLoading back to true when the effect re-runs (e.g., if a different getter is passed in). This can produce incorrect loading state semantics. Consider setting setIsLoading(true) at the start of the effect before invoking getter().
| let mounted = true; | |
| let mounted = true; | |
| setIsLoading(true); |
There was a problem hiding this comment.
^agree but see how it plays out in practice
apps/frontend/src/api/apiClient.ts
Outdated
| .catch((err: Error) => { | ||
| if (mounted) { | ||
| setError(err); |
There was a problem hiding this comment.
The .catch((err: Error) => ...) annotation is unsound: promise rejections can be non-Error values (and Axios often rejects with AxiosError, typed as unknown in some configs). Consider catching unknown and normalizing to an Error instance before storing it in state.
| .catch((err: Error) => { | |
| if (mounted) { | |
| setError(err); | |
| .catch((err: unknown) => { | |
| if (mounted) { | |
| const normalizedError = | |
| err instanceof Error ? err : new Error(String(err)); | |
| setError(normalizedError); |
| it('should return approved or active count', async () => { | ||
| mockRepository.count.mockResolvedValue(102); | ||
|
|
||
| const result = await service.countApprovedOrActive(); | ||
|
|
||
| expect(repository.count).toHaveBeenCalled(); | ||
| expect(result).toBe(102); |
There was a problem hiding this comment.
The countApprovedOrActive test only asserts repository.count was called, but not that it was called with the expected where: { appStatus: In([ACCEPTED, ACTIVE]) } filter. This means the test would still pass if the implementation counted all applications. Tighten the assertion to validate the filter arguments.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
No additional comments - everything looks good besides what copilot said |
| @@ -0,0 +1,45 @@ | |||
| import { render, screen } from '@testing-library/react'; | |||
There was a problem hiding this comment.
Woah frontend tests, cool. Usually we don't do frontend tests but I like it!
ℹ️ Issue
Closes
📝 Description
Write a short summary of what you added. Why is it important? Any member of C4C should be able to read this and understand your contribution -- not just your team members.
Briefly list the changes made to the code:
✔️ Verification
What steps did you take to verify your changes work? These should be clear enough for someone to be able to clone the branch and follow the steps themselves.
Provide screenshots of any new components, styling changes, or pages.
🏕️ (Optional) Future Work / Notes
Did you notice anything ugly during the course of this ticket? Any bugs, design challenges, or unexpected behavior? Write it down so we can clean it up in a future ticket!