feat: implement presentation activity view (#93) - #96
Conversation
Add activity history list and detail pages with filters, pagination, delete confirmation, and API client for /presentation/activity.
Keep OpenAPI presentation endpoints out of this UI PR; file remains editable locally for backend alignment. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Hello @Vitalisn4 |
I don't even think we should have an error massage like the one in red on this page, @mbunwe-victor what do you think? |
Map API failures to readable copy instead of raw GET paths and status codes; hide empty state when the list fails to load.
Bring in CI workflow update (e2e job removed from GitHub Actions). Co-authored-by: Cursor <cursoragent@cursor.com>
Yes, we shouldn't have the error displayed on this page, after which we get the note saying there was no "past activity," which I also understand because we are calling the backend to check for the various activities, which is not yet fully implemented. We should gladly just move to the Activity page for now, without the error pop-up. |
mbunwe-victor
left a comment
There was a problem hiding this comment.
Hello @Vitalisn4, thank you so much for this PR. I have a concern.
So, going through the implementation, I noticed you added a certain page, PresentationActivityDetailsPage, and I don't recall us having that, or maybe it's a missing design. Does it follow the happy path?
Ngha-Boris
left a comment
There was a problem hiding this comment.
Code Review: Presentation Activity View Implementation
Summary
The implementation largely meets the ticket requirements with good overall code quality, strong type safety, and proper privacy considerations. Most acceptance criteria are satisfied including chronological ordering, pagination, filtering, deletion with confirmation, and privacy safeguards.
✅ Requirements Met
PresentationActivityPageandPresentationActivityItemcomponents createdGET /presentation/activityandDELETE /presentation/activity/:idendpoints integrated- Chronological ordering (newest first) with proper sorting
- Verifier information (name, logo, client_id) displayed
- Credential types and claim count (metadata only) shown
- Details view with
PresentationActivityDetailPage - Pagination with "Load more" pattern
- Date range and verifier name filters
- Delete/forget option with confirmation dialog
- Auto-expiry configuration (30 days default)
- No sensitive claim values stored
🔴 Issues Requiring Attention
Issue 1: Race Condition in Filter Debounce
File: src/hooks/usePresentationActivity.ts (lines 68-71)
The debounce pattern can cause stale filter updates to overwrite newer ones if filters change rapidly within the 350ms window.
useEffect(() => {
const timeoutId = window.setTimeout(() => setAppliedFilters(filters), 350)
return () => window.clearTimeout(timeoutId)
}, [filters])Suggestion: Use a ref to track latest filters:
const latestFilters = useRef(filters)
latestFilters.current = filters
useEffect(() => {
const timeoutId = window.setTimeout(() => {
setAppliedFilters(latestFilters.current)
}, 350)
return () => window.clearTimeout(timeoutId)
}, [filters])Issue 2: Stale Closure in removeItem Callback
File: src/hooks/usePresentationActivity.ts (lines 122-130)
The setHasMore calculation uses page and total from closure which may be stale due to React's batched state updates.
setHasMore(page * DEFAULT_PRESENTATION_ACTIVITY_PAGE_SIZE < total - 1)Suggestion: Calculate reactively in a separate useEffect based on items.length, page, and total, or use functional updates to ensure consistency.
Issue 3: Error State Not Cleared on Successful Delete
File: src/hooks/usePresentationActivity.ts (lines 122-130)
After successful deletion, any previous error message remains displayed.
Suggestion: Add setErrorMessage(null) or call clearError() after successful deletion in the removeItem function.
🟡 Suggestions for Improvement
-
Date Range Validation: Add validation to ensure
fromdate is not aftertodate inPresentationActivityFilters.tsx -
Accessibility Enhancement: Add
aria-busy={loadingMore}to the "Load more" button for better screen reader support -
Zero Claims Message: Consider showing "No claims shared" instead of "0 claims shared" for better UX
-
Test Coverage: Add tests for:
PresentationActivityDetailPageerror statesDeletePresentationActivityDialoginteractions- Filter functionality and edge cases
Positive Highlights
- ✅ Strong privacy practices (metadata only, no claim values)
- ✅ Defensive client-side retention filtering
- ✅ Proper UUID validation before API calls
- ✅ Context-specific, user-friendly error messages
- ✅ Good accessibility with ARIA labels and roles
- ✅ Comprehensive TypeScript types with runtime validation
- ✅ Proper AbortController cleanup for API requests
- ✅ Clean architecture with separation of concerns
Overall: Good implementation that meets the requirements. Please address the race condition (Issue 1) and stale closure (Issue 2) before merging, as these could cause subtle bugs in production.
Align Activity History and Shared Claims with design specs: sticky header/footer, clickable activity cards with hover, Figma-style delete confirmation, and full-width Shared Claims detail. Remove dev filters and mock activity data so all screens call the real presentation activity endpoints.
Reduce the Shared Claims title and header padding to match Figma via a reusable compact mode on Header.
Keep both presentation request entry (/present) from main and presentation activity routes (/activity) from this branch.
Match delete confirmation width to activity cards and use compact outline buttons. Limit Show All to expanding the credential description only and update detail page tests.
mbunwe-victor
left a comment
There was a problem hiding this comment.
Hello @Vitalisn4, I have a few comments I would like you to check. Also, the screens you shared earlier looked good, and now I am waiting for the delete card as we spoke about, if you can share a screenshot.
There was a problem hiding this comment.
I honestly don't know why we have all these changes here
There was a problem hiding this comment.
I honestly don't know why we have all these changes here
That's for the Shared Claims page to mirror our existing wallet in the word size and card thickness
There was a problem hiding this comment.
Oh, I see, thanks. I'd prefer we stay consistent with the existing wallet pattern link in CredentialTypesPage and CredentialTypeDetailsPage, where we made use of a sub-header. Rather than adding a compact mode to the shared Header. WDYT
There was a problem hiding this comment.
Oh, I see, thanks. I'd prefer we stay consistent with the existing wallet pattern link in
CredentialTypesPageandCredentialTypeDetailsPage,where we made use of asub-header.Rather than adding acompactmode to the shared Header. WDYT
That makes sense, meaning the header for that Share Claims will have to be left as big as it was before trying to reduce right?
There was a problem hiding this comment.
No, if it should follow the flow in the files I mentioned, I suppose the only thing that needs to change is the title, and everything else stays the same.
There was a problem hiding this comment.
No, if it should follow the flow in the files I mentioned, I suppose the only thing that needs to change is the title, and everything else stays the same.
Great, working on that
Remove unused rightSlot and titleClassName from Header, keeping only compact mode for Shared Claims. Drop the settings icon from Activity History, top-align empty state copy, and update tests.
Size the modal slightly inside the card column, tighten edge padding, and offset margins so the dialog sits centered under the activity list.
|
Hello @mbunwe-victor @Ngha-Boris , can you check again now, I have implemented the reviews |








Summary
Implements Presentation Activity (#93): Activity History list, Shared Claims detail, and delete confirmation — aligned with Figma and wired to the live API.
Changes
/activity) — sticky header/footer, scrollable cards, settings icon/activity/:id) — full-width detail view from card click#e6f4e6), trash opens delete modalGET/DELETE /presentation/activity; mock data and filter UI removedTest plan
npm testpasses for presentation activity modulesCloses #93