feat: load authenticated profile card
Title: feat(frontend): render authenticated user profile card
Description: The profile dropdown only shows the stored phone number and a placeholder “U,” even though the backend exposes /api/v1/auth/me. As a result, operators cannot see their authenticated name/username/phone, and the menu looks incomplete. We need to fetch the actual profile and present it as a polished mini profile page in the toolbar.
Current Behavior:
- The dropdown only displays the login phone and a generic “U” avatar.
- No authenticated metadata (name/username/phone) is shown.
- The logout button is small and left-aligned, lacking a standout visual state.
Expected Behavior:
- After login, the app should call
/api/v1/auth/meand store the returned profile. - The dropdown should display name, username (case-sensitive), and phone inside a styled profile card with a gradient initial avatar.
- The logout button should be a full-width, right-aligned bar that highlights in red on hover.
Problem Statement
- What’s broken/missing? The toolbar cannot surface the authenticated user’s name/username/phone even though the API already provides it.
- Who is affected? All front-end users (admins/coordinators) who rely on the profile dropdown to confirm their identity.
- Impact? UX feels incomplete and confusing because the profile menu doesn’t reflect the actual logged-in user.
- How to reproduce? Log in, open the profile menu, and see only the phone number and placeholder “U” initial. No actual profile fields appear.
Proposed Solution
- Introduce
getCurrentUserincorpusServiceto call/api/v1/auth/mevia the configured base URL. - In
App.tsx, call this helper whenever we have an auth token, store the returnedInternSummary, and render a redesigned profile card (name, case-sensitive username, phone, gradient initial, wide logout with hover). - Revise the intern search mapping/type so it continues to return a strongly typed
Internarray despite the enriched profile data. - Update tests to cover the new helper and ensure lint/tests pass.
Test-Driven Development / Acceptance Criteria
Scenario 1: Dropdown shows authenticated profile
Given an auth token exists and /api/v1/auth/me returns profile data
When the profile menu opens
Then the card shows the returned name, username (case-sensitive), and phone
And the avatar circle displays the uppercase first letter of the name.
Scenario 2: Logout bar is prominent
Given the profile card is visible
When the user hovers over the logout button
Then the button background turns light red and the text/border become a darker red
And the button occupies the full width of the footer.
Scenario 3: Fallback when profile incomplete
Given /api/v1/auth/me returns only an identifier or fails
When the dropdown opens
Then we fallback to the stored username/phone without crashing
And logout remains accessible.
Test Cases
| Test ID | Test Description | Precondition | Test Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| TC-001 | Profile card renders API data | Auth token present | Open profile menu | Name/username/phone from /api/v1/auth/me display |
High |
| TC-002 | Logout hover state | Profile card open | Hover logout | Button turns red, remains full width | Medium |
| TC-003 | Fallback rendering | API missing data | Open profile menu | Uses stored username/phone | Medium |
Unit Test Requirements
| Module/Component | Function/Hook | Test Cases to Cover |
|---|---|---|
corpusService.ts |
getCurrentUser |
TC-001, TC-003 |
App.tsx |
Profile effect/render | TC-001, TC-003 |
InternSearch.tsx |
Search mapping/filter | verify Intern[] output |
-
Test assertions:
-
getCurrentUserhits/api/v1/auth/meand parses name/username/phone. - Profile card uses parsed data; handles missing fields.
- Logout button renders with full width and hover class.
-
Implementation Details
| File Path | Action | Purpose |
|---|---|---|
src/services/corpus/corpusService.ts |
Modify | Add getCurrentUser hitting /api/v1/auth/me and parse fields. |
src/services/corpus/index.ts |
Modify | Export the new helper. |
src/App.tsx |
Modify | Call helper, maintain profile state, render new card, remove unused imports. |
src/styles.css |
Modify | Style profile card, gradient avatar, logout hover. |
tests/corpusService.test.ts |
Modify | Cover getCurrentUser success/fallback plus existing search logic. |
src/components/intern/InternSearch.tsx |
Modify | Ensure search mapping returns typed Intern[]. |
Technical Considerations
- Reuse existing
configureCorpusServicebase URL for API calls. - Keep profile state localized in
App.tsx. - Preserve TypeScript typing for intern search results.
- UI must remain responsive and accessible (aria label on profile button).
UI/UX Requirements
- Layout: Profile card containing avatar + name/username header, phone row, footer with big logout button.
- Interaction: Gradient initial derived from name, hover state on logout uses red backgrounds.
- Responsive: Dropdown stays aligned to toolbar on desktop; card padding consistent.
- Accessibility: Profile button labeled, focusable, logout on Enter/Space.
Testing Strategy
-
Manual:
- Browser: Chrome Desktop.
- Steps: Login, open profile menu, verify values + logout hover.
- Role: Coordinator.
-
Automated:
- Unit tests for
getCurrentUsersuccess + fallback. - Lint/tests (
vp test run tests/corpusService.test.ts).
- Unit tests for
-
Test Data:
- Mock
/api/v1/auth/meresponse with name/username/phone. - Variant with missing fields to verify fallback.
- Mock
Definition of Done
- All acceptance criteria pass.
- TC-001..TC-003 executed and successful.
- Unit tests and
npm run test -- tests/corpusService.test.tspass. - No lint/type errors.
- UI matches design with gradient avatar/logout bar.
- Accessibility/keyboard navigation verified.
- No console warnings/errors.
- Types remain strict (no
any). - i18n strings used for labels.
- Documentation (issue/changelog) updated.
Additional Context
- Extends previous profile enhancements (avatar initial, logout styling).
- Focus is frontend display + a new corpus helper; backend unchanged.