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,
Easing,
} 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 CustomModal from "../components/common/CustomModal";
@@ -77,9 +77,13 @@ const ContributionDetails: React.FC<ContributionProps> = ({
>
<Text style={styles.label}>Base Amount</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.value}>{data?.dueDate}</Text>
+3 -2
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.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.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.";
setErrors(newErrors);
@@ -76,6 +76,7 @@ export default function GroupCreationForm() {
navigation.navigate("GroupReview", { form: payload });
} else {
Alert.alert("Incomplete Form", "Please fill out all required fields correctly.");
setErrors('')
}
};
@@ -88,7 +89,7 @@ export default function GroupCreationForm() {
>
<ScrollView contentContainerStyle={styles.container} showsVerticalScrollIndicator={false}>
<View style={styles.titleContainer}><Text style={styles.title}>Create New Group</Text></View>
<CustomInput label="Group Name" placeholder="e.g., 'Family Savings'" value={form.groupName} onChangeText={(val) => handleChange("groupName", val)} icon="people" error={errors.groupName} />
<CustomInput label="Description" placeholder="e.g., 'Monthly fund for family needs'" value={form.description} onChangeText={(val) => handleChange("description", val)} multiline icon="document-text" error={errors.description} />
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 isFull = item.currentParticipants >= item.maxParticipants;
const cardStyle = isGrid ? styles.gridCard : styles.listCard;
const navigation = useNavigation()
return (
<View style={cardStyle}>
{/* <TouchableOpacity onPress={()=> navigation.navigate("GroupDetails" as never)}> */}
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}>
<View>
<Text style={styles.groupName} numberOfLines={1}>{item.groupName}</Text>
<Text style={styles.groupDescription} numberOfLines={isGrid ? 2 : 1}>{item.description}</Text>
</View>
<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 }}
/>
</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.cycleType}</Text>
</View>
{/* </TouchableOpacity> */}
<View style={styles.buttonContainer}>
{/* <TouchableOpacity style={styles.viewButton} onPress={() => onView(item)}>
<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 }) => {
return (
<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}>
<Text style={styles.featuredName} numberOfLines={1}>{item.groupName}</Text>
<Text style={styles.featuredCreator}>by {item.createdByName}</Text>
@@ -167,11 +169,11 @@ export default function GroupScreen() {
console.log("JOIN_GROUP_URL response:", res);
// if (res.statusCode === 200) {
// Alert.alert("Success", "You requested to join the group.");
// } else {
// Alert.alert("Error", res.message || "Failed to join group.");
// }
if (res.statusCode === 200) {
Alert.alert("Success", "You requested to join the group.");
} else {
Alert.alert("Error", res.message || "Failed to join group.");
}
} catch (error) {
console.error("Join Group Error:", error);
Alert.alert("Error", "An unexpected error occurred.");
@@ -307,7 +309,7 @@ export default function GroupScreen() {
<View style={styles.tabHeader}>
<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)}>
<Text style={[styles.segmentText, activeTab === tab && styles.segmentTextActive]}>{tab}</Text>
</TouchableOpacity>
@@ -358,7 +360,7 @@ const styles = StyleSheet.create({
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 },
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 },
groupMetaText: { fontSize: 12, color: '#888', fontWeight: '500', textTransform: 'capitalize' },
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 [loading, setLoading] = 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
const group = {
id: route.params.item?.id,
@@ -108,7 +109,7 @@ const GroupDetails = () => {
const confirmPayment = async () => {
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)
if (res.status) {
ToastAndroid.show('Payment done!', ToastAndroid.SHORT)
+33 -24
View File
@@ -153,14 +153,23 @@ const EditGroupScreen: React.FC<EditGroupScreenProps> = ({ route }) => {
setLoading(false);
}
}, [groupId]);
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 };
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(`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)
// if (response.status === 'success') {
// setPaymentStatus(response.data?.status || false);
// 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(() => {
@@ -199,7 +208,7 @@ const getPaymentStatus = 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 () => {
@@ -235,7 +244,7 @@ const getPaymentStatus = async()=>{
if (!groupDetails) return;
setInviting(true);
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;
@@ -411,7 +420,7 @@ const getPaymentStatus = async()=>{
setSelectedImage(selectedImage.uri);
});
};
const handleUpdateImage = async () => {
try {
const credentials = await Keychain.getGenericPassword();
@@ -522,19 +531,19 @@ const getPaymentStatus = async()=>{
], 'groupInfo')}
{groupDetails.status === 'ACTIVE' ?
renderCard('Financial Rules', [
{ field: 'contributionAmount', label: 'Contribution', displayValue: () => `₹${groupDetails.contributionAmount.toLocaleString('en-IN')}` },
{ field: 'latePaymentCharge', label: 'Late Fee', displayValue: () => `₹${(groupDetails.latePaymentCharge ?? 0).toLocaleString('en-IN')}` },
{ field: 'maxParticipants', label: 'Current Participants', displayValue: () => `${groupDetails.totalParticipants}` },
], 'financialRules')
:
renderCard('Financial Rules', [
{ field: 'contributionAmount', label: 'Contribution', displayValue: () => `₹${groupDetails.contributionAmount.toLocaleString('en-IN')}` },
{ field: 'maxParticipants', label: 'Max Participants', displayValue: () => `${groupDetails.totalParticipants} / ${groupDetails.maxParticipants}` },
{ field: 'minParticipants', label: 'Min Participants', displayValue: () => `${groupDetails.minParticipants}` },
{ field: 'latePaymentCharge', label: 'Late Fee', displayValue: () => `₹${(groupDetails.latePaymentCharge ?? 0).toLocaleString('en-IN')}` },
], 'financialRules')
{groupDetails.status === 'ACTIVE' ?
renderCard('Financial Rules', [
{ field: 'contributionAmount', label: 'Contribution', displayValue: () => `₹${groupDetails.contributionAmount.toLocaleString('en-IN')}` },
{ field: 'latePaymentCharge', label: 'Late Fee', displayValue: () => `₹${(groupDetails.latePaymentCharge ?? 0).toLocaleString('en-IN')}` },
{ field: 'maxParticipants', label: 'Current Participants', displayValue: () => `${groupDetails.totalParticipants}` },
], 'financialRules')
:
renderCard('Financial Rules', [
{ field: 'contributionAmount', label: 'Contribution', displayValue: () => `₹${groupDetails.contributionAmount.toLocaleString('en-IN')}` },
{ field: 'maxParticipants', label: 'Max Participants', displayValue: () => `${groupDetails.totalParticipants} / ${groupDetails.maxParticipants}` },
{ field: 'minParticipants', label: 'Min Participants', displayValue: () => `${groupDetails.minParticipants}` },
{ field: 'latePaymentCharge', label: 'Late Fee', displayValue: () => `₹${(groupDetails.latePaymentCharge ?? 0).toLocaleString('en-IN')}` },
], 'financialRules')
}
@@ -580,7 +589,7 @@ const getPaymentStatus = async()=>{
</TouchableOpacity>
</View>
)}
{paymentStatus && (
{paymentStatus && (
<View style={styles.floatingButtonContainer}>
<TouchableOpacity
style={styles.activateButton}
@@ -78,9 +78,9 @@ const RandomSelectUserScreen: React.FC<{ route: any }> = ({ route }) => {
const payload = { groupId: groupId };
try {
const response = await apiCall('https://exotic-humpback-mistakenly.ngrok-free.app/api/fund/method/based/userSelect', 'POST', payload) as any;
if (response.status === 'success' && response.data?.id) {
const winnerData = { id: response.data.id, name: `${response.data.firstName} ${response.data.lastName}` };
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}` };
const winnerIndex = users.findIndex(u => u.id === winnerData.id);
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.');
}
} 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 {
setIsAnimating(false);
}