diff --git a/src/components/DashboardLayout.tsx b/src/components/DashboardLayout.tsx index e12806b..d96365c 100644 --- a/src/components/DashboardLayout.tsx +++ b/src/components/DashboardLayout.tsx @@ -61,9 +61,9 @@ export function DashboardLayout() { setCommandPaletteOpen(false) }, []) + // eslint-disable-next-line @typescript-eslint/no-unused-vars const handleSectionClick = useCallback((_sectionId: string) => { - // Section click is already handled in SubNav component - // This is just a placeholder for any additional logic needed + // SubNav handles scrolling internally }, []) // Global Ctrl+K listener to open command palette diff --git a/src/components/LoginScreen.tsx b/src/components/LoginScreen.tsx index 2a89c17..84a1455 100644 --- a/src/components/LoginScreen.tsx +++ b/src/components/LoginScreen.tsx @@ -16,9 +16,10 @@ export function LoginScreen({ onComplete }: LoginScreenProps) { const [isExiting, setIsExiting] = useState(false) const [typingComplete, setTypingComplete] = useState(false) const [buttonHovered, setButtonHovered] = useState(false) + const [connectionState, setConnectionState] = useState<'connecting' | 'connected'>('connecting') const { requestFocusAfterLogin } = useAccessibility() - const fullUsername = 'A.CHARLWOOD' + const fullUsername = 'a.recruiter' const passwordLength = 8 const prefersReducedMotion = typeof window !== 'undefined' @@ -38,8 +39,10 @@ export function LoginScreen({ onComplete }: LoginScreenProps) { return id }, []) + const canLogin = typingComplete && connectionState === 'connected' + const handleLogin = useCallback(() => { - if (!typingComplete || isExiting) return + if (!canLogin || isExiting) return setButtonPressed(true) addTimeout(() => { setIsExiting(true) @@ -48,7 +51,7 @@ export function LoginScreen({ onComplete }: LoginScreenProps) { onComplete() }, prefersReducedMotion ? 0 : 200) }, 100) - }, [typingComplete, isExiting, onComplete, requestFocusAfterLogin, prefersReducedMotion, addTimeout]) + }, [canLogin, isExiting, onComplete, requestFocusAfterLogin, prefersReducedMotion, addTimeout]) const startLoginSequence = useCallback(() => { if (prefersReducedMotion) { @@ -93,12 +96,12 @@ export function LoginScreen({ onComplete }: LoginScreenProps) { }, 80) }, [prefersReducedMotion, addTimeout]) - // Focus the login button when typing completes for keyboard accessibility + // Focus the login button when login becomes available for keyboard accessibility useEffect(() => { - if (typingComplete && loginButtonRef.current) { + if (canLogin && loginButtonRef.current) { loginButtonRef.current.focus() } - }, [typingComplete]) + }, [canLogin]) useEffect(() => { // Cursor blink: 530ms interval @@ -106,6 +109,11 @@ export function LoginScreen({ onComplete }: LoginScreenProps) { setShowCursor(prev => !prev) }, 530) + // Connection status: transitions to connected after ~2000ms + const connectionTimeout = addTimeout(() => { + setConnectionState('connected') + }, 2000) + // Delay start slightly for card entrance animation const startTimeout = addTimeout(() => { startLoginSequence() @@ -119,13 +127,14 @@ export function LoginScreen({ onComplete }: LoginScreenProps) { if (usernameIntervalRef.current) clearInterval(usernameIntervalRef.current) if (passwordIntervalRef.current) clearInterval(passwordIntervalRef.current) clearTimeout(startTimeout) + clearTimeout(connectionTimeout) pendingTimeouts.forEach(id => clearTimeout(id)) } }, [startLoginSequence, addTimeout]) const buttonBg = buttonPressed ? '#085858' - : buttonHovered && typingComplete + : buttonHovered && canLogin ? '#0A8080' : '#0D6E6E' @@ -284,7 +293,7 @@ export function LoginScreen({ onComplete }: LoginScreenProps) { + + {/* Connection Status Indicator */} +