165 lines
4.9 KiB
TypeScript
165 lines
4.9 KiB
TypeScript
import React, { useEffect, useRef } from "react";
|
|
import { View, Text, StyleSheet, ActivityIndicator, Animated, Alert } from "react-native";
|
|
import * as Keychain from "react-native-keychain";
|
|
import { StackNavigationProp } from "@react-navigation/stack";
|
|
import { useNavigation } from "@react-navigation/native";
|
|
import { RootStackParamList } from "../navigation/AppNavigator"; // adjust path
|
|
import { BASE_URL } from "../utils/ApiUrls";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import { setUserData } from "../redux/userSlice";
|
|
import colors from "../components/colors";
|
|
import { ApiResponse } from "./home/UserProfileStatus";
|
|
|
|
const SplashScreen = () => {
|
|
const dispatch = useDispatch();
|
|
const user = useSelector((state: any) => state.user);
|
|
const navigation = useNavigation<StackNavigationProp<RootStackParamList>>();
|
|
const fadeAnim = useRef(new Animated.Value(1)).current;
|
|
|
|
|
|
const fetchUserProfile = async () => {
|
|
try {
|
|
const credentials = await Keychain.getGenericPassword();
|
|
if (!credentials) {
|
|
Alert.alert("Error", "You are not logged in");
|
|
return;
|
|
}
|
|
const token = credentials.password;
|
|
|
|
const response = await fetch(
|
|
`${BASE_URL}user/profile/view`,
|
|
{
|
|
method: "GET",
|
|
headers: {
|
|
Accept: "*/*",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
}
|
|
);
|
|
|
|
const result = await response.json();
|
|
if (result.status === "success") {
|
|
dispatch(setUserData({
|
|
id: result?.data.id,
|
|
userId: result?.data.userId,
|
|
username: result?.data.username,
|
|
firstName: result?.data.firstName,
|
|
lastName: result?.data.lastName,
|
|
gender: result?.data.gender,
|
|
mobile: result?.data.mobile,
|
|
email: result?.data.email,
|
|
address: result?.data.address,
|
|
bankAccountNumber: result?.data.bankAccountNumber,
|
|
bankName: result?.data.bankName,
|
|
branchCode: result?.data.branchCode,
|
|
profilePicture: result?.data.filePath, // or keep as `filePath`
|
|
filePath: result?.data.filePath,
|
|
imageBlob: result?.data.imageBlob,
|
|
role: result?.data.role,
|
|
organizerId: result?.data.organizerId,
|
|
organizerStatus: result?.data.organizerStatus,
|
|
profileStatus: true, // set true once profile is fetched
|
|
}));
|
|
|
|
console.log("splash user data:", result.data);
|
|
} else {
|
|
Alert.alert("Error", "Failed to fetch user profile");
|
|
}
|
|
} catch (error) {
|
|
console.error("❌ Error fetching profile:", error);
|
|
Alert.alert("Error", "Could not connect to server");
|
|
}
|
|
};
|
|
|
|
|
|
const userStatus = async () => {
|
|
try {
|
|
const credentials = await Keychain.getGenericPassword();
|
|
if (!credentials) {
|
|
Alert.alert("Error", "You are not logged in");
|
|
return;
|
|
}
|
|
const token = credentials.password;
|
|
|
|
const response = await fetch(`${BASE_URL}user/profile/status`, {
|
|
method: "GET",
|
|
headers: {
|
|
Accept: "*/*",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
const json: ApiResponse = await response.json();
|
|
|
|
console.log("👤 Profile Status Response:", json);
|
|
if (json.status === "success") {
|
|
|
|
} else {
|
|
// setError(json.message || "Failed to fetch status");
|
|
}
|
|
} catch (err) {
|
|
// setError("Something went wrong. Please try again.");
|
|
}
|
|
};
|
|
|
|
|
|
console.log("redux user", user);
|
|
|
|
useEffect(() => {
|
|
const checkLogin = async () => {
|
|
try {
|
|
const creds = await Keychain.getGenericPassword();
|
|
if (creds) {
|
|
console.log("🔑 Found token:", creds.password);
|
|
navigation.replace("Home"); // go to bottom tabs if logged in
|
|
} else {
|
|
navigation.replace("Login");
|
|
}
|
|
} catch (error) {
|
|
console.error("Error checking login:", error);
|
|
navigation.replace("Login");
|
|
}
|
|
};
|
|
|
|
// Start fade out animation
|
|
Animated.timing(fadeAnim, {
|
|
toValue: 0,
|
|
duration: 1500, // fade out in 1.5s
|
|
useNativeDriver: true,
|
|
delay: 1500, // wait before fading
|
|
}).start(() => {
|
|
checkLogin(); // only navigate after animation
|
|
});
|
|
}, [navigation, fadeAnim]);
|
|
|
|
useEffect(() => {
|
|
fetchUserProfile();
|
|
}, [])
|
|
|
|
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", // white background
|
|
},
|
|
title: {
|
|
fontSize: 28,
|
|
fontWeight: "800",
|
|
color: colors.Home,
|
|
letterSpacing: 1,
|
|
},
|
|
});
|