Files
circle-collect/src/screens/SplashScreen.tsx
T
2025-09-22 13:54:57 +05:30

126 lines
4.1 KiB
TypeScript

import React, { useEffect, useRef, useState } from "react";
import { View, StyleSheet, ActivityIndicator, Animated, Alert } from "react-native";
import * as Keychain from "react-native-keychain";
import { useNavigation } from "@react-navigation/native";
import { StackNavigationProp } from "@react-navigation/stack";
import { useDispatch } from "react-redux";
// --- Import your project files ---
import { RootStackParamList } from "../navigation/AppNavigator"; // Adjust path
import { BASE_URL } from "../utils/ApiUrls";
import { fetchUserProfile } from "../utils/HelperFunction";
import { setUserData } from "../redux/userSlice";
import colors from "../components/colors";
import { ApiResponse } from "./home/UserProfileStatus";
const SplashScreen = () => {
const navigation = useNavigation<StackNavigationProp<RootStackParamList>>();
const dispatch = useDispatch();
const fadeAnim = useRef(new Animated.Value(1)).current;
// State to track the outcome of initialization
const [isReady, setIsReady] = useState(false);
const [isLoggedIn, setIsLoggedIn] = useState(false);
useEffect(() => {
// A single function to handle all startup tasks
const initializeApp = async () => {
try {
// 1. Check for stored credentials
const credentials = await Keychain.getGenericPassword();
if (!credentials) {
console.log("No credentials found. User needs to log in.");
setIsLoggedIn(false);
return; // Stop here if not logged in
}
console.log("🔑 Credentials found. Proceeding with user data fetches.");
const { password: token } = credentials;
// 2. Fetch all necessary data in parallel for efficiency
const [statusResponse, userProfile] = await Promise.all([
fetch(`${BASE_URL}user/profile/status`, {
method: "GET",
headers: {
Accept: "*/*",
Authorization: `Bearer ${token}`,
},
}),
fetchUserProfile(dispatch), // Assuming fetchUserProfile handles its own errors and dispatches to Redux
]);
// 3. Process the profile status response
if (!statusResponse.ok) {
throw new Error(`Server responded with status: ${statusResponse.status}`);
}
const statusJson: ApiResponse = await statusResponse.json();
console.log("👤 Profile Status Response:", statusJson);
if (statusJson.status === "success") {
// You could dispatch more data here if needed
// dispatch(setUserData(statusJson.data));
setIsLoggedIn(true);
} else {
throw new Error(statusJson.message || "Failed to verify user status.");
}
} catch (error) {
console.error("Initialization failed:", error);
Alert.alert("Error", "Your session may have expired. Please log in again.");
setIsLoggedIn(false); // Ensure login status is false on any error
} finally {
// 4. Signal that all tasks are done, whether they succeeded or failed
setIsReady(true);
}
};
// Trigger the animation, and run initialization logic after it completes
Animated.timing(fadeAnim, {
toValue: 0,
duration: 1500,
useNativeDriver: true,
delay: 1500,
}).start(() => {
initializeApp();
});
}, [fadeAnim, dispatch]);
// This effect handles the final navigation step once everything is ready
useEffect(() => {
if (isReady) {
if (isLoggedIn) {
navigation.replace("Home");
} else {
navigation.replace("Login");
}
}
}, [isReady, isLoggedIn, navigation]);
return (
<View style={styles.container}>
<Animated.Text style={[styles.title, { opacity: fadeAnim }]}>
Circle Collect
</Animated.Text>
<ActivityIndicator size="large" color={colors.Home} style={{ marginTop: 20 }} />
</View>
);
};
export default SplashScreen;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#FFFFFF",
},
title: {
fontSize: 28,
fontWeight: "800",
color: colors.Home,
letterSpacing: 1,
},
});