feat: add user and role view sheets with detailed information display
- Created UserViewSheet component to display user details including username, full name, role, status, and timestamps. - Created RoleViewSheet component to display role details including name, level, status, creation date, and associated permissions. - Introduced permissions configuration in a new permissions.ts file, defining categories and permission codes for better management. - Implemented middleware for authentication, ensuring access control for protected routes.
This commit is contained in:
@@ -1,101 +1,109 @@
|
||||
'use client'
|
||||
|
||||
import { createContext, useContext, useState, type ReactNode } from 'react'
|
||||
import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { api, registerUnauthorizedHandler } from '@/lib/api'
|
||||
|
||||
export type Role = 'admin' | 'warehouse' | 'sales'
|
||||
|
||||
export interface MockUser {
|
||||
id: string
|
||||
fullName: string
|
||||
export interface User {
|
||||
userId: string
|
||||
username: string
|
||||
roleId: string
|
||||
role: Role
|
||||
roleCode: string
|
||||
roleLevel: number
|
||||
}
|
||||
|
||||
interface AuthContextValue {
|
||||
user: MockUser
|
||||
permissions: string[]
|
||||
setRole: (role: Role) => void
|
||||
user: User | null
|
||||
permissions: Set<string>
|
||||
loading: boolean
|
||||
login: (identifier: string, password: string) => Promise<void>
|
||||
logout: () => Promise<void>
|
||||
hasPermission: (code: string) => boolean
|
||||
}
|
||||
|
||||
// Mock permissions per role — replace with real API call once auth is implemented
|
||||
const MOCK_PERMISSIONS: Record<Role, string[]> = {
|
||||
admin: ['*'],
|
||||
warehouse: [
|
||||
'items.view',
|
||||
'categories.view',
|
||||
'regions.view',
|
||||
'routes.view',
|
||||
'vehicles.view',
|
||||
'warehouses.view',
|
||||
'loading.view',
|
||||
'loading.dispatch',
|
||||
'loading.receive',
|
||||
'loading.resolve',
|
||||
'rides.view',
|
||||
'rides.manage',
|
||||
'rides.cancel.request',
|
||||
'driver_profiles.view',
|
||||
'compliance.manage',
|
||||
],
|
||||
sales: [
|
||||
'stores.view',
|
||||
'stores.create',
|
||||
'stores.update',
|
||||
'orders.view',
|
||||
'orders.create',
|
||||
'orders.update',
|
||||
'items.view',
|
||||
'categories.view',
|
||||
'regions.view',
|
||||
'routes.view',
|
||||
'rides.view',
|
||||
'driver_profiles.view',
|
||||
'sales_visits.checkin',
|
||||
],
|
||||
const PERMISSIONS_KEY = 'app:permissions'
|
||||
|
||||
function savePermissions(perms: string[]): void {
|
||||
try {
|
||||
localStorage.setItem(PERMISSIONS_KEY, JSON.stringify(perms))
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const MOCK_USERS: Record<Role, MockUser> = {
|
||||
admin: {
|
||||
id: '00000000-0000-0000-0000-000000000001',
|
||||
fullName: 'Admin User',
|
||||
username: 'admin',
|
||||
roleId: '00000000-0000-0000-0000-000000000010',
|
||||
role: 'admin',
|
||||
},
|
||||
warehouse: {
|
||||
id: '00000000-0000-0000-0000-000000000002',
|
||||
fullName: 'Warehouse Staff',
|
||||
username: 'warehouse',
|
||||
roleId: '00000000-0000-0000-0000-000000000011',
|
||||
role: 'warehouse',
|
||||
},
|
||||
sales: {
|
||||
id: '00000000-0000-0000-0000-000000000003',
|
||||
fullName: 'Sales Rep',
|
||||
username: 'sales',
|
||||
roleId: '00000000-0000-0000-0000-000000000012',
|
||||
role: 'sales',
|
||||
},
|
||||
function readPermissions(): Set<string> {
|
||||
try {
|
||||
const raw = localStorage.getItem(PERMISSIONS_KEY)
|
||||
if (raw) return new Set(JSON.parse(raw) as string[])
|
||||
} catch {}
|
||||
return new Set()
|
||||
}
|
||||
|
||||
function clearPermissions(): void {
|
||||
try {
|
||||
localStorage.removeItem(PERMISSIONS_KEY)
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextValue | null>(null)
|
||||
|
||||
export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
const [role, setRoleState] = useState<Role>('admin')
|
||||
const router = useRouter()
|
||||
const [user, setUser] = useState<User | null>(null)
|
||||
const [permissions, setPermissions] = useState<Set<string>>(new Set())
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
function setRole(newRole: Role) {
|
||||
setRoleState(newRole)
|
||||
const loadSession = useCallback(async () => {
|
||||
setLoading(true)
|
||||
try {
|
||||
const { data } = await api.get<User>('/auth/me')
|
||||
setUser(data)
|
||||
setPermissions(readPermissions())
|
||||
} catch {
|
||||
setUser(null)
|
||||
setPermissions(new Set())
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
loadSession()
|
||||
}, [loadSession])
|
||||
|
||||
useEffect(() => {
|
||||
return registerUnauthorizedHandler(() => {
|
||||
clearPermissions()
|
||||
setUser(null)
|
||||
setPermissions(new Set())
|
||||
router.push('/login')
|
||||
})
|
||||
}, [router])
|
||||
|
||||
async function login(identifier: string, password: string) {
|
||||
const { data: loginData } = await api.post<{ profile: User }>('/auth/login', { identifier, password, deviceName: 'Web' })
|
||||
setUser(loginData.profile)
|
||||
const { data: permData } = await api.get<{ permissions: string[] }>('/authorization/my-permissions')
|
||||
savePermissions(permData.permissions)
|
||||
setPermissions(new Set(permData.permissions))
|
||||
router.push('/')
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
try {
|
||||
await api.post('/auth/logout')
|
||||
} finally {
|
||||
clearPermissions()
|
||||
setUser(null)
|
||||
setPermissions(new Set())
|
||||
router.push('/login')
|
||||
}
|
||||
}
|
||||
|
||||
function hasPermission(code: string): boolean {
|
||||
return permissions.has(code)
|
||||
}
|
||||
|
||||
return (
|
||||
<AuthContext.Provider
|
||||
value={{
|
||||
user: MOCK_USERS[role],
|
||||
permissions: MOCK_PERMISSIONS[role],
|
||||
setRole,
|
||||
}}
|
||||
>
|
||||
<AuthContext.Provider value={{ user, permissions, loading, login, logout, hasPermission }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user