- Add NavigationController for centralized routing logic - Add useNavigationFlow hook for easy usage in components - Update subscription flow with Stripe integration - Simplify activate.tsx - Update beneficiaries and profile screens - Update CLAUDE.md with navigation documentation
180 lines
4.7 KiB
TypeScript
180 lines
4.7 KiB
TypeScript
/**
|
|
* 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, replace = false) => {
|
|
const href = result.params
|
|
? { pathname: result.path, params: result.params }
|
|
: result.path;
|
|
|
|
if (replace) {
|
|
router.replace(href as any);
|
|
} else {
|
|
router.push(href as any);
|
|
}
|
|
}, [router]);
|
|
|
|
/**
|
|
* Navigate after successful login/OTP verification
|
|
*/
|
|
const navigateAfterLogin = useCallback((
|
|
profile: UserProfile | null,
|
|
beneficiaries: Beneficiary[]
|
|
) => {
|
|
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,
|
|
hasExistingDevices: boolean
|
|
) => {
|
|
const result = NavigationController.getRouteAfterAddBeneficiary(
|
|
beneficiaryId,
|
|
hasExistingDevices
|
|
);
|
|
navigate(result);
|
|
}, [navigate]);
|
|
|
|
/**
|
|
* Navigate after purchase completion
|
|
*/
|
|
const navigateAfterPurchase = useCallback((
|
|
beneficiaryId: number,
|
|
options: { skipToActivate?: boolean; demo?: boolean } = {}
|
|
) => {
|
|
const result = NavigationController.getRouteAfterPurchase(beneficiaryId, options);
|
|
navigate(result);
|
|
}, [navigate]);
|
|
|
|
/**
|
|
* Navigate after device activation
|
|
*/
|
|
const navigateAfterActivation = useCallback((beneficiaryId: number) => {
|
|
const result = NavigationController.getRouteAfterActivation(beneficiaryId);
|
|
navigate(result, true); // replace to prevent going back
|
|
}, [navigate]);
|
|
|
|
/**
|
|
* Navigate to beneficiary-specific screens
|
|
*/
|
|
const navigateToBeneficiary = useCallback((
|
|
beneficiary: Beneficiary,
|
|
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) => {
|
|
const result = NavigationController.getRouteForBeneficiarySetup(beneficiary);
|
|
navigate(result);
|
|
}, [navigate]);
|
|
|
|
/**
|
|
* Navigate to specific route
|
|
*/
|
|
const goTo = useCallback((
|
|
path: string,
|
|
params?: Record<string, string | number | boolean>,
|
|
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) => {
|
|
navigate({
|
|
path: ROUTES.AUTH.PURCHASE,
|
|
params: { beneficiaryId },
|
|
});
|
|
}, [navigate]);
|
|
|
|
const goToActivate = useCallback((beneficiaryId: number, demo?: boolean) => {
|
|
navigate({
|
|
path: ROUTES.AUTH.ACTIVATE,
|
|
params: { beneficiaryId, demo },
|
|
});
|
|
}, [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;
|