Repository navigation
Display active identity in application shell - #49
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Problem
After entering the protected application area, there was no visible indication of whether the visitor was using a registered account or temporary guest mode. The application shell also had no typed identity available for future account-related controls.
Identity data flow
The existing access boundary already determines whether a visitor may enter. This PR extends that responsibility so it produces one of two valid identities:
The data flows through the shared pathless route layout:
Render-prop pattern
DashboardAccessBoundaryreceives a function as itschildrenprop:This is a render prop. Once the boundary resolves access, it calls that function with either
{ kind: 'guest' }or{ kind: 'user', user }. The_approute can then pass the resolved identity into the shell while<Outlet />continues to render the selected child page.The access boundary owns authentication decisions. The shell only owns presentation.
Registered-user presentation
Registered users display:
Only the browser-safe
PublicUsercontract is passed to the shell.Guest presentation
Guests display:
GuestProgress is temporaryThis makes the temporary nature of guest mode visible without adding exit behavior to this PR.
Responsive behavior
The desktop sidebar displays the complete identity summary below navigation.
The mobile header uses the same component with its custom
compactpresentation.compactis a React prop, not device detection: it tells the component to conserve space, while Tailwind responsive classes determine when the secondary detail is visible.Discriminated authentication state
useCurrentUser()previously returnedauthenticationStatusanduseras values whose relationship TypeScript could not prove. That required a redundant defensive condition before using the user.It now returns explicit branches:
loadingwithuser: nullerrorwithuser: nullanonymouswithuser: nullauthenticatedwithuser: PublicUserAfter the boundary handles loading, error, and anonymous states, TypeScript knows the remaining state is authenticated and the user cannot be null. The old standalone status alias was removed because the return branches now infer the union directly.
Scope
This PR intentionally does not add:
Those behaviors will be implemented as separate reviewable tasks.
Project convention
AGENTS.mdnow records the TypeScript readability convention that required properties should be listed before optional properties in object types and interfaces.Verification