manage user credancial
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<intent-filter android:autoVerify="true">
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
@@ -27,9 +27,11 @@
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="https"
|
||||
android:host="api.godemo.in"
|
||||
android:pathPrefix="/EProcurementSB" />
|
||||
<data android:scheme="myapp" android:host="invite"/>
|
||||
|
||||
<data android:scheme="http"
|
||||
android:host="192.168.1.19"
|
||||
android:pathPrefix="/invite" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
||||
@@ -14,6 +14,7 @@ import YourContacts from "../screens/management/YourContacts";
|
||||
import Transaction from "../screens/profile/Transaction";
|
||||
import GroupDetails from "../screens/home/user-home/GroupDetails";
|
||||
import EditGroupScreen from "../screens/management/EditGroupScreen";
|
||||
import EditBankDetails from "../screens/profile/EditBankDetails";
|
||||
|
||||
export type RootStackParamList = {
|
||||
Splash: undefined;
|
||||
@@ -30,16 +31,20 @@ export type RootStackParamList = {
|
||||
BecomeOrg: undefined;
|
||||
YourContacts: undefined;
|
||||
Transaction: undefined;
|
||||
EditBankDetails: { currentBankName: string | null; currentAccountNumber: string | null; currentBranchCode: string | null };
|
||||
};
|
||||
|
||||
const Stack = createNativeStackNavigator<RootStackParamList>();
|
||||
|
||||
export default function AppNavigator() {
|
||||
const linking = {
|
||||
prefixes: ["myapp://", "https://api.godemo.in"],
|
||||
prefixes: [
|
||||
"myapp://", // A custom scheme for internal or test links.
|
||||
"https://192.168.1.19" // Your production domain for verified App Links.
|
||||
],
|
||||
config: {
|
||||
screens: {
|
||||
Profile: "EProcurementSB",
|
||||
Profile: "invite",
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -60,6 +65,7 @@ export default function AppNavigator() {
|
||||
<Stack.Screen name="Transaction" component={Transaction} options={{ headerShown: false }} />
|
||||
<Stack.Screen name="GroupDetails" component={GroupDetails} options={{ headerShown: false }} />
|
||||
<Stack.Screen name="EditGroup" component={EditGroupScreen} options={{ headerShown: false }} />
|
||||
<Stack.Screen name="EditBankDetails" component={EditBankDetails} options={{ headerShown: false }} />
|
||||
</Stack.Navigator>
|
||||
</NavigationContainer>
|
||||
);
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { View, Text, StyleSheet, ActivityIndicator, Animated, Alert, ToastAndroid } 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";
|
||||
import { PROFILE_URL } from "../utils/ApiUrls";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { clearUser, setUserData } from "../redux/userSlice";
|
||||
import colors from "../components/colors";
|
||||
import { StackNavigationProp } from "@react-navigation/stack";
|
||||
|
||||
const SplashScreen = () => {
|
||||
const navigation = useNavigation<StackNavigationProp<RootStackParamList>>();
|
||||
const fadeAnim = useRef(new Animated.Value(1)).current;
|
||||
const dispatch = useDispatch();
|
||||
|
||||
|
||||
const fadeAnim = useRef(new Animated.Value(1)).current;
|
||||
|
||||
|
||||
const fetchUserProfile = async (dispatch: any, navigation: any) => {
|
||||
try {
|
||||
|
||||
@@ -58,7 +58,7 @@ const RequestList: React.FC = () => {
|
||||
setError(null);
|
||||
|
||||
const response = await fetch(
|
||||
"https://api.godemo.in/FundCollect/api/fund/group/pending/request",
|
||||
"https://exotic-humpback-mistakenly.ngrok-free.app/api/fund/group/pending/request",
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
@@ -124,7 +124,7 @@ const RequestList: React.FC = () => {
|
||||
|
||||
// Make API call to approve the request
|
||||
const response = await fetch(
|
||||
`https://api.godemo.in/FundCollect/api/fund/requests/${requestId}/approve`,
|
||||
`https://exotic-humpback-mistakenly.ngrok-free.app/api/fund/requests/${requestId}/approve`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers: {
|
||||
@@ -170,7 +170,7 @@ const RequestList: React.FC = () => {
|
||||
|
||||
// Make API call to decline the request
|
||||
const response = await fetch(
|
||||
`https://api.godemo.in/FundCollect/api/fund/requests/${requestedId}/reject?reason=/${reason}`,
|
||||
`https://exotic-humpback-mistakenly.ngrok-free.app/api/fund/requests/${requestedId}/reject?reason=/${reason}`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers: {
|
||||
|
||||
@@ -85,7 +85,7 @@ const EditGroupScreen: React.FC<EditGroupScreenProps> = ({ route }) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const response = await apiCall(`https://api.godemo.in/FundCollect/api/fund/group/details?groupId=${groupId}`, 'GET') as { status: string; data?: GroupDetails; message?: string };
|
||||
const response = await apiCall(`https://exotic-humpback-mistakenly.ngrok-free.app/api/fund/group/details?groupId=${groupId}`, 'GET') as { status: string; data?: GroupDetails; message?: string };
|
||||
if (response.status === 'success' && response.data) {
|
||||
setGroupDetails(response.data);
|
||||
setEditableData({
|
||||
@@ -141,7 +141,7 @@ const EditGroupScreen: React.FC<EditGroupScreenProps> = ({ route }) => {
|
||||
|
||||
setSaving(true);
|
||||
try {
|
||||
await apiCall(`https://api.godemo.in/FundCollect/api/fund/groups/${groupDetails.id}/edit`, 'PUT', editableData);
|
||||
await apiCall(`https://exotic-humpback-mistakenly.ngrok-free.app/apifund/groups/${groupDetails.id}/edit`, 'PUT', editableData);
|
||||
Alert.alert('Success', 'Group has been updated.');
|
||||
setEditingField(null);
|
||||
await fetchGroupDetails();
|
||||
@@ -165,7 +165,7 @@ const EditGroupScreen: React.FC<EditGroupScreenProps> = ({ route }) => {
|
||||
onPress: async () => {
|
||||
setStarting(true);
|
||||
try {
|
||||
await apiCall(`https://api.godemo.in/FundCollect/api/fund/group/start?groupId=${groupDetails.id}`, 'GET');
|
||||
await apiCall(`https://exotic-humpback-mistakenly.ngrok-free.app/api/fund/group/start?groupId=${groupDetails.id}`, 'GET');
|
||||
Alert.alert('Success', 'Group has been started successfully.');
|
||||
await fetchGroupDetails();
|
||||
} catch (e: any) {
|
||||
|
||||
@@ -40,16 +40,15 @@ const ManagementScreen: FC = () => {
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [userRequest, setUserRequest] = useState<UserJoinRequest[]>([])
|
||||
|
||||
|
||||
const fetchData = useCallback(async () => {
|
||||
if (loading) return;
|
||||
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
console.log(" abin user : ", userRole)
|
||||
if (userRole.role === "ORGANIZER") {
|
||||
// Fetch all data concurrently
|
||||
// Fetch all data concurrently for organizers
|
||||
const [myGroupsRes, joinedGroupsRes, requestsRes] = await Promise.all([
|
||||
apiCall(MY_GROUPS_URL, "GET") as Promise<ApiResponse<MyGroup[]>>,
|
||||
apiCall(GET_JOINED_GROUP_URL, "GET") as Promise<ApiResponse<JoinedGroup[]>>,
|
||||
@@ -59,19 +58,22 @@ const ManagementScreen: FC = () => {
|
||||
console.log("My Groups:", myGroupsRes.data);
|
||||
console.log("Joined Groups:", joinedGroupsRes.data);
|
||||
console.log("Requests:", requestsRes.data);
|
||||
|
||||
setMyGroups(myGroupsRes.data || []);
|
||||
setJoinedGroups(joinedGroupsRes.data || []);
|
||||
setRequests(requestsRes.data || []);
|
||||
} else {
|
||||
// Fetch only joined groups for non-organizers
|
||||
const [joinedGroupsRes, userRequest] = await Promise.all([
|
||||
apiCall(GET_JOINED_GROUP_URL, "GET") as Promise<ApiResponse<JoinedGroup[]>>, // Assuming this is also needed
|
||||
apiCall(USER_REQUEST, "GET") as Promise<ApiResponse<UserJoinRequest[]>>, // Assuming this is also needed
|
||||
// Fetch only joined groups and user requests for non-organizers
|
||||
const [joinedGroupsRes, userRequestRes] = await Promise.all([
|
||||
apiCall(GET_JOINED_GROUP_URL, "GET") as Promise<ApiResponse<JoinedGroup[]>>,
|
||||
apiCall(USER_REQUEST, "GET") as Promise<ApiResponse<UserJoinRequest[]>>,
|
||||
]);
|
||||
|
||||
console.log("Joined Groups:", joinedGroupsRes.data);
|
||||
console.log("User Requests:", userRequestRes.data);
|
||||
|
||||
setJoinedGroups(joinedGroupsRes.data || []);
|
||||
setUserRequest(userRequest?.data || []);
|
||||
console.log("joinedGroupsRes data : ", joinedGroupsRes)
|
||||
console.log("user request data : ", userRequest)
|
||||
setUserRequest(userRequestRes.data || []);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Fetch Data Error:", e);
|
||||
|
||||
@@ -41,7 +41,7 @@ const BecomeOrg = () => {
|
||||
const token = credentials.password;
|
||||
|
||||
const response = await fetch(
|
||||
"https://api.godemo.in/FundCollect/api/organizer/registration/apply",
|
||||
"https://exotic-humpback-mistakenly.ngrok-free.app/api/organizer/registration/apply",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
StyleSheet,
|
||||
View,
|
||||
Text,
|
||||
Alert,
|
||||
ActivityIndicator,
|
||||
TouchableOpacity,
|
||||
} from "react-native";
|
||||
import { useNavigation, useRoute } from "@react-navigation/native";
|
||||
import { CustomButton, CustomInput } from "../../components/common/Custom";
|
||||
import colors from "../../components/colors";
|
||||
import AppView from "../../components/AppView";
|
||||
import { Ionicons } from "@react-native-vector-icons/ionicons";
|
||||
import { UPDATE_BANK_URL } from "../../utils/ApiUrls";
|
||||
import { apiCall } from "../../utils/ApiHelper";
|
||||
|
||||
const EditBankDetails = () => {
|
||||
const navigation = useNavigation<any>();
|
||||
const route = useRoute();
|
||||
|
||||
// Get initial data from route parameters passed from the Profile screen
|
||||
const {
|
||||
currentBankName,
|
||||
currentAccountNumber,
|
||||
currentBranchCode
|
||||
} = route.params as {
|
||||
currentBankName?: string;
|
||||
currentAccountNumber?: string;
|
||||
currentBranchCode?: string;
|
||||
};
|
||||
|
||||
// Initialize state with the passed-in details
|
||||
const [bankName, setBankName] = useState(currentBankName || "");
|
||||
const [bankAccountNumber, setBankAccountNumber] = useState(currentAccountNumber || "");
|
||||
const [branchCode, setBranchCode] = useState(currentBranchCode || "");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// The update function remains the same, using the local state
|
||||
const handleUpdateBankDetails = async () => {
|
||||
if (!bankName || !bankAccountNumber || !branchCode) {
|
||||
Alert.alert("Validation Error", "Please fill in all bank details.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await apiCall(UPDATE_BANK_URL, 'PUT', {
|
||||
bankName,
|
||||
bankAccountNumber,
|
||||
branchCode,
|
||||
}) as { status: string; message?: string };
|
||||
console.log("Update Bank Response:", response);
|
||||
if (response.status === "success") {
|
||||
Alert.alert("Success", response.message || "Bank details updated successfully!");
|
||||
navigation.goBack();
|
||||
} else {
|
||||
Alert.alert("Update Failed", response.message || "Could not update bank details.");
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error("Error updating bank details:", error);
|
||||
Alert.alert("Error", error.message || "An unexpected error occurred. Please try again.");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<AppView>
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity onPress={() => navigation.goBack()} style={styles.backButton}>
|
||||
<Ionicons name="arrow-back" size={24} color={colors.Profile} />
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.headerTitle}>Edit Bank Details</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.sectionTitle}>Update Your Bank Information</Text>
|
||||
|
||||
<CustomInput
|
||||
label="Bank Name"
|
||||
placeholder="Enter your bank's name"
|
||||
value={bankName}
|
||||
onChangeText={setBankName}
|
||||
icon="business"
|
||||
error=""
|
||||
/>
|
||||
|
||||
<CustomInput
|
||||
label="Bank Account Number"
|
||||
placeholder="Enter your account number"
|
||||
value={bankAccountNumber}
|
||||
onChangeText={setBankAccountNumber}
|
||||
icon="card"
|
||||
keyboardType="numeric"
|
||||
error=""
|
||||
/>
|
||||
|
||||
<CustomInput
|
||||
label="Branch Code"
|
||||
placeholder="Enter the branch code (IFSC)"
|
||||
value={branchCode}
|
||||
onChangeText={setBranchCode}
|
||||
icon="barcode"
|
||||
error=""
|
||||
/>
|
||||
|
||||
<View style={styles.buttonContainer}>
|
||||
<CustomButton
|
||||
title={loading ? "Saving..." : "Save Changes"}
|
||||
onPress={handleUpdateBankDetails}
|
||||
icon={loading ? undefined : "save"}
|
||||
|
||||
buttonBackground={colors.pastelBlue}
|
||||
/>
|
||||
<CustomButton
|
||||
title="Cancel"
|
||||
onPress={() => navigation.goBack()}
|
||||
style={styles.cancelButton}
|
||||
buttonBackground={colors.pastelBlue}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</AppView>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
header: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
padding: 16,
|
||||
},
|
||||
backButton: {
|
||||
marginRight: 16,
|
||||
},
|
||||
headerTitle: {
|
||||
fontSize: 22,
|
||||
fontWeight: "600",
|
||||
color: colors.Profile,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
padding: 16,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: "700",
|
||||
color: "#1e293b",
|
||||
marginBottom: 20,
|
||||
},
|
||||
buttonContainer: {
|
||||
marginTop: 24,
|
||||
},
|
||||
cancelButton: {
|
||||
marginTop: 12,
|
||||
borderWidth: 1,
|
||||
borderColor: "#cbd5e1",
|
||||
},
|
||||
});
|
||||
|
||||
export default EditBankDetails;
|
||||
+109
-13
@@ -26,6 +26,9 @@ import { BASE_URL, PUT_USER_PROFILE, PUT_USER_PROFILE_IMG, PUT_USER_STATUS } fro
|
||||
import AppView from "../../components/AppView";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { clearUser, setUserData } from "../../redux/userSlice";
|
||||
import { StackNavigationProp } from "@react-navigation/stack";
|
||||
import { RootStackParamList } from "../../navigation/AppNavigator";
|
||||
|
||||
|
||||
type UserProfile = {
|
||||
id: string;
|
||||
@@ -46,8 +49,9 @@ type UserProfile = {
|
||||
role?: string;
|
||||
};
|
||||
|
||||
|
||||
const Profile = () => {
|
||||
const navigation = useNavigation<any>();
|
||||
const navigation = useNavigation<StackNavigationProp<RootStackParamList>>();
|
||||
const dispatch = useDispatch()
|
||||
const [user, setUser] = useState<UserProfile | null | any>(null);
|
||||
const [fetching, setFetching] = useState(true);
|
||||
@@ -58,6 +62,7 @@ const Profile = () => {
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
|
||||
|
||||
const fetchUserProfile = async () => {
|
||||
try {
|
||||
const credentials = await Keychain.getGenericPassword();
|
||||
@@ -67,6 +72,7 @@ const Profile = () => {
|
||||
}
|
||||
const token = credentials.password;
|
||||
|
||||
|
||||
setFetching(true);
|
||||
const response = await fetch(
|
||||
`${BASE_URL}user/profile/view`,
|
||||
@@ -79,6 +85,7 @@ const Profile = () => {
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
const result = await response.json();
|
||||
console.log("👤 Profile Response:", result);
|
||||
if (result.status === "success") {
|
||||
@@ -115,6 +122,7 @@ const Profile = () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const updateProfile = async () => {
|
||||
try {
|
||||
const credentials = await Keychain.getGenericPassword();
|
||||
@@ -124,6 +132,7 @@ const Profile = () => {
|
||||
}
|
||||
const token = credentials.password;
|
||||
|
||||
|
||||
const response = await fetch(
|
||||
PUT_USER_PROFILE,
|
||||
{
|
||||
@@ -144,6 +153,7 @@ const Profile = () => {
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
const result = await response.json();
|
||||
if (result.status === "success") {
|
||||
Alert.alert("Success", "Profile updated successfully");
|
||||
@@ -158,6 +168,7 @@ const Profile = () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const pickImage = () => {
|
||||
launchImageLibrary({ mediaType: "photo", quality: 0.5 }, (response) => {
|
||||
if (response.didCancel) return;
|
||||
@@ -165,13 +176,14 @@ 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:any) =>
|
||||
setUser((prev: any) =>
|
||||
prev ? { ...prev, filePath: selectedImage.uri ?? null } : prev
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const handleUpdateImage = async () => {
|
||||
try {
|
||||
const credentials = await Keychain.getGenericPassword();
|
||||
@@ -181,13 +193,16 @@ const Profile = () => {
|
||||
}
|
||||
const token = credentials.password;
|
||||
|
||||
|
||||
if (!user?.filePath) {
|
||||
Alert.alert("Error", "Please select an image first");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
setImageUpdating(true);
|
||||
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("file", {
|
||||
uri: user?.filePath,
|
||||
@@ -195,6 +210,7 @@ const Profile = () => {
|
||||
name: "profile.jpg",
|
||||
} as any);
|
||||
|
||||
|
||||
const response = await fetch(
|
||||
PUT_USER_PROFILE_IMG,
|
||||
{
|
||||
@@ -207,18 +223,21 @@ const Profile = () => {
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
const result = await response.json();
|
||||
if (result.status === "success") {
|
||||
Alert.alert("Success", "Profile image updated successfully");
|
||||
|
||||
|
||||
// If API returns updated image, set it
|
||||
if (result.data?.imageBlob) {
|
||||
setUser((prev:any) => 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:any) => prev ? { ...prev, filePath: user?.filePath } : prev);
|
||||
setUser((prev: any) => prev ? { ...prev, filePath: user?.filePath } : prev);
|
||||
}
|
||||
|
||||
|
||||
// Refresh profile from API as well
|
||||
fetchUserProfile();
|
||||
} else {
|
||||
@@ -232,6 +251,7 @@ const Profile = () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const userStatus = async () => {
|
||||
try {
|
||||
const credentials = await Keychain.getGenericPassword();
|
||||
@@ -241,6 +261,7 @@ const Profile = () => {
|
||||
}
|
||||
const token = credentials.password;
|
||||
|
||||
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const response = await fetch(PUT_USER_STATUS, {
|
||||
@@ -251,13 +272,16 @@ const Profile = () => {
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const json: ApiResponse = await response.json();
|
||||
|
||||
|
||||
console.log("👤 Profile Status Response:", json);
|
||||
if (json.status === "success") {
|
||||
setStatusData(json.data);
|
||||
console.log("statusData response :", json);
|
||||
|
||||
|
||||
} else {
|
||||
setError(json.message || "Failed to fetch status");
|
||||
}
|
||||
@@ -268,15 +292,18 @@ const Profile = () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const logout = async (navigation: any) => {
|
||||
try {
|
||||
const credentials = await Keychain.getGenericPassword();
|
||||
|
||||
|
||||
if (!credentials) {
|
||||
Alert.alert("Info", "No user is currently logged in");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Clear stored credentials
|
||||
await Keychain.resetGenericPassword();
|
||||
dispatch(clearUser())
|
||||
@@ -288,6 +315,7 @@ const Profile = () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const confirmLogout = (navigation: any) => {
|
||||
Alert.alert(
|
||||
"Logout",
|
||||
@@ -299,17 +327,22 @@ const Profile = () => {
|
||||
);
|
||||
};
|
||||
|
||||
console.log("statusData?.role :", statusData?.role);
|
||||
console.log("statusData?.organizerStatus :", statusData?.organizerStatus);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
userStatus();
|
||||
}, [])
|
||||
);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
userStatus();
|
||||
fetchUserProfile();
|
||||
}, []);
|
||||
|
||||
|
||||
const onRefresh = () => {
|
||||
setRefreshing(true);
|
||||
// Simulate a network request or data fetching
|
||||
@@ -319,6 +352,7 @@ const Profile = () => {
|
||||
}, 2000); // 2 seconds delay
|
||||
};
|
||||
|
||||
|
||||
console.log("user image :", user?.filePath);
|
||||
const getProfileImage = () => {
|
||||
if (user?.imageBlob) {
|
||||
@@ -333,6 +367,7 @@ const Profile = () => {
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<AppView>
|
||||
{/* Header */}
|
||||
@@ -350,6 +385,7 @@ const Profile = () => {
|
||||
<Text style={styles.loadingText}>Loading profile...</Text>
|
||||
</View>
|
||||
|
||||
|
||||
}
|
||||
<KeyboardAvoidingView
|
||||
// style={{ flex: 1 }}
|
||||
@@ -363,6 +399,7 @@ const Profile = () => {
|
||||
}
|
||||
>
|
||||
|
||||
|
||||
{/* Profile Card */}
|
||||
<View style={styles.profileCard}>
|
||||
{/* Profile Image Section */}
|
||||
@@ -388,6 +425,7 @@ const Profile = () => {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
<View style={styles.profileImageSection}>
|
||||
<View style={styles.avatarContainer}>
|
||||
<Image
|
||||
@@ -400,6 +438,7 @@ const Profile = () => {
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
|
||||
<CustomButton
|
||||
title={imageUpdating ? "Updating..." : "Update Image"}
|
||||
onPress={handleUpdateImage}
|
||||
@@ -407,9 +446,11 @@ const Profile = () => {
|
||||
style={styles.updateImageButton}
|
||||
buttonBackground={colors.pastelBlue}
|
||||
|
||||
|
||||
/>
|
||||
</View>
|
||||
|
||||
|
||||
{!editing ? (
|
||||
<>
|
||||
{/* Profile Details */}
|
||||
@@ -420,8 +461,9 @@ const Profile = () => {
|
||||
<Text style={{ color: "#64748b", marginBottom: 16 }}>Become Organizer</Text>
|
||||
{/* <View style={{ marginBottom: 16 }}>
|
||||
|
||||
|
||||
</View> */}
|
||||
|
||||
|
||||
</View> */}
|
||||
</View>
|
||||
<View>
|
||||
<TouchableOpacity onPress={() => navigation.navigate('Transaction')}>
|
||||
@@ -444,6 +486,7 @@ const Profile = () => {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
|
||||
<View style={styles.detailRow}>
|
||||
<Ionicons name="mail" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
|
||||
<View>
|
||||
@@ -452,6 +495,7 @@ const Profile = () => {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
|
||||
<View style={styles.detailRow}>
|
||||
<Ionicons name="call" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
|
||||
<View>
|
||||
@@ -460,6 +504,7 @@ const Profile = () => {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
|
||||
<View style={styles.detailRow}>
|
||||
<Ionicons name="at-circle" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
|
||||
<View>
|
||||
@@ -468,6 +513,7 @@ const Profile = () => {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
|
||||
<View style={styles.detailRow}>
|
||||
<Ionicons name="location" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
|
||||
<View>
|
||||
@@ -476,6 +522,7 @@ const Profile = () => {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
|
||||
<View style={styles.detailRow}>
|
||||
<Ionicons name="male-female" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
|
||||
<View>
|
||||
@@ -484,6 +531,7 @@ const Profile = () => {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
|
||||
<View style={styles.detailRow}>
|
||||
<Ionicons name="key" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
|
||||
<View>
|
||||
@@ -492,7 +540,46 @@ const Profile = () => {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* BANK DETAILS SECTION */}
|
||||
<View style={{ marginTop: 20 }}>
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Text style={styles.sectionTitle}>Bank Information</Text>
|
||||
{/* Navigate to a screen you will create for editing bank details */}
|
||||
<CustomButton
|
||||
title="Edit Bank Details"
|
||||
onPress={() =>{ navigation.navigate("EditBankDetails", {
|
||||
currentBankName: user?.bankName,
|
||||
currentAccountNumber: user?.bankAccountNumber,
|
||||
currentBranchCode: user?.branchCode,
|
||||
})}}
|
||||
|
||||
icon="create-outline"
|
||||
style={styles.editButton}
|
||||
buttonBackground={colors.pastelBlue}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.detailRow}>
|
||||
<Ionicons name="business" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
|
||||
<View>
|
||||
<Text style={styles.detailLabel}>Bank Name</Text>
|
||||
<Text style={styles.detailText}>{user?.bankName || "Not provided"}</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.detailRow}>
|
||||
<Ionicons name="barcode" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
|
||||
<View>
|
||||
<Text style={styles.detailLabel}>Branch Code</Text>
|
||||
<Text style={styles.detailText}>{user?.branchCode || "Not provided"}</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.detailRow}>
|
||||
<Ionicons name="card" size={20} color={colors.pastelBlue} style={styles.detailIcon} />
|
||||
<View>
|
||||
<Text style={styles.detailLabel}>Account Number</Text>
|
||||
<Text style={styles.detailText}>{user?.bankAccountNumber || "Not provided"}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
|
||||
</View>
|
||||
@@ -503,8 +590,9 @@ const Profile = () => {
|
||||
<View style={styles.editSection}>
|
||||
<Text style={styles.sectionTitle}>Edit Profile</Text>
|
||||
|
||||
|
||||
<CustomInput
|
||||
error=""
|
||||
error=""
|
||||
label="First Name"
|
||||
placeholder="Enter first name"
|
||||
value={user?.firstName ?? ""}
|
||||
@@ -512,8 +600,9 @@ const Profile = () => {
|
||||
icon="person"
|
||||
/>
|
||||
|
||||
|
||||
<CustomInput
|
||||
error=""
|
||||
error=""
|
||||
label="Last Name"
|
||||
placeholder="Enter last name"
|
||||
value={user?.lastName ?? ""}
|
||||
@@ -521,8 +610,9 @@ const Profile = () => {
|
||||
icon="person"
|
||||
/>
|
||||
|
||||
|
||||
<CustomInput
|
||||
error=""
|
||||
error=""
|
||||
label="Email"
|
||||
placeholder="Enter email"
|
||||
value={user?.email ?? ""}
|
||||
@@ -531,8 +621,9 @@ const Profile = () => {
|
||||
keyboardType="email-address"
|
||||
/>
|
||||
|
||||
|
||||
<CustomInput
|
||||
error=""
|
||||
error=""
|
||||
label="Username"
|
||||
placeholder="Enter username"
|
||||
value={user?.username ?? ""}
|
||||
@@ -540,7 +631,7 @@ const Profile = () => {
|
||||
icon="at"
|
||||
/>
|
||||
<CustomInput
|
||||
error=""
|
||||
error=""
|
||||
label="Address"
|
||||
placeholder="Enter address"
|
||||
value={user?.address ?? ""}
|
||||
@@ -549,7 +640,7 @@ const Profile = () => {
|
||||
multiline
|
||||
/>
|
||||
<CustomInput
|
||||
error=""
|
||||
error=""
|
||||
label="Gender"
|
||||
placeholder="Enter gender"
|
||||
value={user?.gender ?? ""}
|
||||
@@ -557,6 +648,7 @@ const Profile = () => {
|
||||
icon="male-female"
|
||||
/>
|
||||
|
||||
|
||||
<View style={styles.editButtons}>
|
||||
<CustomButton
|
||||
title="Save Changes"
|
||||
@@ -574,6 +666,7 @@ const Profile = () => {
|
||||
/>
|
||||
</View>
|
||||
|
||||
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
@@ -584,6 +677,7 @@ const Profile = () => {
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
@@ -616,6 +710,7 @@ const styles = StyleSheet.create({
|
||||
padding: 4,
|
||||
},
|
||||
|
||||
|
||||
profileCard: {
|
||||
borderRadius: 20,
|
||||
margin: 16,
|
||||
@@ -775,4 +870,5 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
export default Profile;
|
||||
|
||||
export default Profile;
|
||||
|
||||
@@ -17,7 +17,7 @@ export async function apiCall<T>(
|
||||
try {
|
||||
// Get saved credentials from Keychain
|
||||
const creds = await Keychain.getGenericPassword();
|
||||
|
||||
console.log("hihihi", creds);
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
...(creds ? { Authorization: `Bearer ${creds.password}` } : {}),
|
||||
|
||||
@@ -17,3 +17,4 @@ export const PUT_USER_PROFILE = `${BASE_URL}user/profile/update`
|
||||
export const PUT_USER_STATUS = `${BASE_URL}user/profile/status`
|
||||
export const USER_REQUEST = `${BASE_URL}fund/my-requests`
|
||||
export const GROUP_ALL_MEMBER = `${BASE_URL}fund/group/all/member`
|
||||
export const UPDATE_BANK_URL = `${BASE_URL}user/bank/update`;
|
||||
|
||||
Reference in New Issue
Block a user