Intersection API Email Subscription Management Frontend#323
Conversation
…bscription-frontend
There was a problem hiding this comment.
Pull request overview
Updates the webapp’s email subscription management UI to use the new Intersection API endpoints and adds a public, token-authenticated unsubscribe page, while removing the legacy Python API admin-notification functionality.
Changes:
- Added
/unsubscribe?token=...public route and UI for managing email subscriptions without logging in. - Replaced the previous “settings” notification management UI with an RTK Query–backed subscription management page calling Intersection API subscription endpoints.
- Removed legacy Python API admin notification endpoints and corresponding webapp Redux slices/components/tests.
Reviewed changes
Copilot reviewed 27 out of 28 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| webapp/src/Unsubscribe.tsx | New public unsubscribe page that loads/saves subscriptions using a token query param. |
| webapp/src/Unsubscribe.test.tsx | Updated snapshot test intended to cover the unsubscribe page. |
| webapp/src/store.tsx | Removed legacy notification reducers; registered new RTK Query slices/middleware. |
| webapp/src/pages/Admin.tsx | Removed notification-fetch side effects tied to the deleted admin notification feature. |
| webapp/src/models/email-subscriptions.d.ts | Added TypeScript types for email subscription data exchanged with Intersection API. |
| webapp/src/features/api/unsubscribeApiSlice.ts | New RTK Query API slice for token-authenticated unsubscribe endpoints. |
| webapp/src/features/api/subscriptionManagementApiSlice.ts | New RTK Query API slice for authenticated subscription management endpoints. |
| webapp/src/features/adminNotificationTab/adminNotificationTabSlice.tsx | Deleted legacy notification slice (Python API–backed). |
| webapp/src/features/adminNotificationTab/adminNotificationTabSlice.test.ts | Deleted tests for removed legacy notification slice. |
| webapp/src/features/adminNotificationTab/AdminNotificationTab.tsx | Deleted legacy admin notification UI. |
| webapp/src/features/adminEditNotification/adminEditNotificationSlice.tsx | Deleted legacy edit-notification slice. |
| webapp/src/features/adminEditNotification/adminEditNotificationSlice.test.ts | Deleted tests for removed edit-notification slice. |
| webapp/src/features/adminEditNotification/AdminEditNotification.tsx | Deleted legacy edit-notification UI. |
| webapp/src/features/adminAddNotification/adminAddNotificationSlice.tsx | Deleted legacy add-notification slice. |
| webapp/src/features/adminAddNotification/adminAddNotificationSlice.test.ts | Deleted tests for removed add-notification slice. |
| webapp/src/features/adminAddNotification/AdminAddNotification.tsx | Deleted legacy add-notification UI. |
| webapp/src/features/adminAddNotification/AdminAddNotification.test.tsx | Deleted snapshot test for removed add-notification UI. |
| webapp/src/EnvironmentVars.tsx | Removed environment variables for deleted legacy notification endpoints. |
| webapp/src/Dashboard.tsx | Routed settings/* to the new subscription management component. |
| webapp/src/components/SubscriptionManagement.tsx | New authenticated subscription management page using RTK Query. |
| webapp/src/components/SubscriptionManagement.test.tsx | Updated snapshot test for the new subscription management page. |
| webapp/src/components/SubscriptionForm.tsx | New reusable form component for editing subscription frequencies and saving. |
| webapp/src/components/SubscriptionForm.test.tsx | Added snapshot test for the new subscription form component. |
| webapp/src/App.tsx | Added a public /unsubscribe route outside Keycloak-protected routing. |
| services/api/src/middleware.py | Removed legacy Python API endpoint mappings for admin notification routes. |
| services/api/src/main.py | Removed legacy Python API resources for admin notification routes. |
| services/api/src/admin_new_email_notification.py | Deleted legacy Python API endpoint for adding notifications. |
| services/api/src/admin_email_notification.py | Deleted legacy Python API endpoint for listing/modifying/deleting notifications. |
Comments suppressed due to low confidence (2)
webapp/src/Unsubscribe.test.tsx:16
- This test is rendering
Unsubscribefrom@mui/icons-material(an icon), not theUnsubscribepage component in./Unsubscribe. As written it won’t validate the unsubscribe page at all; import the page component instead (and consider setting a token search param for the router if you want meaningful coverage).
webapp/src/components/SubscriptionManagement.test.tsx:22 - Rendering
SubscriptionManagementtriggers an RTK Query request on mount. This snapshot test doesn’t mockfetch, so it will attempt a real network request during the test run (and the snapshot will likely just capture the loading spinner). Mock the endpoint response (e.g., withfetchMock.mockResponseOnce(...)) and/or wait for the loaded UI before snapshotting to keep the test deterministic.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…om/CDOT-CV/jpo-cvmanager into iapi-email-unsubscription-frontend
…bscription-frontend
…bscription-frontend
…/api/services/EmailService.java Co-authored-by: Matt Cook <matt.cook@trihydro.com>
…bscription-frontend
…bscription-frontend
…bscription-frontend
…bscription-frontend
Michael7371
left a comment
There was a problem hiding this comment.
Good end-to-end migration to IAPI subscription management and token-based unsubscribe. Follow-ups on error UX and additional unit tests, but otherwise LGTM.
| const Unsubscribe = () => { | ||
| const [searchParams] = useSearchParams() | ||
| const token = searchParams.get('token') | ||
| const { data, isLoading, isFetching } = useGetEmailSubscriptionsQuery(token ?? '', { skip: !token }) |
There was a problem hiding this comment.
(question): have you considered including the isError RTK query to be able to display error status to the user (403, 401, or 500)? Expired token vs network error shouldn’t both show “invalid unsubscribe link”.
| @@ -1,19 +1,19 @@ | |||
| import { render } from '@testing-library/react' | |||
There was a problem hiding this comment.
chore: new tests are snapshot-only (loading/empty). Can we add at least one interaction test (toggle + save) and an error-state test for invalid token?
PR Details
Description
This PR updates the webapp to point to the new Intersection API endpoints in #322. This also includes re-working the email subscription management pages as well as adding a new token authenticated unsubscribe page.
How Has This Been Tested?
2026-04-21.13-21-11.mp4
Types of changes
Checklist: