From 6ed8163d25093e71a798b76506ce9331270b1924 Mon Sep 17 00:00:00 2001 From: Jaanu423 Date: Tue, 16 Sep 2025 16:21:01 +0530 Subject: [PATCH 1/3] dummy home screen --- src/components/common/Custom.tsx | 2 +- src/screens/GroupScreen.tsx | 8 +- src/screens/home/GroupList.tsx | 206 +++++++++++++++++++ src/screens/home/GroupsTabs.tsx | 261 +++++++++++++++++++++++++ src/screens/home/Home.tsx | 156 +++------------ src/screens/home/UserProfileStatus.tsx | 2 +- src/screens/profile/Profile.tsx | 87 +++++---- 7 files changed, 551 insertions(+), 171 deletions(-) create mode 100644 src/screens/home/GroupList.tsx create mode 100644 src/screens/home/GroupsTabs.tsx diff --git a/src/components/common/Custom.tsx b/src/components/common/Custom.tsx index b1d17f1..ae3f3ec 100644 --- a/src/components/common/Custom.tsx +++ b/src/components/common/Custom.tsx @@ -63,7 +63,7 @@ const CustomButton: React.FC = ({ ? colors.pastelOrange : colors.primary); - const textColor = type === "secondary" ? colors.textDark : colors.white; + const textColor = type === "secondary" ? colors.textDark : '#000'; return ( { - let data ; + let data: Group[]; switch (activeTab) { case "My Groups": data = myGroups; break; case "Joined": data = joinedGroups; break; @@ -168,7 +168,11 @@ export default function GroupScreen() { renderItem={({ item }) => ( { }} + onJoin={() => { + if (activeTab === 'Public') { + handleJoinGroup + } + }} onView={handleViewGroup} isGrid={isGridView} /> diff --git a/src/screens/home/GroupList.tsx b/src/screens/home/GroupList.tsx new file mode 100644 index 0000000..7c13a42 --- /dev/null +++ b/src/screens/home/GroupList.tsx @@ -0,0 +1,206 @@ +import React, { useState, useEffect } from "react"; +import { + View, + Text, + TextInput, + StyleSheet, + FlatList, + ActivityIndicator, + TouchableOpacity, + LayoutAnimation, + UIManager, + Platform, +} from "react-native"; +import Ionicons from "react-native-vector-icons/Ionicons"; +import colors from "../../components/colors"; + +// ✅ Enable LayoutAnimation for Android +if (Platform.OS === "android" && UIManager.setLayoutAnimationEnabledExperimental) { + UIManager.setLayoutAnimationEnabledExperimental(true); +} + +const API_URL = "https://api.godemo.in/FundCollect/api/fund/getAll/my/groups"; +const TOKEN = + "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI2MjY1MjI5MzcxIiwidXNlcklkIjoiMTAwMDAxIiwiaWF0IjoxNzU4MDAyOTkxLCJleHAiOjE3NTgwODkzOTF9.mMRPsULcvdfdCrJJBDjnT2okE3dJsTn42JBqi_vP0Xk"; + +// ✅ Each group card with expandable details +const GroupCard = ({ item }: { item: any }) => { + const [expanded, setExpanded] = useState(false); + + const toggleExpand = () => { + LayoutAnimation.easeInEaseOut(); + setExpanded(!expanded); + }; + + const initial = item.groupName ? item.groupName.charAt(0).toUpperCase() : "?"; + + return ( + + + + {initial} + + + {item.groupName} + {item.description} + + {item.visibility} • {item.cycleType} + + + + + + + + {expanded && ( + + {Object.entries(item).map(([key, value]) => ( + + {key}:{" "} + {Array.isArray(value) ? value.join(", ") : String(value)} + + ))} + + )} + + ); +}; + +// ✅ Group list with search +const GroupList = () => { + const [groups, setGroups] = useState([]); + const [filteredGroups, setFilteredGroups] = useState([]); + const [loading, setLoading] = useState(true); + const [search, setSearch] = useState(""); + + useEffect(() => { + const fetchGroups = async () => { + try { + const res = await fetch(API_URL, { + headers: { Accept: "*/*", Authorization: TOKEN }, + }); + const data = await res.json(); + setGroups(data.data || []); + setFilteredGroups(data.data || []); + } catch (e) { + console.error("API error", e); + } finally { + setLoading(false); + } + }; + fetchGroups(); + }, []); + + useEffect(() => { + if (search.trim() === "") { + setFilteredGroups(groups); + } else { + setFilteredGroups( + groups.filter((g) => + g.groupName.toLowerCase().includes(search.toLowerCase()) + ) + ); + } + }, [search, groups]); + + if (loading) { + return ( + + ); + } + + return ( + + {/* Search bar */} + + + + + + {/* Group list */} + item.id} + renderItem={({ item }) => } + ListEmptyComponent={ + No groups found + } + contentContainerStyle={{ paddingBottom: 20 }} + /> + + ); +}; + +export default GroupList; + +const styles = StyleSheet.create({ + searchContainer: { + flexDirection: "row", + alignItems: "center", + backgroundColor: colors.white, + borderRadius: 12, + paddingHorizontal: 12, + margin: 10, + height: 45, + shadowColor: "#000", + shadowOpacity: 0.05, + shadowRadius: 5, + elevation: 2, + }, + searchInput: { flex: 1, marginLeft: 8, color: colors.textDark }, + + groupCard: { + backgroundColor: colors.white, + padding: 14, + borderRadius: 14, + marginHorizontal: 10, + marginBottom: 12, + shadowColor: "#000", + shadowOpacity: 0.05, + shadowRadius: 4, + elevation: 2, + }, + groupHeader: { flexDirection: "row", alignItems: "center" }, + avatar: { + width: 50, + height: 50, + borderRadius: 25, + backgroundColor: colors.primary + "33", + justifyContent: "center", + alignItems: "center", + marginRight: 12, + }, + avatarText: { fontSize: 18, fontWeight: "700", color: colors.primary }, + groupName: { fontSize: 16, fontWeight: "600", color: colors.textDark }, + groupDescription: { fontSize: 13, color: colors.textLight, marginTop: 2 }, + groupMeta: { fontSize: 12, color: colors.primary, marginTop: 2 }, + + groupDetails: { + marginTop: 10, + padding: 10, + borderRadius: 8, + backgroundColor: "#f9f9f9", + }, + detailText: { fontSize: 12, color: colors.textDark, marginBottom: 4 }, + + emptyText: { + textAlign: "center", + color: colors.textLight, + marginTop: 20, + fontSize: 14, + }, +}); diff --git a/src/screens/home/GroupsTabs.tsx b/src/screens/home/GroupsTabs.tsx new file mode 100644 index 0000000..aecc24d --- /dev/null +++ b/src/screens/home/GroupsTabs.tsx @@ -0,0 +1,261 @@ +import React, { useState, useEffect } from "react"; +import { + View, + Text, + StyleSheet, + TouchableOpacity, + TextInput, + FlatList, + ActivityIndicator, + LayoutAnimation, + UIManager, + Platform, +} from "react-native"; +import { Ionicons } from "@react-native-vector-icons/ionicons"; +import colors from "../../components/colors"; +import AppView from "../../components/AppView"; + +// Enable LayoutAnimation for Android +if (Platform.OS === "android" && UIManager.setLayoutAnimationEnabledExperimental) { + UIManager.setLayoutAnimationEnabledExperimental(true); +} + +const API_URL = "https://api.godemo.in/FundCollect/api/fund/getAll/my/groups"; +const TOKEN = + "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI2MjY1MjI5MzcxIiwidXNlcklkIjoiMTAwMDAxIiwiaWF0IjoxNzU4MDAyOTkxLCJleHAiOjE3NTgwODkzOTF9.mMRPsULcvdfdCrJJBDjnT2okE3dJsTn42JBqi_vP0Xk"; + +// ✅ Group Card +const GroupCard = ({ item }: { item: any }) => { + const [expanded, setExpanded] = useState(false); + + const toggleExpand = () => { + LayoutAnimation.easeInEaseOut(); + setExpanded(!expanded); + }; + + const initial = item.groupName ? item.groupName.charAt(0).toUpperCase() : "?"; + + return ( + + + + {initial} + + + {item.groupName} + {item.description} + + {item.visibility} • {item.cycleType} + + + + + + + + {expanded && ( + + {Object.entries(item).map(([key, value]) => ( + + {key}:{" "} + {Array.isArray(value) ? value.join("-") : String(value)} + + ))} + + )} + + ); +}; + +// ✅ Group List with Search +const GroupList = () => { + const [groups, setGroups] = useState([]); + const [filteredGroups, setFilteredGroups] = useState([]); + const [loading, setLoading] = useState(true); + const [search, setSearch] = useState(""); + + useEffect(() => { + const fetchGroups = async () => { + try { + const res = await fetch(API_URL, { + headers: { Accept: "*/*", Authorization: TOKEN }, + }); + const data = await res.json(); + setGroups(data.data || []); + setFilteredGroups(data.data || []); + } catch (e) { + console.error("API error", e); + } finally { + setLoading(false); + } + }; + fetchGroups(); + }, []); + + useEffect(() => { + if (search.trim() === "") { + setFilteredGroups(groups); + } else { + setFilteredGroups( + groups.filter((g) => + g.groupName.toLowerCase().includes(search.toLowerCase()) + ) + ); + } + }, [search, groups]); + + if (loading) return ; + + return ( + <> + + + + + + item.id} + renderItem={({ item }) => } + ListEmptyComponent={ + No groups found + } + /> + + ); +}; + +// ✅ Tab Layout +const GroupsTabs = () => { + const [activeTab, setActiveTab] = useState("MyGroups"); + + const renderContent = () => { + switch (activeTab) { + case "MyGroups": + return ; + case "Create": + return ( + + Create Group Screen + + ); + case "History": + return ( + + History Screen + + ); + default: + return null; + } + }; + + return ( + + + {/* Tabs */} + + {["MyGroups", "Create", "History"].map((tab) => ( + setActiveTab(tab)} + > + + {tab === "MyGroups" ? "My Groups" : tab} + + + ))} + + + {/* Content */} + {renderContent()} + + + ); +}; + +export default GroupsTabs; + +const styles = StyleSheet.create({ + container: { }, + tabs: { + flexDirection: "row", + justifyContent: "space-around", + // marginVertical: 10, + borderBottomWidth: 1, + borderBottomColor: "#ddd", + }, + tabButton: { paddingVertical: 10, flex: 1, alignItems: "center" }, + tabText: { fontSize: 16, color: colors.textLight }, + activeTabButton: { borderBottomWidth: 2, borderBottomColor: colors.primary }, + activeTabText: { color: colors.primary, fontWeight: "600" }, + + searchContainer: { + flexDirection: "row", + alignItems: "center", + backgroundColor: colors.white, + borderRadius: 12, + paddingHorizontal: 12, + marginVertical: 10, + height: 45, + shadowColor: "#000", + shadowOpacity: 0.05, + shadowRadius: 5, + elevation: 2, + }, + searchInput: { flex: 1, marginLeft: 8, color: colors.textDark }, + + groupCard: { + backgroundColor: colors.white, + padding: 14, + borderRadius: 14, + marginBottom: 12, + shadowColor: "#000", + shadowOpacity: 0.05, + shadowRadius: 4, + elevation: 2, + }, + groupLeft: { flexDirection: "row", alignItems: "center" }, + groupAvatar: { + width: 50, + height: 50, + borderRadius: 25, + backgroundColor: colors.primary + "33", + justifyContent: "center", + alignItems: "center", + marginRight: 12, + }, + avatarText: { fontSize: 18, fontWeight: "700", color: colors.primary }, + groupName: { fontSize: 16, fontWeight: "600", color: colors.textDark }, + groupDescription: { fontSize: 13, color: colors.textLight, marginTop: 2 }, + groupMeta: { fontSize: 12, color: colors.primary, marginTop: 2 }, + detailsBox: { + marginTop: 10, + padding: 10, + borderRadius: 8, + backgroundColor: "#f9f9f9", + }, + detailText: { fontSize: 12, color: colors.textDark, marginBottom: 4 }, + emptyText: { textAlign: "center", color: colors.textLight, marginTop: 20 }, + centered: { flex: 1, justifyContent: "center", alignItems: "center" }, + sectionTitle: { fontSize: 18, fontWeight: "600", color: colors.textDark }, +}); diff --git a/src/screens/home/Home.tsx b/src/screens/home/Home.tsx index ebe88cf..bf6f9a2 100644 --- a/src/screens/home/Home.tsx +++ b/src/screens/home/Home.tsx @@ -1,82 +1,43 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import { StyleSheet, Text, View, - TextInput, TouchableOpacity, - FlatList, - Image, + UIManager, + Platform, } from "react-native"; import AppView from "../../components/AppView"; import UserProfileStatus from "./UserProfileStatus"; import colors from "../../components/colors"; -import {Ionicons} from "@react-native-vector-icons/ionicons"; +import { Ionicons } from "@react-native-vector-icons/ionicons"; +import GroupsTabs from "./GroupsTabs"; + +// Enable animation for Android +if (Platform.OS === "android" && UIManager.setLayoutAnimationEnabledExperimental) { + UIManager.setLayoutAnimationEnabledExperimental(true); +} -const dummyChats = [ - { id: "1", name: "Amit Sharma", lastMessage: "Sent ₹500", avatar: "https://i.pravatar.cc/100?img=1" }, - { id: "2", name: "Sneha Patel", lastMessage: "Requested ₹200", avatar: "https://i.pravatar.cc/100?img=2" }, - { id: "3", name: "Group Savings", lastMessage: "Target reached 🎉", avatar: "https://i.pravatar.cc/100?img=3" }, -]; const Home = () => { return ( - - + {/* Header */} Hello, Pooja 👋 - + {/* Status */} + - {/* Search Bar */} - - - - - - {/* Quick Actions */} - - - - Send - - - - Request - - - - History - - - - {/* Recent Chats / Transactions */} - Recent Activity - item.id} - renderItem={({ item }) => ( - - - - {item.name} - {item.lastMessage} - - - - )} - /> - ); }; @@ -84,87 +45,14 @@ const Home = () => { export default Home; const styles = StyleSheet.create({ - container: { - flex: 1, - // padding: 16, - }, + container: { }, header: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", marginBottom: 12, }, - greeting: { - fontSize: 22, - fontWeight: "600", - color: colors.textDark, - }, - searchContainer: { - flexDirection: "row", - alignItems: "center", - backgroundColor: colors.white, - borderRadius: 12, - paddingHorizontal: 12, - marginVertical: 10, - height: 45, - shadowColor: "#000", - shadowOpacity: 0.05, - shadowRadius: 5, - elevation: 2, - }, - searchInput: { - flex: 1, - marginLeft: 8, - color: colors.textDark, - }, - quickActions: { - flexDirection: "row", - justifyContent: "space-between", - marginVertical: 16, - }, - actionButton: { - alignItems: "center", - flex: 1, - }, - actionText: { - marginTop: 6, - fontSize: 14, - color: colors.textDark, - }, - sectionTitle: { - fontSize: 18, - fontWeight: "600", - marginVertical: 10, - color: colors.textDark, - }, - chatItem: { - flexDirection: "row", - alignItems: "center", - backgroundColor: colors.white, - padding: 12, - borderRadius: 12, - marginBottom: 10, - shadowColor: "#000", - shadowOpacity: 0.05, - shadowRadius: 4, - elevation: 1, - }, - avatar: { - width: 45, - height: 45, - borderRadius: 22, - marginRight: 12, - }, - chatInfo: { - flex: 1, - }, - chatName: { - fontSize: 16, - fontWeight: "500", - color: colors.textDark, - }, - chatMessage: { - fontSize: 14, - color: colors.textLight, - }, -}); + greeting: { fontSize: 22, fontWeight: "600", color: colors.textDark }, + + +}); \ No newline at end of file diff --git a/src/screens/home/UserProfileStatus.tsx b/src/screens/home/UserProfileStatus.tsx index d3f4a4d..c0318fe 100644 --- a/src/screens/home/UserProfileStatus.tsx +++ b/src/screens/home/UserProfileStatus.tsx @@ -153,7 +153,7 @@ export default UserProfileStatus; const styles = StyleSheet.create({ container: { - flex: 1, + // flex: 1, // padding: 16, // backgroundColor: "#f5f7fb", }, diff --git a/src/screens/profile/Profile.tsx b/src/screens/profile/Profile.tsx index 90f5e83..0aad48d 100644 --- a/src/screens/profile/Profile.tsx +++ b/src/screens/profile/Profile.tsx @@ -240,6 +240,40 @@ const Profile = () => { } }; + + const handleLogout = (navigation: any) => { + Alert.alert( + "Logout", + "Are you sure you want to logout?", + [ + { + text: "Cancel", + style: "cancel", + }, + { + text: "Yes, Logout", + style: "destructive", + onPress: async () => { + try { + // Clear saved credentials from Keychain + await Keychain.resetGenericPassword(); + + // Navigate to login screen + navigation.reset({ + index: 0, + routes: [{ name: "Login" }], + }); + } catch (error) { + console.error("Logout error:", error); + Alert.alert("Error", "Failed to logout. Please try again."); + } + }, + }, + ], + { cancelable: true } + ); + }; + useFocusEffect( useCallback(() => { userStatus(); @@ -267,7 +301,7 @@ const Profile = () => { if (fetching || !user) { return ( - + Loading profile... ); @@ -281,7 +315,7 @@ const Profile = () => { User Profile - + { onError={() => console.log("Error loading image")} /> - + @@ -318,7 +352,7 @@ const Profile = () => { onPress={handleUpdateImage} icon={imageUpdating ? undefined : "cloud-upload"} style={styles.updateImageButton} - buttonBackground={colors.Profile} + buttonBackground={colors.pastelBlue} /> @@ -334,7 +368,7 @@ const Profile = () => { - + Name {user.firstName} {user.lastName} @@ -342,7 +376,7 @@ const Profile = () => { - + Email {user.email || "Not provided"} @@ -350,7 +384,7 @@ const Profile = () => { - + Mobile {user.mobile || "Not provided"} @@ -358,7 +392,7 @@ const Profile = () => { - + Username {user.username} @@ -366,7 +400,7 @@ const Profile = () => { - + Address {user.address || "Not provided"} @@ -374,7 +408,7 @@ const Profile = () => { - + Gender {user.gender || "Not specified"} @@ -382,7 +416,7 @@ const Profile = () => { - + Role {user.role || "User"} @@ -395,7 +429,7 @@ const Profile = () => { onPress={() => setEditing(true)} icon="create" style={styles.editButton} - buttonBackground={colors.Profile} + buttonBackground={colors.pastelBlue} /> ) : ( @@ -521,13 +555,13 @@ const styles = StyleSheet.create({ profileCard: { borderRadius: 20, margin: 16, - backgroundColor: "#fff", - padding: 20, - shadowColor: "#000", - shadowOpacity: 0.1, - shadowRadius: 10, - shadowOffset: { width: 0, height: 4 }, - elevation: 5, + // backgroundColor: "#fff", + // padding: 20, + // shadowColor: "#000", + // shadowOpacity: 0.1, + // shadowRadius: 10, + // shadowOffset: { width: 0, height: 4 }, + // elevation: 5, }, profileImageSection: { alignItems: "center", @@ -551,7 +585,7 @@ const styles = StyleSheet.create({ position: "absolute", right: 0, bottom: 0, - backgroundColor: "#6366f1", + backgroundColor: colors.pastelBlue, borderRadius: 20, width: 40, height: 40, @@ -645,19 +679,6 @@ const styles = StyleSheet.create({ inputWithIcon: { paddingLeft: 40, }, - button: { - backgroundColor: "#6366f1", - paddingVertical: 14, - borderRadius: 12, - alignItems: "center", - justifyContent: "center", - flexDirection: "row", - shadowColor: "#6366f1", - shadowOpacity: 0.3, - shadowRadius: 6, - shadowOffset: { width: 0, height: 3 }, - elevation: 4, - }, buttonSecondary: { backgroundColor: "#f1f5f9", }, From a931f886b2ad8154cceca68209dba624c4613bab Mon Sep 17 00:00:00 2001 From: Jaanu423 Date: Tue, 16 Sep 2025 18:30:30 +0530 Subject: [PATCH 2/3] implement redux toolkit for manage globle state --- index.js | 13 +- package-lock.json | 358 ++++++++++++++++++++------------ package.json | 4 +- src/redux/store.ts | 13 ++ src/redux/userSlice.ts | 46 ++++ src/screens/home/GroupsTabs.tsx | 4 - src/screens/home/Home.tsx | 39 ++-- 7 files changed, 317 insertions(+), 160 deletions(-) create mode 100644 src/redux/store.ts create mode 100644 src/redux/userSlice.ts diff --git a/index.js b/index.js index 9b73932..0007f0e 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,18 @@ /** * @format */ - +import React from 'react'; import { AppRegistry } from 'react-native'; import App from './App'; import { name as appName } from './app.json'; +import { Provider } from 'react-redux'; +import { store } from './src/redux/store'; -AppRegistry.registerComponent(appName, () => App); +// ✅ Wrapper with Provider +const ReduxWrapper = () => ( + + + +); + +AppRegistry.registerComponent(appName, () => ReduxWrapper); diff --git a/package-lock.json b/package-lock.json index a0b731d..8e4674c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@react-navigation/native": "^7.1.17", "@react-navigation/native-stack": "^7.3.26", "@react-navigation/stack": "^7.4.8", + "@reduxjs/toolkit": "^2.9.0", "axios": "^1.12.2", "install": "^0.13.0", "npm": "^11.6.0", @@ -32,7 +33,8 @@ "react-native-paper": "^5.14.5", "react-native-safe-area-context": "^5.6.1", "react-native-screens": "^4.16.0", - "react-native-walkthrough-tooltip": "^1.6.0" + "react-native-walkthrough-tooltip": "^1.6.0", + "react-redux": "^9.2.0" }, "devDependencies": { "@babel/core": "^7.25.2", @@ -2680,9 +2682,9 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.30", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", - "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -3511,19 +3513,6 @@ "react-native-screens": ">= 4.0.0" } }, - "node_modules/@react-navigation/bottom-tabs/node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, "node_modules/@react-navigation/core": { "version": "7.12.4", "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.12.4.tgz", @@ -3542,12 +3531,6 @@ "react": ">= 18.2.0" } }, - "node_modules/@react-navigation/core/node_modules/react-is": { - "version": "19.1.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.1.tgz", - "integrity": "sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==", - "license": "MIT" - }, "node_modules/@react-navigation/elements": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.6.4.tgz", @@ -3571,19 +3554,6 @@ } } }, - "node_modules/@react-navigation/elements/node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, "node_modules/@react-navigation/native": { "version": "7.1.17", "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.17.tgz", @@ -3645,17 +3615,30 @@ "react-native-screens": ">= 4.0.0" } }, - "node_modules/@react-navigation/stack/node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "node_modules/@reduxjs/toolkit": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.9.0.tgz", + "integrity": "sha512-fSfQlSRu9Z5yBkvsNhYF2rPS8cGXn/TZVrlwN1948QyZ8xMZ0JvP50S2acZNaf+o63u6aEeMjipFyksjIcWrog==", "license": "MIT", "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" }, - "engines": { - "node": ">=12.5.0" + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } } }, "node_modules/@sideway/address": { @@ -3706,6 +3689,18 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -3806,18 +3801,18 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.1.tgz", - "integrity": "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==", + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.0.tgz", + "integrity": "sha512-y1dMvuvJspJiPSDZUQ+WMBvF7dpnEqN4x9DDC9ie5Fs/HUZJA3wFp7EhHoVaKX/iI0cRoECV8X2jL8zi0xrHCg==", "license": "MIT", "dependencies": { - "undici-types": "~7.10.0" + "undici-types": "~7.12.0" } }, "node_modules/@types/react": { - "version": "19.1.12", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz", - "integrity": "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==", + "version": "19.1.13", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.13.tgz", + "integrity": "sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==", "license": "MIT", "dependencies": { "csstype": "^3.0.2" @@ -3865,6 +3860,12 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "license": "MIT" }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, "node_modules/@types/yargs": { "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", @@ -4735,6 +4736,15 @@ ], "license": "MIT" }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.4.tgz", + "integrity": "sha512-L+YvJwGAgwJBV1p6ffpSTa2KRc69EeeYGYjRVWKs0GKrK+LON0GC0gV+rKSNtALEDvMDqkvCFq9r1r94/Gjwxw==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -4793,7 +4803,6 @@ "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" @@ -4812,9 +4821,9 @@ } }, "node_modules/browserslist": { - "version": "4.25.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.4.tgz", - "integrity": "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==", + "version": "4.26.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz", + "integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==", "funding": [ { "type": "opencollective", @@ -4831,9 +4840,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001737", - "electron-to-chromium": "^1.5.211", - "node-releases": "^2.0.19", + "baseline-browser-mapping": "^2.8.3", + "caniuse-lite": "^1.0.30001741", + "electron-to-chromium": "^1.5.218", + "node-releases": "^2.0.21", "update-browserslist-db": "^1.1.3" }, "bin": { @@ -4995,9 +5005,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001741", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001741.tgz", - "integrity": "sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==", + "version": "1.0.30001743", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001743.tgz", + "integrity": "sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==", "funding": [ { "type": "opencollective", @@ -5187,13 +5197,16 @@ "license": "MIT" }, "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", "license": "MIT", "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" } }, "node_modules/color-convert": { @@ -5224,21 +5237,6 @@ "simple-swizzle": "^0.2.2" } }, - "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" - }, "node_modules/colorette": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", @@ -5522,9 +5520,9 @@ "license": "MIT" }, "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -5732,9 +5730,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.214", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.214.tgz", - "integrity": "sha512-TpvUNdha+X3ybfU78NoQatKvQEm1oq3lf2QbnmCEdw+Bd9RuIAY+hJTvq1avzHM0f7EJfnH3vbCnbzKzisc/9Q==", + "version": "1.5.218", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.218.tgz", + "integrity": "sha512-uwwdN0TUHs8u6iRgN8vKeWZMRll4gBkz+QMqdS7DDe49uiK68/UX92lFb61oiFPrpYZNeZIqa4bA7O6Aiasnzg==", "license": "ISC" }, "node_modules/emittery": { @@ -5789,9 +5787,9 @@ } }, "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -7479,6 +7477,16 @@ "node": ">=16.x" } }, + "node_modules/immer": { + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.3.tgz", + "integrity": "sha512-tmjF/k8QDKydUlm3mZU+tjM6zeq9/fFpPqH9SzWmBnVVKsPBg/V66qsMwb3/Bo90cgUN+ghdVBess+hPsxUyRw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -8091,7 +8099,6 @@ "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": { @@ -8848,7 +8855,6 @@ "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": { @@ -9780,7 +9786,6 @@ "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" @@ -9872,9 +9877,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.20.tgz", - "integrity": "sha512-7gK6zSXEH6neM212JgfYFXe+GmZQM+fia5SsusuBIUgnPheLFBmIPhtFoAQRj8/7wASYQnbDlHPVwY0BefoFgA==", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.21.tgz", + "integrity": "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==", "license": "MIT" }, "node_modules/node-stream-zip": { @@ -12930,6 +12935,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, "node_modules/promise": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", @@ -13151,9 +13162,9 @@ } }, "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.1.tgz", + "integrity": "sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==", "license": "MIT" }, "node_modules/react-native": { @@ -13266,6 +13277,31 @@ "react-native-vector-icons": ">7.0.0" } }, + "node_modules/react-native-elements/node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/react-native-elements/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/react-native-elements/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, "node_modules/react-native-gesture-handler": { "version": "2.28.0", "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.28.0.tgz", @@ -13345,6 +13381,31 @@ "react-native-safe-area-context": "*" } }, + "node_modules/react-native-paper/node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/react-native-paper/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/react-native-paper/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, "node_modules/react-native-ratings": { "version": "8.0.4", "resolved": "https://registry.npmjs.org/react-native-ratings/-/react-native-ratings-8.0.4.tgz", @@ -13491,6 +13552,29 @@ "node": ">=10" } }, + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", @@ -13514,13 +13598,6 @@ "react": "^19.1.0" } }, - "node_modules/react-test-renderer/node_modules/react-is": { - "version": "19.1.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.1.tgz", - "integrity": "sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==", - "dev": true, - "license": "MIT" - }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -13551,6 +13628,21 @@ "react-native": ">= 0.30.0" } }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -13582,9 +13674,9 @@ "license": "MIT" }, "node_modules/regenerate-unicode-properties": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", - "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "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": { @@ -13622,18 +13714,18 @@ } }, "node_modules/regexpu-core": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", - "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.3.1.tgz", + "integrity": "sha512-DzcswPr252wEr7Qz8AyAVbfyBDKLoYp6eRA1We2Fa9qirRFSdtkP5sHr3yglDKy2BbA0fd2T+j/CUSKes3FeVQ==", "devOptional": true, "license": "MIT", "dependencies": { "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.0", + "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" + "unicode-match-property-value-ecmascript": "^2.2.1" }, "engines": { "node": ">=4" @@ -13688,6 +13780,12 @@ "devOptional": true, "license": "ISC" }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -14188,18 +14286,18 @@ "license": "ISC" }, "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", "license": "MIT", "dependencies": { "is-arrayish": "^0.3.1" } }, "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", "license": "MIT" }, "node_modules/sisteransi": { @@ -14687,7 +14785,6 @@ "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": { @@ -14926,9 +15023,9 @@ } }, "node_modules/undici-types": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", - "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.12.0.tgz", + "integrity": "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==", "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -14956,9 +15053,9 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", - "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "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": { @@ -14966,9 +15063,9 @@ } }, "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "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": { @@ -15146,7 +15243,6 @@ "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 dbdff86..6210659 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@react-navigation/native": "^7.1.17", "@react-navigation/native-stack": "^7.3.26", "@react-navigation/stack": "^7.4.8", + "@reduxjs/toolkit": "^2.9.0", "axios": "^1.12.2", "install": "^0.13.0", "npm": "^11.6.0", @@ -34,7 +35,8 @@ "react-native-paper": "^5.14.5", "react-native-safe-area-context": "^5.6.1", "react-native-screens": "^4.16.0", - "react-native-walkthrough-tooltip": "^1.6.0" + "react-native-walkthrough-tooltip": "^1.6.0", + "react-redux": "^9.2.0" }, "devDependencies": { "@babel/core": "^7.25.2", diff --git a/src/redux/store.ts b/src/redux/store.ts new file mode 100644 index 0000000..4182583 --- /dev/null +++ b/src/redux/store.ts @@ -0,0 +1,13 @@ +// store.ts +import { configureStore } from "@reduxjs/toolkit"; +import userReducer from "./userSlice"; // adjust the path + +export const store = configureStore({ + reducer: { + user: userReducer, // register user slice here + }, +}); + +// ✅ Types for TypeScript +export type RootState = ReturnType; +export type AppDispatch = typeof store.dispatch; diff --git a/src/redux/userSlice.ts b/src/redux/userSlice.ts new file mode 100644 index 0000000..562a5b9 --- /dev/null +++ b/src/redux/userSlice.ts @@ -0,0 +1,46 @@ +import { createSlice } from "@reduxjs/toolkit"; +import type { PayloadAction } from "@reduxjs/toolkit"; + +export interface UserState { + id: string; + name: string; + email: string; + profilePicture: string; + role: string; + organizerStatus: string; + profileStatus: boolean; +} + +const initialState: UserState = { + id: "", + name: "", + email: "", + profilePicture: "", + role: "", + organizerStatus: "", + profileStatus: false, +}; + +export const userSlice = createSlice({ + name: "user", + initialState, + reducers: { + // ✅ set all user details at once (e.g. after login) + setUser: (state, action: PayloadAction) => { + return { ...action.payload }; + }, + + // ✅ update only selected fields (e.g. profile update) + updateUser: (state, action: PayloadAction>) => { + return { ...state, ...action.payload }; + }, + + // ✅ clear user data (e.g. on logout) + clearUser: () => initialState, + }, +}); + +// Action creators +export const { setUser, updateUser, clearUser } = userSlice.actions; + +export default userSlice.reducer; diff --git a/src/screens/home/GroupsTabs.tsx b/src/screens/home/GroupsTabs.tsx index aecc24d..3443e02 100644 --- a/src/screens/home/GroupsTabs.tsx +++ b/src/screens/home/GroupsTabs.tsx @@ -24,17 +24,13 @@ const API_URL = "https://api.godemo.in/FundCollect/api/fund/getAll/my/groups"; const TOKEN = "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI2MjY1MjI5MzcxIiwidXNlcklkIjoiMTAwMDAxIiwiaWF0IjoxNzU4MDAyOTkxLCJleHAiOjE3NTgwODkzOTF9.mMRPsULcvdfdCrJJBDjnT2okE3dJsTn42JBqi_vP0Xk"; -// ✅ Group Card const GroupCard = ({ item }: { item: any }) => { const [expanded, setExpanded] = useState(false); - const toggleExpand = () => { LayoutAnimation.easeInEaseOut(); setExpanded(!expanded); }; - const initial = item.groupName ? item.groupName.charAt(0).toUpperCase() : "?"; - return ( diff --git a/src/screens/home/Home.tsx b/src/screens/home/Home.tsx index bf6f9a2..b0a1439 100644 --- a/src/screens/home/Home.tsx +++ b/src/screens/home/Home.tsx @@ -12,32 +12,27 @@ import UserProfileStatus from "./UserProfileStatus"; import colors from "../../components/colors"; import { Ionicons } from "@react-native-vector-icons/ionicons"; import GroupsTabs from "./GroupsTabs"; - // Enable animation for Android if (Platform.OS === "android" && UIManager.setLayoutAnimationEnabledExperimental) { UIManager.setLayoutAnimationEnabledExperimental(true); } - - const Home = () => { return ( - {/* Header */} - - Hello, Pooja 👋 - - - - - - {/* Status */} - - - + {/* Header */} + + Hello, Pooja 👋 + + + + + {/* Status */} + + ); }; @@ -45,7 +40,7 @@ const Home = () => { export default Home; const styles = StyleSheet.create({ - container: { }, + container: {}, header: { flexDirection: "row", justifyContent: "space-between", @@ -53,6 +48,6 @@ const styles = StyleSheet.create({ marginBottom: 12, }, greeting: { fontSize: 22, fontWeight: "600", color: colors.textDark }, - - + + }); \ No newline at end of file From dd603dcff71e853baf600ac7be5639877b8a5468 Mon Sep 17 00:00:00 2001 From: Jaanu423 Date: Wed, 17 Sep 2025 16:24:06 +0530 Subject: [PATCH 3/3] Requeste api implelented --- package-lock.json | 16 + package.json | 1 + src/components/colors.ts | 2 +- src/redux/userSlice.ts | 34 +- src/screens/LoginScreen.tsx | 44 +- src/screens/OtpVarificationScreen.tsx | 7 +- src/screens/SplashScreen.tsx | 74 +++- src/screens/home/DeclineModal.tsx | 74 ++++ src/screens/home/GroupList.tsx | 86 ++-- src/screens/home/GroupsTabs.tsx | 207 ++------- src/screens/home/Home.tsx | 27 +- src/screens/home/RequestList.tsx | 606 ++++++++++++++++++++++++++ src/screens/profile/Profile.tsx | 46 +- 13 files changed, 921 insertions(+), 303 deletions(-) create mode 100644 src/screens/home/DeclineModal.tsx create mode 100644 src/screens/home/RequestList.tsx diff --git a/package-lock.json b/package-lock.json index 8e4674c..541717d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "react": "19.1.0", "react-native": "0.81.1", "react-native-calendars": "^1.1313.0", + "react-native-dialog": "^9.3.0", "react-native-elements": "^3.4.3", "react-native-image-picker": "^8.2.1", "react-native-keychain": "^10.0.0", @@ -4803,6 +4804,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" @@ -8099,6 +8101,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": { @@ -8855,6 +8858,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": { @@ -9786,6 +9790,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" @@ -13256,6 +13261,15 @@ "react-native": "*" } }, + "node_modules/react-native-dialog": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/react-native-dialog/-/react-native-dialog-9.3.0.tgz", + "integrity": "sha512-JEOJY/0AzTM9grIl0BL8o/IJPIJru7k5MPj9POTE9RRezUEtgn0YSvCpTlBtG0obWgOdzg2otMz1OQvMXS0wMQ==", + "license": "MIT", + "peerDependencies": { + "react-native": ">=0.63.0" + } + }, "node_modules/react-native-elements": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/react-native-elements/-/react-native-elements-3.4.3.tgz", @@ -14785,6 +14799,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": { @@ -15243,6 +15258,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 6210659..8825a10 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "react": "19.1.0", "react-native": "0.81.1", "react-native-calendars": "^1.1313.0", + "react-native-dialog": "^9.3.0", "react-native-elements": "^3.4.3", "react-native-image-picker": "^8.2.1", "react-native-keychain": "^10.0.0", diff --git a/src/components/colors.ts b/src/components/colors.ts index 0206238..7431c86 100644 --- a/src/components/colors.ts +++ b/src/components/colors.ts @@ -15,7 +15,7 @@ const colors = { textLight: "#555555", white: "#FFFFFF", black: "#000000", - primary: "#007AFF", + primary: "#a57ae9ff", }; export default colors; diff --git a/src/redux/userSlice.ts b/src/redux/userSlice.ts index 562a5b9..2b7c211 100644 --- a/src/redux/userSlice.ts +++ b/src/redux/userSlice.ts @@ -3,20 +3,44 @@ import type { PayloadAction } from "@reduxjs/toolkit"; export interface UserState { id: string; - name: string; + userId: number | null; + username: string; + firstName: string; + lastName: string; + gender: string; + mobile: string; email: string; + address: string; + bankAccountNumber: string; + bankName: string; + branchCode: string; profilePicture: string; + filePath: string; + imageBlob: string; role: string; + organizerId: string; organizerStatus: string; profileStatus: boolean; } const initialState: UserState = { id: "", - name: "", + userId: null, + username: "", + firstName: "", + lastName: "", + gender: "", + mobile: "", email: "", + address: "", + bankAccountNumber: "", + bankName: "", + branchCode: "", profilePicture: "", + filePath: "", + imageBlob: "", role: "", + organizerId: "", organizerStatus: "", profileStatus: false, }; @@ -26,12 +50,12 @@ export const userSlice = createSlice({ initialState, reducers: { // ✅ set all user details at once (e.g. after login) - setUser: (state, action: PayloadAction) => { + setUserData: (state, action: PayloadAction) => { return { ...action.payload }; }, // ✅ update only selected fields (e.g. profile update) - updateUser: (state, action: PayloadAction>) => { + updateUserData: (state, action: PayloadAction>) => { return { ...state, ...action.payload }; }, @@ -41,6 +65,6 @@ export const userSlice = createSlice({ }); // Action creators -export const { setUser, updateUser, clearUser } = userSlice.actions; +export const { setUserData, updateUserData, clearUser } = userSlice.actions; export default userSlice.reducer; diff --git a/src/screens/LoginScreen.tsx b/src/screens/LoginScreen.tsx index 048ca04..9e53fac 100644 --- a/src/screens/LoginScreen.tsx +++ b/src/screens/LoginScreen.tsx @@ -10,24 +10,29 @@ import { Platform, 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 type { StackNavigationProp } from "@react-navigation/stack"; import { RootStackParamList } from "../navigation/AppNavigator"; +import { CustomButton, CustomInput } from "../components/common/Custom"; +import colors from "../components/colors"; const theme = { primary: "#111111", - accent: "#FF7A00", + accent: colors.primary, background: "#F9F9F9", + surface: "#FFFFFF", text: "#1A1A1A", subText: "#6B6B6B", outline: "#E5E5E5", + error: "#E53935", + success: "#2E7D32", }; export default function LoginScreen() { - const navigation = useNavigation>(); const [mobile, setMobile] = useState(""); const [loading, setLoading] = useState(false); @@ -48,16 +53,14 @@ export default function LoginScreen() { if (mobile.length === 10) { setLoading(true); try { - console.log("Mobile submitted:", mobile); - const res = await axios.get(LOGIN_URL + mobile) - console.log('loginres', res.data) + const res = await axios.get(LOGIN_URL + mobile); if (res.data.statusCode === 200) { - navigation.navigate('OtpVarify', { mobile: mobile }) + navigation.navigate("OtpVarify", { mobile }); } } catch (error) { console.error("Login error:", error); Alert.alert("Error", "Failed to send OTP. Please try again."); - }finally { + } finally { setLoading(false); } } else { @@ -102,15 +105,14 @@ export default function LoginScreen() { { opacity: fade, transform: [{ translateY: slide }] }, ]} > - Mobile Number - @@ -119,14 +121,8 @@ export default function LoginScreen() { - - Continue - + + By continuing, you agree to our{" "} @@ -142,7 +138,7 @@ const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: theme.background, padding: 20 }, topSection: { flex: 1, justifyContent: "center" }, brand: { - fontSize: 20, + fontSize: 30, fontWeight: "700", color: theme.accent, marginBottom: 24, @@ -166,7 +162,7 @@ const styles = StyleSheet.create({ color: theme.text, }, input: { - backgroundColor: "#fff", + backgroundColor: theme.surface, borderRadius: 14, padding: 14, fontSize: 16, diff --git a/src/screens/OtpVarificationScreen.tsx b/src/screens/OtpVarificationScreen.tsx index f3e2ebc..c611f49 100644 --- a/src/screens/OtpVarificationScreen.tsx +++ b/src/screens/OtpVarificationScreen.tsx @@ -20,10 +20,11 @@ import { RootStackParamList } from "../navigation/AppNavigator"; import * as Keychain from "react-native-keychain"; import { LOGIN_URL, VARIFY_OTP_URL } from "../utils/ApiUrls"; import { StackNavigationProp } from "@react-navigation/stack"; +import colors from "../components/colors"; const theme = { primary: "#111111", - accent: "#FF7A00", + accent: colors.primary, background: "#F9F9F9", text: "#1A1A1A", subText: "#6B6B6B", @@ -245,13 +246,13 @@ const styles = StyleSheet.create({ cellFilled: { borderColor: "#D1D1D1" }, bottomSection: { marginBottom: 30 }, button: { - backgroundColor: theme.primary, + backgroundColor: colors.primary, paddingVertical: 18, borderRadius: 14, alignItems: "center", justifyContent: "center", }, - buttonText: { color: "#fff", fontWeight: "700", fontSize: 16 }, + buttonText: { color: "#000", fontWeight: "700", fontSize: 16 }, footerText: { textAlign: "center", color: theme.subText, diff --git a/src/screens/SplashScreen.tsx b/src/screens/SplashScreen.tsx index 541c028..38b6529 100644 --- a/src/screens/SplashScreen.tsx +++ b/src/screens/SplashScreen.tsx @@ -1,13 +1,75 @@ import React, { useEffect, useRef } from "react"; -import { View, Text, StyleSheet, ActivityIndicator, Animated } from "react-native"; +import { View, Text, StyleSheet, ActivityIndicator, Animated, Alert } from "react-native"; import * as Keychain from "react-native-keychain"; import { StackNavigationProp } from "@react-navigation/stack"; import { useNavigation } from "@react-navigation/native"; import { RootStackParamList } from "../navigation/AppNavigator"; // adjust path +import { BASE_URL } from "../utils/ApiUrls"; +import { useDispatch, useSelector } from "react-redux"; +import { setUserData } from "../redux/userSlice"; +import colors from "../components/colors"; const SplashScreen = () => { + const dispatch = useDispatch(); + const user = useSelector((state: any) => state.user); const navigation = useNavigation>(); - const fadeAnim = useRef(new Animated.Value(1)).current; // opacity starts at 1 + const fadeAnim = useRef(new Animated.Value(1)).current; + + const fetchUserProfile = async () => { + try { + const credentials = await Keychain.getGenericPassword(); + if (!credentials) { + Alert.alert("Error", "You are not logged in"); + return; + } + const token = credentials.password; + + const response = await fetch( + `${BASE_URL}user/profile/view`, + { + method: "GET", + headers: { + Accept: "*/*", + Authorization: `Bearer ${token}`, + }, + } + ); + + const result = await response.json(); + if (result.status === "success") { + dispatch(setUserData({ + id: result?.data.id, + userId: result?.data.userId, + username: result?.data.username, + firstName: result?.data.firstName, + lastName: result?.data.lastName, + gender: result?.data.gender, + mobile: result?.data.mobile, + email: result?.data.email, + address: result?.data.address, + bankAccountNumber: result?.data.bankAccountNumber, + bankName: result?.data.bankName, + branchCode: result?.data.branchCode, + profilePicture: result?.data.filePath, // or keep as `filePath` + filePath: result?.data.filePath, + imageBlob: result?.data.imageBlob, + role: result?.data.role, + organizerId: result?.data.organizerId, + organizerStatus: result?.data.organizerStatus, + profileStatus: true, // set true once profile is fetched + })); + + console.log("splash user data:", result.data); + } else { + Alert.alert("Error", "Failed to fetch user profile"); + } + } catch (error) { + console.error("❌ Error fetching profile:", error); + Alert.alert("Error", "Could not connect to server"); + } + }; + + console.log("redux user", user); useEffect(() => { const checkLogin = async () => { @@ -36,12 +98,16 @@ const SplashScreen = () => { }); }, [navigation, fadeAnim]); + useEffect(() => { + fetchUserProfile(); + }, []) + return ( Circle Collect - + ); }; @@ -58,7 +124,7 @@ const styles = StyleSheet.create({ title: { fontSize: 28, fontWeight: "800", - color: "#FF7A00", + color: colors.Home, letterSpacing: 1, }, }); diff --git a/src/screens/home/DeclineModal.tsx b/src/screens/home/DeclineModal.tsx new file mode 100644 index 0000000..93bd75e --- /dev/null +++ b/src/screens/home/DeclineModal.tsx @@ -0,0 +1,74 @@ +import React, { useState } from "react"; +import { View, Text, TextInput, Button, Modal, StyleSheet } from "react-native"; + +const DeclineModal = ({ visible, onClose, onSubmit }: { + visible: boolean; + onClose: () => void; + onSubmit: (reason: string) => void; +}) => { + const [reason, setReason] = useState(""); + + return ( + + + + Decline Request + + +