handle user profile session

This commit is contained in:
Jaanu423
2025-09-22 13:52:38 +05:30
18 changed files with 1537 additions and 711 deletions
+3 -2
View File
@@ -100,14 +100,14 @@ const BecomeOrg = () => {
keyboardType="numeric"
value={bankAccountNumber}
onChangeText={setBankAccountNumber}
icon="card-outline"
/>
icon="card-outline" error={""} />
<CustomInput
placeholder="Bank Name"
value={bankName}
onChangeText={setBankName}
icon="business-outline"
error=""
/>
<CustomInput
@@ -115,6 +115,7 @@ const BecomeOrg = () => {
value={branchCode}
onChangeText={setBranchCode}
icon="key-outline"
error=""
/>
<CustomButton
+40 -31
View File
@@ -25,7 +25,7 @@ import { ApiResponse } from "../home/UserProfileStatus";
import { BASE_URL, PUT_USER_PROFILE, PUT_USER_PROFILE_IMG, PUT_USER_STATUS } from "../../utils/ApiUrls";
import AppView from "../../components/AppView";
import { useDispatch } from "react-redux";
import { setUserData } from "../../redux/userSlice";
import { clearUser, setUserData } from "../../redux/userSlice";
type UserProfile = {
id: string;
@@ -49,7 +49,7 @@ type UserProfile = {
const Profile = () => {
const navigation = useNavigation<any>();
const dispatch = useDispatch()
const [user, setUser] = useState<UserProfile | null>(null);
const [user, setUser] = useState<UserProfile | null | any>(null);
const [fetching, setFetching] = useState(true);
const [editing, setEditing] = useState(false);
const [imageUpdating, setImageUpdating] = useState(false);
@@ -165,7 +165,7 @@ const Profile = () => {
Alert.alert("Error", response.errorMessage || "Something went wrong");
} else if (response.assets && response.assets.length > 0) {
const selectedImage = response.assets[0];
setUser((prev) =>
setUser((prev:any) =>
prev ? { ...prev, filePath: selectedImage.uri ?? null } : prev
);
}
@@ -190,7 +190,7 @@ const Profile = () => {
const formData = new FormData();
formData.append("file", {
uri: user.filePath,
uri: user?.filePath,
type: "image/jpeg",
name: "profile.jpg",
} as any);
@@ -213,10 +213,10 @@ const Profile = () => {
// If API returns updated image, set it
if (result.data?.imageBlob) {
setUser((prev) => prev ? { ...prev, imageBlob: result.data.imageBlob, filePath: null } : prev);
setUser((prev:any) => prev ? { ...prev, imageBlob: result.data.imageBlob, filePath: null } : prev);
} else {
// Otherwise, keep the local filePath until next fetch
setUser((prev) => prev ? { ...prev, filePath: user.filePath } : prev);
setUser((prev:any) => prev ? { ...prev, filePath: user?.filePath } : prev);
}
// Refresh profile from API as well
@@ -279,6 +279,7 @@ const Profile = () => {
// Clear stored credentials
await Keychain.resetGenericPassword();
dispatch(clearUser())
Alert.alert("Success", "You have been logged out");
navigation.replace("Login");
} catch (error) {
@@ -324,23 +325,16 @@ const Profile = () => {
console.log("user image :", user?.filePath);
const getProfileImage = () => {
if (user?.imageBlob) {
return `data:image/jpeg;base64,${user.imageBlob}`;
return `data:image/jpeg;base64,${user?.imageBlob}`;
}
if (user?.filePath) {
return user.filePath;
return user?.filePath;
}
return "https://randomuser.me/api/portraits/men/1.jpg";
return "https://randomuser?.me/api/portraits/men/1.jpg";
};
if (fetching || !user) {
return (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color={colors.pastelBlue} />
<Text style={styles.loadingText}>Loading profile...</Text>
</View>
);
}
return (
<AppView>
@@ -351,6 +345,15 @@ const Profile = () => {
<Ionicons name="log-out-outline" size={24} color={colors.Profile} />
</TouchableOpacity>
</View>
{/* if (fetching || !user) {
return ( */}
{fetching || !user &&
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color={colors.pastelBlue} />
<Text style={styles.loadingText}>Loading profile...</Text>
</View>
}
<KeyboardAvoidingView
// style={{ flex: 1 }}
behavior={Platform.OS === "ios" ? "padding" : undefined}
@@ -424,7 +427,7 @@ const Profile = () => {
</View> */}
</View>
<View>
<TouchableOpacity onPress={()=>navigation.navigate('Transaction')}>
<TouchableOpacity onPress={() => navigation.navigate('Transaction')}>
<Text>View Transaction</Text>
</TouchableOpacity>
<CustomButton
@@ -440,7 +443,7 @@ const Profile = () => {
<Ionicons name="person" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
<View>
<Text style={styles.detailLabel}>Name</Text>
<Text style={styles.detailText}>{user.firstName} {user.lastName}</Text>
<Text style={styles.detailText}>{user?.firstName} {user?.lastName}</Text>
</View>
</View>
@@ -448,7 +451,7 @@ const Profile = () => {
<Ionicons name="mail" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
<View>
<Text style={styles.detailLabel}>Email</Text>
<Text style={styles.detailText}>{user.email || "Not provided"}</Text>
<Text style={styles.detailText}>{user?.email || "Not provided"}</Text>
</View>
</View>
@@ -456,7 +459,7 @@ const Profile = () => {
<Ionicons name="call" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
<View>
<Text style={styles.detailLabel}>Mobile</Text>
<Text style={styles.detailText}>{user.mobile || "Not provided"}</Text>
<Text style={styles.detailText}>{user?.mobile || "Not provided"}</Text>
</View>
</View>
@@ -464,7 +467,7 @@ const Profile = () => {
<Ionicons name="at-circle" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
<View>
<Text style={styles.detailLabel}>Username</Text>
<Text style={styles.detailText}>{user.username}</Text>
<Text style={styles.detailText}>{user?.username}</Text>
</View>
</View>
@@ -472,7 +475,7 @@ const Profile = () => {
<Ionicons name="location" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
<View>
<Text style={styles.detailLabel}>Address</Text>
<Text style={styles.detailText}>{user.address || "Not provided"}</Text>
<Text style={styles.detailText}>{user?.address || "Not provided"}</Text>
</View>
</View>
@@ -480,7 +483,7 @@ const Profile = () => {
<Ionicons name="male-female" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
<View>
<Text style={styles.detailLabel}>Gender</Text>
<Text style={styles.detailText}>{user.gender || "Not specified"}</Text>
<Text style={styles.detailText}>{user?.gender || "Not specified"}</Text>
</View>
</View>
@@ -488,7 +491,7 @@ const Profile = () => {
<Ionicons name="key" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
<View>
<Text style={styles.detailLabel}>Role</Text>
<Text style={styles.detailText}>{user.role || "User"}</Text>
<Text style={styles.detailText}>{user?.role || "User"}</Text>
</View>
</View>
@@ -504,49 +507,55 @@ const Profile = () => {
<Text style={styles.sectionTitle}>Edit Profile</Text>
<CustomInput
error=""
label="First Name"
placeholder="Enter first name"
value={user.firstName ?? ""}
value={user?.firstName ?? ""}
onChangeText={(text) => setUser({ ...user, firstName: text })}
icon="person"
/>
<CustomInput
error=""
label="Last Name"
placeholder="Enter last name"
value={user.lastName ?? ""}
value={user?.lastName ?? ""}
onChangeText={(text) => setUser({ ...user, lastName: text })}
icon="person"
/>
<CustomInput
error=""
label="Email"
placeholder="Enter email"
value={user.email ?? ""}
value={user?.email ?? ""}
onChangeText={(text) => setUser({ ...user, email: text })}
icon="mail"
keyboardType="email-address"
/>
<CustomInput
error=""
label="Username"
placeholder="Enter username"
value={user.username ?? ""}
value={user?.username ?? ""}
onChangeText={(text) => setUser({ ...user, username: text })}
icon="at"
/>
<CustomInput
error=""
label="Address"
placeholder="Enter address"
value={user.address ?? ""}
value={user?.address ?? ""}
onChangeText={(text) => setUser({ ...user, address: text })}
icon="location"
multiline
/>
<CustomInput
error=""
label="Gender"
placeholder="Enter gender"
value={user.gender ?? ""}
value={user?.gender ?? ""}
onChangeText={(text) => setUser({ ...user, gender: text })}
icon="male-female"
/>