[Issue #8499] Update Opportunities List page to single-agency view#8671
[Issue #8499] Update Opportunities List page to single-agency view#8671
Conversation
- Add userAgenciesFetcher to fetch the logged-in user's agencies - Add AgencySelector client component with dropdown for multi-agency users - Update OpportunitiesListPage to filter opportunities by selected agency, redirect to first agency if no agency param, and show error states for no agencies or unauthorized agency access - Add i18n strings for agency selector label and error messages
…ortunities page
|
[low priority] consider adding |
|
[question] Since the default agency depends on |
Thanks for the suggestion. Agreed this type may belong in a shared types module as usage grows. For this PR, I kept it scoped to the fetcher/feature implementation to minimize surface-area changes. I’ll open a follow-up to move UserAgency into frontend/src/types once we confirm all intended consumers for the opportunity publishing flow. |
Agreed, relying on API order without an explicit contract can be brittle. I’ll make the updates so first-load behavior is stable. |
myduong-navapbc
left a comment
There was a problem hiding this comment.
I ran through all three scenarios with no issues.
Nice work!
Summary
Work for #8499
Changes proposed
userAgenciesFetcher.ts— server-only fetcher that callsPOST /v1/users/<user_id>/agenciesto retrieve the logged-in user's associated agenciesAgencySelector.tsx— client component that renders a dropdown for multi-agency users and updates the URL on changeOpportunitiesListPageto:?agency=<first_agency_id>if no agency param is in the URLagency_codeagencySelector,agencyNotAuthorized,noAgenciesContext for reviewers
The page now uses URL state (
?agency=<agency_id>) to track the selected agency. The frontend enforces the authorization check by comparing the URL agency against the list returned by the user agencies endpoint — no separate API call is needed for this check.The
AgencySelectoris a client component to supportuseRouterfor navigation on dropdown change. The page itself remains a server component.Validation steps
Prerequisites
Ensure API and frontend are running locally.
Scenario 1 — Single agency: no dropdown
one_agency_opp_editon the Mock OAuth2 Sign-in pagehttp://localhost:3000/opportunities?agency=<uuid>automaticallyScenario 2 — Multi-agency: dropdown shown
two_agency_opp_pubhttp://localhost:3000/opportunities?agency=<uuid>for the first agency?agency=<other-uuid>and table refreshesScenario 3 — Unauthorized agency in URL
one_agency_opp_edit, navigate to:http://localhost:3000/opportunities?agency=00000000-0000-0000-0000-000000000000Scenario 4 — Copy/paste URL preserves agency view
two_agency_opp_pub, navigate to/opportunities?agency=<uuid-B>