Promote uat → main (PROD): GRO-2373 in-portal chrome sign-out button (web) (#81)
CI / Test (push) Successful in 22s
CI / Lint & Typecheck (push) Successful in 29s
CI / Build & Push Docker Image (push) Failing after 10s

Promote uat → main (PROD): GRO-2373 in-portal chrome sign-out button (web) — cherry-pick of PR #78 (commit 532869f9). UAT_PLAYBOOK §3.2 (TC-WEB-5.25.6f) updated.

Refs: GRO-2360 (P3), GRO-2355 (parent), GRO-2357 (breakdown), GRO-2358 (P1), GRO-2359 (P2).
Co-authored-by: Flea Flicker <22+gb_flea@noreply.git.farh.net>
Co-committed-by: Flea Flicker <22+gb_flea@noreply.git.farh.net>
This commit was merged in pull request #81.
This commit is contained in:
2026-06-13 02:52:46 +00:00
committed by The Dogfather
parent 1480a37de1
commit a7db93f386
3 changed files with 89 additions and 1 deletions
+17 -1
View File
@@ -451,7 +451,14 @@ export function CustomerPortal() {
})}
</div>
{/* Session controls (only shown during active impersonation) */}
{/* Session controls — Sign out is always reachable from the portal
chrome (GRO-2373). End Impersonation is staff-only and only
appears during an active impersonation session. Both share the
same LogOut icon for visual consistency, but route to distinct
handlers: handleSignOut calls the canonical Better Auth
`signOut()` (mirroring OOBE and the no-access card); handleEnd
tears down the staff impersonation session and returns to the
admin clients list. */}
<div className="border-t border-stone-100 p-4 space-y-2">
{session?.status === "active" && (
<button
@@ -462,6 +469,15 @@ export function CustomerPortal() {
End Impersonation
</button>
)}
<button
type="button"
onClick={() => { void handleSignOut(); }}
className="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-xs font-medium text-stone-700 bg-stone-50 hover:bg-stone-100 transition-colors"
data-testid="portal-chrome-signout"
>
<LogOut size={14} />
Sign out
</button>
<div className="flex items-center gap-2 px-3 py-2 text-xs text-stone-400">
<Shield size={12} />
Customer Portal v1.0