www_site/apps/cms/src/components/CmsLogoutButton.tsx

73 lines
1.9 KiB
TypeScript

"use client";
import React, { useState } from "react";
import { LogOutIcon, toast, useAuth, useConfig, useTranslation } from "@payloadcms/ui";
import { formatAdminURL } from "payload/shared";
type Props = {
tabIndex?: number;
};
function withCurrentBasePath(path: string) {
if (typeof window === "undefined") {
return path;
}
const basePath = window.location.pathname === "/cms" || window.location.pathname.startsWith("/cms/") ? "/cms" : "";
if (!basePath || path === basePath || path.startsWith(`${basePath}/`)) {
return path;
}
return `${basePath}${path.startsWith("/") ? path : `/${path}`}`;
}
export function CmsLogoutButton({ tabIndex = 0 }: Props) {
const [busy, setBusy] = useState(false);
const { logOut } = useAuth();
const { config } = useConfig();
const { t } = useTranslation();
async function handleLogout() {
if (busy) {
return;
}
setBusy(true);
try {
await logOut();
} catch (error) {
console.error("Payload logout failed", error);
}
try {
await fetch(withCurrentBasePath(formatAdminURL({ apiRoute: config.routes.api, path: "/cms-logout" })), {
cache: "no-store",
credentials: "include",
method: "POST",
});
} catch (error) {
console.error("CMS cookie cleanup failed", error);
} finally {
toast.success(t("authentication:loggedOutSuccessfully"));
window.location.replace(withCurrentBasePath(formatAdminURL({ adminRoute: config.routes.admin, path: "/login" })));
}
}
return (
<button
aria-label={t("authentication:logOut")}
className="nav__log-out"
disabled={busy}
onClick={() => void handleLogout()}
style={{ appearance: "none", background: "transparent", border: 0, cursor: busy ? "wait" : "pointer", padding: 0 }}
tabIndex={tabIndex}
title={t("authentication:logOut")}
type="button"
>
<LogOutIcon />
</button>
);
}