feat: wire survey into header user menu

Add SurveyIndicator (purple dot) around the avatar and render
SurveyMenuItem + SurveyModal in the user avatar dropdown menu.
This commit is contained in:
Thomas Camlong committed 2026-06-08 23:55:01 +02:00
1 parent 3a9f10e6ba
commit e6403bbe52
2 files changed
+53 -45

No files matched your search

@@ -6,6 +6,7 @@ import { auth } from "@homarr/auth/next";
import { CurrentUserAvatar } from "~/components/user-avatar";
import { UserAvatarMenu } from "~/components/user-avatar-menu";
import { SurveyIndicator } from "./survey";
import { UpdateIndicator } from "./update";
export const UserButton = async () => {
@@ -16,9 +17,11 @@ export const UserButton = async () => {
<UserAvatarMenu availableUpdatesPromise={availableUpdatesPromise}>
<UnstyledButton>
<Suspense fallback={<CurrentUserAvatar size="md" />}>
<UpdateIndicator availableUpdatesPromise={availableUpdatesPromise} disabled={!isAdmin}>
<CurrentUserAvatar size="md" />
</UpdateIndicator>
<SurveyIndicator>
<UpdateIndicator availableUpdatesPromise={availableUpdatesPromise} disabled={!isAdmin}>
<CurrentUserAvatar size="md" />
</UpdateIndicator>
</SurveyIndicator>
</Suspense>
</UnstyledButton>
</UserAvatarMenu>
+47 -42
View File
@@ -18,6 +18,7 @@ import { useAuthContext } from "~/app/[locale]/_client-providers/session";
import { CurrentColorSchemeCombobox } from "./color-scheme/current-color-scheme-combobox";
import { CurrentLanguageCombobox } from "./language/current-language-combobox";
import { AvailableUpdatesMenuItem } from "./layout/header/update";
import { SurveyMenuItem, SurveyModal } from "./layout/header/survey";
interface UserAvatarMenuProps {
children: ReactNode;
@@ -51,50 +52,54 @@ export const UserAvatarMenu = ({ children, availableUpdatesPromise }: UserAvatar
}, [logoutUrl, openModal, router]);
return (
// We use keepMounted so we can add event listeners to prevent navigating away without saving the board
<Menu width={300} withinPortal keepMounted>
<Menu.Dropdown>
<AvailableUpdatesMenuItem availableUpdatesPromise={availableUpdatesPromise} />
<Menu.Item component={Link} href="/boards" leftSection={<IconHome size="1rem" />}>
{t("homeBoard")}
</Menu.Item>
<Menu.Divider />
<Menu.Item p={0} closeMenuOnClick={false} component="div">
<CurrentColorSchemeCombobox />
</Menu.Item>
<Menu.Item p={0} closeMenuOnClick={false} component="div">
<CurrentLanguageCombobox />
</Menu.Item>
<Menu.Divider />
{Boolean(session.data) && (
<>
<Menu.Item
component={Link}
href={`/manage/users/${session.data?.user.id}/general`}
leftSection={<IconSettings size="1rem" />}
>
{t("preferences")}
</Menu.Item>
<Menu.Item component={Link} href="/manage" leftSection={<IconTool size="1rem" />}>
{t("management")}
</Menu.Item>
</>
)}
<Menu.Divider />
{session.status === "authenticated" ? (
<Menu.Item onClick={handleSignout} leftSection={<IconLogout size="1rem" />} color="red">
{t("logout")}
<>
<SurveyModal />
{/* We use keepMounted so we can add event listeners to prevent navigating away without saving the board */}
<Menu width={300} withinPortal keepMounted>
<Menu.Dropdown>
<AvailableUpdatesMenuItem availableUpdatesPromise={availableUpdatesPromise} />
<SurveyMenuItem />
<Menu.Item component={Link} href="/boards" leftSection={<IconHome size="1rem" />}>
{t("homeBoard")}
</Menu.Item>
) : (
<Menu.Item component={Link} href="/auth/login" leftSection={<IconLogin size="1rem" />}>
{t("login")}
<Menu.Divider />
<Menu.Item p={0} closeMenuOnClick={false} component="div">
<CurrentColorSchemeCombobox />
</Menu.Item>
)}
</Menu.Dropdown>
<Menu.Target>{children}</Menu.Target>
</Menu>
<Menu.Item p={0} closeMenuOnClick={false} component="div">
<CurrentLanguageCombobox />
</Menu.Item>
<Menu.Divider />
{Boolean(session.data) && (
<>
<Menu.Item
component={Link}
href={`/manage/users/${session.data?.user.id}/general`}
leftSection={<IconSettings size="1rem" />}
>
{t("preferences")}
</Menu.Item>
<Menu.Item component={Link} href="/manage" leftSection={<IconTool size="1rem" />}>
{t("management")}
</Menu.Item>
</>
)}
<Menu.Divider />
{session.status === "authenticated" ? (
<Menu.Item onClick={handleSignout} leftSection={<IconLogout size="1rem" />} color="red">
{t("logout")}
</Menu.Item>
) : (
<Menu.Item component={Link} href="/auth/login" leftSection={<IconLogin size="1rem" />}>
{t("login")}
</Menu.Item>
)}
</Menu.Dropdown>
<Menu.Target>{children}</Menu.Target>
</Menu>
</>
);
};