diff --git a/android/app/release/CircleCollect.apk b/android/app/release/CircleCollect.apk new file mode 100644 index 0000000..bfad9c0 Binary files /dev/null and b/android/app/release/CircleCollect.apk differ diff --git a/android/app/release/baselineProfiles/0/app-release.dm b/android/app/release/baselineProfiles/0/app-release.dm new file mode 100644 index 0000000..a8daac4 Binary files /dev/null and b/android/app/release/baselineProfiles/0/app-release.dm differ diff --git a/android/app/release/baselineProfiles/1/app-release.dm b/android/app/release/baselineProfiles/1/app-release.dm new file mode 100644 index 0000000..d8c7c1a Binary files /dev/null and b/android/app/release/baselineProfiles/1/app-release.dm differ diff --git a/android/app/release/output-metadata.json b/android/app/release/output-metadata.json new file mode 100644 index 0000000..08b0ec4 --- /dev/null +++ b/android/app/release/output-metadata.json @@ -0,0 +1,37 @@ +{ + "version": 3, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "com.circlecollect", + "variantName": "release", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "attributes": [], + "versionCode": 1, + "versionName": "1.0", + "outputFile": "app-release.apk" + } + ], + "elementType": "File", + "baselineProfiles": [ + { + "minApi": 28, + "maxApi": 30, + "baselineProfiles": [ + "baselineProfiles/1/app-release.dm" + ] + }, + { + "minApi": 31, + "maxApi": 2147483647, + "baselineProfiles": [ + "baselineProfiles/0/app-release.dm" + ] + } + ], + "minSdkVersionForDexing": 24 +} \ No newline at end of file diff --git a/android/appKeyStore b/android/appKeyStore new file mode 100644 index 0000000..b483839 Binary files /dev/null and b/android/appKeyStore differ diff --git a/package-lock.json b/package-lock.json index 90e8877..0bb25eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,6 +38,7 @@ "react-native-inset-shadow": "^1.0.3", "react-native-keychain": "^10.0.0", "react-native-linear-gradient": "^2.8.3", + "react-native-material-ripple": "^0.9.1", "react-native-paper": "^5.14.5", "react-native-reanimated": "^4.1.2", "react-native-safe-area-context": "^5.6.1", @@ -12932,6 +12933,19 @@ "react-native": "*" } }, + "node_modules/react-native-material-ripple": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/react-native-material-ripple/-/react-native-material-ripple-0.9.1.tgz", + "integrity": "sha512-dHjARdKoGD3LXwPh2TkURabywM5BfdpKc/AHplJTfBMalhVZ2bc7iJoJmNhNnmT/TZ+B3szL6uV1mO7Pv8zNeA==", + "license": "BSD-3-Clause", + "dependencies": { + "prop-types": "^15.5.10" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-paper": { "version": "5.14.5", "license": "MIT", diff --git a/package.json b/package.json index f618d1b..e43c628 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "react-native-inset-shadow": "^1.0.3", "react-native-keychain": "^10.0.0", "react-native-linear-gradient": "^2.8.3", + "react-native-material-ripple": "^0.9.1", "react-native-paper": "^5.14.5", "react-native-reanimated": "^4.1.2", "react-native-safe-area-context": "^5.6.1", diff --git a/src/components/common/Header.tsx b/src/components/common/Header.tsx index 076b9f9..9ce3fd0 100644 --- a/src/components/common/Header.tsx +++ b/src/components/common/Header.tsx @@ -33,12 +33,12 @@ const Header: React.FC = ({ return ( - {showBack && ( + {/* {showBack && ( - )} - {title} + )} */} + {title} {rightAction} ); diff --git a/src/screens/LoginScreen.tsx b/src/screens/LoginScreen.tsx index 6690701..abaad1b 100644 --- a/src/screens/LoginScreen.tsx +++ b/src/screens/LoginScreen.tsx @@ -1,6 +1,4 @@ -// src/screens/LoginScreen.tsx - -import React, { useState, useRef, useEffect } from "react"; +import React, { useState, useRef, useEffect } from 'react'; import { View, Text, @@ -12,27 +10,34 @@ import { Animated, StatusBar, ActivityIndicator, -} from "react-native"; -import { LOGIN_URL } from "../utils/ApiUrls"; -import axios from "axios"; -import { useNavigation } from "@react-navigation/native"; -import type { StackNavigationProp } from "@react-navigation/stack"; -import { RootStackParamList } from "../navigation/AppNavigator"; -import LinearGradient from "react-native-linear-gradient"; + Dimensions, +} from 'react-native'; +import { LOGIN_URL } from '../utils/ApiUrls'; +import axios from 'axios'; +import { useNavigation } from '@react-navigation/native'; +import type { StackNavigationProp } from '@react-navigation/stack'; +import { RootStackParamList } from '../navigation/AppNavigator'; +import LinearGradient from 'react-native-linear-gradient'; import Ionicons from '@react-native-vector-icons/ionicons'; -import CustomAlert from "../components/CostomAlart"; -import colors from "../components/colors"; // Centralized colors from your file +import MaterialRipple from 'react-native-material-ripple'; // For the button ripple effect +import CustomAlert from '../components/CostomAlart'; +import colors from '../components/colors'; + +const { width } = Dimensions.get('window'); +const BLOCK_SIZE = width / 3; + +// Note: You will need to install react-native-material-ripple +// npm install react-native-material-ripple export default function LoginScreen() { const navigation = useNavigation>(); - const [mobile, setMobile] = useState(""); + const [mobile, setMobile] = useState(''); const [loading, setLoading] = useState(false); - const [alertInfo, setAlertInfo] = useState({ visible: false, - title: "", - message: "", - buttons: [] as { text: string; onPress: () => void; style?: "cancel" | "destructive" | "default" }[], + title: '', + message: '', + buttons: [] as { text: string; onPress: () => void; style?: 'cancel' | 'destructive' | 'default' }[], alertType: 'info' as 'info' | 'success' | 'error', }); @@ -50,12 +55,12 @@ export default function LoginScreen() { const showAlert = ( title: string, message: string, - buttons: { text: string; onPress: () => void; style?: "cancel" | "destructive" | "default" }[], - alertType: 'info' | 'success' | 'error' = 'info' + buttons: { text: string; onPress: () => void; style?: 'cancel' | 'destructive' | 'default' }[], + alertType: 'info' | 'success' | 'error' = 'info', ) => { setAlertInfo({ visible: true, title, message, buttons, alertType }); }; - + const hideAlert = () => { setAlertInfo({ ...alertInfo, visible: false }); }; @@ -64,68 +69,70 @@ export default function LoginScreen() { if (mobile.length === 10) { setLoading(true); try { - console.log("Login api call:"); - // FIX: Used the imported LOGIN_URL constant instead of a string literal const res = await axios.get(LOGIN_URL, { params: { mobile } }); - console.log("Login response:", res.data); if (res.data.statusCode === 200) { - navigation.navigate("OtpVarify", { mobile }); + navigation.navigate('OtpVarify', { mobile }); } else { - showAlert( - "Login Failed", - res.data.message || "Could not send OTP.", - [{ text: "Try Again", onPress: hideAlert }], - 'error' - ); - + showAlert('Login Failed', res.data.message || 'Could not send OTP.', [{ text: 'Try Again', onPress: hideAlert }], 'error'); } } catch (error: any) { - console.error("Login error:", error); - showAlert( - "An Error Occurred", - "Failed to send OTP. Please check your connection and try again.", - [{ text: "OK", onPress: hideAlert }], - 'error' - ); + showAlert('An Error Occurred', 'Failed to send OTP. Please check your connection and try again.', [{ text: 'OK', onPress: hideAlert }], 'error'); } finally { setLoading(false); } } else { - showAlert( - "Invalid Number", - "Please enter a valid 10-digit mobile number.", - [{ text: "Got it", onPress: hideAlert }], - 'info' - ); + showAlert('Invalid Number', 'Please enter a valid 10-digit mobile number.', [{ text: 'Got it', onPress: hideAlert }], 'info'); } }; + const colorsBlocks = [ + colors.pastelPink, + colors.pastelBlue, + colors.pastelGreen, + colors.pastelOrange, + colors.pastelBlue, + colors.pastelPink, + colors.pastelGreen, + colors.pastelOrange, + colors.pastelPink, + ]; + return ( - + + + + {/* Funky grid blocks background (Unchanged) */} + + {colorsBlocks.map((bgColor, index) => ( + + ))} + + - - - - - + + + + CircleCollect + Welcome Back! + + Let's get you signed in to your community. + + + - - CircleCollect - Welcome! - - Glad to see you again. Let's get you signed in to your community. - - - - - - - - + + + + + + + {loading ? ( + + ) : ( + + Continue + + + )} + + + + Your privacy is our priority. Your information is always secure. + + - - - - {loading ? ( - - ) : ( - Continue with Mobile - )} - - - Your privacy is our priority. Your information is always secure. - - - - + ); } const styles = StyleSheet.create({ - gradientContainer: { - flex: 1, - }, container: { flex: 1, + }, + gridContainer: { + ...StyleSheet.absoluteFillObject, + flexDirection: 'row', + flexWrap: 'wrap', + }, + gridBlock: { + width: BLOCK_SIZE, + height: BLOCK_SIZE, + margin: 2, + borderRadius: 16, + }, + elevatedBlock: { + shadowColor: '#000', + shadowOffset: { width: 0, height: 5 }, + shadowOpacity: 0.15, + shadowRadius: 10, + elevation: 7, + }, + keyboardAvoidingContainer: { + flex: 1, + }, + contentContainer: { + flex: 1, + justifyContent: 'space-between', padding: 24, - justifyContent: "space-between", - }, - shape: { - position: 'absolute', - borderRadius: 1000, - opacity: 0.6, - }, - shape1: { - width: 400, - height: 400, - backgroundColor: colors.pastelPink, - top: -150, - left: -100, - }, - shape2: { - width: 300, - height: 300, - backgroundColor: colors.pastelBlue, - bottom: -100, - right: -120, - }, - shape3: { - width: 200, - height: 200, - backgroundColor: colors.pastelGreen, - bottom: '40%', - left: -80, - opacity: 0.5 }, topSection: { flex: 0.8, - justifyContent: "center", - alignItems: 'center' - }, - formSection: { - flex: 1, - justifyContent: 'flex-start' + justifyContent: 'center', + alignItems: 'center', }, brand: { - fontSize: 24, - fontWeight: "600", + fontSize: 28, + fontWeight: '700', color: colors.primary, - textAlign: "center", - letterSpacing: 1.5, + textAlign: 'center', + letterSpacing: 2, marginBottom: 16, + textShadowColor: 'rgba(0, 0, 0, 0.1)', + textShadowOffset: { width: 1, height: 1 }, + textShadowRadius: 2, }, title: { - fontSize: 38, - fontWeight: "bold", + fontSize: 40, + fontWeight: 'bold', color: colors.textDark, - textAlign: "center", - marginBottom: 12, + textAlign: 'center', + marginBottom: 14, }, subtitle: { fontSize: 16, - color: colors.textLight, - textAlign: "center", - lineHeight: 24, + color: colors.textDark, + textAlign: 'center', + lineHeight: 26, maxWidth: 320, }, - inputContainer: { - flexDirection: "row", - alignItems: "center", - backgroundColor: colors.white, - borderRadius: 16, - borderWidth: 1, - borderColor: colors.inputBorder, - paddingHorizontal: 16, - marginTop: 32, - shadowColor: colors.black, - shadowOffset: { width: 0, height: 4 }, - shadowOpacity: 0.05, - shadowRadius: 10, - elevation: 3, + inputWrapper: { + flexDirection: 'row', + alignItems: 'center', + backgroundColor: 'rgba(255, 255, 255, 0.85)', + borderRadius: 36, + borderWidth: 2, + borderColor: colors.pastelPink, + paddingHorizontal: 20, + shadowColor: colors.primary, + shadowOffset: { width: 0, height: 6 }, + shadowOpacity: 0.2, + shadowRadius: 14, + elevation: 8, }, inputIcon: { - marginRight: 12, + marginRight: 16, }, input: { flex: 1, + fontSize: 18, + fontWeight: '600', + color: colors.textLight, height: 58, - fontSize: 16, - color: colors.textDark, }, bottomSection: { - paddingBottom: Platform.OS === "ios" ? 20 : 10, - paddingHorizontal: 10 + alignItems: 'center', + paddingBottom: Platform.OS === 'ios' ? 20 : 10, }, button: { - backgroundColor: colors.primary, - paddingVertical: 18, + width: '100%', borderRadius: 30, - alignItems: "center", - justifyContent: "center", - flexDirection: "row", shadowColor: colors.primary, - shadowOffset: { width: 0, height: 8 }, - shadowOpacity: 0.3, - shadowRadius: 15, - elevation: 8, + shadowOffset: { width: 0, height: 10 }, + shadowOpacity: 0.4, + shadowRadius: 20, + elevation: 14, + marginTop: 20, + }, + buttonGradient: { + borderRadius: 30, + paddingVertical: 18, + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', + }, + buttonContent: { + flexDirection: 'row', + alignItems: 'center', }, buttonText: { color: colors.white, - fontWeight: "700", - fontSize: 16, + fontWeight: '800', + fontSize: 18, }, footerText: { - textAlign: "center", - color: colors.textLight, - fontSize: 12, - marginTop: 20, + fontSize: 14, + color: 'rgba(0,0,0,0.5)', + marginTop: 28, + textAlign: 'center', + maxWidth: 300, }, }); diff --git a/src/screens/OtpVarificationScreen.tsx b/src/screens/OtpVarificationScreen.tsx index d4580b4..66afa93 100644 --- a/src/screens/OtpVarificationScreen.tsx +++ b/src/screens/OtpVarificationScreen.tsx @@ -1,4 +1,4 @@ -import { RouteProp, useNavigation, useRoute } from "@react-navigation/native"; +import { CommonActions, RouteProp, useNavigation, useRoute } from "@react-navigation/native"; import axios from "axios"; import React, { useEffect, useRef, useState } from "react"; import { @@ -13,16 +13,18 @@ import { TextInputKeyPressEventData, KeyboardAvoidingView, StatusBar, + Dimensions, } from "react-native"; import { RootStackParamList } from "../navigation/AppNavigator"; import * as Keychain from "react-native-keychain"; import { LOGIN_URL, VARIFY_OTP_URL } from "../utils/ApiUrls"; import colors from "../components/colors"; -import LinearGradient from "react-native-linear-gradient"; import CustomAlert from "../components/CostomAlart"; import { getFcmToken } from "../utils/firebase/firebaseServices"; const CELL_COUNT = 6; +const { width } = Dimensions.get('window'); +const BLOCK_SIZE = width / 3; type OtpVerifyRouteProp = RouteProp; interface AlertButton { @@ -53,21 +55,21 @@ export default function OtpVerificationScreen() { const route = useRoute(); const { mobile } = route.params; const navigation = useNavigation(); - + // Refs for auto-closing logic const successActionRef = useRef<(() => void) | null>(null); const successTimerRef = useRef(null); const fade = useRef(new Animated.Value(0)).current; - const slide = useRef(new Animated.Value(24)).current; + const slide = useRef(new Animated.Value(30)).current; const ctaScale = useRef(new Animated.Value(1)).current; useEffect(() => { Animated.parallel([ - Animated.timing(fade, { toValue: 1, duration: 600, useNativeDriver: true }), - Animated.timing(slide, { toValue: 0, duration: 600, useNativeDriver: true }), + Animated.timing(fade, { toValue: 1, duration: 800, useNativeDriver: true }), + Animated.spring(slide, { toValue: 0, friction: 5, tension: 40, useNativeDriver: true }), ]).start(); - }, [fade, slide]); + }, []); useEffect(() => { if (timer <= 0) return; @@ -77,8 +79,8 @@ export default function OtpVerificationScreen() { const hideAlert = () => { if (successTimerRef.current) { - clearTimeout(successTimerRef.current); - successTimerRef.current = null; + clearTimeout(successTimerRef.current); + successTimerRef.current = null; } setAlertConfig(prev => ({ ...prev, visible: false })); }; @@ -91,12 +93,12 @@ export default function OtpVerificationScreen() { autoCloseAction?: () => void ) => { setAlertConfig({ visible: true, title, message, buttons, alertType }); - + if (alertType === 'success' && autoCloseAction) { - successActionRef.current = autoCloseAction; - successTimerRef.current = setTimeout(() => { - successActionRef.current?.(); - }, 2000); // Auto-close after 2 seconds + successActionRef.current = autoCloseAction; + successTimerRef.current = setTimeout(() => { + successActionRef.current?.(); + }, 2000); } }; @@ -130,14 +132,18 @@ export default function OtpVerificationScreen() { await saveToken(jwt); await getFcmToken(res.data?.data?.userId); - let hasActionRun = false; - const successAction = () => { - if (hasActionRun) return; - hasActionRun = true; - hideAlert(); - navigation.replace("Home"); - }; + const successAction = () => { + if (hasActionRun) return; + hasActionRun = true; + hideAlert(); + navigation.dispatch( + CommonActions.reset({ + index: 0, + routes: [{ name: 'Home' }], + }) + ); +}; triggerAlert( 'Success!', @@ -162,20 +168,18 @@ export default function OtpVerificationScreen() { try { setIsResending(true); setTimer(30); - await axios.get(`${LOGIN_URL}?mobile=${mobile}`, { - headers: { "Content-Type": "application/json", Accept: "*/*" }, - }); - + await axios.get(LOGIN_URL, { params: { mobile } }) + setCode(Array(CELL_COUNT).fill("")); inputs.current[0]?.focus(); - + let hasActionRun = false; const successAction = () => { - if (hasActionRun) return; - hasActionRun = true; - hideAlert(); + if (hasActionRun) return; + hasActionRun = true; + hideAlert(); }; - + triggerAlert( 'OTP Sent', 'A new code has been sent to your mobile number.', @@ -233,73 +237,130 @@ export default function OtpVerificationScreen() { inputs.current[idx - 1]?.focus(); } }; + + const colorsBlocks = [ + colors.pastelPink, + colors.pastelBlue, + colors.pastelGreen, + colors.pastelOrange, + colors.pastelBlue, + colors.pastelPink, + colors.pastelGreen, + colors.pastelOrange, + colors.pastelPink, + ]; return ( - - - - + + + + + {colorsBlocks.map((bgColor, index) => ( + + ))} + + + + - - Verify Your Code 🔒 - We’ve sent a 6-digit verification code to +91 {mobile}. + + + Verify Your Code + We’ve sent a 6-digit verification code to +91 {mobile}. - - {Array.from({ length: CELL_COUNT }).map((_, i) => ( - { inputs.current[i] = r; }} - style={[styles.cell, code[i] ? styles.cellFilled : null]} - keyboardType="number-pad" - maxLength={i === 0 ? CELL_COUNT : 1} - value={code[i]} - onChangeText={(t) => (i === 0 ? handleFirstCellChange(t) : updateIndex(i, t))} - onKeyPress={(e) => handleKeyPress(i, e)} - placeholder="•" - placeholderTextColor="#BDBDBD" - textContentType="oneTimeCode" - /> - ))} + + {Array.from({ length: CELL_COUNT }).map((_, i) => ( + { inputs.current[i] = r; }} + style={[styles.cell, code[i] ? styles.cellFilled : null]} + keyboardType="number-pad" + maxLength={i === 0 ? CELL_COUNT : 1} + value={code[i]} + onChangeText={(t) => (i === 0 ? handleFirstCellChange(t) : updateIndex(i, t))} + onKeyPress={(e) => handleKeyPress(i, e)} + placeholder="•" + placeholderTextColor="#BDBDBD" + textContentType="oneTimeCode" + /> + ))} + + + + + Animated.spring(ctaScale, { toValue: 0.97, useNativeDriver: true }).start()} + onPressOut={() => Animated.spring(ctaScale, { toValue: 1, useNativeDriver: true }).start()} + onPress={() => onSubmit(code.join(""), mobile)} + style={styles.button} + > + Verify & Continue + + + {timer > 0 ? ( + Resend code in 00:{timer.toString().padStart(2, "0")} + ) : ( + + + {isResending ? "Resending..." : "Resend Code"} + + + )} - - - Animated.spring(ctaScale, { toValue: 0.97, useNativeDriver: true }).start()} - onPressOut={() => Animated.spring(ctaScale, { toValue: 1, useNativeDriver: true }).start()} - onPress={() => onSubmit(code.join(""), mobile)} - style={styles.button} - > - Verify & Continue - - - {timer > 0 ? ( - Resend code in 00:{timer.toString().padStart(2, "0")} - ) : ( - - - {isResending ? "Resending..." : "Resend Code"} - - - )} - - + ); } const styles = StyleSheet.create({ - gradientContainer: { flex: 1 }, - container: { flex: 1, padding: 24, justifyContent: "space-between" }, - topSection: { flex: 1, justifyContent: "center", alignItems: 'center' }, + container: { flex: 1 }, + gridContainer: { + ...StyleSheet.absoluteFillObject, + flexDirection: 'row', + flexWrap: 'wrap', + }, + gridBlock: { + width: BLOCK_SIZE, + height: BLOCK_SIZE, + margin: 2, + borderRadius: 16, + }, + elevatedBlock: { + shadowColor: '#000', + shadowOffset: { width: 0, height: 5 }, + shadowOpacity: 0.15, + shadowRadius: 10, + elevation: 7, + }, + keyboardAvoidingContainer: { flex: 1, justifyContent: 'center' }, + contentPanel: { + marginHorizontal: 24, + backgroundColor: 'rgba(255, 255, 255, 0.95)', + borderRadius: 32, + padding: 28, + shadowColor: '#000', + shadowOffset: { width: 0, height: 10 }, + shadowOpacity: 0.14, + shadowRadius: 24, + elevation: 12, + }, + topSection: { alignItems: 'center', marginBottom: 24 }, title: { fontSize: 28, fontWeight: "bold", color: colors.textDark, textAlign: 'center', marginBottom: 12 }, subtitle: { fontSize: 16, color: colors.textLight, textAlign: 'center', marginBottom: 32, lineHeight: 24, maxWidth: 300 }, otpRow: { flexDirection: "row", justifyContent: "space-between", width: '100%', paddingHorizontal: 10 }, cell: { width: 48, height: 56, borderRadius: 12, borderWidth: 1.5, borderColor: colors.inputBorder, backgroundColor: colors.white, textAlign: "center", fontSize: 22, fontWeight: '700', color: colors.textDark, shadowColor: "#000", shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.08, shadowRadius: 8, elevation: 3 }, cellFilled: { borderColor: colors.primary, backgroundColor: '#F7F2FF' }, - bottomSection: { paddingBottom: Platform.OS === "ios" ? 20 : 10 }, - button: { backgroundColor: colors.primary, paddingVertical: 18, borderRadius: 30, alignItems: "center", justifyContent: "center", shadowColor: colors.primary, shadowOffset: { width: 0, height: 8 }, shadowOpacity: 0.3, shadowRadius: 15, elevation: 8 }, + bottomSection: { paddingBottom: Platform.OS === "ios" ? 20 : 10, paddingTop: 10 }, + button: { backgroundColor: colors.pastelPink, paddingVertical: 18, borderRadius: 30, alignItems: "center", justifyContent: "center", shadowColor: colors.primary, shadowOffset: { width: 0, height: 8 }, shadowOpacity: 0.3, shadowRadius: 15, elevation: 8 ,borderWidth:2, borderColor:colors.pastelPink}, buttonText: { color: colors.white, fontWeight: "700", fontSize: 16 }, footerText: { textAlign: "center", color: colors.textLight, fontSize: 14, marginTop: 20 }, }); diff --git a/src/screens/SplashScreen.tsx b/src/screens/SplashScreen.tsx index 8d9f920..d41038b 100644 --- a/src/screens/SplashScreen.tsx +++ b/src/screens/SplashScreen.tsx @@ -110,7 +110,7 @@ const SplashScreen = () => { Circle Collect - + ); }; diff --git a/src/screens/home/user-home/CycleDashboard.tsx b/src/screens/home/user-home/CycleDashboard.tsx index 0f4c8e9..4d0259e 100644 --- a/src/screens/home/user-home/CycleDashboard.tsx +++ b/src/screens/home/user-home/CycleDashboard.tsx @@ -164,7 +164,7 @@ const CycleDashboard = ({ data }: { data: CycleDashboardData }) => { Cycles - {data.currentCycle}/{data.totalCycles} + {data.currentCycle}/{data.totalParticipants} diff --git a/src/screens/home/user-home/GroupDetails.tsx b/src/screens/home/user-home/GroupDetails.tsx index f93a12c..b439f60 100644 --- a/src/screens/home/user-home/GroupDetails.tsx +++ b/src/screens/home/user-home/GroupDetails.tsx @@ -86,6 +86,7 @@ const GroupDetails = () => { const getCycleDashboard = async () => { try { const response = await apiCall(`${BASE_URL}payments/groups/${group.id}/cycle-dashboard`, "GET") as any; + console.log("Cycle Dashboard Response: ", response); const responseData = response.data; setCycleDashboardData(responseData); @@ -117,6 +118,7 @@ const GroupDetails = () => { const handleContribution = async () => { try { const res = await apiCall(`${CONTRIBUTE}${group.id}/calculate-contribution`, 'GET') as any; + console.log("Contribution Calculation Response: ", res); setPayable(res.data); } catch (error) { console.log("Error in handleContribution: ", error); @@ -169,20 +171,20 @@ const GroupDetails = () => { } contentContainerStyle={styles.scrollContent} > -
+
{group.description} - {group.members.length ?? 0} + {memberData.length ?? 0} Members - ₹{group.collected} + ₹{cycleDashboardData?.contributionAmount|| group.collected} Contribution - ₹{group.goal} + ₹{cycleDashboardData?.contributionAmount*memberData.length|| group.goal} Total Amount @@ -203,7 +205,7 @@ const GroupDetails = () => { Members - {group.status} + {cycleDashboardData?.status || group?.status} @@ -219,7 +221,7 @@ const GroupDetails = () => { ))} {/* Button at the bottom inside scroll (no absolute positioning) */} - {group.status === 'ACTIVE' && !payable?.hasPaid && ( + {cycleDashboardData?.status === 'ACTIVE' && !payable?.hasPaid && ( setOpenModal(true)} style={styles.button}> Contribute diff --git a/src/screens/profile/Profile.tsx b/src/screens/profile/Profile.tsx index cd8f078..eed046b 100644 --- a/src/screens/profile/Profile.tsx +++ b/src/screens/profile/Profile.tsx @@ -381,7 +381,7 @@ const Profile = () => { User Profile confirmLogout(navigation)} style={styles.refreshButton}> - + {/* if (fetching || !user) { @@ -707,7 +707,7 @@ const styles = StyleSheet.create({ borderBottomRightRadius: 20, }, headerTitle: { - fontSize: 22, fontWeight: "600", color: colors.primary + fontSize: 22, fontWeight: "600", color: colors.black }, refreshButton: { padding: 4,