all over
This commit is contained in:
@@ -52,12 +52,12 @@ export default function GroupCreationForm() {
|
||||
const newErrors: any = {};
|
||||
if (!form.groupName.trim()) newErrors.groupName = "Group name is required.";
|
||||
if (!form.description.trim()) newErrors.description = "Description is required.";
|
||||
if (!form.minParticipants || Number(form.minParticipants) <= 1) newErrors.minParticipants = "Min participants must be at least 2.";
|
||||
if (!form.minParticipants || Number(form.minParticipants) <= 0) newErrors.minParticipants = "Min participants must be at least 1.";
|
||||
if (!form.maxParticipants || Number(form.maxParticipants) < Number(form.minParticipants)) newErrors.maxParticipants = "Max must be greater than or equal to min.";
|
||||
if (!form.contributionAmount || Number(form.contributionAmount) <= 0) newErrors.contributionAmount = "Amount must be greater than 0.";
|
||||
// if (form.cycleType === "CUSTOM" && (!form.customCycleDays || Number(form.customCycleDays) <= 0)) newErrors.customCycleDays = "Custom days must be greater than 0.";
|
||||
if (form.lateFeeMode && (!form.lateFeeValue || Number(form.lateFeeValue) <= 0)) newErrors.lateFeeValue = "Late fee value is required.";
|
||||
|
||||
if (form.cycleType === "CUSTOM" && (!form.customCycleDays || Number(form.customCycleDays) <= 0)) newErrors.customCycleDays = "Custom days must be greater than 0.";
|
||||
if (!form.lateFeeMode && (!form.lateFeeValue || Number(form.lateFeeValue) <= 0)) newErrors.lateFeeValue = "Late fee value is required.";
|
||||
console.log("new errors : ", newErrors)
|
||||
setErrors(newErrors);
|
||||
return Object.keys(newErrors).length === 0;
|
||||
};
|
||||
@@ -82,7 +82,6 @@ export default function GroupCreationForm() {
|
||||
|
||||
|
||||
return (
|
||||
|
||||
<KeyboardAvoidingView
|
||||
style={{ flex: 1, backgroundColor: "#f5f6fa", paddingTop: Platform.OS === "android" ? 40 : 0 }}
|
||||
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
||||
|
||||
@@ -178,11 +178,11 @@ export default function GroupScreen() {
|
||||
if (res.statusCode === 200) {
|
||||
Alert.alert("Success", "You requested to join the group.");
|
||||
} else {
|
||||
Alert.alert("Error", res.message || "Failed to join group.");
|
||||
// Alert.alert("Error", res.message || "Failed to join group.");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Join Group Error:", error);
|
||||
Alert.alert("Error", "An unexpected error occurred.");
|
||||
// Alert.alert("Error", "An unexpected error occurred.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ const handleSubmit = async () => {
|
||||
Alert.alert("Success", "Organizer registered successfully!");
|
||||
} catch (err: any) {
|
||||
console.error("❌ Register Error:", err?.response?.data || err.message);
|
||||
Alert.alert("Error", "Failed to register. Please try again.");
|
||||
// Alert.alert("Error", "Failed to register. Please try again.");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ const RequestList: React.FC = () => {
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : "An unknown error occurred";
|
||||
Alert.alert("Error", `Failed to accept request: ${errorMessage}`);
|
||||
// Alert.alert("Error", `Failed to accept request: ${errorMessage}`);
|
||||
console.error("Accept Error:", error);
|
||||
} finally {
|
||||
setProcessingRequest(null);
|
||||
@@ -198,7 +198,7 @@ const RequestList: React.FC = () => {
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : "An unknown error occurred";
|
||||
Alert.alert("Error", `Failed to decline request: ${errorMessage}`);
|
||||
// Alert.alert("Error", `Failed to decline request: ${errorMessage}`);
|
||||
console.error("Decline Error:", error);
|
||||
} finally {
|
||||
setProcessingRequest(null);
|
||||
|
||||
@@ -84,7 +84,7 @@ const UserHome = () => {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ Error fetching groups:", error);
|
||||
Alert.alert("Error", "Could not connect to server");
|
||||
// Alert.alert("Error", "Could not connect to server");
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
@@ -22,12 +22,14 @@ import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import { CompositeScreenProps, useNavigation } from '@react-navigation/native';
|
||||
import { BottomTabScreenProps } from '@react-navigation/bottom-tabs';
|
||||
// Adjust path
|
||||
import { UPLOAD_GROUP_IMAGE } from '../../utils/ApiUrls';
|
||||
import { BASE_URL, UPLOAD_GROUP_IMAGE } from '../../utils/ApiUrls';
|
||||
import { launchImageLibrary } from 'react-native-image-picker';
|
||||
import *as Keychain from 'react-native-keychain'
|
||||
import Ionicons from '@react-native-vector-icons/ionicons';
|
||||
import { CustomButton } from '../../components/common/Custom';
|
||||
import { StackNavigationProp } from '@react-navigation/stack';
|
||||
import CustomModal from '../../components/common/CustomModal';
|
||||
import WinnerUser from './WinnerUser';
|
||||
|
||||
|
||||
// --- Type Definitions ---
|
||||
@@ -91,7 +93,9 @@ type EditingCard = 'groupInfo' | 'financialRules' | 'configuration' | null;
|
||||
type GroupManagementNavProp = StackNavigationProp<RootStackParamList, 'EditGroup'>;
|
||||
// --- Main Screen Component ---
|
||||
const EditGroupScreen: React.FC<EditGroupScreenProps> = ({ route }) => {
|
||||
const { groupId } = route.params;
|
||||
const { groupId } = route?.params;
|
||||
|
||||
console.log("edit group screen groupId : ", route?.params)
|
||||
const navigation = useNavigation<GroupManagementNavProp>();
|
||||
|
||||
const [editingCard, setEditingCard] = useState<EditingCard>(null);
|
||||
@@ -118,7 +122,8 @@ const EditGroupScreen: React.FC<EditGroupScreenProps> = ({ route }) => {
|
||||
const [currentCycle, setCurrentCycle] = useState<number | null>(null);
|
||||
const [selectedImage, setSelectedImage] = useState<string | null>()
|
||||
const [imageUpdating, setImageUpdating] = useState<boolean>(false)
|
||||
|
||||
const [selectedUser, setSelectedUser] = useState() as any
|
||||
const [selectedUserModal, setSelectedUserModel] = useState(false)
|
||||
const initializeEditableData = (data: GroupDetails) => {
|
||||
setEditableData({
|
||||
groupName: data.groupName,
|
||||
@@ -139,8 +144,9 @@ const EditGroupScreen: React.FC<EditGroupScreenProps> = ({ route }) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const response = await apiCall(`http://192.168.1.9:9060/api/fund/group/details?groupId=${groupId}`, 'GET') as { status: string; data?: GroupDetails; message?: string };
|
||||
const response = await apiCall(`${BASE_URL}fund/group/details?groupId=${groupId}`, 'GET') as { status: string; data?: GroupDetails; message?: string };
|
||||
console.log("groupDetails", response)
|
||||
|
||||
if (response.status === 'success' && response.data) {
|
||||
setGroupDetails(response.data);
|
||||
initializeEditableData(response.data);
|
||||
@@ -153,19 +159,32 @@ const EditGroupScreen: React.FC<EditGroupScreenProps> = ({ route }) => {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [groupId]);
|
||||
const getPaymentStatus = async()=>{
|
||||
const response = await apiCall(`http://192.168.1.9:9060/api/payments/group/${groupId}/payment/paid`, 'GET') as { status: string; data?: { currentCycle: number ,allPaid: boolean }; message?: string };
|
||||
console.log("paymentStatus",response)
|
||||
if (response.status === 'success') {
|
||||
setPaymentStatus(response.data?.allPaid || false);
|
||||
setCurrentCycle(response.data?.currentCycle || null);
|
||||
}
|
||||
}
|
||||
// const getPaymentStatus = async()=>{
|
||||
// const response = await apiCall(`${BASE_URL}payments/group/${groupId}/payment/paid`, 'GET') as { status: string; data?: { currentCycle: number ,status: boolean }; message?: string };
|
||||
// console.log("paymentStatus",response)
|
||||
// if (response.status === 'success') {
|
||||
// setPaymentStatus(response.data?.status || false);
|
||||
// setCurrentCycle(response.data?.currentCycle || null);
|
||||
// }
|
||||
// }
|
||||
|
||||
const getPaymentStatus = async () => {
|
||||
const response = await apiCall(`${BASE_URL}payments/group/${groupId}/payment/paid`, 'GET') as { status: string; data?: { currentCycle: number, allPaid: boolean, selectedUser: any }; message?: string };
|
||||
console.log("paymentStatus", response)
|
||||
if (response.status === 'success') {
|
||||
setPaymentStatus(response.data?.allPaid || false);
|
||||
setCurrentCycle(response.data?.currentCycle || null);
|
||||
setSelectedUser(response.data)
|
||||
}
|
||||
}
|
||||
|
||||
console.log("groupid : ", groupId)
|
||||
useEffect(() => {
|
||||
getPaymentStatus()
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
fetchGroupDetails();
|
||||
getPaymentStatus();
|
||||
}, [fetchGroupDetails]);
|
||||
|
||||
|
||||
@@ -188,7 +207,7 @@ const getPaymentStatus = async()=>{
|
||||
|
||||
setSaving(true);
|
||||
try {
|
||||
await apiCall(`http://192.168.1.9:9060/api/fund/groups/${groupDetails.id}/edit`, 'PUT', editableData);
|
||||
await apiCall(`${BASE_URL}fund/groups/${groupDetails.id}/edit`, 'PUT', editableData);
|
||||
Alert.alert('Success', 'Group has been updated.');
|
||||
setEditingCard(null);
|
||||
await fetchGroupDetails();
|
||||
@@ -198,10 +217,14 @@ const getPaymentStatus = async()=>{
|
||||
setSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const handleDistribute = async () => {
|
||||
navigation.navigate('RandomSelectUserScreen', { groupId: groupDetails?.id || '', cycleNumber: currentCycle || 0 });
|
||||
navigation.navigate('RandomSelectUserScreen', { groupId , cycleNumber: currentCycle || 0 });
|
||||
};
|
||||
|
||||
|
||||
|
||||
const handleStartGroup = async () => {
|
||||
if (!groupDetails) return;
|
||||
|
||||
@@ -216,9 +239,10 @@ const getPaymentStatus = async()=>{
|
||||
onPress: async () => {
|
||||
setStarting(true);
|
||||
try {
|
||||
await apiCall(`http://192.168.1.9:9060/api/fund/group/start?groupId=${groupDetails.id}`, 'GET');
|
||||
await apiCall(`${BASE_URL}fund/group/start?groupId=${groupDetails.id}`, 'GET');
|
||||
Alert.alert('Success', 'Group has been started successfully.');
|
||||
await fetchGroupDetails();
|
||||
navigation.goBack()
|
||||
} catch (e: any) {
|
||||
Alert.alert('Start Error', e.message || 'An unexpected error occurred.');
|
||||
} finally {
|
||||
@@ -235,7 +259,7 @@ const getPaymentStatus = async()=>{
|
||||
if (!groupDetails) return;
|
||||
setInviting(true);
|
||||
try {
|
||||
const response = await apiCall(`http://192.168.1.9:9060/api/invite/generate?groupId=${groupDetails.id}`, 'GET') as { data?: string };
|
||||
const response = await apiCall(`${BASE_URL}invite/generate?groupId=${groupDetails.id}`, 'GET') as { data?: string };
|
||||
|
||||
|
||||
const inviteLink = response.data;
|
||||
@@ -354,6 +378,7 @@ const getPaymentStatus = async()=>{
|
||||
const isInvitable = groupDetails.status === 'APPROVED';
|
||||
const canStartGroup = groupDetails.status === 'APPROVED' && groupDetails.totalParticipants >= groupDetails.minParticipants;
|
||||
|
||||
console.log(" myu status : ", groupDetails.status)
|
||||
// const pickImage = () => {
|
||||
// launchImageLibrary({ mediaType: "photo", quality: 0.5 }, (response) => {
|
||||
// if (response.didCancel) return;
|
||||
@@ -403,7 +428,7 @@ const getPaymentStatus = async()=>{
|
||||
|
||||
console.log("✅ Image selected:", {
|
||||
uri: selectedImage.uri,
|
||||
size: (selectedImage.fileSize / 1024).toFixed(2) + "KB",
|
||||
size: (selectedImage?.fileSize / 1024).toFixed(2) + "KB",
|
||||
width: selectedImage.width,
|
||||
height: selectedImage.height
|
||||
});
|
||||
@@ -461,7 +486,7 @@ const getPaymentStatus = async()=>{
|
||||
|
||||
} catch (error: any) {
|
||||
console.error("❌ Error updating group image:", error);
|
||||
Alert.alert("Error", error.message || "Could not update group image");
|
||||
// Alert.alert("Error", error.message || "Could not update group image");
|
||||
} finally {
|
||||
setImageUpdating(false);
|
||||
}
|
||||
@@ -580,7 +605,7 @@ const getPaymentStatus = async()=>{
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
{paymentStatus && (
|
||||
{selectedUser?.cycleStatus !== "PENDING_PAYMENTS" && groupDetails.status === 'ACTIVE' &&(
|
||||
<View style={styles.floatingButtonContainer}>
|
||||
<TouchableOpacity
|
||||
style={styles.activateButton}
|
||||
@@ -594,7 +619,24 @@ const getPaymentStatus = async()=>{
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
selectedUser?.selectedUser !== null && selectedUser?.cycleStatus === "READY_FOR_WITHDRAWAL" && selectedUser?.canProceedToWithdrawal &&
|
||||
<View style={styles.floatingButtonContainer}>
|
||||
<CustomButton
|
||||
buttonBackground={colors?.pastelBlue}
|
||||
style={{ paddingHorizontal: 20 }}
|
||||
title="View Winner of this Cycle"
|
||||
onPress={() => setSelectedUserModel(true)}
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
|
||||
{
|
||||
selectedUserModal && <WinnerUser groupId={groupId} data={selectedUser} visible={selectedUserModal} onClose={() => setSelectedUserModel(false)} />
|
||||
}
|
||||
</AppView>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -108,7 +108,7 @@ const ManagementScreen: FC = () => {
|
||||
throw new Error(res?.message || failureMessage);
|
||||
}
|
||||
} catch (err: any) {
|
||||
Alert.alert("Error", err.message || "An unexpected error occurred.");
|
||||
// Alert.alert("Error", err.message || "An unexpected error occurred.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Ionicons } from "@react-native-vector-icons/ionicons";
|
||||
import colors from '../../components/colors';
|
||||
import AppView from '../../components/AppView';
|
||||
import { apiCall } from '../../utils/ApiHelper';
|
||||
import { BASE_URL } from '../../utils/ApiUrls';
|
||||
|
||||
// --- CONSTANTS ---
|
||||
const API_BASE_URL = 'http://192.168.1.9:9060/api/payments';
|
||||
@@ -73,14 +74,17 @@ const Payments: React.FC = () => {
|
||||
const fetchPaymentDetails = useCallback(async () => {
|
||||
if (!refreshing) setLoading(true);
|
||||
try {
|
||||
const response = await apiCall(`${API_BASE_URL}/current/payment/details/${groupId}`, 'GET') as ApiResponse<PaymentDetails>;
|
||||
const response = await apiCall(`${BASE_URL}payments/current/payment/details/${groupId}`, 'GET') as ApiResponse<PaymentDetails>;
|
||||
|
||||
console.log("payment response :", response)
|
||||
if (response && response.statusCode === 200) {
|
||||
setPaymentDetails(response.data);
|
||||
} else {
|
||||
Alert.alert("Error", response?.message || "Failed to fetch details.");
|
||||
}
|
||||
} catch (error: any) {
|
||||
Alert.alert("Error", error.message || "An unexpected error occurred.");
|
||||
// Alert.alert("Error", error.message || "An unexpected error occurred.");
|
||||
console.log("payment error : ", error)
|
||||
} finally {
|
||||
setLoading(false);
|
||||
setRefreshing(false);
|
||||
@@ -122,9 +126,9 @@ const Payments: React.FC = () => {
|
||||
|
||||
try {
|
||||
// Construct the exact URL as provided
|
||||
const url = `${API_BASE_URL}/groups/${groupId}/cycles/${paymentDetails.currentCycle}/waive/${currentParticipant.userId}?amountToWaive=${amountToWaive}`;
|
||||
const url = `${BASE_URL}groups/${groupId}/cycles/${paymentDetails.currentCycle}/waive/${currentParticipant.userId}?amountToWaive=${amountToWaive}`;
|
||||
|
||||
const response = await apiCall(url, 'PUT', {}); // Body is empty as amount is in URL
|
||||
const response = await apiCall(url, 'PUT', {}) as any; // Body is empty as amount is in URL
|
||||
|
||||
if (response && response.statusCode === 200) {
|
||||
Alert.alert("Success", `₹${amountToWaive} has been waived successfully.`);
|
||||
|
||||
@@ -4,14 +4,17 @@ import { apiCall } from '../../utils/ApiHelper';
|
||||
import { Ionicons } from "@react-native-vector-icons/ionicons";
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import ContributionDetails from '../ContributionScreen';
|
||||
import { BASE_URL } from '../../utils/ApiUrls';
|
||||
|
||||
const { width } = Dimensions.get('window');
|
||||
const NUM_COLUMNS = 3;
|
||||
const ITEM_SIZE = width / NUM_COLUMNS - 20;
|
||||
|
||||
const RandomSelectUserScreen: React.FC<{ route: any }> = ({ route }) => {
|
||||
const navigation = useNavigation() as never
|
||||
const navigation = useNavigation()
|
||||
const { groupId, cycleNumber } = route.params;
|
||||
|
||||
|
||||
const [users, setUsers] = useState<{ id: string; name: string }[]>([]);
|
||||
const [highlightedIndex, setHighlightedIndex] = useState<number | null>(null);
|
||||
const [winner, setWinner] = useState<{ id: string; name: string } | null>(null);
|
||||
@@ -24,7 +27,7 @@ const RandomSelectUserScreen: React.FC<{ route: any }> = ({ route }) => {
|
||||
useEffect(() => {
|
||||
const fetchParticipants = async () => {
|
||||
try {
|
||||
const response = await apiCall(`http://192.168.1.9:9060/api/fund/group/all/member?groupId=${groupId}`, "GET") as any;
|
||||
const response = await apiCall(`${BASE_URL}fund/group/all/member?groupId=${groupId}`, "GET") as any;
|
||||
if (response.status === 'success' && response.data) {
|
||||
const formattedUsers = response.data.map((u: any) => ({
|
||||
id: u.id,
|
||||
@@ -77,7 +80,7 @@ const RandomSelectUserScreen: React.FC<{ route: any }> = ({ route }) => {
|
||||
const fetchWinner = async () => {
|
||||
const payload = { groupId: groupId };
|
||||
try {
|
||||
const response = await apiCall('http://192.168.1.9:9060/api/fund/method/based/userSelect', 'POST', payload) as any;
|
||||
const response = await apiCall(`${BASE_URL}fund/method/based/userSelect`, 'POST', payload) as any;
|
||||
console.log("random select user response : ", response)
|
||||
if (response.status === 'success' && response.data?.selectedUser?.id) {
|
||||
const winnerData = { id: response?.data?.selectedUser?.id, name: `${response.data.selectedUser.firstName} ${response.data.selectedUser.lastName}` };
|
||||
@@ -92,6 +95,7 @@ const RandomSelectUserScreen: React.FC<{ route: any }> = ({ route }) => {
|
||||
} else {
|
||||
Alert.alert('Error', 'Failed to determine a winner from the API.');
|
||||
}
|
||||
navigation.navigate('EditGroup',{groupId})
|
||||
} catch (error) {
|
||||
// Alert.alert('Error', 'Could not connect to the server to fetch the winner.');
|
||||
} finally {
|
||||
@@ -156,7 +160,6 @@ const RandomSelectUserScreen: React.FC<{ route: any }> = ({ route }) => {
|
||||
</View>
|
||||
)}
|
||||
|
||||
<Button title='Pay' onPress={() => setOpenModal(true)} />
|
||||
{
|
||||
openModal && <ContributionDetails data={undefined} visible={openModal} onClose={() => setOpenModal(false)} onConfirm={() => setOpenModal(false)} />
|
||||
}
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
import React, { useEffect, useRef } from 'react'
|
||||
import { StyleSheet, Text, View, Animated, ToastAndroid } from 'react-native'
|
||||
import { Ionicons } from '@react-native-vector-icons/ionicons'
|
||||
import CustomModal from '../../components/common/CustomModal'
|
||||
import { apiCall } from '../../utils/ApiHelper'
|
||||
import { BASE_URL } from '../../utils/ApiUrls'
|
||||
|
||||
interface WinnerUserProps {
|
||||
data: {
|
||||
withdrawalDone: boolean
|
||||
selectionDone: boolean
|
||||
selectionId: string
|
||||
currentCycle: number
|
||||
pendingParticipants: number
|
||||
withdrawalDetails: any
|
||||
paidParticipants: number
|
||||
selectedUser: {
|
||||
firstName: string
|
||||
lastName: string
|
||||
mobile: string
|
||||
id: string
|
||||
userId: number
|
||||
email: string
|
||||
}
|
||||
cycleEndDate: number[]
|
||||
cycleStartDate: number[]
|
||||
allPaid: boolean
|
||||
selectionDate: number[]
|
||||
totalParticipants: number
|
||||
cycleStatus: string
|
||||
selectionMethod: string
|
||||
canProceedToWithdrawal: boolean
|
||||
}
|
||||
visible: boolean
|
||||
onClose: () => void
|
||||
groupId:string
|
||||
}
|
||||
|
||||
const WinnerUser: React.FC<WinnerUserProps> = ({ data, visible, onClose, groupId }) => {
|
||||
const {
|
||||
withdrawalDone,
|
||||
selectionDone,
|
||||
currentCycle,
|
||||
totalParticipants,
|
||||
paidParticipants,
|
||||
pendingParticipants,
|
||||
allPaid,
|
||||
selectedUser,
|
||||
cycleStatus,
|
||||
selectionMethod,
|
||||
canProceedToWithdrawal,
|
||||
} = data || {}
|
||||
|
||||
const scaleAnim = useRef(new Animated.Value(0)).current
|
||||
const pulseAnim = useRef(new Animated.Value(1)).current
|
||||
const fadeAnim = useRef(new Animated.Value(0)).current
|
||||
|
||||
console.log("winner data : ", data)
|
||||
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
Animated.spring(scaleAnim, {
|
||||
toValue: 1,
|
||||
friction: 5,
|
||||
useNativeDriver: true,
|
||||
}).start()
|
||||
|
||||
Animated.loop(
|
||||
Animated.sequence([
|
||||
Animated.timing(pulseAnim, {
|
||||
toValue: 1.1,
|
||||
duration: 600,
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
Animated.timing(pulseAnim, {
|
||||
toValue: 1,
|
||||
duration: 600,
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
])
|
||||
).start()
|
||||
|
||||
Animated.timing(fadeAnim, {
|
||||
toValue: 1,
|
||||
duration: 1500,
|
||||
useNativeDriver: true,
|
||||
}).start()
|
||||
} else {
|
||||
scaleAnim.setValue(0)
|
||||
pulseAnim.setValue(1)
|
||||
fadeAnim.setValue(0)
|
||||
}
|
||||
}, [visible])
|
||||
|
||||
const onConfirm = async () => {
|
||||
try {
|
||||
const res = await apiCall(`${BASE_URL}payments/withdraw/${groupId}/${data?.selectedUser?.id}`, 'PUT')
|
||||
console.log("res winner user : ", res)
|
||||
ToastAndroid.show('Withdrawal successful', ToastAndroid.SHORT)
|
||||
onClose()
|
||||
} catch (error) {
|
||||
console.log('Confirm payment error : ', error)
|
||||
} finally {
|
||||
onClose()
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<CustomModal
|
||||
visible={visible}
|
||||
onClose={onClose}
|
||||
confirmText={canProceedToWithdrawal ? 'Proceed to Withdraw' : 'Close'}
|
||||
onConfirm={canProceedToWithdrawal ? onConfirm : onClose}
|
||||
>
|
||||
<View style={styles.container}>
|
||||
<Animated.View style={{ transform: [{ scale: scaleAnim }] }}>
|
||||
{/* Header */}
|
||||
<View style={styles.header}>
|
||||
<Ionicons name="trophy" size={24} color="#ff9800" />
|
||||
<Text style={styles.cycle}>Cycle {currentCycle} Winner</Text>
|
||||
<Ionicons name="trophy" size={24} color="#ff9800" />
|
||||
</View>
|
||||
|
||||
{/* Winner Name */}
|
||||
<Animated.Text style={[styles.name, { transform: [{ scale: pulseAnim }] }]}>
|
||||
{selectedUser?.firstName} {selectedUser?.lastName}
|
||||
</Animated.Text>
|
||||
|
||||
{/* Details */}
|
||||
<View style={styles.row}>
|
||||
<Ionicons name="call" size={18} color="#555" />
|
||||
<Text style={styles.label}>Mobile:</Text>
|
||||
<Text style={styles.value}>{selectedUser?.mobile}</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.row}>
|
||||
<Ionicons name="mail" size={18} color="#555" />
|
||||
<Text style={styles.label}>Email:</Text>
|
||||
<Text style={styles.value}>{selectedUser?.email}</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.row}>
|
||||
<Ionicons name="people" size={18} color="#555" />
|
||||
<Text style={styles.label}>Total Participants:</Text>
|
||||
<Text style={styles.value}>{totalParticipants}</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.row}>
|
||||
<Ionicons name="cash" size={18} color="#555" />
|
||||
<Text style={styles.label}>Paid Participants:</Text>
|
||||
<Text style={styles.value}>{paidParticipants}</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.row}>
|
||||
<Ionicons name="hourglass" size={18} color="#555" />
|
||||
<Text style={styles.label}>Pending Participants:</Text>
|
||||
<Text style={styles.value}>{pendingParticipants}</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.row}>
|
||||
<Ionicons
|
||||
name={allPaid ? 'checkmark-circle' : 'close-circle'}
|
||||
size={18}
|
||||
color={allPaid ? '#4caf50' : '#f44336'}
|
||||
/>
|
||||
<Text style={styles.label}>All Paid:</Text>
|
||||
<Text style={styles.value}>{allPaid ? 'Yes' : 'No'}</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.row}>
|
||||
<Ionicons
|
||||
name={withdrawalDone ? 'checkmark-done' : 'time'}
|
||||
size={18}
|
||||
color={withdrawalDone ? '#4caf50' : '#ff9800'}
|
||||
/>
|
||||
<Text style={styles.label}>Withdrawal Status:</Text>
|
||||
<Text style={styles.value}>{withdrawalDone ? 'Completed' : 'Pending'}</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.row}>
|
||||
<Ionicons name="git-branch" size={18} color="#555" />
|
||||
<Text style={styles.label}>Selection Method:</Text>
|
||||
<Text style={styles.value}>{selectionMethod}</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.row}>
|
||||
<Ionicons name="stats-chart" size={18} color="#555" />
|
||||
<Text style={styles.label}>Cycle Status:</Text>
|
||||
<Text style={styles.value}>{cycleStatus}</Text>
|
||||
</View>
|
||||
|
||||
<Animated.Text style={[styles.congrats, { opacity: fadeAnim }]}>
|
||||
{selectionDone ? 'Congratulations!' : 'Selection Pending'}
|
||||
</Animated.Text>
|
||||
</Animated.View>
|
||||
</View>
|
||||
</CustomModal>
|
||||
)
|
||||
}
|
||||
|
||||
export default WinnerUser
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
padding: 20,
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
marginBottom: 16,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
cycle: {
|
||||
fontSize: 18,
|
||||
fontWeight: '700',
|
||||
color: '#ff9800',
|
||||
marginHorizontal: 8,
|
||||
textAlign: 'center',
|
||||
},
|
||||
name: {
|
||||
fontSize: 22,
|
||||
fontWeight: '800',
|
||||
color: '#333',
|
||||
marginBottom: 20,
|
||||
textAlign: 'center',
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginBottom: 12,
|
||||
},
|
||||
label: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
color: '#555',
|
||||
marginLeft: 6,
|
||||
marginRight: 4,
|
||||
},
|
||||
value: {
|
||||
fontSize: 16,
|
||||
color: '#000',
|
||||
},
|
||||
congrats: {
|
||||
fontSize: 20,
|
||||
fontWeight: '700',
|
||||
color: '#4caf50',
|
||||
marginTop: 20,
|
||||
textAlign: 'center',
|
||||
},
|
||||
})
|
||||
@@ -71,7 +71,7 @@ const BecomeOrg = () => {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ Registration error:", error);
|
||||
Alert.alert("Error", "An unexpected error occurred. Please try again.");
|
||||
// Alert.alert("Error", "An unexpected error occurred. Please try again.");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ const EditBankDetails = () => {
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error("Error updating bank details:", error);
|
||||
Alert.alert("Error", error.message || "An unexpected error occurred. Please try again.");
|
||||
// Alert.alert("Error", error.message || "An unexpected error occurred. Please try again.");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ const Profile = () => {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ Error fetching profile:", error);
|
||||
Alert.alert("Error", "Could not connect to server");
|
||||
// Alert.alert("Error", "Could not connect to server");
|
||||
} finally {
|
||||
setFetching(false);
|
||||
}
|
||||
@@ -164,7 +164,7 @@ const Profile = () => {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ Error updating profile:", error);
|
||||
Alert.alert("Error", "Could not update profile");
|
||||
// Alert.alert("Error", "Could not update profile");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -245,7 +245,7 @@ const Profile = () => {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ Error updating profile image:", error);
|
||||
Alert.alert("Error", "Could not update profile image");
|
||||
// Alert.alert("Error", "Could not update profile image");
|
||||
} finally {
|
||||
setImageUpdating(false);
|
||||
}
|
||||
@@ -311,7 +311,7 @@ const Profile = () => {
|
||||
navigation.replace("Login");
|
||||
} catch (error) {
|
||||
console.error("Logout error:", error);
|
||||
Alert.alert("Error", "Failed to log out. Please try again.");
|
||||
// Alert.alert("Error", "Failed to log out. Please try again.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export const BASE_URL = "http://192.168.1.9:9060/api/"
|
||||
|
||||
// export const BASE_URL = "https://api.godemo.in/FundCollect/api/"
|
||||
export const BASE_URL = "http://192.168.1.9:9060/api/"
|
||||
export const LOGIN_URL = `${BASE_URL}user/generate/otp?mobiles=`
|
||||
export const VARIFY_OTP_URL = `${BASE_URL}user/otp/verify`
|
||||
export const ORGRAGISTRATION = `${BASE_URL}organizer/registration/apply`
|
||||
|
||||
@@ -56,7 +56,7 @@ export const fetchUserProfile = async () => {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ Error fetching profile:", error);
|
||||
Alert.alert("Error", "Could not connect to server");
|
||||
// Alert.alert("Error", "Could not connect to server");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user