currect api payload

This commit is contained in:
Jaanu423
2025-09-29 16:15:50 +05:30
parent b78d29ce6c
commit f854bd6765
7 changed files with 62 additions and 45 deletions
+7 -3
View File
@@ -6,7 +6,7 @@ import {
Animated, Animated,
Easing, Easing,
} from "react-native"; } from "react-native";
import {Ionicons} from "@react-native-vector-icons/ionicons"; import { Ionicons } from "@react-native-vector-icons/ionicons";
import colors from "../components/colors"; import colors from "../components/colors";
import CustomModal from "../components/common/CustomModal"; import CustomModal from "../components/common/CustomModal";
@@ -77,9 +77,13 @@ const ContributionDetails: React.FC<ContributionProps> = ({
> >
<Text style={styles.label}>Base Amount</Text> <Text style={styles.label}>Base Amount</Text>
<Text style={styles.value}>₹{data?.baseAmount}</Text> <Text style={styles.value}>₹{data?.baseAmount}</Text>
{
data?.alreadyPaid ? <Text style={styles?.valueHighlight}>Already Paid Amount</Text> :
<View>
<Text style={styles.label}>Total Payable</Text>
<Text style={styles.valueHighlight}>₹{data?.totalPayable}</Text>
</View>}
<Text style={styles.label}>Total Payable</Text>
<Text style={styles.valueHighlight}>₹{data?.totalPayable}</Text>
<Text style={styles.label}>Due Date</Text> <Text style={styles.label}>Due Date</Text>
<Text style={styles.value}>{data?.dueDate}</Text> <Text style={styles.value}>{data?.dueDate}</Text>
+2 -1
View File
@@ -55,7 +55,7 @@ export default function GroupCreationForm() {
if (!form.minParticipants || Number(form.minParticipants) <= 1) newErrors.minParticipants = "Min participants must be at least 2."; if (!form.minParticipants || Number(form.minParticipants) <= 1) newErrors.minParticipants = "Min participants must be at least 2.";
if (!form.maxParticipants || Number(form.maxParticipants) < Number(form.minParticipants)) newErrors.maxParticipants = "Max must be greater than or equal to min."; 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.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.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.lateFeeMode && (!form.lateFeeValue || Number(form.lateFeeValue) <= 0)) newErrors.lateFeeValue = "Late fee value is required.";
setErrors(newErrors); setErrors(newErrors);
@@ -76,6 +76,7 @@ export default function GroupCreationForm() {
navigation.navigate("GroupReview", { form: payload }); navigation.navigate("GroupReview", { form: payload });
} else { } else {
Alert.alert("Incomplete Form", "Please fill out all required fields correctly."); Alert.alert("Incomplete Form", "Please fill out all required fields correctly.");
setErrors('')
} }
}; };
View File
+12 -10
View File
@@ -44,16 +44,17 @@ interface Group {
const GroupCard = ({ item, onJoin, onView, isGrid }: { item: Group; onJoin: (groupId: string) => void; onView: (group: Group) => void; isGrid?: boolean; }) => { const GroupCard = ({ item, onJoin, onView, isGrid }: { item: Group; onJoin: (groupId: string) => void; onView: (group: Group) => void; isGrid?: boolean; }) => {
const isFull = item.currentParticipants >= item.maxParticipants; const isFull = item.currentParticipants >= item.maxParticipants;
const cardStyle = isGrid ? styles.gridCard : styles.listCard; const cardStyle = isGrid ? styles.gridCard : styles.listCard;
const navigation = useNavigation()
return ( return (
<View style={cardStyle}> <View style={cardStyle}>
{/* <TouchableOpacity onPress={()=> navigation.navigate("GroupDetails" as never)}> */}
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}> <View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}>
<View> <View>
<Text style={styles.groupName} numberOfLines={1}>{item.groupName}</Text> <Text style={styles.groupName} numberOfLines={1}>{item.groupName}</Text>
<Text style={styles.groupDescription} numberOfLines={isGrid ? 2 : 1}>{item.description}</Text> <Text style={styles.groupDescription} numberOfLines={isGrid ? 2 : 1}>{item.description}</Text>
</View> </View>
<Image <Image
source={{ uri: item?.imageBlob !== null ? `data:image/jpeg;base64${item?.imageBlob}` : `https://i.pravatar.cc/150?u=${item.id}` }} source={{ uri: item?.imageBlob !== null ? `data:image/jpeg;base64${item?.imageBlob}` : `https://i.pravatar.cc/150?u=${item.id}` }}
style={{ width: 50, borderWidth: 1, height: 50, borderColor: colors.pastelGreen, borderRadius: 25 }} style={{ width: 50, borderWidth: 1, height: 50, borderColor: colors.pastelGreen, borderRadius: 25 }}
/> />
</View> </View>
@@ -62,6 +63,7 @@ const GroupCard = ({ item, onJoin, onView, isGrid }: { item: Group; onJoin: (gro
<Text style={styles.groupMetaText}>{item.currentParticipants}/{item.maxParticipants} Members</Text> <Text style={styles.groupMetaText}>{item.currentParticipants}/{item.maxParticipants} Members</Text>
<Text style={styles.groupMetaText}>{item.cycleType}</Text> <Text style={styles.groupMetaText}>{item.cycleType}</Text>
</View> </View>
{/* </TouchableOpacity> */}
<View style={styles.buttonContainer}> <View style={styles.buttonContainer}>
{/* <TouchableOpacity style={styles.viewButton} onPress={() => onView(item)}> {/* <TouchableOpacity style={styles.viewButton} onPress={() => onView(item)}>
<Text style={styles.viewButtonText}>View</Text> <Text style={styles.viewButtonText}>View</Text>
@@ -81,7 +83,7 @@ const GroupCard = ({ item, onJoin, onView, isGrid }: { item: Group; onJoin: (gro
const FeaturedGroupCard = ({ item }: { item: Group }) => { const FeaturedGroupCard = ({ item }: { item: Group }) => {
return ( return (
<View style={styles.featuredCard}> <View style={styles.featuredCard}>
<Image source={{ uri: item?.imageBlob !== null ? `data:image/jpeg;base64${item?.imageBlob}` : `https://i.pravatar.cc/150?u=${item.id}` }} style={styles.featuredImage} /> <Image source={{ uri: item?.imageBlob !== null ? `data:image/jpeg;base64${item?.imageBlob}` : `https://i.pravatar.cc/150?u=${item.id}` }} style={styles.featuredImage} />
<View style={styles.featuredContent}> <View style={styles.featuredContent}>
<Text style={styles.featuredName} numberOfLines={1}>{item.groupName}</Text> <Text style={styles.featuredName} numberOfLines={1}>{item.groupName}</Text>
<Text style={styles.featuredCreator}>by {item.createdByName}</Text> <Text style={styles.featuredCreator}>by {item.createdByName}</Text>
@@ -167,11 +169,11 @@ export default function GroupScreen() {
console.log("JOIN_GROUP_URL response:", res); console.log("JOIN_GROUP_URL response:", res);
// if (res.statusCode === 200) { if (res.statusCode === 200) {
// Alert.alert("Success", "You requested to join the group."); Alert.alert("Success", "You requested to join the group.");
// } else { } else {
// Alert.alert("Error", res.message || "Failed to join group."); Alert.alert("Error", res.message || "Failed to join group.");
// } }
} catch (error) { } catch (error) {
console.error("Join Group Error:", error); console.error("Join Group Error:", error);
Alert.alert("Error", "An unexpected error occurred."); Alert.alert("Error", "An unexpected error occurred.");
@@ -307,7 +309,7 @@ export default function GroupScreen() {
<View style={styles.tabHeader}> <View style={styles.tabHeader}>
<View style={styles.segmentedControl}> <View style={styles.segmentedControl}>
{role === "ORGANIZER" ? (["My Groups", "Joined", "Public"].map((tab) => ( {role === "ORGANIZER" ? (["Public"].map((tab) => (
<TouchableOpacity key={tab} style={[styles.segmentButton, activeTab === tab && styles.segmentButtonActive]} onPress={() => setActiveTab(tab)}> <TouchableOpacity key={tab} style={[styles.segmentButton, activeTab === tab && styles.segmentButtonActive]} onPress={() => setActiveTab(tab)}>
<Text style={[styles.segmentText, activeTab === tab && styles.segmentTextActive]}>{tab}</Text> <Text style={[styles.segmentText, activeTab === tab && styles.segmentTextActive]}>{tab}</Text>
</TouchableOpacity> </TouchableOpacity>
@@ -358,7 +360,7 @@ const styles = StyleSheet.create({
listCard: { backgroundColor: '#fff', padding: 16, borderRadius: 12, marginBottom: 12, elevation: 1 }, listCard: { backgroundColor: '#fff', padding: 16, borderRadius: 12, marginBottom: 12, elevation: 1 },
gridCard: { backgroundColor: '#fff', padding: 12, borderRadius: 12, marginBottom: 12, elevation: 1, width: (width - 48) / 2 }, gridCard: { backgroundColor: '#fff', padding: 12, borderRadius: 12, marginBottom: 12, elevation: 1, width: (width - 48) / 2 },
groupName: { fontSize: 16, fontWeight: 'bold', color: '#333' }, groupName: { fontSize: 16, fontWeight: 'bold', color: '#333' },
groupDescription: { fontSize: 14, color: '#666', marginVertical: 4 }, groupDescription: { fontSize: 14, color: '#666', marginVertical: 4, width: '40%' },
groupMeta: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 8, borderTopWidth: 1, borderTopColor: '#f0f0f0', paddingTop: 8, marginBottom: 10 }, groupMeta: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 8, borderTopWidth: 1, borderTopColor: '#f0f0f0', paddingTop: 8, marginBottom: 10 },
groupMetaText: { fontSize: 12, color: '#888', fontWeight: '500', textTransform: 'capitalize' }, groupMetaText: { fontSize: 12, color: '#888', fontWeight: '500', textTransform: 'capitalize' },
emptyText: { textAlign: 'center', marginTop: 40, fontSize: 16, color: '#888' }, emptyText: { textAlign: 'center', marginTop: 40, fontSize: 16, color: '#888' },
+3 -2
View File
@@ -37,8 +37,9 @@ const GroupDetails = () => {
const [memberData, setMemberData] = useState<Member[]>([]); const [memberData, setMemberData] = useState<Member[]>([]);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [openModal, setOpenModal] = useState(false) const [openModal, setOpenModal] = useState(false)
const [payable, setPayable] = useState() const [payable, setPayable] = useState() as any
console.log("route param ggggggggggg : ", route?.params)
// Group object // Group object
const group = { const group = {
id: route.params.item?.id, id: route.params.item?.id,
@@ -108,7 +109,7 @@ const GroupDetails = () => {
const confirmPayment = async () => { const confirmPayment = async () => {
try { try {
const res = await apiCall(`${BASE_URL}payments/contribute/${group?.id}?amount=${group?.collected}`, 'POST') as any const res = await apiCall(`${BASE_URL}payments/contribute/${group?.id}?amount=${payable?.totalPayable}`, 'POST') as any
console.log("payment response : ", res) console.log("payment response : ", res)
if (res.status) { if (res.status) {
ToastAndroid.show('Payment done!', ToastAndroid.SHORT) ToastAndroid.show('Payment done!', ToastAndroid.SHORT)
+31 -22
View File
@@ -153,14 +153,23 @@ const EditGroupScreen: React.FC<EditGroupScreenProps> = ({ route }) => {
setLoading(false); setLoading(false);
} }
}, [groupId]); }, [groupId]);
const getPaymentStatus = async()=>{ // const getPaymentStatus = async()=>{
const response = await apiCall(`https://exotic-humpback-mistakenly.ngrok-free.app/api/payments/group/${groupId}/payment/paid`, 'GET') as { status: string; data?: { currentCycle: number ,status: boolean }; message?: string }; // const response = await apiCall(`https://exotic-humpback-mistakenly.ngrok-free.app/api/payments/group/${groupId}/payment/paid`, 'GET') as { status: string; data?: { currentCycle: number ,status: boolean }; message?: string };
console.log("paymentStatus",response) // console.log("paymentStatus",response)
if (response.status === 'success') { // if (response.status === 'success') {
setPaymentStatus(response.data?.status || false); // setPaymentStatus(response.data?.status || false);
setCurrentCycle(response.data?.currentCycle || null); // setCurrentCycle(response.data?.currentCycle || null);
// }
// }
const getPaymentStatus = async () => {
const response = await apiCall(`https://exotic-humpback-mistakenly.ngrok-free.app/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);
}
} }
}
useEffect(() => { useEffect(() => {
@@ -199,7 +208,7 @@ const getPaymentStatus = async()=>{
} }
}; };
const handleDistribute = async () => { const handleDistribute = async () => {
navigation.navigate('RandomSelectUserScreen', { groupId: groupDetails?.id || '', cycleNumber: currentCycle || 0 }); navigation.navigate('RandomSelectUserScreen', { groupId: groupDetails?.id || '', cycleNumber: currentCycle || 0 });
}; };
const handleStartGroup = async () => { const handleStartGroup = async () => {
@@ -235,7 +244,7 @@ const getPaymentStatus = async()=>{
if (!groupDetails) return; if (!groupDetails) return;
setInviting(true); setInviting(true);
try { try {
const response = await apiCall(`https://exotic-humpback-mistakenly.ngrok-free.app/api/invite/generate?groupId=${groupDetails.id}`, 'GET') as { data?: string }; const response = await apiCall(`https://exotic-humpback-mistakenly.ngrok-free.app/api/invite/generate?groupId=${groupDetails.id}`, 'GET') as { data?: string };
const inviteLink = response.data; const inviteLink = response.data;
@@ -523,18 +532,18 @@ const getPaymentStatus = async()=>{
{groupDetails.status === 'ACTIVE' ? {groupDetails.status === 'ACTIVE' ?
renderCard('Financial Rules', [ renderCard('Financial Rules', [
{ field: 'contributionAmount', label: 'Contribution', displayValue: () => `₹${groupDetails.contributionAmount.toLocaleString('en-IN')}` }, { field: 'contributionAmount', label: 'Contribution', displayValue: () => `₹${groupDetails.contributionAmount.toLocaleString('en-IN')}` },
{ field: 'latePaymentCharge', label: 'Late Fee', displayValue: () => `₹${(groupDetails.latePaymentCharge ?? 0).toLocaleString('en-IN')}` }, { field: 'latePaymentCharge', label: 'Late Fee', displayValue: () => `₹${(groupDetails.latePaymentCharge ?? 0).toLocaleString('en-IN')}` },
{ field: 'maxParticipants', label: 'Current Participants', displayValue: () => `${groupDetails.totalParticipants}` }, { field: 'maxParticipants', label: 'Current Participants', displayValue: () => `${groupDetails.totalParticipants}` },
], 'financialRules') ], 'financialRules')
: :
renderCard('Financial Rules', [ renderCard('Financial Rules', [
{ field: 'contributionAmount', label: 'Contribution', displayValue: () => `₹${groupDetails.contributionAmount.toLocaleString('en-IN')}` }, { field: 'contributionAmount', label: 'Contribution', displayValue: () => `₹${groupDetails.contributionAmount.toLocaleString('en-IN')}` },
{ field: 'maxParticipants', label: 'Max Participants', displayValue: () => `${groupDetails.totalParticipants} / ${groupDetails.maxParticipants}` }, { field: 'maxParticipants', label: 'Max Participants', displayValue: () => `${groupDetails.totalParticipants} / ${groupDetails.maxParticipants}` },
{ field: 'minParticipants', label: 'Min Participants', displayValue: () => `${groupDetails.minParticipants}` }, { field: 'minParticipants', label: 'Min Participants', displayValue: () => `${groupDetails.minParticipants}` },
{ field: 'latePaymentCharge', label: 'Late Fee', displayValue: () => `₹${(groupDetails.latePaymentCharge ?? 0).toLocaleString('en-IN')}` }, { field: 'latePaymentCharge', label: 'Late Fee', displayValue: () => `₹${(groupDetails.latePaymentCharge ?? 0).toLocaleString('en-IN')}` },
], 'financialRules') ], 'financialRules')
} }
@@ -580,7 +589,7 @@ const getPaymentStatus = async()=>{
</TouchableOpacity> </TouchableOpacity>
</View> </View>
)} )}
{paymentStatus && ( {paymentStatus && (
<View style={styles.floatingButtonContainer}> <View style={styles.floatingButtonContainer}>
<TouchableOpacity <TouchableOpacity
style={styles.activateButton} style={styles.activateButton}
@@ -78,9 +78,9 @@ const RandomSelectUserScreen: React.FC<{ route: any }> = ({ route }) => {
const payload = { groupId: groupId }; const payload = { groupId: groupId };
try { try {
const response = await apiCall('https://exotic-humpback-mistakenly.ngrok-free.app/api/fund/method/based/userSelect', 'POST', payload) as any; const response = await apiCall('https://exotic-humpback-mistakenly.ngrok-free.app/api/fund/method/based/userSelect', 'POST', payload) as any;
console.log("random select user response : ", response)
if (response.status === 'success' && response.data?.id) { if (response.status === 'success' && response.data?.selectedUser?.id) {
const winnerData = { id: response.data.id, name: `${response.data.firstName} ${response.data.lastName}` }; const winnerData = { id: response?.data?.selectedUser?.id, name: `${response.data.selectedUser.firstName} ${response.data.selectedUser.lastName}` };
const winnerIndex = users.findIndex(u => u.id === winnerData.id); const winnerIndex = users.findIndex(u => u.id === winnerData.id);
if (winnerIndex !== -1) { if (winnerIndex !== -1) {
@@ -93,7 +93,7 @@ const RandomSelectUserScreen: React.FC<{ route: any }> = ({ route }) => {
Alert.alert('Error', 'Failed to determine a winner from the API.'); Alert.alert('Error', 'Failed to determine a winner from the API.');
} }
} catch (error) { } catch (error) {
Alert.alert('Error', 'Could not connect to the server to fetch the winner.'); // Alert.alert('Error', 'Could not connect to the server to fetch the winner.');
} finally { } finally {
setIsAnimating(false); setIsAnimating(false);
} }