helper funtion
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".MainApplication"
|
android:name=".MainApplication"
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.circlecollect
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.content.ContentResolver
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.provider.ContactsContract
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
import com.facebook.react.bridge.*
|
||||||
|
|
||||||
|
class ContactsModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
||||||
|
|
||||||
|
override fun getName(): String {
|
||||||
|
return "ContactsModule"
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun getContacts(promise: Promise) {
|
||||||
|
val context = reactApplicationContext
|
||||||
|
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
promise.reject("PERMISSION_DENIED", "Read contacts permission not granted")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val contactsList = Arguments.createArray()
|
||||||
|
val resolver: ContentResolver = context.contentResolver
|
||||||
|
val cursor = resolver.query(
|
||||||
|
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor?.use {
|
||||||
|
val nameIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)
|
||||||
|
val numberIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
|
||||||
|
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
val contact = Arguments.createMap()
|
||||||
|
contact.putString("name", cursor.getString(nameIndex))
|
||||||
|
contact.putString("phone", cursor.getString(numberIndex))
|
||||||
|
contactsList.pushMap(contact)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
promise.resolve(contactsList)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.circlecollect
|
||||||
|
|
||||||
|
import com.facebook.react.ReactPackage
|
||||||
|
import com.facebook.react.bridge.NativeModule
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext
|
||||||
|
import com.facebook.react.uimanager.ViewManager
|
||||||
|
|
||||||
|
class ContactsPackage : ReactPackage {
|
||||||
|
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
||||||
|
return listOf(ContactsModule(reactContext))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import com.facebook.react.ReactNativeHost
|
|||||||
import com.facebook.react.ReactPackage
|
import com.facebook.react.ReactPackage
|
||||||
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
|
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
|
||||||
import com.facebook.react.defaults.DefaultReactNativeHost
|
import com.facebook.react.defaults.DefaultReactNativeHost
|
||||||
|
import com.circlecollect.ContactsPackage
|
||||||
|
|
||||||
class MainApplication : Application(), ReactApplication {
|
class MainApplication : Application(), ReactApplication {
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ class MainApplication : Application(), ReactApplication {
|
|||||||
PackageList(this).packages.apply {
|
PackageList(this).packages.apply {
|
||||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||||
// add(MyReactNativePackage())
|
// add(MyReactNativePackage())
|
||||||
|
add(ContactsPackage())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getJSMainModuleName(): String = "index"
|
override fun getJSMainModuleName(): String = "index"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export const RequestCard: FC<RequestCardProps> = ({ item, onApprove, onDecline }
|
|||||||
/>
|
/>
|
||||||
<View style={styles.userInfo}>
|
<View style={styles.userInfo}>
|
||||||
<Text style={styles.userName} numberOfLines={1}>{item.userName}</Text>
|
<Text style={styles.userName} numberOfLines={1}>{item.userName}</Text>
|
||||||
<Text style={styles.userMeta}><Ionicons name="call-outline" size={14} color={colors.textSecondary} /> {item.mobile}</Text>
|
<Text style={styles.userMeta}><Ionicons name="call-outline" size={14} color={colors.textLight} /> {item.mobile}</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
@@ -37,13 +37,13 @@ export const RequestCard: FC<RequestCardProps> = ({ item, onApprove, onDecline }
|
|||||||
{/* Bottom section with action buttons */}
|
{/* Bottom section with action buttons */}
|
||||||
<View style={styles.actionsSection}>
|
<View style={styles.actionsSection}>
|
||||||
<TouchableOpacity style={[styles.actionButton, styles.declineButton]} onPress={() => onDecline(item)}>
|
<TouchableOpacity style={[styles.actionButton, styles.declineButton]} onPress={() => onDecline(item)}>
|
||||||
<Ionicons name="close-outline" size={20} color={colors.danger} />
|
<Ionicons name="close-outline" size={20} color={colors.pastelOrange} />
|
||||||
<Text style={[styles.actionButtonText, { color: colors.danger }]}>Decline</Text>
|
<Text style={[styles.actionButtonText, { color: colors.pastelOrange }]}>Decline</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity style={[styles.actionButton, styles.approveButton]} onPress={() => onApprove(item)}>
|
<TouchableOpacity style={[styles.actionButton, styles.approveButton]} onPress={() => onApprove(item)}>
|
||||||
{/* Corrected icon color and updated text color for better contrast */}
|
{/* Corrected icon color and updated text color for better contrast */}
|
||||||
<Ionicons name="checkmark-outline" size={20} color={colors.textPrimary} />
|
<Ionicons name="checkmark-outline" size={20} color={colors.textDark} />
|
||||||
<Text style={[styles.actionButtonText, { color: colors.textPrimary }]}>Approve</Text>
|
<Text style={[styles.actionButtonText, { color: colors.textDark }]}>Approve</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@@ -77,7 +77,7 @@ const styles = StyleSheet.create({
|
|||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
borderBottomWidth: 1,
|
borderBottomWidth: 1,
|
||||||
borderBottomColor: colors.border,
|
borderBottomColor: colors.textLight,
|
||||||
paddingBottom: 12,
|
paddingBottom: 12,
|
||||||
},
|
},
|
||||||
avatar: {
|
avatar: {
|
||||||
@@ -125,7 +125,7 @@ const styles = StyleSheet.create({
|
|||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
},
|
},
|
||||||
declineButton: {
|
declineButton: {
|
||||||
backgroundColor: colors.lightDanger,
|
backgroundColor: colors.pastelPink,
|
||||||
},
|
},
|
||||||
approveButton: {
|
approveButton: {
|
||||||
// Set background color as requested
|
// Set background color as requested
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { PermissionsAndroid, Platform, NativeModules } from "react-native";
|
||||||
|
|
||||||
|
const { ContactsModule } = NativeModules;
|
||||||
|
|
||||||
|
async function fetchContacts() {
|
||||||
|
if (Platform.OS === "android") {
|
||||||
|
const granted = await PermissionsAndroid.request(
|
||||||
|
PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
|
||||||
|
{
|
||||||
|
title: "Contacts Permission",
|
||||||
|
message: "This app would like to view your contacts.",
|
||||||
|
buttonPositive: "OK",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
|
||||||
|
console.log("Contacts permission denied");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const contacts = await ContactsModule.getContacts();
|
||||||
|
console.log("Contacts:", contacts);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching contacts:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export { fetchContacts };
|
||||||
@@ -12,6 +12,7 @@ import GroupReview from "../screens/GroupReview";
|
|||||||
import BottomTabs from "./BottomTabs";
|
import BottomTabs from "./BottomTabs";
|
||||||
import BecomeOrg from "../screens/profile/BecomeOrg";
|
import BecomeOrg from "../screens/profile/BecomeOrg";
|
||||||
import EditGroupScreen from "../screens/management/EditGroupScreen";
|
import EditGroupScreen from "../screens/management/EditGroupScreen";
|
||||||
|
import YourContacts from "../screens/management/YourContacts";
|
||||||
|
|
||||||
const Stack = createNativeStackNavigator();
|
const Stack = createNativeStackNavigator();
|
||||||
export type RootStackParamList = {
|
export type RootStackParamList = {
|
||||||
@@ -62,7 +63,8 @@ export default function AppNavigator() {
|
|||||||
<Stack.Screen name="GroupCreation" component={GroupCreation} options={{ headerShown: false }} />
|
<Stack.Screen name="GroupCreation" component={GroupCreation} options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="GroupReview" component={GroupReview} options={{ headerShown: false }} />
|
<Stack.Screen name="GroupReview" component={GroupReview} options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="BecomeOrg" component={BecomeOrg} options={{ headerShown: false }} />
|
<Stack.Screen name="BecomeOrg" component={BecomeOrg} options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="EditGroup" component={EditGroupScreen} options={{ headerShown: false }} />
|
<Stack.Screen name="YourContacts" component={YourContacts} options={{ headerShown: false }} />
|
||||||
|
{/* <Stack.Screen name="EditGroup" component={EditGroupScreen} options={{ headerShown: false }} /> */}
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
</NavigationContainer>
|
</NavigationContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ export default function OtpVerificationScreen() {
|
|||||||
{ headers: { "Content-Type": "application/json", Accept: "*/*" } }
|
{ headers: { "Content-Type": "application/json", Accept: "*/*" } }
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log("📩 OTP Resent:", res.data);
|
console.log("📩 OTP Resent:", res);
|
||||||
setCode(Array(CELL_COUNT).fill(""));
|
setCode(Array(CELL_COUNT).fill(""));
|
||||||
inputs.current[0]?.focus();
|
inputs.current[0]?.focus();
|
||||||
ToastAndroid.show("OTP Sent", ToastAndroid.SHORT);
|
ToastAndroid.show("OTP Sent", ToastAndroid.SHORT);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import { MyGroupCard } from "../../components/MyGroupCard";
|
|||||||
import { JoinedGroupCard } from "../../components/JoinedGroupCard";
|
import { JoinedGroupCard } from "../../components/JoinedGroupCard";
|
||||||
import { RequestCard } from "../../components/RequestCard";
|
import { RequestCard } from "../../components/RequestCard";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
|
import Ionicons from "@react-native-vector-icons/ionicons";
|
||||||
|
|
||||||
type GroupManagementNavProp = StackNavigationProp<RootStackParamList>;
|
type GroupManagementNavProp = StackNavigationProp<RootStackParamList>;
|
||||||
type ActiveTab = "My Groups" | "Joined Groups" | "Requests" | "Your Requests";
|
type ActiveTab = "My Groups" | "Joined Groups" | "Requests" | "Your Requests";
|
||||||
@@ -172,6 +173,32 @@ const ManagementScreen: FC = () => {
|
|||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.contentArea}>
|
<View style={styles.contentArea}>
|
||||||
|
{
|
||||||
|
activeTab === "Requests" && userRole === "ORGANIZER" ? (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
bottom: 85,
|
||||||
|
right: 20,
|
||||||
|
backgroundColor: colors.pastelOrange,
|
||||||
|
width: 60,
|
||||||
|
height: 60,
|
||||||
|
borderRadius: 30,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.2,
|
||||||
|
shadowRadius: 5,
|
||||||
|
shadowOffset: { width: 0, height: 3 },
|
||||||
|
elevation: 5, // for Android shadow
|
||||||
|
}}
|
||||||
|
onPress={() => navigation.navigate("YourContacts" as never)}
|
||||||
|
>
|
||||||
|
<Ionicons name="person-add" size={28} color={colors.textDark} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
|
||||||
{renderContent()}
|
{renderContent()}
|
||||||
</View>
|
</View>
|
||||||
</AppView>
|
</AppView>
|
||||||
|
|||||||
@@ -0,0 +1,274 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import {
|
||||||
|
StyleSheet,
|
||||||
|
Text,
|
||||||
|
View,
|
||||||
|
FlatList,
|
||||||
|
TouchableOpacity,
|
||||||
|
Modal,
|
||||||
|
PermissionsAndroid,
|
||||||
|
Platform,
|
||||||
|
NativeModules,
|
||||||
|
Linking,
|
||||||
|
Alert,
|
||||||
|
} from "react-native";
|
||||||
|
import AppView from "../../components/AppView";
|
||||||
|
|
||||||
|
const { ContactsModule } = NativeModules;
|
||||||
|
|
||||||
|
const APP_URL = "https://play.google.com/store/apps/details?id=com.yourapp"; // replace with your real app url
|
||||||
|
|
||||||
|
const YourContacts = () => {
|
||||||
|
const [contacts, setContacts] = useState<any[]>([]);
|
||||||
|
const [selectedContact, setSelectedContact] = useState<any>(null);
|
||||||
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
handleFetchContacts();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleFetchContacts = async () => {
|
||||||
|
try {
|
||||||
|
if (Platform.OS === "android") {
|
||||||
|
const granted = await PermissionsAndroid.request(
|
||||||
|
PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
|
||||||
|
{
|
||||||
|
title: "Contacts Permission",
|
||||||
|
message: "This app would like to view your contacts.",
|
||||||
|
buttonPositive: "OK",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
|
||||||
|
console.log("Contacts permission denied");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchedContacts = await ContactsModule.getContacts();
|
||||||
|
setContacts(fetchedContacts);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching contacts:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const APP_URL = "https://play.google.com/store/apps/details?id=com.yourapp"; // your app link
|
||||||
|
const WHATSAPP_URL = "https://play.google.com/store/apps/details?id=com.whatsapp"; // fallback store link
|
||||||
|
|
||||||
|
const handleSend = async (contact: any) => {
|
||||||
|
if (!contact) return;
|
||||||
|
|
||||||
|
const message = `Hey ${contact.name}, check out this awesome app! Download here: ${APP_URL}`;
|
||||||
|
|
||||||
|
// direct send to contact if you want
|
||||||
|
const url = `whatsapp://send?phone=${contact.phone}&text=${encodeURIComponent(
|
||||||
|
message
|
||||||
|
)}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const supported = await Linking.canOpenURL("whatsapp://send");
|
||||||
|
if (supported) {
|
||||||
|
// WhatsApp installed
|
||||||
|
await Linking.openURL(url);
|
||||||
|
} else {
|
||||||
|
// WhatsApp not installed → send user to Play Store/App Store
|
||||||
|
if (Platform.OS === "android") {
|
||||||
|
await Linking.openURL(WHATSAPP_URL);
|
||||||
|
} else if (Platform.OS === "ios") {
|
||||||
|
await Linking.openURL("itms-apps://apps.apple.com/app/whatsapp-messenger/id310633997");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error sending to WhatsApp:", err);
|
||||||
|
Alert.alert("Error", "Something went wrong while trying to open WhatsApp");
|
||||||
|
}
|
||||||
|
|
||||||
|
setModalVisible(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const renderContact = ({ item }: { item: any }) => (
|
||||||
|
<View style={styles.contactRow}>
|
||||||
|
<View style={styles.avatar}>
|
||||||
|
<Text style={styles.avatarText}>
|
||||||
|
{item.name ? item.name.charAt(0).toUpperCase() : "?"}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.contactInfo}>
|
||||||
|
<Text style={styles.contactName}>{item.name}</Text>
|
||||||
|
<Text style={styles.contactPhone}>{item.phone}</Text>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.inviteButton}
|
||||||
|
onPress={() => {
|
||||||
|
setSelectedContact(item);
|
||||||
|
setModalVisible(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={styles.inviteText}>Invite</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppView>
|
||||||
|
<View>
|
||||||
|
<Text style={styles.header}>Select Contact</Text>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<FlatList
|
||||||
|
data={contacts}
|
||||||
|
keyExtractor={(item, index) => index.toString()}
|
||||||
|
renderItem={renderContact}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Send Modal */}
|
||||||
|
<Modal
|
||||||
|
transparent={true}
|
||||||
|
visible={modalVisible}
|
||||||
|
animationType="slide"
|
||||||
|
onRequestClose={() => setModalVisible(false)}
|
||||||
|
>
|
||||||
|
<View style={styles.modalOverlay}>
|
||||||
|
<View style={styles.modalContent}>
|
||||||
|
<Text style={styles.modalTitle}>Send Invite</Text>
|
||||||
|
{selectedContact && (
|
||||||
|
<Text style={styles.modalText}>
|
||||||
|
Send invite to {selectedContact.name} ({selectedContact.phone})
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
<View style={styles.modalActions}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.cancelButton}
|
||||||
|
onPress={() => setModalVisible(false)}
|
||||||
|
>
|
||||||
|
<Text style={styles.cancelText}>Cancel</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.sendButton}
|
||||||
|
onPress={() => handleSend(selectedContact)}
|
||||||
|
>
|
||||||
|
<Text style={styles.sendText}>Send</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</Modal>
|
||||||
|
</AppView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default YourContacts;
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
paddingTop: 20,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: 15,
|
||||||
|
},
|
||||||
|
contactRow: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
paddingVertical: 12,
|
||||||
|
borderBottomWidth: 0.5,
|
||||||
|
borderBottomColor: "#ddd",
|
||||||
|
},
|
||||||
|
avatar: {
|
||||||
|
width: 45,
|
||||||
|
height: 45,
|
||||||
|
borderRadius: 25,
|
||||||
|
backgroundColor: "#25D366",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
marginRight: 12,
|
||||||
|
},
|
||||||
|
avatarText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
contactInfo: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
contactName: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "600",
|
||||||
|
},
|
||||||
|
contactPhone: {
|
||||||
|
fontSize: 13,
|
||||||
|
color: "gray",
|
||||||
|
},
|
||||||
|
inviteButton: {
|
||||||
|
paddingHorizontal: 14,
|
||||||
|
paddingVertical: 6,
|
||||||
|
borderRadius: 8,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#25D366",
|
||||||
|
},
|
||||||
|
inviteText: {
|
||||||
|
color: "#25D366",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
modalOverlay: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "rgba(0,0,0,0.5)",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
modalContent: {
|
||||||
|
width: "80%",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderRadius: 10,
|
||||||
|
padding: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
modalTitle: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
modalText: {
|
||||||
|
fontSize: 15,
|
||||||
|
marginBottom: 20,
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
modalActions: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
width: "100%",
|
||||||
|
},
|
||||||
|
cancelButton: {
|
||||||
|
flex: 1,
|
||||||
|
marginRight: 10,
|
||||||
|
paddingVertical: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
backgroundColor: "#ddd",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
cancelText: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
sendButton: {
|
||||||
|
flex: 1,
|
||||||
|
marginLeft: 10,
|
||||||
|
paddingVertical: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
backgroundColor: "#25D366",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
sendText: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#fff",
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -23,6 +23,7 @@ import { useFocusEffect, useNavigation } from "@react-navigation/native";
|
|||||||
import { ApiResponse } from "../home/UserProfileStatus";
|
import { ApiResponse } from "../home/UserProfileStatus";
|
||||||
import { BASE_URL } from "../../utils/ApiUrls";
|
import { BASE_URL } from "../../utils/ApiUrls";
|
||||||
import AppView from "../../components/AppView";
|
import AppView from "../../components/AppView";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ type UserProfile = {
|
|||||||
|
|
||||||
const Profile = () => {
|
const Profile = () => {
|
||||||
const navigation = useNavigation<any>();
|
const navigation = useNavigation<any>();
|
||||||
|
const user1 = useSelector((state: any) => state.user);
|
||||||
const [user, setUser] = useState<UserProfile | null>(null);
|
const [user, setUser] = useState<UserProfile | null>(null);
|
||||||
const [fetching, setFetching] = useState(true);
|
const [fetching, setFetching] = useState(true);
|
||||||
const [editing, setEditing] = useState(false);
|
const [editing, setEditing] = useState(false);
|
||||||
@@ -222,7 +224,7 @@ const Profile = () => {
|
|||||||
const response = await fetch(`${BASE_URL}user/profile/status`, {
|
const response = await fetch(`${BASE_URL}user/profile/status`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "/",
|
Accept: "*/*",
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -232,6 +234,7 @@ const Profile = () => {
|
|||||||
console.log("👤 Profile Status Response:", json);
|
console.log("👤 Profile Status Response:", json);
|
||||||
if (json.status === "success") {
|
if (json.status === "success") {
|
||||||
setStatusData(json.data);
|
setStatusData(json.data);
|
||||||
|
console.log("statusData response :", json);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
setError(json.message || "Failed to fetch status");
|
setError(json.message || "Failed to fetch status");
|
||||||
@@ -273,6 +276,8 @@ const Profile = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log("statusData?.role :", statusData?.role);
|
||||||
|
console.log("statusData?.organizerStatus :", statusData?.organizerStatus);
|
||||||
|
|
||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
useCallback(() => {
|
useCallback(() => {
|
||||||
@@ -327,15 +332,28 @@ const Profile = () => {
|
|||||||
{/* Profile Card */}
|
{/* Profile Card */}
|
||||||
<View style={styles.profileCard}>
|
<View style={styles.profileCard}>
|
||||||
{/* Profile Image Section */}
|
{/* Profile Image Section */}
|
||||||
{user?.role !== "USER"
|
{
|
||||||
&&
|
statusData?.role === "USER" && statusData?.organizerStatus !== "NOT_APPLIED" ? (
|
||||||
(user?.role === "ORGANIZER" &&
|
<Text
|
||||||
(user?.organizerStatus === "NOT_APPLIED" || user?.organizerStatus !== "PENDING")) ? (
|
style={{
|
||||||
<Text style={{ color: "#64748b", marginBottom: 16, textAlign: 'center', fontSize: 18 }}>Your Role: {user.role} | Organizer Status: {user.organizerStatus}</Text>
|
color: "#64748b",
|
||||||
) : (
|
marginBottom: 16,
|
||||||
<SwitchNavigator role={user?.role || ''} status={user?.organizerStatus === "NOT_APPLIED" ? '' : user?.organizerStatus || ''} />
|
textAlign: "center",
|
||||||
|
fontSize: 18,
|
||||||
)}
|
}}
|
||||||
|
>
|
||||||
|
Your Role: {statusData.role} | Organizer Status: {statusData.organizerStatus}
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
statusData?.role !== "ORGANIZER" && (
|
||||||
|
<SwitchNavigator
|
||||||
|
role={statusData?.role || ""}
|
||||||
|
status={statusData?.organizerStatus || ""}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
<View style={styles.profileImageSection}>
|
<View style={styles.profileImageSection}>
|
||||||
<View style={styles.avatarContainer}>
|
<View style={styles.avatarContainer}>
|
||||||
<Image
|
<Image
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import React, { useState } from "react";
|
|||||||
import { View, Text, StyleSheet, Switch } from "react-native";
|
import { View, Text, StyleSheet, Switch } from "react-native";
|
||||||
import { useNavigation } from "@react-navigation/native";
|
import { useNavigation } from "@react-navigation/native";
|
||||||
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
|
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
|
||||||
import colors from "../../components/colors";
|
|
||||||
|
|
||||||
type RootStackParamList = {
|
type RootStackParamList = {
|
||||||
BecomeOrg: undefined;
|
BecomeOrg: undefined;
|
||||||
@@ -25,10 +24,6 @@ const SwitchNavigator: React.FC<SwitchNavigatorProps> = ({ role, status }) => {
|
|||||||
|
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
navigation.navigate("BecomeOrg"); // Navigate when ON
|
navigation.navigate("BecomeOrg"); // Navigate when ON
|
||||||
setTimeout(() => {
|
|
||||||
setIsEnabled(false);
|
|
||||||
}, 2000);
|
|
||||||
// Reset switch to OFF after navigation
|
|
||||||
} else {
|
} else {
|
||||||
navigation.navigate("Profile"); // Navigate when OFF
|
navigation.navigate("Profile"); // Navigate when OFF
|
||||||
}
|
}
|
||||||
@@ -40,18 +35,17 @@ const SwitchNavigator: React.FC<SwitchNavigatorProps> = ({ role, status }) => {
|
|||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.text}>
|
<Text style={styles.text}>
|
||||||
{!isEnabled && role !== "USER"
|
{!isEnabled && role !== "USER"
|
||||||
? "Become an Organizer"
|
? "Become an Organizer"
|
||||||
: `Request Organizer Role ${status}`}
|
: `Request Organizer Role ${status}`}
|
||||||
</Text>
|
</Text>
|
||||||
{role !== "USER" ? (
|
<Switch
|
||||||
<Switch
|
trackColor={{ false: "#767577", true: "#81b0ff" }}
|
||||||
trackColor={{ false: "#767577", true: colors.textLight }}
|
thumbColor={isEnabled ? "#007AFF" : "#f4f3f4"}
|
||||||
thumbColor={isEnabled ? colors.pastelBlue : "#f4f3f4"}
|
ios_backgroundColor="#3e3e3e"
|
||||||
ios_backgroundColor="#3e3e3e"
|
onValueChange={toggleSwitch}
|
||||||
onValueChange={toggleSwitch}
|
value={isEnabled}
|
||||||
value={isEnabled}
|
/>
|
||||||
/>) : <View> <Text> </Text></View>}
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user