Skip to content

Commit 5875379

Browse files
authored
chore: move sidebar items to footer (#527)
1 parent 1b9414f commit 5875379

File tree

5 files changed

+395
-373
lines changed

5 files changed

+395
-373
lines changed

api/api/versions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{
44
"version": "v1",
55
"status": "active",
6-
"release_date": "2025-10-22T08:48:21.923083+05:30",
6+
"release_date": "2025-10-22T16:45:33.662757+05:30",
77
"end_of_life": "0001-01-01T00:00:00Z",
88
"changes": [
99
"Initial API version"
Lines changed: 55 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,21 @@
11
'use client';
22

33
import * as React from 'react';
4-
import { Folder, Home, Package, SettingsIcon, Container, Puzzle } from 'lucide-react';
4+
import { AlertCircle, HelpCircle, Heart, LogOut } from 'lucide-react';
55
import { NavMain } from '@/components/layout/nav-main';
6-
import { NavUser } from '@/components/layout/nav-user';
76
import { TeamSwitcher } from '@/components/ui/team-switcher';
87
import {
98
Sidebar,
109
SidebarContent,
1110
SidebarFooter,
1211
SidebarHeader,
13-
SidebarRail
12+
SidebarRail,
13+
SidebarMenu,
14+
SidebarMenuButton,
15+
SidebarMenuItem
1416
} from '@/components/ui/sidebar';
15-
import { useAppSelector, useAppDispatch } from '@/redux/hooks';
16-
import { useGetUserOrganizationsQuery } from '@/redux/services/users/userApi';
17-
import { useNavigationState } from '@/hooks/use_navigation_state';
18-
import { setActiveOrganization } from '@/redux/features/users/userSlice';
19-
import { useTranslation } from '@/hooks/use-translation';
20-
import { useRBAC } from '@/lib/rbac';
21-
22-
const data = {
23-
navMain: [
24-
{
25-
title: 'navigation.dashboard',
26-
url: '/dashboard',
27-
icon: Home,
28-
resource: 'dashboard'
29-
},
30-
{
31-
title: 'navigation.extensions',
32-
url: '/extensions',
33-
icon: Puzzle,
34-
resource: 'extensions'
35-
},
36-
{
37-
title: 'navigation.selfHost',
38-
url: '/self-host',
39-
icon: Package,
40-
resource: 'deploy'
41-
},
42-
{
43-
title: 'navigation.containers',
44-
url: '/containers',
45-
icon: Container,
46-
resource: 'container'
47-
},
48-
{
49-
title: 'navigation.fileManager',
50-
url: '/file-manager',
51-
icon: Folder,
52-
resource: 'file-manager'
53-
},
54-
{
55-
title: 'navigation.settings',
56-
url: '/settings/general',
57-
icon: SettingsIcon,
58-
resource: 'settings',
59-
items: [
60-
{
61-
title: 'navigation.general',
62-
url: '/settings/general',
63-
resource: 'settings'
64-
},
65-
{
66-
title: 'navigation.notifications',
67-
url: '/settings/notifications',
68-
resource: 'notification'
69-
},
70-
{
71-
title: 'navigation.team',
72-
url: '/settings/teams',
73-
resource: 'organization'
74-
},
75-
{
76-
title: 'navigation.domains',
77-
url: '/settings/domains',
78-
resource: 'domain'
79-
}
80-
]
81-
}
82-
]
83-
};
17+
import { useAppSidebar } from '@/hooks/use-app-sidebar';
18+
import { LogoutDialog } from '@/components/ui/logout-dialog';
8419

8520
export function AppSidebar({
8621
toggleAddTeamModal,
@@ -90,71 +25,23 @@ export function AppSidebar({
9025
toggleAddTeamModal?: () => void;
9126
addTeamModalOpen?: boolean;
9227
}) {
93-
const { t } = useTranslation();
94-
const user = useAppSelector((state) => state.auth.user);
95-
const { isLoading, refetch } = useGetUserOrganizationsQuery();
96-
const organizations = useAppSelector((state) => state.user.organizations);
97-
const { activeNav, setActiveNav } = useNavigationState();
98-
const activeOrg = useAppSelector((state) => state.user.activeOrganization);
99-
const dispatch = useAppDispatch();
100-
const { canAccessResource } = useRBAC();
101-
102-
const hasAnyPermission = React.useMemo(() => {
103-
const allowedResources = ['dashboard', 'settings', 'extensions'];
104-
105-
return (resource: string) => {
106-
if (!user || !activeOrg) return false;
107-
108-
if (allowedResources.includes(resource)) {
109-
return true;
110-
}
111-
112-
return (
113-
canAccessResource(resource as any, 'read') ||
114-
canAccessResource(resource as any, 'create') ||
115-
canAccessResource(resource as any, 'update') ||
116-
canAccessResource(resource as any, 'delete')
117-
);
118-
};
119-
}, [user, activeOrg, canAccessResource]);
120-
121-
const filteredNavItems = React.useMemo(
122-
() =>
123-
data.navMain
124-
.filter((item) => {
125-
if (!item.resource) return false;
126-
127-
if (item.items) {
128-
const filteredSubItems = item.items.filter(
129-
(subItem) => subItem.resource && hasAnyPermission(subItem.resource)
130-
);
131-
return filteredSubItems.length > 0;
132-
}
133-
134-
return hasAnyPermission(item.resource);
135-
})
136-
.map((item) => ({
137-
...item,
138-
title: t(item.title as any),
139-
items: item.items?.map((subItem) => ({
140-
...subItem,
141-
title: t(subItem.title as any)
142-
}))
143-
})),
144-
[data.navMain, hasAnyPermission, t]
145-
);
146-
147-
React.useEffect(() => {
148-
if (organizations && organizations.length > 0 && !activeOrg) {
149-
dispatch(setActiveOrganization(organizations[0].organization));
150-
}
151-
}, [organizations, activeOrg, dispatch]);
152-
153-
React.useEffect(() => {
154-
if (activeOrg?.id) {
155-
refetch();
156-
}
157-
}, [activeOrg?.id, refetch]);
28+
const {
29+
user,
30+
refetch,
31+
activeNav,
32+
setActiveNav,
33+
activeOrg,
34+
hasAnyPermission,
35+
t,
36+
showLogoutDialog,
37+
filteredNavItems,
38+
handleSponsor,
39+
handleReportIssue,
40+
handleHelp,
41+
handleLogoutClick,
42+
handleLogoutConfirm,
43+
handleLogoutCancel
44+
} = useAppSidebar();
15845

15946
if (!user || !activeOrg) {
16047
return null;
@@ -182,9 +69,39 @@ export function AppSidebar({
18269
/>
18370
</SidebarContent>
18471
<SidebarFooter>
185-
<NavUser user={user} />
72+
<SidebarMenu>
73+
<SidebarMenuItem>
74+
<SidebarMenuButton onClick={handleSponsor} className="cursor-pointer">
75+
<Heart className="text-red-500" />
76+
<span>{t('user.menu.sponsor')}</span>
77+
</SidebarMenuButton>
78+
</SidebarMenuItem>
79+
<SidebarMenuItem>
80+
<SidebarMenuButton onClick={handleHelp} className="cursor-pointer">
81+
<HelpCircle />
82+
<span>{t('user.menu.help')}</span>
83+
</SidebarMenuButton>
84+
</SidebarMenuItem>
85+
<SidebarMenuItem>
86+
<SidebarMenuButton onClick={handleReportIssue} className="cursor-pointer">
87+
<AlertCircle />
88+
<span>{t('user.menu.reportIssue')}</span>
89+
</SidebarMenuButton>
90+
</SidebarMenuItem>
91+
<SidebarMenuItem>
92+
<SidebarMenuButton onClick={handleLogoutClick} className="cursor-pointer">
93+
<LogOut />
94+
<span>{t('user.menu.logout')}</span>
95+
</SidebarMenuButton>
96+
</SidebarMenuItem>
97+
</SidebarMenu>
18698
</SidebarFooter>
18799
<SidebarRail />
100+
<LogoutDialog
101+
open={showLogoutDialog}
102+
onConfirm={handleLogoutConfirm}
103+
onCancel={handleLogoutCancel}
104+
/>
188105
</Sidebar>
189106
);
190107
}

0 commit comments

Comments
 (0)