mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
- Fix TypeScript compilation errors in debug API route that were causing JavaScript bundling failures - Add proper type definitions for API responses and test results - Fix type conversions and parameter typing throughout debug route - Update auth controls with proper error state typing - Resolve 'Cannot access xs before initialization' runtime error in production This fixes the EKS deployment crash by eliminating TypeScript compilation issues that were causing JavaScript module loading problems.
176 lines
6.5 KiB
TypeScript
176 lines
6.5 KiB
TypeScript
import { Link } from '@remix-run/react';
|
|
import { useAuth } from '~/lib/hooks/useAuth';
|
|
import { useState, useEffect } from 'react';
|
|
|
|
/**
|
|
* Authentication controls component for the header
|
|
* Separated into a client component to prevent module loading issues
|
|
*/
|
|
export default function HeaderAuthControls() {
|
|
// Error state for component-level error handling
|
|
const [renderError, setRenderError] = useState<Error | null>(null);
|
|
|
|
// Call useAuth at the top level of the component as required by React hooks rules
|
|
let authState;
|
|
try {
|
|
// Properly use the hook at component top level
|
|
authState = useAuth();
|
|
} catch (error) {
|
|
console.error('Error initializing auth hook:', error);
|
|
// Return fallback UI immediately if hook initialization fails
|
|
return (
|
|
<div className="flex items-center">
|
|
<button
|
|
className="flex items-center gap-2 px-3 py-1.5 rounded-md bg-bolt-elements-background-depth-2 text-bolt-content-secondary hover:bg-bolt-elements-background-depth-3 transition-colors text-sm font-medium"
|
|
onClick={() => window.location.href = '/auth/login'}
|
|
>
|
|
<div className="i-ph:user-circle w-4 h-4" />
|
|
Sign in
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Safely extract values from auth state
|
|
const { isAuthenticated, isLoading, user, login, logout } = authState || {};
|
|
|
|
// Reset render error when dependencies change
|
|
useEffect(() => {
|
|
if (renderError) {
|
|
setRenderError(null);
|
|
}
|
|
}, [isAuthenticated, isLoading, user]);
|
|
|
|
// Safely handle login with fallback
|
|
const handleLogin = () => {
|
|
try {
|
|
if (typeof login === 'function') {
|
|
login();
|
|
} else {
|
|
// Fallback if login function is unavailable
|
|
window.location.href = '/auth/login';
|
|
}
|
|
} catch (error) {
|
|
console.error('Error during login:', error);
|
|
// Fallback to direct navigation on error
|
|
window.location.href = '/auth/login';
|
|
}
|
|
};
|
|
|
|
// Safely handle logout with fallback
|
|
const handleLogout = () => {
|
|
try {
|
|
if (typeof logout === 'function') {
|
|
logout();
|
|
} else {
|
|
// Fallback if logout function is unavailable
|
|
window.location.href = '/auth/logout';
|
|
}
|
|
} catch (error) {
|
|
console.error('Error during logout:', error);
|
|
// Fallback to direct navigation on error
|
|
window.location.href = '/auth/logout';
|
|
}
|
|
};
|
|
|
|
// Handle loading state
|
|
if (isLoading) {
|
|
return (
|
|
<div className="flex items-center h-8 px-2 text-bolt-elements-textTertiary">
|
|
<div className="i-svg-spinners:270-ring-with-bg w-5 h-5" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Handle render errors
|
|
if (renderError) {
|
|
return (
|
|
<div className="flex items-center">
|
|
<button
|
|
className="flex items-center gap-2 px-3 py-1.5 rounded-md bg-bolt-elements-background-depth-2 text-bolt-content-secondary hover:bg-bolt-elements-background-depth-3 transition-colors text-sm font-medium"
|
|
onClick={() => window.location.href = '/auth/login'}
|
|
>
|
|
<div className="i-ph:user-circle w-4 h-4" />
|
|
Sign in
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
try {
|
|
// Handle authenticated state
|
|
if (isAuthenticated && user) {
|
|
return (
|
|
<div className="flex items-center">
|
|
<div className="relative group">
|
|
<button
|
|
className="flex items-center gap-2 px-2 py-1 rounded-md hover:bg-bolt-elements-item-backgroundActive transition-colors"
|
|
aria-label="User menu"
|
|
>
|
|
<img
|
|
src={user.avatar}
|
|
alt={`${user.username}'s avatar`}
|
|
className="w-8 h-8 rounded-full border border-bolt-elements-borderColor"
|
|
onError={(e) => {
|
|
// Fallback for broken image links
|
|
e.currentTarget.src = 'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"%3E%3Ccircle cx="12" cy="12" r="10"/%3E%3Cpath d="M12 8v8"/%3E%3Cpath d="M8 12h8"/%3E%3C/svg%3E';
|
|
}}
|
|
/>
|
|
<span className="text-sm font-medium text-bolt-elements-textPrimary hidden sm:block">
|
|
{user.username || 'User'}
|
|
</span>
|
|
<div className="i-ph:caret-down w-4 h-4 text-bolt-elements-textTertiary" />
|
|
</button>
|
|
|
|
<div className="absolute right-0 mt-1 w-48 py-1 bg-bolt-elements-background-depth-2 rounded-md shadow-lg border border-bolt-elements-borderColor hidden group-hover:block z-50">
|
|
<div className="px-4 py-2 text-sm text-bolt-elements-textSecondary border-b border-bolt-elements-borderColor">
|
|
Signed in as <span className="font-semibold text-bolt-elements-textPrimary">{user.username || 'User'}</span>
|
|
</div>
|
|
|
|
<Link
|
|
to="/profile"
|
|
className="block px-4 py-2 text-sm text-bolt-elements-textPrimary hover:bg-bolt-elements-item-backgroundActive"
|
|
>
|
|
Your profile
|
|
</Link>
|
|
|
|
<button
|
|
onClick={handleLogout}
|
|
className="block w-full text-left px-4 py-2 text-sm text-bolt-elements-textPrimary hover:bg-bolt-elements-item-backgroundActive"
|
|
>
|
|
Sign out
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Handle unauthenticated state (default)
|
|
return (
|
|
<button
|
|
onClick={handleLogin}
|
|
className="flex items-center gap-2 px-3 py-1.5 rounded-md bg-bolt-elements-item-backgroundAccent text-bolt-elements-item-contentAccent hover:bg-bolt-elements-item-backgroundAccentHover transition-colors text-sm font-medium"
|
|
>
|
|
<div className="i-ph:sign-in w-4 h-4" />
|
|
Sign in
|
|
</button>
|
|
);
|
|
} catch (error) {
|
|
// Catch any rendering errors
|
|
console.error('Error rendering auth controls:', error);
|
|
setRenderError(error instanceof Error ? error : new Error(String(error)));
|
|
|
|
// Return fallback UI
|
|
return (
|
|
<button
|
|
onClick={() => window.location.href = '/auth/login'}
|
|
className="flex items-center gap-2 px-3 py-1.5 rounded-md bg-bolt-elements-background-depth-2 text-bolt-content-secondary hover:bg-bolt-elements-background-depth-3 transition-colors text-sm font-medium"
|
|
>
|
|
<div className="i-ph:user-circle w-4 h-4" />
|
|
Sign in
|
|
</button>
|
|
);
|
|
}
|
|
}
|