feat(navigation): integrate roles into app navigation
- Add all roles routes to App.tsx - Add roles menu item to sidebar with Shield icon - Update user display to use AdminUser properties - Fix TypeScript compatibility issues with new auth types
This commit is contained in:
parent
ebd2c3c8f7
commit
f43e7ca0e5
13
src/App.tsx
13
src/App.tsx
|
|
@ -16,6 +16,12 @@ import { Reports } from './pages/Reports';
|
||||||
import { Notifications } from './pages/Notifications';
|
import { Notifications } from './pages/Notifications';
|
||||||
import { Layout } from './components/layout/Layout';
|
import { Layout } from './components/layout/Layout';
|
||||||
|
|
||||||
|
// Roles Pages
|
||||||
|
import RolesListPage from './pages/roles/roles-list/RolesListPage';
|
||||||
|
import RoleFormPage from './pages/roles/role-form/RoleFormPage';
|
||||||
|
import RoleDetailPage from './pages/roles/role-detail/RoleDetailPage';
|
||||||
|
import RolePermissionsPage from './pages/roles/role-permissions/RolePermissionsPage';
|
||||||
|
|
||||||
const ProtectedRoute = ({ children }: { children: any }) => {
|
const ProtectedRoute = ({ children }: { children: any }) => {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
return user ? children : <Navigate to="/login" replace />;
|
return user ? children : <Navigate to="/login" replace />;
|
||||||
|
|
@ -36,6 +42,13 @@ const AppRoutes = () => {
|
||||||
<Route path="orders" element={<Orders />} />
|
<Route path="orders" element={<Orders />} />
|
||||||
<Route path="reports" element={<Reports />} />
|
<Route path="reports" element={<Reports />} />
|
||||||
<Route path="notifications" element={<Notifications />} />
|
<Route path="notifications" element={<Notifications />} />
|
||||||
|
|
||||||
|
{/* Roles Routes */}
|
||||||
|
<Route path="roles" element={<RolesListPage />} />
|
||||||
|
<Route path="roles/create" element={<RoleFormPage />} />
|
||||||
|
<Route path="roles/:id" element={<RoleDetailPage />} />
|
||||||
|
<Route path="roles/:id/edit" element={<RoleFormPage />} />
|
||||||
|
<Route path="roles/:id/permissions" element={<RolePermissionsPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -51,11 +51,11 @@ export const Header = ({ onMenuClick }: HeaderProps) => {
|
||||||
>
|
>
|
||||||
<div className="w-8 h-8 bg-primary-600 rounded-full flex items-center justify-center">
|
<div className="w-8 h-8 bg-primary-600 rounded-full flex items-center justify-center">
|
||||||
<span className="text-white text-sm font-medium">
|
<span className="text-white text-sm font-medium">
|
||||||
{user?.name?.charAt(0) || 'A'}
|
{user?.first_name?.charAt(0) || 'A'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm font-medium text-gray-700 dark:text-gray-300 hidden md:block">
|
<span className="text-sm font-medium text-gray-700 dark:text-gray-300 hidden md:block">
|
||||||
{user?.name || 'کاربر'}
|
{user?.first_name} {user?.last_name}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
@ -64,10 +64,10 @@ export const Header = ({ onMenuClick }: HeaderProps) => {
|
||||||
<div className="py-1">
|
<div className="py-1">
|
||||||
<div className="px-4 py-2 border-b border-gray-200 dark:border-gray-700">
|
<div className="px-4 py-2 border-b border-gray-200 dark:border-gray-700">
|
||||||
<p className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
<p className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||||
{user?.name}
|
{user?.first_name} {user?.last_name}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||||
{user?.email}
|
{user?.username}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button className="w-full text-right px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center">
|
<button className="w-full text-right px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center">
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ import {
|
||||||
FileText,
|
FileText,
|
||||||
Bell,
|
Bell,
|
||||||
X,
|
X,
|
||||||
ChevronDown
|
ChevronDown,
|
||||||
|
Shield
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { useAuth } from '../../contexts/AuthContext';
|
import { useAuth } from '../../contexts/AuthContext';
|
||||||
import { PermissionWrapper } from '../common/PermissionWrapper';
|
import { PermissionWrapper } from '../common/PermissionWrapper';
|
||||||
|
|
@ -28,6 +29,13 @@ const menuItems: MenuItem[] = [
|
||||||
path: '/users',
|
path: '/users',
|
||||||
permission: 10,
|
permission: 10,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'roles',
|
||||||
|
label: 'نقشها',
|
||||||
|
icon: Shield,
|
||||||
|
path: '/roles',
|
||||||
|
permission: 5,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'products',
|
id: 'products',
|
||||||
label: 'محصولات',
|
label: 'محصولات',
|
||||||
|
|
@ -64,7 +72,7 @@ interface SidebarProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Sidebar = ({ isOpen, onClose }: SidebarProps) => {
|
export const Sidebar = ({ isOpen, onClose }: SidebarProps) => {
|
||||||
const { user } = useAuth();
|
const { user, hasPermission } = useAuth();
|
||||||
const [expandedItems, setExpandedItems] = useState<string[]>([]);
|
const [expandedItems, setExpandedItems] = useState<string[]>([]);
|
||||||
|
|
||||||
const toggleExpanded = (itemId: string) => {
|
const toggleExpanded = (itemId: string) => {
|
||||||
|
|
@ -189,15 +197,15 @@ export const Sidebar = ({ isOpen, onClose }: SidebarProps) => {
|
||||||
<div className="flex items-center mb-6 p-3 bg-gray-50 dark:bg-gray-700 rounded-lg">
|
<div className="flex items-center mb-6 p-3 bg-gray-50 dark:bg-gray-700 rounded-lg">
|
||||||
<div className="w-10 h-10 bg-primary-600 rounded-full flex items-center justify-center">
|
<div className="w-10 h-10 bg-primary-600 rounded-full flex items-center justify-center">
|
||||||
<span className="text-white font-medium">
|
<span className="text-white font-medium">
|
||||||
{user?.name?.charAt(0) || 'A'}
|
{user?.first_name?.charAt(0) || 'A'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="mr-3">
|
<div className="mr-3">
|
||||||
<p className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
<p className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||||
{user?.name || 'کاربر'}
|
{user?.first_name} {user?.last_name}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||||
{user?.role || 'مدیر'}
|
{user?.username}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue