From dbdd51243d1a6aaf3d47d51b8f681062338eec8c Mon Sep 17 00:00:00 2001 From: Andy Charlwood Date: Sat, 14 Feb 2026 03:04:16 +0000 Subject: [PATCH] US-029: Add post-login loading state and update TopBar session name --- src/components/LoginScreen.tsx | 437 ++++++++++++++++++--------------- src/components/TopBar.tsx | 2 +- src/index.css | 15 ++ 3 files changed, 255 insertions(+), 199 deletions(-) diff --git a/src/components/LoginScreen.tsx b/src/components/LoginScreen.tsx index 84a1455..4cc6aad 100644 --- a/src/components/LoginScreen.tsx +++ b/src/components/LoginScreen.tsx @@ -14,6 +14,7 @@ export function LoginScreen({ onComplete }: LoginScreenProps) { const [activeField, setActiveField] = useState<'username' | 'password' | 'done' | null>('username') const [buttonPressed, setButtonPressed] = useState(false) const [isExiting, setIsExiting] = useState(false) + const [isLoading, setIsLoading] = useState(false) const [typingComplete, setTypingComplete] = useState(false) const [buttonHovered, setButtonHovered] = useState(false) const [connectionState, setConnectionState] = useState<'connecting' | 'connected'>('connecting') @@ -42,16 +43,19 @@ export function LoginScreen({ onComplete }: LoginScreenProps) { const canLogin = typingComplete && connectionState === 'connected' const handleLogin = useCallback(() => { - if (!canLogin || isExiting) return + if (!canLogin || isExiting || isLoading) return setButtonPressed(true) addTimeout(() => { - setIsExiting(true) + setIsLoading(true) addTimeout(() => { - requestFocusAfterLogin() - onComplete() - }, prefersReducedMotion ? 0 : 200) + setIsExiting(true) + addTimeout(() => { + requestFocusAfterLogin() + onComplete() + }, prefersReducedMotion ? 0 : 200) + }, prefersReducedMotion ? 0 : 600) }, 100) - }, [canLogin, isExiting, onComplete, requestFocusAfterLogin, prefersReducedMotion, addTimeout]) + }, [canLogin, isExiting, isLoading, onComplete, requestFocusAfterLogin, prefersReducedMotion, addTimeout]) const startLoginSequence = useCallback(() => { if (prefersReducedMotion) { @@ -159,216 +163,253 @@ export function LoginScreen({ onComplete }: LoginScreenProps) { animate={isExiting ? { scale: 1.03, opacity: 0 } : { scale: 1, opacity: 1 }} transition={{ duration: 0.2, ease: 'easeOut' }} > - {/* Branding Header */} -
-
- -
- - CareerRecord PMR - - - Clinical Information System - -
- - {/* Login Form */} -
- {/* Username Field */} -
- -
- {username} - {activeField === 'username' && ( - - )} -
-
- - {/* Password Field */} -
- -
- {'\u2022'.repeat(passwordDots)} - {activeField === 'password' && ( - - )} -
-
- - {/* Log In Button — user clicks to proceed */} - - - {/* Connection Status Indicator */} + {isLoading ? (
- - {connectionState === 'connected' - ? 'Secure connection established' - : 'Awaiting secure connection...'} + Loading clinical records...
-
+ ) : ( + <> + {/* Branding Header */} +
+
+ +
+ + CareerRecord PMR + + + Clinical Information System + +
- {/* Footer */} -
-

- Secure clinical system login -

-
+ {/* Login Form */} +
+ {/* Username Field */} +
+ +
+ {username} + {activeField === 'username' && ( + + )} +
+
+ + {/* Password Field */} +
+ +
+ {'\u2022'.repeat(passwordDots)} + {activeField === 'password' && ( + + )} +
+
+ + {/* Log In Button — user clicks to proceed */} + + + {/* Connection Status Indicator */} +
+ + + {connectionState === 'connected' + ? 'Secure connection established' + : 'Awaiting secure connection...'} + +
+
+ + {/* Footer */} +
+

+ Secure clinical system login +

+
+ + )} ) diff --git a/src/components/TopBar.tsx b/src/components/TopBar.tsx index 4770ffc..cb360af 100644 --- a/src/components/TopBar.tsx +++ b/src/components/TopBar.tsx @@ -169,7 +169,7 @@ export function TopBar({ onSearchClick }: TopBarProps) { fontFamily: 'var(--font-ui)', }} > - Dr. A.CHARLWOOD + A.RECRUITER