ui-nyla/src/hooks/useUsers.ts
2025-09-03 21:49:23 +02:00

186 lines
No EOL
4.2 KiB
TypeScript

import { useState, useEffect } from 'react';
import { useApiRequest } from './useApi';
// User interfaces
export interface User {
id: string;
username: string;
email: string;
fullName: string;
language: string;
enabled: boolean;
privilege: string;
authenticationAuthority: string;
mandateId: string;
}
export type UserUpdateData = Partial<Omit<User, 'id' | 'mandateId'>>;
// Current user hook
export function useCurrentUser() {
const [user, setUser] = useState<User | null>(null);
const { request, isLoading, error } = useApiRequest<null, User>();
const fetchCurrentUser = async () => {
try {
const data = await request({
url: '/api/local/me',
method: 'get'
});
setUser(data);
} catch (error) {
setUser(null);
}
};
const logout = async (msalInstance?: any) => {
if (!user) {
throw new Error('No user to logout');
}
try {
let logoutEndpoint = '/api/local/logout';
// Determine the correct logout endpoint based on authentication authority
if (user.authenticationAuthority === 'msft') {
logoutEndpoint = '/api/msft/logout';
} else if (user.authenticationAuthority === 'local') {
logoutEndpoint = '/api/local/logout';
}
await request({
url: logoutEndpoint,
method: 'post'
});
// Clear user state after successful logout
setUser(null);
// Clear any local storage data
localStorage.clear();
// Handle MSAL logout for Microsoft authentication
if (user.authenticationAuthority === 'msft' && msalInstance) {
try {
await msalInstance.logoutRedirect({
onRedirectNavigate: () => true
});
return; // MSAL will handle the redirect
} catch (msalError) {
console.error('MSAL logout failed:', msalError);
// Continue with regular redirect if MSAL logout fails
}
}
// Redirect to login or home page
window.location.href = '/login';
} catch (error) {
console.error('Logout failed:', error);
throw error;
}
};
useEffect(() => {
fetchCurrentUser();
}, []);
return {
user,
error,
isLoading,
refetch: fetchCurrentUser,
logout
};
}
// Organization users hook (list, update, delete)
export function useOrgUsers() {
const [users, setUsers] = useState<User[]>([]);
const { request, isLoading: loading, error } = useApiRequest();
const fetchUsers = async () => {
try {
const data = await request({
url: '/api/users/',
method: 'get'
});
setUsers(data);
} catch (error) {
// Error is already handled by useApiRequest
}
};
const updateUser = async (userId: string, userData: User) => {
await request({
url: `/api/users/${userId}`,
method: 'put',
data: userData
});
await fetchUsers(); // Refresh the list after update
};
const deleteUser = async (userId: string) => {
await request({
url: `/api/users/${userId}`,
method: 'delete'
});
await fetchUsers(); // Refresh the list after deletion
};
const getUser = async (userId: string): Promise<User> => {
return await request({
url: `/api/users/${userId}`,
method: 'get'
});
};
useEffect(() => {
fetchUsers();
}, []);
return {
users,
loading,
error,
refetch: fetchUsers,
updateUser,
deleteUser,
getUser
};
}
// Individual user operations hook (for use when you don't need the full list)
export function useUser() {
const { request, isLoading, error } = useApiRequest();
const getUser = async (userId: string): Promise<User> => {
return await request({
url: `/api/users/${userId}`,
method: 'get'
});
};
const updateUser = async (userId: string, userData: User): Promise<User> => {
return await request({
url: `/api/users/${userId}`,
method: 'put',
data: userData
});
};
const deleteUser = async (userId: string): Promise<void> => {
await request({
url: `/api/users/${userId}`,
method: 'delete'
});
};
return {
getUser,
updateUser,
deleteUser,
isLoading,
error
};
}