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:
Kalana B. Thilakarathna
2026-10-18 23:11:01 +05:30
parent 558afc6f9d
commit 0052725b88
86 changed files with 41117 additions and 939 deletions
+85 -77
View File
@@ -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>
)