layout access admin and manager

This commit is contained in:
David 2025-11-30 13:48:04 +01:00
parent cca6eda9d3
commit 591213aaf7
3 changed files with 27 additions and 4 deletions

View File

@ -164,9 +164,10 @@ export class UsersController {
* Get user by ID * Get user by ID
*/ */
@Get(':id') @Get(':id')
@Roles('admin', 'manager')
@ApiOperation({ @ApiOperation({
summary: 'Get user by ID', summary: 'Get user by ID',
description: 'Retrieve user details. Users can view users in their org, admins can view any.', description: 'Retrieve user details. Only ADMIN and MANAGER can access this endpoint.',
}) })
@ApiParam({ @ApiParam({
name: 'id', name: 'id',
@ -324,10 +325,11 @@ export class UsersController {
* List users in organization * List users in organization
*/ */
@Get() @Get()
@Roles('admin', 'manager')
@ApiOperation({ @ApiOperation({
summary: 'List users', summary: 'List users',
description: description:
'Retrieve a paginated list of users in your organization. Admins can see all users.', 'Retrieve a paginated list of users in your organization. Only ADMIN and MANAGER can access this endpoint.',
}) })
@ApiQuery({ @ApiQuery({
name: 'page', name: 'page',

View File

@ -24,7 +24,10 @@ export default function DashboardLayout({ children }: { children: React.ReactNod
{ name: 'Search Rates', href: '/dashboard/search-advanced', icon: '🔎' }, { name: 'Search Rates', href: '/dashboard/search-advanced', icon: '🔎' },
{ name: 'My Profile', href: '/dashboard/profile', icon: '👤' }, { name: 'My Profile', href: '/dashboard/profile', icon: '👤' },
{ name: 'Organization', href: '/dashboard/settings/organization', icon: '🏢' }, { name: 'Organization', href: '/dashboard/settings/organization', icon: '🏢' },
{ name: 'Users', href: '/dashboard/settings/users', icon: '👥' }, // ADMIN and MANAGER only navigation items
...(user?.role === 'ADMIN' || user?.role === 'MANAGER' ? [
{ name: 'Users', href: '/dashboard/settings/users', icon: '👥' },
] : []),
// ADMIN only navigation items // ADMIN only navigation items
...(user?.role === 'ADMIN' ? [ ...(user?.role === 'ADMIN' ? [
{ name: 'CSV Rates', href: '/dashboard/admin/csv-rates', icon: '📄' }, { name: 'CSV Rates', href: '/dashboard/admin/csv-rates', icon: '📄' },

View File

@ -6,13 +6,15 @@
'use client'; 'use client';
import { useState } from 'react'; import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { listUsers, updateUser, deleteUser } from '@/lib/api'; import { listUsers, updateUser, deleteUser } from '@/lib/api';
import { createInvitation } from '@/lib/api/invitations'; import { createInvitation } from '@/lib/api/invitations';
import { useAuth } from '@/lib/context/auth-context'; import { useAuth } from '@/lib/context/auth-context';
export default function UsersManagementPage() { export default function UsersManagementPage() {
const router = useRouter();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const { user: currentUser } = useAuth(); const { user: currentUser } = useAuth();
const [showInviteModal, setShowInviteModal] = useState(false); const [showInviteModal, setShowInviteModal] = useState(false);
@ -100,6 +102,22 @@ export default function UsersManagementPage() {
}, },
}); });
// Restrict access to ADMIN and MANAGER only
useEffect(() => {
if (currentUser && currentUser.role !== 'ADMIN' && currentUser.role !== 'MANAGER') {
router.push('/dashboard');
}
}, [currentUser, router]);
// Don't render until we've checked permissions
if (!currentUser || (currentUser.role !== 'ADMIN' && currentUser.role !== 'MANAGER')) {
return (
<div className="flex items-center justify-center min-h-screen">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
</div>
);
}
const handleInvite = (e: React.FormEvent) => { const handleInvite = (e: React.FormEvent) => {
e.preventDefault(); e.preventDefault();
setError(''); setError('');