From 44a782920e7aa8c8d1c75d562185f06191801471 Mon Sep 17 00:00:00 2001 From: Abin Toppo Date: Thu, 23 Oct 2025 17:37:36 +0530 Subject: [PATCH] dashboard api not implimented --- src/components/common/AnimatedCard.tsx | 145 +----- src/screens/home/Home.tsx | 261 ++++++----- src/screens/home/UserProfileStatus.tsx | 623 +++++-------------------- src/screens/management/Payments.tsx | 2 +- src/utils/ApiUrls.tsx | 5 +- src/utils/test.js | 8 + 6 files changed, 303 insertions(+), 741 deletions(-) create mode 100644 src/utils/test.js diff --git a/src/components/common/AnimatedCard.tsx b/src/components/common/AnimatedCard.tsx index 565b408..678803c 100644 --- a/src/components/common/AnimatedCard.tsx +++ b/src/components/common/AnimatedCard.tsx @@ -1,16 +1,8 @@ import React, { useRef } from "react"; -import { - View, - Text, - StyleSheet, - TouchableWithoutFeedback, - Animated, - ViewStyle, - StyleProp, -} from "react-native"; +import { View, Text, StyleSheet, Animated, TouchableWithoutFeedback } from "react-native"; import LinearGradient from "react-native-linear-gradient"; -import { Ionicons, IoniconsIconName } from "@react-native-vector-icons/ionicons"; -import colors from "../colors"; // Assuming your pastel colors are defined here +import { Ionicons } from "@react-native-vector-icons/ionicons"; +import colors from "../colors"; type CardProps = { title: string; @@ -19,68 +11,31 @@ type CardProps = { onPress?: () => void; backOne?: string; backTwo?: string; - style?: StyleProp; }; const AnimatedCard: React.FC = ({ title, subtitle, - iconName = "ellipse", + iconName = "ellipse-outline", onPress, - backOne = colors.pastelPink, // Defaulting to pastelPink from your preferences - backTwo = colors.primary, - style, + backOne = colors.primary, + backTwo = colors.pastelPink, }) => { const scale = useRef(new Animated.Value(1)).current; - const handlePressIn = () => { - Animated.spring(scale, { - toValue: 0.96, - useNativeDriver: true, - friction: 4, - }).start(); - }; - - const handlePressOut = () => { - Animated.spring(scale, { - toValue: 1, - useNativeDriver: true, - friction: 4, - }).start(() => { - if (onPress) { - onPress(); - } - }); + const handlePress = () => { + Animated.sequence([ + Animated.spring(scale, { toValue: 0.95, useNativeDriver: true }), + ]).start(() => onPress && onPress()); }; return ( - - - - {/* Decorative Graphics */} - - - - {/* Content */} - - {iconName && ( - - )} - - {title} - {subtitle && {subtitle}} - - + + + + + {title} + {subtitle && {subtitle}} @@ -89,77 +44,21 @@ const AnimatedCard: React.FC = ({ const styles = StyleSheet.create({ card: { - // minWidth: 170, flex: 1, - height: 170, - marginHorizontal: 8, - marginVertical: 10, - borderRadius: 24, + height: 160, + margin: 8, + borderRadius: 20, overflow: "hidden", - shadowColor: "#000", - shadowOffset: { width: 0, height: 5 }, - shadowOpacity: 0.15, - shadowRadius: 12, elevation: 5, }, gradient: { - position: "relative", - flex: 1, - // justifyContent: "center", - // alignItems: "center", - justifyContent: "space-between", - borderRadius: 24, - overflow: "hidden", - gap: 10, - }, - graphicCircleLarge: { - position: "absolute", - top: -30, - right: -40, - width: 100, - height: 100, - borderRadius: 50, - backgroundColor: "rgba(255, 255, 255, 0.1)", - }, - graphicCircleSmall: { - position: "absolute", - bottom: -20, - left: -25, - width: 70, - height: 70, - borderRadius: 35, - backgroundColor: "rgba(255, 255, 255, 0.08)", - }, - content: { - padding: 20, - position: "relative", - zIndex: 1, flex: 1, justifyContent: "center", alignItems: "center", }, - icon: { - marginBottom: 12, - }, - textContainer: { - alignItems: "center", - }, - title: { - fontSize: 18, - fontWeight: "bold", - color: "#fff", - textTransform: "uppercase", - letterSpacing: 1, - textAlign: "center", - }, - subtitle: { - fontSize: 13, - color: colors.white, - opacity: 0.9, - fontWeight: "500", - textAlign: "center", - marginTop: 4, - }, + icon: { marginBottom: 10 }, + title: { fontSize: 18, fontWeight: "bold", color: "#fff" }, + subtitle: { fontSize: 13, color: "#fff", opacity: 0.9 }, }); export default AnimatedCard; diff --git a/src/screens/home/Home.tsx b/src/screens/home/Home.tsx index f898c50..37330f2 100644 --- a/src/screens/home/Home.tsx +++ b/src/screens/home/Home.tsx @@ -6,23 +6,20 @@ import { TouchableOpacity, UIManager, Platform, - Image, - Alert, FlatList, ListRenderItem, - ToastAndroid, - ScrollView, + Alert, } from "react-native"; import AppView from "../../components/AppView"; import colors from "../../components/colors"; import { useDispatch, useSelector } from "react-redux"; import { useNavigation } from "@react-navigation/native"; -import { PROFILE_URL } from "../../utils/ApiUrls"; +import { DASHBOARD_URL, PROFILE_URL } from "../../utils/ApiUrls"; import { setUserData } from "../../redux/userSlice"; import { TabNavigationProp } from "../../navigation/BottomTabs"; import UserProfileStatus from "./UserProfileStatus"; import AnimatedCard from "../../components/common/AnimatedCard"; -import { Ionicons, IoniconsIconName } from "@react-native-vector-icons/ionicons"; +import { Ionicons } from "@react-native-vector-icons/ionicons"; import { apiCall } from "../../utils/ApiHelper"; import CustomAlert, { CustomAlertProps } from "../../components/CostomAlart"; @@ -45,45 +42,56 @@ interface ActionItem { title: string; action: string; tab?: "My Groups" | "Joined Groups" | "Requests" | "Your Requests"; - iconName?: IoniconsIconName; + iconName?: string; backOne?: string; backTwo?: string; subtitle?: string; } -// Updated action items with a prettier pastel palette const organizerActions: ActionItem[] = [ - { id: "1", title: "My Groups", subtitle: "Manage your groups", action: "NAVIGATE_MANAGEMENT", tab: "My Groups", iconName: "people-circle-outline", backOne: '#decbfcff', backTwo: '#B799FF' }, - { id: "2", title: "Joined Groups", subtitle: "View member groups", action: "NAVIGATE_MANAGEMENT", tab: "Joined Groups", iconName: "people-outline", backOne: '#D7E9F7', backTwo: '#82AAE3' }, - { id: "3", title: "Requests", subtitle: "Check new requests", action: "NAVIGATE_MANAGEMENT", tab: "Requests", iconName: "notifications-outline", backOne: '#DFF6DD', backTwo: '#88D18A' }, - { id: "4", title: "Create Group", subtitle: "Create a new group", action: "NAVIGATE_CREATE_GROUP", tab: "Requests", iconName: "people-outline", backOne: '#DFF6DD', backTwo: '#88D18A' }, + { id: "1", title: "My Groups", subtitle: "Manage your groups", action: "NAVIGATE_MANAGEMENT", tab: "My Groups", iconName: "people-circle-outline", backOne: "#decbfcff", backTwo: "#B799FF" }, + { id: "2", title: "Joined Groups", subtitle: "View member groups", action: "NAVIGATE_MANAGEMENT", tab: "Joined Groups", iconName: "people-outline", backOne: "#D7E9F7", backTwo: "#82AAE3" }, + { id: "3", title: "Requests", subtitle: "Check new requests", action: "NAVIGATE_MANAGEMENT", tab: "Requests", iconName: "notifications-outline", backOne: "#DFF6DD", backTwo: "#88D18A" }, + { id: "4", title: "Create Group", subtitle: "Create a new group", action: "NAVIGATE_CREATE_GROUP", iconName: "add-circle-outline", backOne: "#FFF4D2", backTwo: "#FFB344" }, + { id: "2", title: "Your Requests", subtitle: "Track your requests", action: "NAVIGATE_MANAGEMENT", tab: "Your Requests", iconName: "mail-open-outline", backOne: "#FFF4D2", backTwo: "#FFB344" }, + { id: "3", title: "Transactions", subtitle: "View your history", action: "TRANSACTION", iconName: "receipt-outline", backOne: "#decbfcff", backTwo: "#B799FF" }, + ]; const userActions: ActionItem[] = [ - { id: "1", title: "Joined Groups", subtitle: "See your groups", action: "NAVIGATE_MANAGEMENT", tab: "Joined Groups", iconName: "person-outline", backOne: '#D7E9F7', backTwo: '#82AAE3' }, - { id: "2", title: "Your Requests", subtitle: "Track your requests", action: "NAVIGATE_MANAGEMENT", tab: "Your Requests", iconName: "mail-open-outline", backOne: '#FFF4D2', backTwo: '#FFB344' }, - { id: "3", title: "Transactions", subtitle: "View your history", action: "TRANSACTION", iconName: "receipt-outline", backOne: '#decbfcff', backTwo: '#B799FF' }, - { id: "4", title: "Create Group", subtitle: "Create a new group", action: "NAVIGATE_CREATE_GROUP", tab: "Requests", iconName: "people-outline", backOne: '#DFF6DD', backTwo: '#88D18A' }, + { id: "1", title: "Joined Groups", subtitle: "See your groups", action: "NAVIGATE_MANAGEMENT", tab: "Joined Groups", iconName: "person-outline", backOne: "#D7E9F7", backTwo: "#82AAE3" }, + { id: "2", title: "Your Requests", subtitle: "Track your requests", action: "NAVIGATE_MANAGEMENT", tab: "Your Requests", iconName: "mail-open-outline", backOne: "#FFF4D2", backTwo: "#FFB344" }, + { id: "3", title: "Transactions", subtitle: "View your history", action: "TRANSACTION", iconName: "receipt-outline", backOne: "#decbfcff", backTwo: "#B799FF" }, + { id: "4", title: "Create Group", subtitle: "Create a new group", action: "NAVIGATE_CREATE_GROUP", iconName: "add-circle-outline", backOne: "#DFF6DD", backTwo: "#88D18A" }, ]; const Home: React.FC = () => { const user = useSelector((state: any) => state.user); - const notifications = useSelector( - (state: any) => state.notifications.notifications - ); + const notifications = useSelector((state: any) => state.notifications.notifications); const navigation = useNavigation(); const dispatch = useDispatch(); - const actions = user.role === 'ORGANIZER' ? organizerActions : userActions; + const actions = user.role === "ORGANIZER" ? organizerActions : userActions; const [apiUser, setApiUser] = useState(null); - const [alartVisible, setalartVisible] = useState(false) - const [alartAction, setAlartAction] = useState(null) + const [alertVisible, setAlertVisible] = useState(false); + const [alertAction, setAlertAction] = useState(null); + const [userDashboard, setUserDashboard] = useState(null); + const getDashboardData = async () => { + try { + const result = (await apiCall(DASHBOARD_URL, "GET")) as any; + console.log("DASHBOARD_URL-------", result) + if (result.status === "success") { + setUserDashboard(result.data); + } + } catch (error) { + console.error("❌ Error fetching dashboard data:", error); + } + }; useEffect(() => { const fetchUserProfile = async () => { try { - const result = await apiCall(PROFILE_URL, "GET") as any; - console.log(PROFILE_URL, result) + const result = (await apiCall(PROFILE_URL, "GET")) as any; if (result.status === "success") { setApiUser(result.data); dispatch(setUserData({ ...result.data, profileStatus: true })); @@ -92,66 +100,58 @@ const Home: React.FC = () => { console.error("❌ Error fetching profile:", error); } }; - const unsubscribe = navigation.addListener('focus', fetchUserProfile); + const unsubscribe = navigation.addListener("focus", fetchUserProfile); fetchUserProfile(); - return unsubscribe; - }, [navigation, dispatch]); + getDashboardData(); + var number = 5 + function sumr(n:number){ + var sum:number = 1 + var parv:number = 0 + for(let i = 3;i<=n;i++){ + sum = sum+ i + console.log(sum+",") + + } + } + console.log("sum of number",sumr(10)) + return unsubscribe; +}, [navigation, dispatch]); const handleActionPress = (item: ActionItem) => { if (item.action === "NAVIGATE_MANAGEMENT" && item.tab) { - navigation.navigate('Management', { actionTab: item.tab }); + navigation.navigate("Management", { actionTab: item.tab }); } else if (item.action === "TRANSACTION") { navigation.navigate("TransactionList" as never); } else if (item.action === "NAVIGATE_CREATE_GROUP") { switch (apiUser?.organizerStatus) { - case 'NOT_APPLIED': - setalartVisible(true); - setAlartAction({ + case "NOT_APPLIED": + setAlertVisible(true); + setAlertAction({ visible: true, - title: "Become organizer", - message: "You have to become organizer for creating groups", + title: "Become Organizer", + message: "You have to become an organizer to create groups.", buttons: [ { text: "Continue", onPress: () => { - setalartVisible(false); + setAlertVisible(false); navigation.navigate("BecomeOrg" as never); }, - style: "default", }, { text: "Close", - onPress: () => { - setalartVisible(false); - }, + onPress: () => setAlertVisible(false), style: "cancel", }, ], - alertType: 'error', - onClose: () => setAlartAction(null), + alertType: "error", + onClose: () => setAlertAction(null), }); break; - - case 'PENDING': - setalartVisible(true); - setAlartAction({ - visible: true, - title: "Organizer Application Pending", - message: "Your application to become an organizer is pending approval. You cannot create groups until it's approved.", - buttons: [ - { - text: "Close", - onPress: () => { - setalartVisible(false); - }, - style: "cancel", - }, - ], - alertType: 'info', - onClose: () => setAlartAction(null), - }); + case "PENDING": + Alert.alert("Pending Approval", "Your organizer request is still pending."); break; - case 'APPROVED': + case "APPROVED": navigation.navigate("GroupCreation" as never); break; default: @@ -164,55 +164,73 @@ const Home: React.FC = () => { const unreadCount = notifications.filter((item: any) => !item.read).length; const renderGridItem: ListRenderItem = ({ item }) => ( - - handleActionPress(item)} - /> - + handleActionPress(item)} + /> ); const getProfileImageUri = () => { const blob = user.imageBlob || apiUser?.imageBlob; - return blob ? { uri: `data:image/jpeg;base64,${blob}` } : require('../../assets/images/placeholder.png'); + return blob ? { uri: `data:image/jpeg;base64,${blob}` } : require("../../assets/images/placeholder.png"); }; return ( - // - - - - Hello, - {user.firstName || apiUser?.firstName || 'User'} - - navigation.navigate("Notification" as never)}> - {unreadCount > 0 ? unreadCount : ''} - - - - - - - - Quick Actions - Alert.alert('Info', 'This will allow you to pay all pending contributions in your groups.')}> - Pay All - - - + item.id} - numColumns={2} - contentContainerStyle={{ paddingHorizontal: 8 }} + ListHeaderComponent={ + <> + + + + Hello, {user.firstName || apiUser?.firstName || "User"} + + + navigation.navigate("Notification" as never)}> + {unreadCount > 0 && ( + + {unreadCount} + + )} + + + + + + + + Quick Actions + Alert.alert("Info", "This will allow you to pay all pending contributions.")} + > + Pay All + + + + } + contentContainerStyle={{ paddingBottom: 100 }} /> - + + {alertAction && ( + + )} + ); }; @@ -221,9 +239,7 @@ export default Home; const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: colors.white, // Set background to white - marginBottom: 100, - padding:10 + backgroundColor: colors.white, }, header: { flexDirection: "row", @@ -233,25 +249,34 @@ const styles = StyleSheet.create({ paddingTop: 24, paddingBottom: 16, }, - greeting: { - fontSize: 22, - color: colors.textDark, + greeting: { fontSize: 22, color: colors.textDark }, + userName: { fontSize: 28, fontWeight: "bold", color: colors.textDark }, + sectionTitle: { fontSize: 20, fontWeight: "600", color: colors.textDark }, + actionHeader: { + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + marginHorizontal: 20, + marginBottom: 10, }, - userName: { - fontSize: 28, - fontWeight: 'bold', - color: colors.textDark, + payAllButton: { + paddingHorizontal: 14, + paddingVertical: 6, + backgroundColor: colors.primary, + borderRadius: 8, }, - sectionTitle: { - fontSize: 20, - fontWeight: '600', - color: colors.textDark, - paddingHorizontal: 20, - marginBottom: 8, - }, - cardWrapper: { - flex: 1, - // marginHorizontal: 8, - // backgroundColor:'red' + payAllText: { color: "#fff", fontWeight: "bold", fontSize: 14 }, + badge: { + position: "absolute", + right: -6, + top: -4, + backgroundColor: colors.danger, + borderRadius: 8, + width: 16, + height: 16, + justifyContent: "center", + alignItems: "center", + zIndex: 1, }, + badgeText: { color: colors.white, fontSize: 10, fontWeight: "bold" }, }); diff --git a/src/screens/home/UserProfileStatus.tsx b/src/screens/home/UserProfileStatus.tsx index d7b9f73..2e604f4 100644 --- a/src/screens/home/UserProfileStatus.tsx +++ b/src/screens/home/UserProfileStatus.tsx @@ -1,322 +1,4 @@ -// import React, { useCallback, useEffect, useState } from "react"; -// import { -// StyleSheet, -// Text, -// View, -// TouchableOpacity, -// Modal, -// ToastAndroid, -// Image, -// Animated, -// } from "react-native"; -// import * as Keychain from "react-native-keychain"; -// import { useFocusEffect, useNavigation } from "@react-navigation/native"; -// import { PUT_USER_STATUS } from "../../utils/ApiUrls"; -// import colors from "../../components/colors"; -// import LinearGradient from "react-native-linear-gradient"; -// import {Ionicons} from "@react-native-vector-icons/ionicons"; - -// export type ApiResponse = { -// message: string; -// status: string; -// statusCode: number; -// data: { -// role: string; -// organizerStatus: string; -// profileStatus: boolean; -// }; -// }; - -// type UserProfileStatusProps = { -// profileImage?: { uri: string }; -// }; - -// const UserProfileStatus: React.FC = ({ profileImage }) => { -// const navigation = useNavigation(); -// const [loading, setLoading] = useState(true); -// const [statusData, setStatusData] = useState(null); -// const [showModal, setShowModal] = useState(false); -// const [intervalId, setIntervalId] = useState(null); -// const fadeAnim = useState(new Animated.Value(0))[0]; - -// const userStatus = async () => { -// try { -// const credentials = await Keychain.getGenericPassword(); -// if (!credentials) { -// ToastAndroid.show("You are not logged in", ToastAndroid.SHORT); -// return; -// } -// const token = credentials.password; - -// setLoading(true); -// const response = await fetch(PUT_USER_STATUS, { -// method: "GET", -// headers: { -// Accept: "*/*", -// Authorization: `Bearer ${token}`, -// }, -// }); - -// const json: ApiResponse = await response.json(); -// if (json.status === "success") { -// setStatusData(json.data); -// if (json.data.profileStatus === false) { -// setShowModal(true); -// } -// } else { -// ToastAndroid.show("Failed to fetch status", ToastAndroid.SHORT); -// } -// } catch { -// ToastAndroid.show("Something went wrong", ToastAndroid.SHORT); -// } finally { -// setLoading(false); -// } -// }; - -// useFocusEffect( -// useCallback(() => { -// userStatus(); -// }, []) -// ); - -// useEffect(() => { -// Animated.timing(fadeAnim, { -// toValue: 1, -// duration: 600, -// useNativeDriver: true, -// }).start(); -// }, []); - -// const handleGoToProfile = () => { -// if (intervalId) { -// clearInterval(intervalId); -// setIntervalId(null); -// } -// setShowModal(false); -// navigation.navigate("Profile" as never); -// }; - -// const handlePress = (label: string) => { -// ToastAndroid.show(`${label} clicked`, ToastAndroid.SHORT); -// }; - -// return ( -// -// -// {/* LEFT SECTION */} -// -// Profile Overview - -// -// -// {[ -// "Role", -// "Total Active Groups", -// "Total Joined Groups", -// "Total Created Groups", -// "Total Due Payment", -// "Total Completed Groups", -// ].map((label, i) => ( -// handlePress(label)} -// > -// {label} -// -// ))} -// - -// -// {[ -// statusData?.role || "-", -// "5", -// "3", -// "2", -// "₹1500", -// "4", -// ].map((value, i) => ( -// handlePress(value)} -// > -// {value} -// -// ))} -// -// - -// -// -// Organizer: {statusData?.organizerStatus || "-"} -// -// -// Profile Completed:{" "} -// {statusData?.profileStatus ? "Yes ✅" : "No ❌"} -// -// -// - -// {/* RIGHT SECTION - IMAGE */} -// {/* navigation.navigate("Profile" as never)} -// activeOpacity={0.8} -// > -// {profileImage ? ( -// -// ) : ( -// -// )} -// */} -// - -// {/* Modal */} -// {showModal && ( -// -// -// -// -// Complete Your Profile -// -// Your profile is incomplete. Please update your details to continue. -// - -// -// Go to Profile -// - -// setShowModal(false)} -// > -// Later -// -// -// -// -// )} -// -// ); -// }; - -// export default UserProfileStatus; - -// const styles = StyleSheet.create({ -// container: { -// margin: 12, -// }, -// card: { -// flexDirection: "row", -// justifyContent: "space-between", -// alignItems: "center", -// borderRadius: 16, -// padding: 18, -// elevation: 5, -// shadowColor: "#000", -// shadowOpacity: 0.2, -// shadowRadius: 6, -// }, -// header: { -// fontSize: 20, -// fontWeight: "700", -// color: "#fff", -// marginBottom: 10, -// }, -// leftSection: { -// flex: 1, -// }, -// infoRow: { -// flexDirection: "row", -// justifyContent: "space-between", -// marginBottom: 10, -// }, -// infoLabelBox: { -// marginBottom: 6, -// }, -// infoLabel: { -// color: "rgba(255,255,255,0.8)", -// fontSize: 13, -// }, -// infoValueBox: { -// marginBottom: 6, -// alignItems: "flex-end", -// }, -// infoValue: { -// color: "#fff", -// fontWeight: "600", -// fontSize: 13, -// }, -// statusBox: { -// backgroundColor: "rgba(255,255,255,0.15)", -// padding: 10, -// borderRadius: 8, -// }, -// statusText: { -// color: "#fff", -// fontSize: 13, -// }, -// avatar: { -// width: 80, -// height: 80, -// borderRadius: 40, -// borderWidth: 2, -// borderColor: "#fff", -// }, -// modalOverlay: { -// flex: 1, -// backgroundColor: "rgba(0,0,0,0.5)", -// justifyContent: "center", -// alignItems: "center", -// }, -// modalBox: { -// width: "85%", -// backgroundColor: "#fff", -// borderRadius: 18, -// padding: 20, -// alignItems: "center", -// elevation: 6, -// }, -// modalTitle: { -// fontSize: 20, -// fontWeight: "700", -// color: colors.primary, -// marginVertical: 8, -// }, -// modalText: { -// textAlign: "center", -// color: "#444", -// fontSize: 14, -// marginBottom: 18, -// }, -// button: { -// backgroundColor: colors.primary, -// paddingVertical: 10, -// paddingHorizontal: 30, -// borderRadius: 8, -// marginTop: 8, -// }, -// buttonText: { -// color: "#fff", -// fontWeight: "600", -// }, -// secondaryButton: { -// backgroundColor: "#eee", -// }, -// secondaryText: { -// color: "#333", -// }, -// }); - - - - -import React, { useCallback, useEffect, useState } from "react"; +import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { StyleSheet, Text, @@ -354,35 +36,43 @@ const UserProfileStatus: React.FC = ({ profileImage }) = const [loading, setLoading] = useState(true); const [statusData, setStatusData] = useState(null); const [showModal, setShowModal] = useState(false); - const [intervalId, setIntervalId] = useState(null); - const [moreItem, setMoreItem] = useState(false) - const fadeAnim = useState(new Animated.Value(0))[0]; - const scaleAnim = useState(new Animated.Value(0.9))[0]; + const [moreItem, setMoreItem] = useState(false); - const userStatus = async () => { + // Animation refs to prevent re-creation on re-render + const fadeAnim = useRef(new Animated.Value(0)).current; + const scaleAnim = useRef(new Animated.Value(0.9)).current; + + // Memoized icons list + const icons = useMemo( + () => ["person", "people", "person-add", "create", "card", "checkmark-done"], + [] + ); + + // Fetch user status + const userStatus = useCallback(async () => { try { const credentials = await Keychain.getGenericPassword(); if (!credentials) { ToastAndroid.show("You are not logged in", ToastAndroid.SHORT); return; } - const token = credentials.password; setLoading(true); + const token = credentials.password; + const response = await fetch(PUT_USER_STATUS, { method: "GET", headers: { - Accept: "*/*", + Accept: "/", Authorization: `Bearer ${token}`, }, }); const json: ApiResponse = await response.json(); + if (json.status === "success") { setStatusData(json.data); - if (json.data.profileStatus === false) { - setShowModal(true); - } + if (!json.data.profileStatus) setShowModal(true); } else { ToastAndroid.show("Failed to fetch status", ToastAndroid.SHORT); } @@ -391,62 +81,56 @@ const UserProfileStatus: React.FC = ({ profileImage }) = } finally { setLoading(false); } - }; + }, []); useFocusEffect( useCallback(() => { userStatus(); - }, []) + }, [userStatus]) ); + // Animation start useEffect(() => { Animated.parallel([ - Animated.timing(fadeAnim, { - toValue: 1, - duration: 600, - useNativeDriver: true, - }), - Animated.timing(scaleAnim, { - toValue: 1, - duration: 600, - useNativeDriver: true, - }), + Animated.timing(fadeAnim, { toValue: 1, duration: 600, useNativeDriver: true }), + Animated.timing(scaleAnim, { toValue: 1, duration: 600, useNativeDriver: true }), ]).start(); - }, []); + }, [fadeAnim, scaleAnim]); - const handleGoToProfile = () => { - if (intervalId) { - clearInterval(intervalId); - setIntervalId(null); - } + const handleGoToProfile = useCallback(() => { setShowModal(false); navigation.navigate("Profile" as never); - }; + }, [navigation]); - const handlePress = (label: string) => { + const handlePress = useCallback((label: string) => { ToastAndroid.show(`${label} clicked`, ToastAndroid.SHORT); - }; - - // Graphics and icons for different status items - const getStatusIcon = (index: number) => { - const icons = ["person", "people", "person-add", "create", "card", "checkmark-done"]; - return icons[index]; - }; + }, []); const getValueColor = (value: string) => { - if (value.includes("₹")) return "#4CAF50"; // Green for money - if (value === "Active" || value === "Yes ✅") return "#4CAF50"; + if (value.includes("₹") || value === "Active" || value === "Yes ✅") return "#4CAF50"; if (value === "Inactive" || value === "No ❌") return "#FF6B6B"; return "#fff"; }; + const infoItems = useMemo( + () => [ + { label: "Role", value: statusData?.role || "-" }, + { label: "Active", value: "5" }, + { label: "Joined", value: "3" }, + { label: "Created", value: "2" }, + { label: "Due Pay", value: "₹1500" }, + { label: "Completed", value: "4" }, + ], + [statusData] + ); + return ( - {/* Background Decorative Elements */} + {/* Decorative Background */} - - - + {["circle1", "circle2", "circle3"].map((c, i) => ( + + ))} = ({ profileImage }) = end={{ x: 1, y: 1 }} style={styles.card} > - {/* Header with Graphics */} + {/* Header */} - + Profile Overview @@ -471,31 +155,20 @@ const UserProfileStatus: React.FC = ({ profileImage }) = - {/* Main Content */} + {/* Content Section */} - {/* LEFT SECTION - Stats */} + {/* LEFT SIDE */} - {[ - { label: "Role", value: statusData?.role || "-" }, - { label: "Active Groups", value: "5" }, - { label: "Joined Groups", value: "3" }, - { label: "Created Groups", value: "2" }, - { label: "Due Payment", value: "₹1500" }, - { label: "Completed Groups", value: "4" }, - ].map((item, index) => ( + {infoItems.map((item, index) => ( handlePress(item.label)} > - + {item.label} @@ -504,133 +177,88 @@ const UserProfileStatus: React.FC = ({ profileImage }) = ))} - setMoreItem(!moreItem)}> - - + + + {/* RIGHT SIDE */} + + navigation.navigate("Profile" as never)} activeOpacity={0.8}> + + {profileImage ? ( + + ) : ( + + + + )} + + + + View Profile + + + + setMoreItem(!moreItem)}> + + + + + {moreItem && ( + <> + + + + Status Overview + + + + + Organizer: {statusData?.organizerStatus || "-"} + + + Profile: {statusData?.profileStatus ? "Complete ✅" : "Incomplete ❌"} + + - {/* Status Overview Card */} - { - moreItem && ( - - - - Status Overview - - - - - - - - - Organizer: {statusData?.organizerStatus || "-"} - - - - - - - - - Profile: {statusData?.profileStatus ? "Complete" : "Incomplete"} - - - - - )} - - - {/* RIGHT SECTION - Profile Graphic */} - navigation.navigate("Profile" as never)} - activeOpacity={0.8} - style={styles.profileSection} - > - - {profileImage ? ( - - ) : ( - - - - )} - - + + + Profile Completion + + {statusData?.profileStatus ? "100%" : "60%"} + - View Profile - - - - - {/* Progress Bar for Profile Completion */} - - - Profile Completion - - {statusData?.profileStatus ? "100%" : "60%"} - - - - - - + + + + + + )} - {/* Enhanced Modal */} + {/* Modal */} {showModal && ( - - - - - - + + Complete Your Profile - Your profile is incomplete. Please update your details to unlock all features and improve your experience. + Your profile is incomplete. Update your details to unlock all features. - - Current Progress: 60% - - - - - - + Complete Profile @@ -653,9 +281,10 @@ const UserProfileStatus: React.FC = ({ profileImage }) = export default UserProfileStatus; + const styles = StyleSheet.create({ container: { - margin: 16, + // margin: 16, }, backgroundGraphics: { position: 'absolute', @@ -742,13 +371,13 @@ const styles = StyleSheet.create({ flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between', - marginBottom: 16, + // marginBottom: 16, }, infoCard: { width: '48%', backgroundColor: 'rgba(255,255,255,0.15)', borderRadius: 12, - padding: 12, + padding: 5, marginBottom: 8, borderWidth: 1, borderColor: 'rgba(255,255,255,0.2)', diff --git a/src/screens/management/Payments.tsx b/src/screens/management/Payments.tsx index eef0178..74d43aa 100644 --- a/src/screens/management/Payments.tsx +++ b/src/screens/management/Payments.tsx @@ -131,7 +131,7 @@ const Payments: React.FC = () => { } try { - const url = `https://api.godemo.in/FundCollect/api/payments/groups/${groupId}/cycles/${paymentDetails.currentCycle}/waive/${currentParticipant.userId}?amountToWaive=${amountToWaive}`; + const url = `http://192.168.1.18:9060/api/payments/groups/${groupId}/cycles/${paymentDetails.currentCycle}/waive/${currentParticipant.userId}?amountToWaive=${amountToWaive}`; const response = await apiCall(url, 'PUT', {}) as any; if (response && response.statusCode === 200) { diff --git a/src/utils/ApiUrls.tsx b/src/utils/ApiUrls.tsx index bf4553b..3026c5a 100644 --- a/src/utils/ApiUrls.tsx +++ b/src/utils/ApiUrls.tsx @@ -1,5 +1,5 @@ -export const BASE_URL = "https://api.godemo.in/FundCollect/api/" +export const BASE_URL = "http://192.168.1.18:9060/api/" // export const BASE_URL = "http://192.168.1.5:9060/api/" export const LOGIN_URL = `${BASE_URL}user/generate/otp?mobiles=` export const VARIFY_OTP_URL = `${BASE_URL}user/otp/verify` @@ -23,4 +23,5 @@ export const CONTRIBUTE = `${BASE_URL}payments/groups/`; export const TRANSACTION = `${BASE_URL}payments/my-transactions`; export const UPLOAD_GROUP_IMAGE = `${BASE_URL}fund/groups/`; export const STORE_FCM_TOKEN = `${BASE_URL}token/store?fcmToken=` -export const REMOVE_FCM_TOKEN = `${BASE_URL}token/remove?fcmToken=` \ No newline at end of file +export const REMOVE_FCM_TOKEN = `${BASE_URL}token/remove?fcmToken=` +export const DASHBOARD_URL = `${BASE_URL}fund/dashboard` \ No newline at end of file diff --git a/src/utils/test.js b/src/utils/test.js new file mode 100644 index 0000000..dea85b8 --- /dev/null +++ b/src/utils/test.js @@ -0,0 +1,8 @@ + export const reverseString = (item) =>{ + var j = item.length + console.log("object",j) + for(i=0;i>item.length;i++){ + + + } + } \ No newline at end of file