feat: add theme toggle to navigation bar

This commit is contained in:
Rafael Panisset 2025-03-15 22:25:13 -03:00
parent 21c3ad0ecc
commit d4ed80e751
2 changed files with 103 additions and 76 deletions

View File

@ -14,6 +14,7 @@ import APP_ROUTE from "@/lib/app-route.ts";
import useAuth from "@/features/auth/hooks/use-auth.ts";
import { CustomAvatar } from "@/components/ui/custom-avatar.tsx";
import { useTranslation } from "react-i18next";
import { ThemeToggle } from '@/components/ui/theme-toggle';
export default function TopMenu() {
const { t } = useTranslation();
@ -28,85 +29,88 @@ export default function TopMenu() {
}
return (
<Menu width={250} position="bottom-end" withArrow shadow={"lg"}>
<Menu.Target>
<UnstyledButton>
<Group gap={7} wrap={"nowrap"}>
<CustomAvatar
avatarUrl={workspace?.logo}
name={workspace?.name}
variant="filled"
size="sm"
/>
<Text fw={500} size="sm" lh={1} mr={3} lineClamp={1}>
{workspace?.name}
</Text>
<IconChevronDown size={16} />
</Group>
</UnstyledButton>
</Menu.Target>
<Menu.Dropdown>
<Menu.Label>{t("Workspace")}</Menu.Label>
<Menu.Item
component={Link}
to={APP_ROUTE.SETTINGS.WORKSPACE.GENERAL}
leftSection={<IconSettings size={16} />}
>
{t("Workspace settings")}
</Menu.Item>
<Menu.Item
component={Link}
to={APP_ROUTE.SETTINGS.WORKSPACE.MEMBERS}
leftSection={<IconUsers size={16} />}
>
{t("Manage members")}
</Menu.Item>
<Menu.Divider />
<Menu.Label>{t("Account")}</Menu.Label>
<Menu.Item component={Link} to={APP_ROUTE.SETTINGS.ACCOUNT.PROFILE}>
<Group wrap={"nowrap"}>
<CustomAvatar
size={"sm"}
avatarUrl={user.avatarUrl}
name={user.name}
/>
<div style={{width: 190}}>
<Text size="sm" fw={500} lineClamp={1}>
{user.name}
<>
<ThemeToggle />
<Menu width={250} position="bottom-end" withArrow shadow={"lg"}>
<Menu.Target>
<UnstyledButton>
<Group gap={7} wrap={"nowrap"}>
<CustomAvatar
avatarUrl={workspace?.logo}
name={workspace?.name}
variant="filled"
size="sm"
/>
<Text fw={500} size="sm" lh={1} mr={3} lineClamp={1}>
{workspace?.name}
</Text>
<Text size="xs" c="dimmed" truncate="end">
{user.email}
</Text>
</div>
</Group>
</Menu.Item>
<Menu.Item
component={Link}
to={APP_ROUTE.SETTINGS.ACCOUNT.PROFILE}
leftSection={<IconUserCircle size={16} />}
>
{t("My profile")}
</Menu.Item>
<IconChevronDown size={16} />
</Group>
</UnstyledButton>
</Menu.Target>
<Menu.Dropdown>
<Menu.Label>{t("Workspace")}</Menu.Label>
<Menu.Item
component={Link}
to={APP_ROUTE.SETTINGS.ACCOUNT.PREFERENCES}
leftSection={<IconBrush size={16} />}
>
{t("My preferences")}
</Menu.Item>
<Menu.Item
component={Link}
to={APP_ROUTE.SETTINGS.WORKSPACE.GENERAL}
leftSection={<IconSettings size={16} />}
>
{t("Workspace settings")}
</Menu.Item>
<Menu.Divider />
<Menu.Item
component={Link}
to={APP_ROUTE.SETTINGS.WORKSPACE.MEMBERS}
leftSection={<IconUsers size={16} />}
>
{t("Manage members")}
</Menu.Item>
<Menu.Item onClick={logout} leftSection={<IconLogout size={16} />}>
{t("Logout")}
</Menu.Item>
</Menu.Dropdown>
</Menu>
<Menu.Divider />
<Menu.Label>{t("Account")}</Menu.Label>
<Menu.Item component={Link} to={APP_ROUTE.SETTINGS.ACCOUNT.PROFILE}>
<Group wrap={"nowrap"}>
<CustomAvatar
size={"sm"}
avatarUrl={user.avatarUrl}
name={user.name}
/>
<div style={{width: 190}}>
<Text size="sm" fw={500} lineClamp={1}>
{user.name}
</Text>
<Text size="xs" c="dimmed" truncate="end">
{user.email}
</Text>
</div>
</Group>
</Menu.Item>
<Menu.Item
component={Link}
to={APP_ROUTE.SETTINGS.ACCOUNT.PROFILE}
leftSection={<IconUserCircle size={16} />}
>
{t("My profile")}
</Menu.Item>
<Menu.Item
component={Link}
to={APP_ROUTE.SETTINGS.ACCOUNT.PREFERENCES}
leftSection={<IconBrush size={16} />}
>
{t("My preferences")}
</Menu.Item>
<Menu.Divider />
<Menu.Item onClick={logout} leftSection={<IconLogout size={16} />}>
{t("Logout")}
</Menu.Item>
</Menu.Dropdown>
</Menu>
</>
);
}

View File

@ -0,0 +1,23 @@
import { ActionIcon, useComputedColorScheme, useMantineColorScheme } from '@mantine/core';
import { IconSun, IconMoon } from '@tabler/icons-react';
export function ThemeToggle() {
const { setColorScheme } = useMantineColorScheme();
const computedColorScheme = useComputedColorScheme('light', { getInitialValueInEffect: true });
return (
<ActionIcon
onClick={() => setColorScheme(computedColorScheme === 'light' ? 'dark' : 'light')}
variant="transparent"
size="md"
color="foreground"
aria-label="Toggle color scheme"
>
{computedColorScheme === 'light' ? (
<IconMoon size={18} stroke={1.5} />
) : (
<IconSun size={18} stroke={1.5} />
)}
</ActionIcon>
);
}