From 3f49c283718f4ee1128f3f3cc584651feb48c511 Mon Sep 17 00:00:00 2001 From: Jaanu423 Date: Fri, 26 Sep 2025 18:08:48 +0530 Subject: [PATCH 1/3] themed style --- babel.config.js | 1 + package-lock.json | 119 +++++++++--- package.json | 2 + src/components/common/AnimatedText.tsx | 64 +++++++ src/screens/GroupScreen.tsx | 45 +++-- src/screens/LoginScreen.tsx | 2 + src/screens/management/EditGroupScreen.tsx | 181 +++++++++++------- .../management/ManagementTabNavigation.tsx | 18 +- 8 files changed, 311 insertions(+), 121 deletions(-) create mode 100644 src/components/common/AnimatedText.tsx diff --git a/babel.config.js b/babel.config.js index f7b3da3..02c7d13 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,3 +1,4 @@ module.exports = { presets: ['module:@react-native/babel-preset'], + plugins: ['react-native-reanimated/plugin'], }; diff --git a/package-lock.json b/package-lock.json index cc5d20f..bd3e08d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,10 +32,12 @@ "react-native-keychain": "^10.0.0", "react-native-linear-gradient": "^2.8.3", "react-native-paper": "^5.14.5", + "react-native-reanimated": "^4.1.2", "react-native-safe-area-context": "^5.6.1", "react-native-screens": "^4.16.0", "react-native-svg": "^15.13.0", "react-native-walkthrough-tooltip": "^1.6.0", + "react-native-worklets": "^0.6.0", "react-redux": "^9.2.0" }, "devDependencies": { @@ -154,7 +156,6 @@ "version": "7.27.3", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/types": "^7.27.3" @@ -183,7 +184,6 @@ "version": "7.28.3", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -205,7 +205,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", @@ -249,7 +248,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -293,7 +291,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/types": "^7.27.1" @@ -333,7 +330,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", @@ -351,7 +347,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -699,7 +694,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -817,7 +811,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -850,7 +843,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -934,7 +926,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", @@ -968,7 +959,6 @@ "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -1271,7 +1261,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.27.1", @@ -1357,7 +1346,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1442,7 +1430,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -1664,7 +1651,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1713,7 +1699,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1745,7 +1730,6 @@ "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz", "integrity": "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -1798,7 +1782,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", - "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", @@ -1928,6 +1911,25 @@ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/@babel/preset-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz", + "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", @@ -4822,6 +4824,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -8177,6 +8180,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "devOptional": true, "license": "ISC" }, "node_modules/istanbul-lib-coverage": { @@ -8927,6 +8931,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "devOptional": true, "license": "MIT" }, "node_modules/json-schema-traverse": { @@ -9810,6 +9815,7 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -13422,6 +13428,34 @@ "react-native": "*" } }, + "node_modules/react-native-reanimated": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.1.2.tgz", + "integrity": "sha512-qzmQiFrvjm62pRBcj97QI9Xckc3EjgHQoY1F2yjktd0kpjhoyePeuTEXjYRCAVIy7IV/1cfeSup34+zFThFoHQ==", + "license": "MIT", + "dependencies": { + "react-native-is-edge-to-edge": "^1.2.1", + "semver": "7.7.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0", + "react": "*", + "react-native": "*", + "react-native-worklets": ">=0.5.0" + } + }, + "node_modules/react-native-reanimated/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/react-native-safe-area-context": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.1.tgz", @@ -13549,6 +13583,42 @@ "@types/react": ">=16.8.24" } }, + "node_modules/react-native-worklets": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.6.0.tgz", + "integrity": "sha512-yETMNuCcivdYWteuG4eRqgiAk2DzRCrVAaEBIEWPo4emrf3BNjadFo85L5QvyEusrX9QKE3ZEAx8U5A/nbyFgg==", + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-arrow-functions": "^7.0.0-0", + "@babel/plugin-transform-class-properties": "^7.0.0-0", + "@babel/plugin-transform-classes": "^7.0.0-0", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0", + "@babel/plugin-transform-optional-chaining": "^7.0.0-0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0-0", + "@babel/plugin-transform-template-literals": "^7.0.0-0", + "@babel/plugin-transform-unicode-regex": "^7.0.0-0", + "@babel/preset-typescript": "^7.16.7", + "convert-source-map": "^2.0.0", + "semver": "7.7.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0", + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-worklets/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/react-native/node_modules/commander": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", @@ -13688,14 +13758,12 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "devOptional": true, "license": "MIT" }, "node_modules/regenerate-unicode-properties": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", - "devOptional": true, "license": "MIT", "dependencies": { "regenerate": "^1.4.2" @@ -13735,7 +13803,6 @@ "version": "6.4.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", - "devOptional": true, "license": "MIT", "dependencies": { "regenerate": "^1.4.2", @@ -13753,14 +13820,12 @@ "version": "0.8.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", - "devOptional": true, "license": "MIT" }, "node_modules/regjsparser": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", - "devOptional": true, "license": "BSD-2-Clause", "dependencies": { "jsesc": "~3.1.0" @@ -14790,6 +14855,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, "license": "MIT" }, "node_modules/throat": { @@ -15037,7 +15103,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", - "devOptional": true, "license": "MIT", "engines": { "node": ">=4" @@ -15047,7 +15112,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "devOptional": true, "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", @@ -15061,7 +15125,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", - "devOptional": true, "license": "MIT", "engines": { "node": ">=4" @@ -15071,7 +15134,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", - "devOptional": true, "license": "MIT", "engines": { "node": ">=4" @@ -15248,6 +15310,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "devOptional": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" diff --git a/package.json b/package.json index 8886c8e..0e73695 100644 --- a/package.json +++ b/package.json @@ -34,10 +34,12 @@ "react-native-keychain": "^10.0.0", "react-native-linear-gradient": "^2.8.3", "react-native-paper": "^5.14.5", + "react-native-reanimated": "^4.1.2", "react-native-safe-area-context": "^5.6.1", "react-native-screens": "^4.16.0", "react-native-svg": "^15.13.0", "react-native-walkthrough-tooltip": "^1.6.0", + "react-native-worklets": "^0.6.0", "react-redux": "^9.2.0" }, "devDependencies": { diff --git a/src/components/common/AnimatedText.tsx b/src/components/common/AnimatedText.tsx new file mode 100644 index 0000000..066ce82 --- /dev/null +++ b/src/components/common/AnimatedText.tsx @@ -0,0 +1,64 @@ +import React, { useEffect } from 'react'; +import { View, Text, StyleSheet } from 'react-native'; +import Animated, { + useSharedValue, + useAnimatedStyle, + withTiming, + withRepeat, + withSequence, + withDelay, + Easing, +} from 'react-native-reanimated'; + +const AnimatedText = ({ text, style, delay = 0 }) => { + const opacity = useSharedValue(0); + const translateY = useSharedValue(20); + + useEffect(() => { + opacity.value = withDelay(delay, withTiming(1, { duration: 800 })); + translateY.value = withDelay(delay, withTiming(0, { duration: 800 })); + }, []); + + const animatedStyle = useAnimatedStyle(() => ({ + opacity: opacity.value, + transform: [{ translateY: translateY.value }], + })); + + return ( + + {text} + + ); +}; + +export default AnimatedText; + +// Usage +const MyComponent = () => { + return ( + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + title: { + fontSize: 32, + fontWeight: 'bold', + marginBottom: 10, + }, + subtitle: { + fontSize: 18, + color: '#666', + }, + text: { + textAlign: 'center', + }, +}); \ No newline at end of file diff --git a/src/screens/GroupScreen.tsx b/src/screens/GroupScreen.tsx index 34036bc..d4c5f96 100644 --- a/src/screens/GroupScreen.tsx +++ b/src/screens/GroupScreen.tsx @@ -27,8 +27,6 @@ import { ApiResponse } from "./home/UserProfileStatus"; import * as Keychain from "react-native-keychain"; const { width } = Dimensions.get('window'); - - // --- Types --- interface Group { id: string; @@ -39,6 +37,7 @@ interface Group { contributionAmount: number; cycleType: string; createdByName: string; + imageBlob: string } // --- UI Components --- @@ -48,16 +47,25 @@ const GroupCard = ({ item, onJoin, onView, isGrid }: { item: Group; onJoin: (gro return ( - {item.groupName} - {item.description} + + + {item.groupName} + {item.description} + + + + {item.currentParticipants}/{item.maxParticipants} Members {item.cycleType} - onView(item)}> + {/* onView(item)}> View - + */} onJoin(item.id)} @@ -70,15 +78,19 @@ const GroupCard = ({ item, onJoin, onView, isGrid }: { item: Group; onJoin: (gro ); }; -const FeaturedGroupCard = ({ item }: { item: Group }) => ( - - - - {item.groupName} - by {item.createdByName} +const FeaturedGroupCard = ({ item }: { item: Group }) => { + console.log("image item : ", item) + console.log("image view : ", `data:image/jpeg;base64${item?.imageBlob}`) + return ( + + + + {item.groupName} + by {item.createdByName} + - -); + ) +}; export default function GroupScreen() { const [activeTab, setActiveTab] = useState("Public"); @@ -114,6 +126,7 @@ export default function GroupScreen() { } }; + const fetchJoinedGroups = async () => { if (loading) return; setLoading(true); @@ -166,7 +179,7 @@ export default function GroupScreen() { Alert.alert("Error", "An unexpected error occurred."); } }; - + const userStatus = async () => { try { const credentials = await Keychain.getGenericPassword(); @@ -264,7 +277,7 @@ export default function GroupScreen() { refreshControl={ } - // ListFooterComponent={} + // ListFooterComponent={} /> ); }; diff --git a/src/screens/LoginScreen.tsx b/src/screens/LoginScreen.tsx index 5b37f77..12979a9 100644 --- a/src/screens/LoginScreen.tsx +++ b/src/screens/LoginScreen.tsx @@ -19,6 +19,7 @@ import type { StackNavigationProp } from "@react-navigation/stack"; import { RootStackParamList } from "../navigation/AppNavigator"; import { CustomButton, CustomInput } from "../components/common/Custom"; import colors from "../components/colors"; +import AnimatedText from "../components/common/AnimatedText"; const theme = { primary: "#111111", @@ -94,6 +95,7 @@ return ( {/* Top content */} + {/* */} CircleCollect Welcome Back 👋 diff --git a/src/screens/management/EditGroupScreen.tsx b/src/screens/management/EditGroupScreen.tsx index a342086..d8e7f4b 100644 --- a/src/screens/management/EditGroupScreen.tsx +++ b/src/screens/management/EditGroupScreen.tsx @@ -58,7 +58,7 @@ export interface GroupDetails { organizerId: string; totalParticipants: number; participants: Participant[]; - imageBlob:string + imageBlob: string } export interface EditGroupPayload { @@ -323,82 +323,127 @@ const EditGroupScreen: React.FC = ({ route }) => { const isInvitable = groupDetails.status === 'APPROVED'; const canStartGroup = groupDetails.status === 'APPROVED' && groupDetails.totalParticipants >= groupDetails.minParticipants; + // const pickImage = () => { + // launchImageLibrary({ mediaType: "photo", quality: 0.5 }, (response) => { + // if (response.didCancel) return; + // if (response.errorCode) { + // Alert.alert("Error", response.errorMessage || "Something went wrong"); + // } else if (response.assets && response.assets.length > 0) { + // const selectedImage = response.assets[0]; + // console.log(selectedImage?.uri) + // setSelectedImage(selectedImage?.uri) + // } + // }); + // }; + const pickImage = () => { launchImageLibrary({ mediaType: "photo", quality: 0.5 }, (response) => { if (response.didCancel) return; + if (response.errorCode) { Alert.alert("Error", response.errorMessage || "Something went wrong"); - } else if (response.assets && response.assets.length > 0) { - const selectedImage = response.assets[0]; - console.log(selectedImage?.uri) - setSelectedImage(selectedImage?.uri) + return; } + + if (!response.assets || response.assets.length === 0) { + Alert.alert("Error", "No image selected"); + return; + } + + const selectedImage = response.assets[0]; + const maxSizeKB = 1000; + const maxSizeBytes = maxSizeKB * 1024; + + // Size validation + if (selectedImage.fileSize && selectedImage.fileSize > maxSizeBytes) { + const currentSizeKB = (selectedImage.fileSize / 1024).toFixed(2); + Alert.alert( + "File Too Large", + `Selected image is ${currentSizeKB}KB. Please select an image smaller than ${maxSizeKB}KB.` + ); + return; + } + + // Additional validation for required fields + if (!selectedImage.uri) { + Alert.alert("Error", "Invalid image file"); + return; + } + + console.log("✅ Image selected:", { + uri: selectedImage.uri, + size: (selectedImage.fileSize / 1024).toFixed(2) + "KB", + width: selectedImage.width, + height: selectedImage.height + }); + + setSelectedImage(selectedImage.uri); }); }; - + const handleUpdateImage = async () => { - try { - const credentials = await Keychain.getGenericPassword(); - if (!credentials) { - Alert.alert("Error", "You are not logged in"); - return; - } - const token = credentials.password; - - if (!selectedImage) { - Alert.alert("Error", "Please select an image first"); - return; + try { + const credentials = await Keychain.getGenericPassword(); + if (!credentials) { + Alert.alert("Error", "You are not logged in"); + return; + } + const token = credentials.password; + + if (!selectedImage) { + Alert.alert("Error", "Please select an image first"); + return; + } + + setImageUpdating(true); + + // Get file extension and mime type dynamically + const fileExtension = selectedImage.split('.').pop(); + + const formData = new FormData(); + formData.append("file", { + uri: selectedImage, + type: "image/jpeg", + name: `group_${groupId}_profile.${fileExtension || "jpg"}`, + }); + + const url = `${UPLOAD_GROUP_IMAGE}${groupId}/upload-image`; + + console.log("url : ", url) + console.log("formdata : ", formData) + + // return + const response = await fetch(url, { + method: "PUT", + headers: { + "Content-Type": "multipart/form-data", + "Authorization": `Bearer ${token}`, + }, + body: formData, + }); + + console.log("image response : ", response) + if (response?.status === 200) { + fetchGroupDetails() + ToastAndroid.show('Group uploaded successfully', ToastAndroid.SHORT) + } + + } catch (error: any) { + console.error("❌ Error updating group image:", error); + Alert.alert("Error", error.message || "Could not update group image"); + } finally { + setImageUpdating(false); } + }; - setImageUpdating(true); - - // Get file extension and mime type dynamically - const fileExtension = selectedImage.split('.').pop(); - - const formData = new FormData(); - formData.append("file", { - uri: selectedImage, - type: "image/jpeg", - name: `group_${groupId}_profile.${fileExtension || "jpg"}`, - }); - - const url = `${UPLOAD_GROUP_IMAGE}${groupId}/upload-image`; - - console.log("url : ", url) - console.log("formdata : ", formData) - - // return - const response = await fetch(url, { - method: "PUT", - headers: { - "Content-Type": "multipart/form-data", - "Authorization": `Bearer ${token}`, - }, - body: formData, - }); - - console.log("image response : ", response) - if(response?.status === 200){ - fetchGroupDetails() - ToastAndroid.show('Group uploaded successfully', ToastAndroid.SHORT) - } - - } catch (error:any) { - console.error("❌ Error updating group image:", error); - Alert.alert("Error", error.message || "Could not update group image"); - } finally { - setImageUpdating(false); - } -}; - -const getProfileImage = () => { - return selectedImage - ? selectedImage - : groupDetails?.imageBlob - ? `data:image/jpeg;base64,${groupDetails.imageBlob}` - : "https://img.freepik.com/premium-vector/people-group-frame-icon_791764-2649.jpg"; -}; -// Helper function to get MIME type + const getProfileImage = () => { + return selectedImage + ? selectedImage + : groupDetails?.imageBlob + ? `data:image/jpeg;base64,${groupDetails.imageBlob}` + : "https://img.freepik.com/premium-vector/people-group-frame-icon_791764-2649.jpg"; + }; + // Helper function to get MIME type return ( @@ -430,12 +475,12 @@ const getProfileImage = () => { - + diff --git a/src/screens/management/ManagementTabNavigation.tsx b/src/screens/management/ManagementTabNavigation.tsx index dca74ad..f961a8e 100644 --- a/src/screens/management/ManagementTabNavigation.tsx +++ b/src/screens/management/ManagementTabNavigation.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { View, Text, StyleSheet, Platform, TouchableOpacity } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import Ionicons from 'react-native-vector-icons/Ionicons'; // Correct import for react-native-vector-icons +import {Ionicons} from '@react-native-vector-icons/ionicons'; // Correct import for react-native-vector-icons import { NativeStackScreenProps } from '@react-navigation/native-stack'; import { RootStackParamList } from '../../navigation/AppNavigator'; // Adjust path @@ -28,7 +28,7 @@ const FloatingTabBar = ({ state, descriptors, navigation }: BottomTabBarProps) = console.log("option : ", options) // A custom option to pass the icon name - const iconName = options.tabBarIconName ?? 'help-circle'; + const iconName = label === "Settings" ? "trail-sign-outline" : label === "Payments" ? "trending-up" : label === "Members" ? "people-outline" : "flower"; const isFocused = state.index === index; @@ -79,7 +79,7 @@ const FloatingTabBar = ({ state, descriptors, navigation }: BottomTabBarProps) = // --- Main Tab Navigator Component --- const ManagementTabNavigation: React.FC = ({ route }) => { - const { groupId } = route.params + const { groupId } = route.params return ( = ({ route }) => { options={{ tabBarLabel: 'Settings', // Custom prop to define the icon for our FloatingTabBar - + }} /> - = ({ route }) => { }} /> - {/* You can easily add more tabs here in the future */} From b248e5578f80bed82fbdac8346b4bc89173ba598 Mon Sep 17 00:00:00 2001 From: Jaanu423 Date: Fri, 26 Sep 2025 18:13:59 +0530 Subject: [PATCH 2/3] themed style --- src/screens/LoginScreen.tsx | 154 ++++++++++++++++++------------------ 1 file changed, 76 insertions(+), 78 deletions(-) diff --git a/src/screens/LoginScreen.tsx b/src/screens/LoginScreen.tsx index 12979a9..3f00e4b 100644 --- a/src/screens/LoginScreen.tsx +++ b/src/screens/LoginScreen.tsx @@ -19,7 +19,6 @@ import type { StackNavigationProp } from "@react-navigation/stack"; import { RootStackParamList } from "../navigation/AppNavigator"; import { CustomButton, CustomInput } from "../components/common/Custom"; import colors from "../components/colors"; -import AnimatedText from "../components/common/AnimatedText"; const theme = { primary: "#111111", @@ -50,91 +49,90 @@ export default function LoginScreen() { ]).start(); }, []); - const handleContinue = async () => { - if (mobile.length === 10) { - setLoading(true); - try { - const res = await axios.get(LOGIN_URL, { - params: { mobile }, - }); + const handleContinue = async () => { + if (mobile.length === 10) { + setLoading(true); + try { + const res = await axios.get(LOGIN_URL, { + params: { mobile }, + }); - console.log("OTP sent response:", res.data); + console.log("OTP sent response:", res.data); - if (res.data.statusCode === 200) { - navigation.navigate("OtpVarify", { mobile }); - } else { - Alert.alert("Error", res.data.message || "Failed to send OTP"); + if (res.data.statusCode === 200) { + navigation.navigate("OtpVarify", { mobile }); + } else { + Alert.alert("Error", res.data.message || "Failed to send OTP"); + } + } catch (error: any) { + console.error("Login error:", error); + + if (axios.isAxiosError(error)) { + console.log("Error message:", error.message); + console.log("Error response:", error.response?.data); + console.log("Error status:", error.response?.status); + console.log("Error headers:", error.response?.headers); + } else { + console.log("Unexpected error:", error); + } + + Alert.alert("Error", "Failed to send OTP. Please try again."); + } finally { + setLoading(false); } - } catch (error: any) { - console.error("Login error:", error); - - if (axios.isAxiosError(error)) { - console.log("Error message:", error.message); - console.log("Error response:", error.response?.data); - console.log("Error status:", error.response?.status); - console.log("Error headers:", error.response?.headers); - } else { - console.log("Unexpected error:", error); - } - - Alert.alert("Error", "Failed to send OTP. Please try again."); - } finally { - setLoading(false); + } else { + Alert.alert("Please enter a valid 10-digit mobile number"); } - } else { - Alert.alert("Please enter a valid 10-digit mobile number"); - } -}; + }; -return ( - - - - {/* Top content */} - - {/* */} - CircleCollect - Welcome Back 👋 - - Enter your mobile number to sign in and continue. - - - - - - - - {/* Bottom Button */} - - + - - By continuing, you agree to our{" "} - - Terms & Privacy + {/* Top content */} + + CircleCollect + Welcome Back 👋 + + Enter your mobile number to sign in and continue. - - - -); + + + + + + + {/* Bottom Button */} + + + + + By continuing, you agree to our{" "} + + Terms & Privacy + + + + + ); } const styles = StyleSheet.create({ From f854bd6765ae828bf714f0ab679670dd95506c8e Mon Sep 17 00:00:00 2001 From: Jaanu423 Date: Mon, 29 Sep 2025 16:15:50 +0530 Subject: [PATCH 3/3] currect api payload --- src/screens/ContributionScreen.tsx | 10 +++- src/screens/GroupCreation.tsx | 5 +- src/screens/GroupDetails.tsx | 0 src/screens/GroupScreen.tsx | 22 +++---- src/screens/home/user-home/GroupDetails.tsx | 5 +- src/screens/management/EditGroupScreen.tsx | 57 +++++++++++-------- .../management/RandomSelectUserScreen.tsx | 8 +-- 7 files changed, 62 insertions(+), 45 deletions(-) delete mode 100644 src/screens/GroupDetails.tsx diff --git a/src/screens/ContributionScreen.tsx b/src/screens/ContributionScreen.tsx index cb6691b..ead24ba 100644 --- a/src/screens/ContributionScreen.tsx +++ b/src/screens/ContributionScreen.tsx @@ -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 = ({ > Base Amount ₹{data?.baseAmount} + { + data?.alreadyPaid ? Already Paid Amount : + + Total Payable + ₹{data?.totalPayable} + } - Total Payable - ₹{data?.totalPayable} Due Date {data?.dueDate} diff --git a/src/screens/GroupCreation.tsx b/src/screens/GroupCreation.tsx index 16d1745..62a08bf 100644 --- a/src/screens/GroupCreation.tsx +++ b/src/screens/GroupCreation.tsx @@ -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() { > Create New Group - + handleChange("groupName", val)} icon="people" error={errors.groupName} /> handleChange("description", val)} multiline icon="document-text" error={errors.description} /> diff --git a/src/screens/GroupDetails.tsx b/src/screens/GroupDetails.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/screens/GroupScreen.tsx b/src/screens/GroupScreen.tsx index 287f178..c7a82e3 100644 --- a/src/screens/GroupScreen.tsx +++ b/src/screens/GroupScreen.tsx @@ -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 ( + {/* navigation.navigate("GroupDetails" as never)}> */} {item.groupName} {item.description} @@ -62,6 +63,7 @@ const GroupCard = ({ item, onJoin, onView, isGrid }: { item: Group; onJoin: (gro {item.currentParticipants}/{item.maxParticipants} Members {item.cycleType} + {/* */} {/* onView(item)}> View @@ -81,7 +83,7 @@ const GroupCard = ({ item, onJoin, onView, isGrid }: { item: Group; onJoin: (gro const FeaturedGroupCard = ({ item }: { item: Group }) => { return ( - + {item.groupName} by {item.createdByName} @@ -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() { - {role === "ORGANIZER" ? (["My Groups", "Joined", "Public"].map((tab) => ( + {role === "ORGANIZER" ? (["Public"].map((tab) => ( setActiveTab(tab)}> {tab} @@ -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' }, diff --git a/src/screens/home/user-home/GroupDetails.tsx b/src/screens/home/user-home/GroupDetails.tsx index 4f07746..e17e430 100644 --- a/src/screens/home/user-home/GroupDetails.tsx +++ b/src/screens/home/user-home/GroupDetails.tsx @@ -37,8 +37,9 @@ const GroupDetails = () => { const [memberData, setMemberData] = useState([]); 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) diff --git a/src/screens/management/EditGroupScreen.tsx b/src/screens/management/EditGroupScreen.tsx index dcf8abc..00c5996 100644 --- a/src/screens/management/EditGroupScreen.tsx +++ b/src/screens/management/EditGroupScreen.tsx @@ -153,14 +153,23 @@ const EditGroupScreen: React.FC = ({ 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()=>{ )} - {paymentStatus && ( + {paymentStatus && ( = ({ 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); }