mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
feat(frontend): Add admin button to user profile dropdown (#10774)
<!-- Clearly explain the need for these changes: --> ### Need 💡 This PR addresses Linear issue [OPEN-2232](https://linear.app/autogpt/issue/OPEN-2232/add-admin-pages-in-dropdown) by adding an "Admin" button to the user account dropdown menu. This button is only visible to users with an "admin" role and provides direct navigation to the admin marketplace management page, making existing admin functionalities accessible from the new UI. ### Changes 🏗️ <!-- Concisely describe all of the changes made in this pull request: --> - **Added Admin Icon**: Integrated `IconSliders` into the `IconType` enum and `getAccountMenuOptionIcon` function. - **Dynamic Menu Generation**: Introduced `getAccountMenuItems(userRole?: string)` to dynamically construct the account menu. This function conditionally adds an "Admin" menu item (linking to `/admin/marketplace`) if the `userRole` is "admin". - **Navbar Integration**: Updated `NavbarView.tsx` to utilize the `useSupabase` hook to retrieve the current user's role and then render the account menu using the new dynamic `getAccountMenuItems` function for both desktop and mobile views. ### Checklist 📋 #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: <!-- Put your test plan here: --> - [x] Log in as an admin user and verify the "Admin" button appears in the account dropdown. - [x] Click the "Admin" button and confirm navigation to `/admin/marketplace`. - [x] Log in as a non-admin user and verify the "Admin" button does not appear in the account dropdown. - [x] Verify all other existing menu items (e.g., "Edit profile", "Log out") function correctly for both admin and non-admin users. - [x] Test the above scenarios on both desktop and mobile views. --- Linear Issue: [OPEN-2232](https://linear.app/autogpt/issue/OPEN-2232/add-admin-pages-in-dropdown) <a href="https://cursor.com/background-agent?bcId=bc-2dceda38-31b4-4e8e-8277-fb87c8858abf"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/open-in-cursor-dark.svg"> <source media="(prefers-color-scheme: light)" srcset="https://cursor.com/open-in-cursor-light.svg"> <img alt="Open in Cursor" src="https://cursor.com/open-in-cursor.svg"> </picture> </a> <a href="https://cursor.com/agents?id=bc-2dceda38-31b4-4e8e-8277-fb87c8858abf"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/open-in-web-dark.svg"> <source media="(prefers-color-scheme: light)" srcset="https://cursor.com/open-in-web-light.svg"> <img alt="Open in Web" src="https://cursor.com/open-in-web.svg"> </picture> </a> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
This commit is contained in:
@@ -5,15 +5,17 @@ import { AccountMenu } from "./AccountMenu/AccountMenu";
|
||||
import { LoginButton } from "./LoginButton";
|
||||
import { MobileNavBar } from "./MobileNavbar/MobileNavBar";
|
||||
import { NavbarLink } from "./NavbarLink";
|
||||
import { accountMenuItems, loggedInLinks, loggedOutLinks } from "../helpers";
|
||||
import { getAccountMenuItems, loggedInLinks, loggedOutLinks } from "../helpers";
|
||||
import { useGetV2GetUserProfile } from "@/app/api/__generated__/endpoints/store/store";
|
||||
import { AgentActivityDropdown } from "./AgentActivityDropdown/AgentActivityDropdown";
|
||||
import { useSupabase } from "@/lib/supabase/hooks/useSupabase";
|
||||
|
||||
interface NavbarViewProps {
|
||||
isLoggedIn: boolean;
|
||||
}
|
||||
|
||||
export const NavbarView = ({ isLoggedIn }: NavbarViewProps) => {
|
||||
const { user } = useSupabase();
|
||||
const { data: profile } = useGetV2GetUserProfile({
|
||||
query: {
|
||||
select: (res) => (res.status === 200 ? res.data : null),
|
||||
@@ -21,6 +23,8 @@ export const NavbarView = ({ isLoggedIn }: NavbarViewProps) => {
|
||||
},
|
||||
});
|
||||
|
||||
const dynamicMenuItems = getAccountMenuItems(user?.role);
|
||||
|
||||
return (
|
||||
<>
|
||||
<nav className="sticky top-0 z-40 hidden h-16 items-center border border-white/50 bg-[#f3f4f6]/20 p-3 backdrop-blur-[26px] md:inline-flex">
|
||||
@@ -50,7 +54,7 @@ export const NavbarView = ({ isLoggedIn }: NavbarViewProps) => {
|
||||
userName={profile?.username}
|
||||
userEmail={profile?.name}
|
||||
avatarSrc={profile?.avatar_url ?? ""}
|
||||
menuItemGroups={accountMenuItems}
|
||||
menuItemGroups={dynamicMenuItems}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
@@ -83,7 +87,7 @@ export const NavbarView = ({ isLoggedIn }: NavbarViewProps) => {
|
||||
href: link.href,
|
||||
})),
|
||||
},
|
||||
...accountMenuItems,
|
||||
...dynamicMenuItems,
|
||||
]}
|
||||
userEmail={profile?.name}
|
||||
avatarSrc={profile?.avatar_url ?? ""}
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
IconMarketplace,
|
||||
IconRefresh,
|
||||
IconSettings,
|
||||
IconSliders,
|
||||
IconType,
|
||||
IconUploadCloud,
|
||||
} from "@/components/ui/icons";
|
||||
@@ -90,6 +91,69 @@ export const accountMenuItems: MenuItemGroup[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export function getAccountMenuItems(userRole?: string): MenuItemGroup[] {
|
||||
const baseMenuItems: MenuItemGroup[] = [
|
||||
{
|
||||
items: [
|
||||
{
|
||||
icon: IconType.Edit,
|
||||
text: "Edit profile",
|
||||
href: "/profile",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
items: [
|
||||
{
|
||||
icon: IconType.LayoutDashboard,
|
||||
text: "Creator Dashboard",
|
||||
href: "/profile/dashboard",
|
||||
},
|
||||
{
|
||||
icon: IconType.UploadCloud,
|
||||
text: "Publish an agent",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
// Add admin menu item for admin users
|
||||
if (userRole === "admin") {
|
||||
baseMenuItems.push({
|
||||
items: [
|
||||
{
|
||||
icon: IconType.Sliders,
|
||||
text: "Admin",
|
||||
href: "/admin/marketplace",
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Add settings and logout
|
||||
baseMenuItems.push(
|
||||
{
|
||||
items: [
|
||||
{
|
||||
icon: IconType.Settings,
|
||||
text: "Settings",
|
||||
href: "/profile/settings",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
items: [
|
||||
{
|
||||
icon: IconType.LogOut,
|
||||
text: "Log out",
|
||||
},
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
return baseMenuItems;
|
||||
}
|
||||
|
||||
export function getAccountMenuOptionIcon(icon: IconType) {
|
||||
const iconClass = "w-6 h-6";
|
||||
switch (icon) {
|
||||
@@ -109,6 +173,8 @@ export function getAccountMenuOptionIcon(icon: IconType) {
|
||||
return <IconLibrary className={iconClass} />;
|
||||
case IconType.Builder:
|
||||
return <IconBuilder className={iconClass} />;
|
||||
case IconType.Sliders:
|
||||
return <IconSliders className={iconClass} />;
|
||||
default:
|
||||
return <IconRefresh className={iconClass} />;
|
||||
}
|
||||
|
||||
@@ -1836,6 +1836,7 @@ export enum IconType {
|
||||
Settings,
|
||||
LogOut,
|
||||
AutoGPTLogo,
|
||||
Sliders,
|
||||
}
|
||||
|
||||
export function getIconForSocial(
|
||||
|
||||
Reference in New Issue
Block a user