before merge
This commit is contained in:
+211
-27
@@ -1,40 +1,224 @@
|
||||
import { View, Text } from 'react-native';
|
||||
import React, { useEffect } from 'react';
|
||||
import FontsFamily from '../../Constant/FontsFamily';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import NavigationString from '../../Constant/NavigationString';
|
||||
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
||||
import { Animated, StyleSheet, View } from 'react-native';
|
||||
import { useNavigation, useIsFocused } from '@react-navigation/native';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useStore } from 'react-redux'; // For hydration check
|
||||
|
||||
const Splash = () => {
|
||||
const navigation: any = useNavigation();
|
||||
const Token = useSelector((state: any) => state.token.token)
|
||||
import { showToast } from '../../Constant/ShowDailog';
|
||||
import { useRagistrationState } from '../../Services/BBPS/Hooks';
|
||||
import NavigationString from '../../Constant/NavigationString';
|
||||
|
||||
const handleSplashNavigation = async () => {
|
||||
try {
|
||||
const isOnboardingDone = await AsyncStorage.getItem('onBoarding');
|
||||
if (isOnboardingDone != 'true') {
|
||||
navigation.replace(NavigationString.Onboarding);
|
||||
} else if (Token.token) {
|
||||
navigation.replace(NavigationString.Home);
|
||||
} else {
|
||||
navigation.replace(NavigationString.Login);
|
||||
}
|
||||
} catch (error) {
|
||||
navigation.replace(NavigationString.Onboarding);
|
||||
}
|
||||
};
|
||||
// Navigation type
|
||||
export type Navigation = {
|
||||
reset(arg0: {
|
||||
index: number;
|
||||
routes: { name: string; }[];
|
||||
}): unknown;
|
||||
navigate: (route: string, params?: { [key: string]: any }) => void;
|
||||
replace: (route: string, params?: { [key: string]: any }) => void;
|
||||
};
|
||||
|
||||
const Splash: React.FC = () => {
|
||||
const navigation = useNavigation() as Navigation;
|
||||
const isFocused = useIsFocused();
|
||||
const fadeAnim = useRef(new Animated.Value(0)).current;
|
||||
const reduxToken = useSelector((state: any) => state.token?.token);
|
||||
const store = useStore();
|
||||
const { mutateAsync: registrationStateMutate } = useRagistrationState();
|
||||
const [isHydrated, setIsHydrated] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
// Wait for Redux hydration (works with/without redux-persist)
|
||||
useEffect(() => {
|
||||
handleSplashNavigation()
|
||||
let unsubscribe: any;
|
||||
const checkHydration = () => {
|
||||
const token = (store.getState() as any).token?.token;
|
||||
if (token !== undefined) { // Defined = hydrated (null/empty/string ok)
|
||||
setIsHydrated(true);
|
||||
unsubscribe?.();
|
||||
}
|
||||
};
|
||||
|
||||
unsubscribe = store.subscribe(checkHydration);
|
||||
checkHydration(); // Check immediately
|
||||
|
||||
return () => unsubscribe?.();
|
||||
}, []);
|
||||
|
||||
const getToken = useCallback(async (): Promise<string | null> => {
|
||||
try {
|
||||
// Redux first (post-hydration), then AsyncStorage fallback
|
||||
let token = reduxToken;
|
||||
if (token === undefined) {
|
||||
token = await AsyncStorage.getItem('token');
|
||||
}
|
||||
return token || null;
|
||||
} catch (error) {
|
||||
console.error('Token fetch error:', error);
|
||||
return null;
|
||||
}
|
||||
}, [reduxToken]);
|
||||
|
||||
const routeByOrgType = (params: { otherId: any; orgType: any }) => {
|
||||
const orgType = String(params.orgType);
|
||||
|
||||
if (orgType === '4' || orgType === '5' || orgType === '6') {
|
||||
navigation.replace('StageThree', params);
|
||||
return;
|
||||
}
|
||||
|
||||
if (orgType === '7') {
|
||||
navigation.replace('PartnerShip', params);
|
||||
return;
|
||||
}
|
||||
|
||||
navigation.replace('Dashboard');
|
||||
};
|
||||
|
||||
const handleGetData = async () => {
|
||||
try {
|
||||
const res = await registrationStateMutate();
|
||||
console.log('Registration status response:', res?.statusCode);
|
||||
|
||||
if (res?.statusCode === 404 || res?.statusCode === 401) {
|
||||
navigation.replace('Registration');
|
||||
return;
|
||||
}
|
||||
|
||||
if (res?.statusCode === 200 && res?.data) {
|
||||
const { registrationStatus, contOtherId, contOrganization } = res.data;
|
||||
const params = { otherId: contOtherId, orgType: contOrganization };
|
||||
console.log('Registration status:', registrationStatus);
|
||||
|
||||
switch (registrationStatus) {
|
||||
case null:
|
||||
case undefined:
|
||||
navigation.replace(NavigationString.Registration);
|
||||
break;
|
||||
case 'Pending':
|
||||
routeByOrgType(params);
|
||||
break;
|
||||
case 'Complete':
|
||||
case 'Completed':
|
||||
navigation.replace(NavigationString.Home);
|
||||
break;
|
||||
default:
|
||||
navigation.replace(NavigationString.Registration);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
console.error('API error:', res);
|
||||
showToast(res?.message || 'Something went wrong');
|
||||
navigation.replace('Registration');
|
||||
} catch (error: any) {
|
||||
console.error('Registration status error:', error);
|
||||
showToast(error?.message || 'Something went wrong');
|
||||
|
||||
if (error?.response?.status === 404) {
|
||||
navigation.replace('Registration');
|
||||
} else {
|
||||
await AsyncStorage.removeItem('token');
|
||||
navigation.replace('Signin');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!isFocused || !isHydrated) return;
|
||||
|
||||
const runSplash = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
Animated.timing(fadeAnim, {
|
||||
toValue: 1,
|
||||
duration: 500,
|
||||
useNativeDriver: true,
|
||||
}).start();
|
||||
|
||||
const token = await getToken();
|
||||
console.log("Token after hydration -", token, typeof token, !!token);
|
||||
|
||||
if (!token) {
|
||||
console.log('No valid token, navigating to Login');
|
||||
navigation.reset({
|
||||
index: 0,
|
||||
routes: [{ name: NavigationString.Login || 'Signin' }], // Fallback
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Valid token, fetching registration data');
|
||||
await handleGetData();
|
||||
} catch (error) {
|
||||
console.error('Splash Error:', error);
|
||||
navigation.reset({
|
||||
index: 0,
|
||||
routes: [{ name: NavigationString.Login || 'Signin' }],
|
||||
});
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Small delay ensures hydration + native animation complete
|
||||
const timeoutId = setTimeout(runSplash, 200);
|
||||
return () => clearTimeout(timeoutId);
|
||||
}, [isFocused, isHydrated, getToken]);
|
||||
|
||||
if (!isHydrated) {
|
||||
return (
|
||||
<View style={styles.loadingContainer}>
|
||||
<Animated.Image
|
||||
source={require('../../Images/logo.png')}
|
||||
style={[styles.logo, { opacity: fadeAnim }]}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
||||
<Text style={{ fontFamily: FontsFamily.poppinsBlack }}>
|
||||
Splash
|
||||
</Text>
|
||||
<View style={styles.appView}>
|
||||
<View style={styles.container}>
|
||||
<Animated.Image
|
||||
source={require('../../Images/logo.png')}
|
||||
style={[styles.logo, { opacity: fadeAnim }]}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
{isLoading && (
|
||||
<View style={{ marginTop: 20 }}>
|
||||
{/* Optional spinner */}
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default Splash;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
appView: {
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
logo: {
|
||||
width: 160,
|
||||
height: 160,
|
||||
marginBottom: 20,
|
||||
},
|
||||
loadingContainer: {
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user