From 639afd855093eff09fd856a10fe002abf968a076 Mon Sep 17 00:00:00 2001 From: SkateSpots Date: Tue, 27 Oct 2026 20:48:04 +0700 Subject: [PATCH] fix(auth): open sign-in above menus and close the burger first --- src/components/LanguageToggle.tsx | 8 ++-- src/components/Layout.tsx | 46 +++++++++++++++--- src/components/auth/LoginArea.tsx | 70 +++++++++++++++++++--------- src/components/auth/LoginDialog.tsx | 2 +- src/components/auth/SignupDialog.tsx | 2 +- 5 files changed, 94 insertions(+), 34 deletions(-) diff --git a/src/components/LanguageToggle.tsx b/src/components/LanguageToggle.tsx index 3a50883..86088b5 100644 --- a/src/components/LanguageToggle.tsx +++ b/src/components/LanguageToggle.tsx @@ -22,6 +22,8 @@ interface LanguageToggleProps { inline?: boolean; /** Additional class names */ className?: string; + /** Called after a locale is chosen (e.g. to close a sheet sub-view). */ + onSelect?: () => void; /** Variant style */ variant?: 'default' | 'outline' | 'ghost'; } @@ -52,7 +54,7 @@ function Flag({ flag, className }: { flag: string; className?: string }) { /** * Language toggle dropdown for switching between the available locales */ -export function LanguageToggle({ compact = false, inline = false, className, variant = 'ghost' }: LanguageToggleProps) { +export function LanguageToggle({ compact = false, inline = false, className, variant = 'ghost', onSelect }: LanguageToggleProps) { const { language, setLanguage, t } = useTranslation(); const [query, setQuery] = useState(''); @@ -89,7 +91,7 @@ export function LanguageToggle({ compact = false, inline = false, className, var - + @@ -827,7 +843,7 @@ export function Layout({ children, noPadding }: LayoutProps) { /> )}
- +
{t('settings.selectLanguage')} - + setMobileLanguageView(false)} /> ) : ( @@ -1102,7 +1118,7 @@ export function Layout({ children, noPadding }: LayoutProps) {

{t('chromeUi.loggedOutPrompt')}

- + )} @@ -1256,6 +1272,24 @@ export function Layout({ children, noPadding }: LayoutProps) { /> + {/* Header/burger auth — owned here so closing the sheet cannot unmount it + and it always sits above the sheet + welcome overlay. */} + + setAuthDialog(null)} + onLogin={() => setAuthDialog(null)} + onSignup={() => setAuthDialog('signup')} + /> + + + setAuthDialog(null)} + onUseAmber={() => setAuthDialog('login')} + /> + + {/* Newsletter: floating pill + Monday admin reminder */} diff --git a/src/components/auth/LoginArea.tsx b/src/components/auth/LoginArea.tsx index c231f41..87735d1 100644 --- a/src/components/auth/LoginArea.tsx +++ b/src/components/auth/LoginArea.tsx @@ -15,14 +15,31 @@ export interface LoginAreaProps { className?: string; /** Compact mode for mobile headers - smaller buttons without text */ compact?: boolean; + /** + * Open auth in a caller-owned dialog instead of this component's local one. + * The mobile burger sheet uses this: its local dialog would portal *behind* + * the sheet (z-50 vs z-2100) and leave the menu looking stuck. + */ + onLoginRequest?: () => void; + onSignupRequest?: () => void; } -export function LoginArea({ className, compact }: LoginAreaProps) { +export function LoginArea({ className, compact, onLoginRequest, onSignupRequest }: LoginAreaProps) { const { currentUser } = useLoggedInAccounts(); const { t } = useTranslation(); const [loginDialogOpen, setLoginDialogOpen] = useState(false); const [signupDialogOpen, setSignupDialogOpen] = useState(false); + const globalAuth = !!onLoginRequest && !!onSignupRequest; + const openLogin = () => { + if (onLoginRequest) onLoginRequest(); + else setLoginDialogOpen(true); + }; + const openSignup = () => { + if (onSignupRequest) onSignupRequest(); + else setSignupDialogOpen(true); + }; + const handleLogin = () => { setLoginDialogOpen(false); setSignupDialogOpen(false); @@ -31,12 +48,12 @@ export function LoginArea({ className, compact }: LoginAreaProps) { return (
{currentUser ? ( - setLoginDialogOpen(true)} /> + ) : compact ? ( // Compact mode for mobile headers - icon only
)} - setLoginDialogOpen(false)} - onLogin={handleLogin} - onSignup={() => setSignupDialogOpen(true)} - /> + {!globalAuth && ( + <> + setLoginDialogOpen(false)} + onLogin={handleLogin} + onSignup={() => { + setLoginDialogOpen(false); + setSignupDialogOpen(true); + }} + /> - {/* One signup entry point. The old "Recovery Phrase vs Secret Key" method - chooser was dead code (never opened) and pure jargon for a newcomer — - SignupDialog owns the whole flow now. */} - setSignupDialogOpen(false)} - onUseAmber={() => { - setSignupDialogOpen(false); - setLoginDialogOpen(true); - }} - /> + {/* One signup entry point. The old "Recovery Phrase vs Secret Key" + method chooser was dead code (never opened) and pure jargon for a + newcomer — SignupDialog owns the whole flow now. */} + setSignupDialogOpen(false)} + onUseAmber={() => { + setSignupDialogOpen(false); + setLoginDialogOpen(true); + }} + /> + + )}
); } \ No newline at end of file diff --git a/src/components/auth/LoginDialog.tsx b/src/components/auth/LoginDialog.tsx index 622ddeb..2caa40e 100644 --- a/src/components/auth/LoginDialog.tsx +++ b/src/components/auth/LoginDialog.tsx @@ -321,7 +321,7 @@ export const LoginDialog: React.FC = ({ isOpen, onClose, onLog return ( - + {t('settingsUi.loginDialog.welcomeTitle')} diff --git a/src/components/auth/SignupDialog.tsx b/src/components/auth/SignupDialog.tsx index cdcde83..da8644a 100644 --- a/src/components/auth/SignupDialog.tsx +++ b/src/components/auth/SignupDialog.tsx @@ -375,7 +375,7 @@ const SignupDialog: React.FC = ({ isOpen, onClose, onComplete return (