import { useCallback } from 'react'; import { usePersSDK } from '../providers/PersSDKProvider'; import type { UserDTO, UserCreateRequestDTO, PaginatedResponseDTO } from '@explorins/pers-sdk'; import type { UserPublicProfileDTO, UserQueryOptions } from '@explorins/pers-sdk/user'; // Re-export for consumers export type { UserQueryOptions } from '@explorins/pers-sdk/user'; export const useUsers = () => { const { sdk, isInitialized, isAuthenticated } = usePersSDK(); /** * Get the current authenticated user with optional include relations * * @param options - Query options including include relations * @returns Current user data * * @example * ```typescript * // Basic * const user = await getCurrentUser(); * * // With wallets included * const userWithWallets = await getCurrentUser({ include: ['wallets'] }); * console.log('Wallets:', userWithWallets.included?.wallets); * ``` */ const getCurrentUser = useCallback(async (options?: UserQueryOptions): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } if (!isAuthenticated) { throw new Error('SDK not authenticated. getCurrentUser requires authentication.'); } try { const result = await sdk.users.getCurrentUser(options); return result; } catch (error) { console.error('Failed to fetch current user:', error); throw error; } }, [sdk, isInitialized, isAuthenticated]); const updateCurrentUser = useCallback(async (userData: UserCreateRequestDTO): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } if (!isAuthenticated) { throw new Error('SDK not authenticated. updateCurrentUser requires authentication.'); } try { const result = await sdk.users.updateCurrentUser(userData); return result; } catch (error) { console.error('Failed to update current user:', error); throw error; } }, [sdk, isInitialized, isAuthenticated]); /** * Get user by ID with optional include relations * * @param userId - User identifier (id, email, externalId, etc.) * @param options - Query options including include relations * @returns User data * * @example * ```typescript * // Basic * const user = await getUserById('user-123'); * * // With wallets included * const userWithWallets = await getUserById('user-123', { include: ['wallets'] }); * ``` */ const getUserById = useCallback(async (userId: string, options?: UserQueryOptions): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.users.getUserById(userId, options); return result; } catch (error) { console.error('Failed to fetch user:', error); throw error; } }, [sdk, isInitialized]); const getAllUsersPublic = useCallback(async (filter?: { key: string; value: string }): Promise> => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.users.getAllUsersPublic(filter); return result; } catch (error) { console.error('Failed to fetch public users:', error); throw error; } }, [sdk, isInitialized]); // Admin methods const getAllUsers = useCallback(async (): Promise> => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.users.getAllUsers(); return result; } catch (error) { console.error('Failed to fetch all users:', error); throw error; } }, [sdk, isInitialized]); const updateUser = useCallback(async (userId: string, userData: UserCreateRequestDTO): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.users.updateUser(userId, userData); return result; } catch (error) { console.error('Failed to update user:', error); throw error; } }, [sdk, isInitialized]); /** * Toggle or set a user's active status (admin only) * * @param userId - User ID to update * @param isActive - Optional explicit status. If omitted, toggles current status. * @returns Updated user */ const setUserActiveStatus = useCallback(async (userId: string, isActive?: boolean): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.users.setUserActiveStatus(userId, isActive); return result; } catch (error) { console.error('Failed to set user active status:', error); throw error; } }, [sdk, isInitialized]); return { getCurrentUser, updateCurrentUser, getUserById, getAllUsersPublic, getAllUsers, updateUser, setUserActiveStatus, isAvailable: isInitialized && !!sdk?.users, }; }; export type UserHook = ReturnType;