From c5286e6d1c7e78deb94361f8df8a336af7cff99e Mon Sep 17 00:00:00 2001 From: nathan Date: Wed, 1 Oct 2025 20:44:06 +0800 Subject: [PATCH] chore: logout --- .../more-actions/MoreActionsContent.tsx | 17 ++++- .../app/workspaces/LogoutConfirm.tsx | 69 +++++++++++++++++++ src/components/app/workspaces/Workspaces.tsx | 10 ++- 3 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 src/components/app/workspaces/LogoutConfirm.tsx diff --git a/src/components/_shared/more-actions/MoreActionsContent.tsx b/src/components/_shared/more-actions/MoreActionsContent.tsx index 95bbde2a..06dcfe1c 100644 --- a/src/components/_shared/more-actions/MoreActionsContent.tsx +++ b/src/components/_shared/more-actions/MoreActionsContent.tsx @@ -6,6 +6,7 @@ import { ReactComponent as LoginIcon } from '@/assets/icons/logout.svg'; import { ReactComponent as MoonIcon } from '@/assets/icons/moon.svg'; import { ReactComponent as SunIcon } from '@/assets/icons/sun.svg'; import CacheClearingDialog from '@/components/_shared/modal/CacheClearingDialog'; +import LogoutConfirm from '@/components/app/workspaces/LogoutConfirm'; import { AFConfigContext } from '@/components/main/app.hooks'; import { ThemeModeContext } from '@/components/main/useAppThemeMode'; import { openUrl } from '@/utils/url'; @@ -23,12 +24,21 @@ function MoreActionsContent({ const { t } = useTranslation(); const navigate = useNavigate(); - const handleLogin = useCallback(() => { + const handleLogout = useCallback(() => { clearRedirectTo(); // Clear stored redirect URL from previous user invalidToken(); navigate('/login?redirectTo=' + encodeURIComponent(window.location.href)); }, [navigate]); + + const handleLogin = useCallback(() => { + if (isAuthenticated) { + setOpenLogoutConfirm(true); + } else { + handleLogout(); + } + }, [isAuthenticated, handleLogout]); const [openConfirm, setOpenConfirm] = React.useState(false); + const [openLogoutConfirm, setOpenLogoutConfirm] = React.useState(false); const actions = useMemo(() => { const items = [ @@ -98,6 +108,11 @@ function MoreActionsContent({ <> {actionsContent} setOpenConfirm(false)} /> + setOpenLogoutConfirm(false)} + onConfirm={handleLogout} + /> ); } diff --git a/src/components/app/workspaces/LogoutConfirm.tsx b/src/components/app/workspaces/LogoutConfirm.tsx new file mode 100644 index 00000000..d6489f28 --- /dev/null +++ b/src/components/app/workspaces/LogoutConfirm.tsx @@ -0,0 +1,69 @@ +import { useTranslation } from 'react-i18next'; + +import { Button } from '@/components/ui/button'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog'; +import { createHotkey, HOT_KEY_NAME } from '@/utils/hotkeys'; + +export function LogoutConfirm({ + open, + onClose, + onConfirm, +}: { + open: boolean; + onClose: () => void; + onConfirm: () => void; +}) { + const { t } = useTranslation(); + + const handleLogout = () => { + onConfirm(); + onClose(); + }; + + return ( + { + if (!status) { + onClose(); + } + }} + > + { + e.preventDefault(); + }} + onKeyDown={(e) => { + e.stopPropagation(); + if (createHotkey(HOT_KEY_NAME.ENTER)(e.nativeEvent)) { + handleLogout(); + } + }} + > + + {t('button.logout')} + + + {t('settings.menu.logoutPrompt')} + + + + + + + + ); +} + +export default LogoutConfirm; diff --git a/src/components/app/workspaces/Workspaces.tsx b/src/components/app/workspaces/Workspaces.tsx index a0952afd..6b03b52c 100644 --- a/src/components/app/workspaces/Workspaces.tsx +++ b/src/components/app/workspaces/Workspaces.tsx @@ -40,6 +40,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip import { openUrl } from '@/utils/url'; import { AccountSettings } from './AccountSettings'; +import LogoutConfirm from '@/components/app/workspaces/LogoutConfirm'; export function Workspaces() { const { t } = useTranslation(); @@ -66,6 +67,7 @@ export function Workspaces() { const [openRenameWorkspace, setOpenRenameWorkspace] = useState(null); const [openDeleteWorkspace, setOpenDeleteWorkspace] = useState(null); const [openLeaveWorkspace, setOpenLeaveWorkspace] = useState(null); + const [openLogoutConfirm, setOpenLogoutConfirm] = useState(false); const isOwner = currentWorkspace?.owner?.uid.toString() === currentUser?.uid.toString(); @@ -229,7 +231,7 @@ export function Workspaces() {
{t('web.accountSettings')}
- + setOpenLogoutConfirm(true)}> {t('button.logout')} @@ -323,6 +325,12 @@ export function Workspaces() { openOnChange={() => setOpenLeaveWorkspace(null)} /> )} + + setOpenLogoutConfirm(false)} + onConfirm={handleSignOut} + /> ); }