feat: add login and logout (#436)

This commit is contained in:
Manuel
2024-05-04 22:57:13 +02:00
committed by GitHub
parent b888fad1fc
commit 51aaab2f23
3 changed files with 85 additions and 4 deletions

View File

@@ -1,16 +1,29 @@
"use client";
import type { ReactNode } from "react";
import { useCallback, useEffect } from "react";
import Link from "next/link";
import { Menu, useMantineColorScheme } from "@mantine/core";
import { useRouter } from "next/navigation";
import {
Center,
Menu,
Stack,
Text,
useMantineColorScheme,
} from "@mantine/core";
import { useTimeout } from "@mantine/hooks";
import {
IconCheck,
IconDashboard,
IconLogin,
IconLogout,
IconMoon,
IconSun,
IconTool,
} from "@tabler/icons-react";
import { signOut, useSession } from "@homarr/auth/client";
import { createModal, useModalAction } from "@homarr/modals";
import { useScopedI18n } from "@homarr/translation/client";
interface UserAvatarMenuProps {
@@ -26,6 +39,22 @@ export const UserAvatarMenu = ({ children }: UserAvatarMenuProps) => {
const colorSchemeText =
colorScheme === "dark" ? t("switchToLightMode") : t("switchToDarkMode");
const session = useSession();
const router = useRouter();
const { openModal } = useModalAction(LogoutModal);
const handleSignout = useCallback(async () => {
await signOut({
redirect: false,
});
openModal({
onTimeout: () => {
router.refresh();
},
});
}, [openModal, router]);
return (
<Menu width={200} withArrow withinPortal>
<Menu.Dropdown>
@@ -50,11 +79,58 @@ export const UserAvatarMenu = ({ children }: UserAvatarMenuProps) => {
{t("management")}
</Menu.Item>
<Menu.Divider />
<Menu.Item leftSection={<IconLogout size="1rem" />} color="red">
{t("logout")}
</Menu.Item>
{session.status === "authenticated" ? (
<Menu.Item
onClick={handleSignout}
leftSection={<IconLogout size="1rem" />}
color="red"
>
{t("logout")}
</Menu.Item>
) : (
<Menu.Item
onClick={() => router.push("/auth/login")}
leftSection={<IconLogin size="1rem" />}
>
{t("login")}
</Menu.Item>
)}
</Menu.Dropdown>
<Menu.Target>{children}</Menu.Target>
</Menu>
);
};
const LogoutModal = createModal<{ onTimeout: () => void }>(
({ actions, innerProps }) => {
const t = useScopedI18n("common.userAvatar.menu");
const { start } = useTimeout(() => {
actions.closeModal();
innerProps.onTimeout();
}, 1500);
useEffect(() => {
start();
}, []);
return (
<Center h={200 - 2 * 16}>
<Stack align="center" c="green">
<IconCheck size={50} />
<Text ta="center" fw="bold">
{t("loggedOut")}
</Text>
</Stack>
</Center>
);
},
).withOptions({
centered: true,
withCloseButton: false,
transitionProps: {
transition: "pop",
},
size: 200,
closeOnClickOutside: false,
closeOnEscape: false,
});

View File

@@ -18,6 +18,9 @@ export type CreateModalOptions = Pick<
| "zIndex"
| "scrollAreaComponent"
| "yOffset"
| "transitionProps"
| "closeOnClickOutside"
| "closeOnEscape"
> & {
defaultTitle: stringOrTranslation;
};

View File

@@ -403,7 +403,9 @@ export default {
switchToLightMode: "Switch to light mode",
management: "Management",
logout: "Logout",
login: "Login",
navigateDefaultBoard: "Navigate to default board",
loggedOut: "Logged out",
},
},
menu: {