/** * useNavigationFlow - React hook for centralized navigation * * This hook wraps NavigationController and provides easy-to-use * navigation methods for components. * * USAGE: * const nav = useNavigationFlow(); * nav.navigateAfterLogin(profile, beneficiaries); * nav.navigateAfterAddBeneficiary(42, false); */ import { useCallback } from 'react'; import { useRouter } from 'expo-router'; import { NavigationController, ROUTES, type NavigationResult, type UserProfile } from '@/services/NavigationController'; import type { Beneficiary } from '@/types'; export function useNavigationFlow() { const router = useRouter(); /** * Execute navigation based on NavigationResult */ const navigate = useCallback((result: NavigationResult | null | undefined, replace = false) => { // Null safety: validate navigation result if (!result || !result.path) { console.warn('[useNavigationFlow] Invalid navigation result:', result); return; } const href = result.params ? { pathname: result.path, params: result.params } : result.path; try { if (replace) { router.replace(href as any); } else { router.push(href as any); } } catch (error) { console.error('[useNavigationFlow] Navigation error:', error); } }, [router]); /** * Navigate after successful login/OTP verification */ const navigateAfterLogin = useCallback(( profile: UserProfile | null | undefined, beneficiaries: Beneficiary[] | null | undefined ) => { const result = NavigationController.getRouteAfterLogin(profile, beneficiaries); navigate(result, true); // replace to prevent going back to login }, [navigate]); /** * Navigate after creating a new beneficiary */ const navigateAfterAddBeneficiary = useCallback(( beneficiaryId: number | null | undefined, hasExistingDevices: boolean ) => { const result = NavigationController.getRouteAfterAddBeneficiary( beneficiaryId, hasExistingDevices ); navigate(result); }, [navigate]); /** * Navigate after purchase completion */ const navigateAfterPurchase = useCallback(( beneficiaryId: number | null | undefined, options: { skipToActivate?: boolean; demo?: boolean } | null | undefined = {} ) => { const result = NavigationController.getRouteAfterPurchase(beneficiaryId, options); navigate(result); }, [navigate]); /** * Navigate after device activation */ const navigateAfterActivation = useCallback((beneficiaryId: number | null | undefined) => { const result = NavigationController.getRouteAfterActivation(beneficiaryId); navigate(result, true); // replace to prevent going back }, [navigate]); /** * Navigate to beneficiary-specific screens */ const navigateToBeneficiary = useCallback(( beneficiary: Beneficiary | null | undefined, action: 'view' | 'subscription' | 'equipment' | 'share' = 'view' ) => { const result = NavigationController.getBeneficiaryRoute(beneficiary, action); navigate(result); }, [navigate]); /** * Navigate to beneficiary setup flow (purchase or activate) */ const navigateToBeneficiarySetup = useCallback((beneficiary: Beneficiary | null | undefined) => { const result = NavigationController.getRouteForBeneficiarySetup(beneficiary); navigate(result); }, [navigate]); /** * Navigate to specific route */ const goTo = useCallback(( path: string, params?: Record, replace = false ) => { navigate({ path, params }, replace); }, [navigate]); /** * Quick navigation shortcuts */ const goToDashboard = useCallback(() => { navigate({ path: ROUTES.TABS.DASHBOARD }, true); }, [navigate]); const goToLogin = useCallback(() => { navigate({ path: ROUTES.AUTH.LOGIN }, true); }, [navigate]); const goToAddBeneficiary = useCallback(() => { navigate({ path: ROUTES.AUTH.ADD_LOVED_ONE }); }, [navigate]); const goToPurchase = useCallback((beneficiaryId: number | null | undefined) => { // Null safety: only navigate if beneficiaryId is valid if (!beneficiaryId || typeof beneficiaryId !== 'number') { console.warn('[useNavigationFlow] Invalid beneficiaryId for purchase:', beneficiaryId); return; } navigate({ path: ROUTES.AUTH.PURCHASE, params: { beneficiaryId }, }); }, [navigate]); const goToActivate = useCallback((beneficiaryId: number | null | undefined, demo?: boolean) => { // Null safety: only navigate if beneficiaryId is valid if (!beneficiaryId || typeof beneficiaryId !== 'number') { console.warn('[useNavigationFlow] Invalid beneficiaryId for activation:', beneficiaryId); return; } navigate({ path: ROUTES.AUTH.ACTIVATE, params: demo !== undefined ? { beneficiaryId, demo } : { beneficiaryId }, }); }, [navigate]); const goToProfile = useCallback(() => { navigate({ path: ROUTES.TABS.PROFILE }); }, [navigate]); const goToEditProfile = useCallback(() => { navigate({ path: ROUTES.PROFILE.EDIT }); }, [navigate]); return { // Core navigation methods navigate, goTo, // Flow-based navigation navigateAfterLogin, navigateAfterAddBeneficiary, navigateAfterPurchase, navigateAfterActivation, // Beneficiary navigation navigateToBeneficiary, navigateToBeneficiarySetup, // Quick shortcuts goToDashboard, goToLogin, goToAddBeneficiary, goToPurchase, goToActivate, goToProfile, goToEditProfile, // Direct access to routes ROUTES, // Direct access to controller for advanced use controller: NavigationController, }; } export default useNavigationFlow;