Skip to content

Commit 6d39dfe

Browse files
ntindlecursoragent
andauthored
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 <[email protected]>
1 parent 57ecc10 commit 6d39dfe

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

autogpt_platform/frontend/src/components/layout/Navbar/components/NavbarView.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,26 @@ import { AccountMenu } from "./AccountMenu/AccountMenu";
55
import { LoginButton } from "./LoginButton";
66
import { MobileNavBar } from "./MobileNavbar/MobileNavBar";
77
import { NavbarLink } from "./NavbarLink";
8-
import { accountMenuItems, loggedInLinks, loggedOutLinks } from "../helpers";
8+
import { getAccountMenuItems, loggedInLinks, loggedOutLinks } from "../helpers";
99
import { useGetV2GetUserProfile } from "@/app/api/__generated__/endpoints/store/store";
1010
import { AgentActivityDropdown } from "./AgentActivityDropdown/AgentActivityDropdown";
11+
import { useSupabase } from "@/lib/supabase/hooks/useSupabase";
1112

1213
interface NavbarViewProps {
1314
isLoggedIn: boolean;
1415
}
1516

1617
export const NavbarView = ({ isLoggedIn }: NavbarViewProps) => {
18+
const { user } = useSupabase();
1719
const { data: profile } = useGetV2GetUserProfile({
1820
query: {
1921
select: (res) => (res.status === 200 ? res.data : null),
2022
enabled: isLoggedIn,
2123
},
2224
});
2325

26+
const dynamicMenuItems = getAccountMenuItems(user?.role);
27+
2428
return (
2529
<>
2630
<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) => {
5054
userName={profile?.username}
5155
userEmail={profile?.name}
5256
avatarSrc={profile?.avatar_url ?? ""}
53-
menuItemGroups={accountMenuItems}
57+
menuItemGroups={dynamicMenuItems}
5458
/>
5559
</div>
5660
) : (
@@ -83,7 +87,7 @@ export const NavbarView = ({ isLoggedIn }: NavbarViewProps) => {
8387
href: link.href,
8488
})),
8589
},
86-
...accountMenuItems,
90+
...dynamicMenuItems,
8791
]}
8892
userEmail={profile?.name}
8993
avatarSrc={profile?.avatar_url ?? ""}

autogpt_platform/frontend/src/components/layout/Navbar/helpers.tsx

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
IconMarketplace,
88
IconRefresh,
99
IconSettings,
10+
IconSliders,
1011
IconType,
1112
IconUploadCloud,
1213
} from "@/components/ui/icons";
@@ -90,6 +91,69 @@ export const accountMenuItems: MenuItemGroup[] = [
9091
},
9192
];
9293

94+
export function getAccountMenuItems(userRole?: string): MenuItemGroup[] {
95+
const baseMenuItems: MenuItemGroup[] = [
96+
{
97+
items: [
98+
{
99+
icon: IconType.Edit,
100+
text: "Edit profile",
101+
href: "/profile",
102+
},
103+
],
104+
},
105+
{
106+
items: [
107+
{
108+
icon: IconType.LayoutDashboard,
109+
text: "Creator Dashboard",
110+
href: "/profile/dashboard",
111+
},
112+
{
113+
icon: IconType.UploadCloud,
114+
text: "Publish an agent",
115+
},
116+
],
117+
},
118+
];
119+
120+
// Add admin menu item for admin users
121+
if (userRole === "admin") {
122+
baseMenuItems.push({
123+
items: [
124+
{
125+
icon: IconType.Sliders,
126+
text: "Admin",
127+
href: "/admin/marketplace",
128+
},
129+
],
130+
});
131+
}
132+
133+
// Add settings and logout
134+
baseMenuItems.push(
135+
{
136+
items: [
137+
{
138+
icon: IconType.Settings,
139+
text: "Settings",
140+
href: "/profile/settings",
141+
},
142+
],
143+
},
144+
{
145+
items: [
146+
{
147+
icon: IconType.LogOut,
148+
text: "Log out",
149+
},
150+
],
151+
},
152+
);
153+
154+
return baseMenuItems;
155+
}
156+
93157
export function getAccountMenuOptionIcon(icon: IconType) {
94158
const iconClass = "w-6 h-6";
95159
switch (icon) {
@@ -109,6 +173,8 @@ export function getAccountMenuOptionIcon(icon: IconType) {
109173
return <IconLibrary className={iconClass} />;
110174
case IconType.Builder:
111175
return <IconBuilder className={iconClass} />;
176+
case IconType.Sliders:
177+
return <IconSliders className={iconClass} />;
112178
default:
113179
return <IconRefresh className={iconClass} />;
114180
}

autogpt_platform/frontend/src/components/ui/icons.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,6 +1836,7 @@ export enum IconType {
18361836
Settings,
18371837
LogOut,
18381838
AutoGPTLogo,
1839+
Sliders,
18391840
}
18401841

18411842
export function getIconForSocial(

0 commit comments

Comments
 (0)