manage theme

This commit is contained in:
Jaanu423
2025-09-22 10:48:14 +05:30
parent 04f91c0b03
commit e7158df0f8
9 changed files with 122 additions and 87 deletions
+2
View File
@@ -13,6 +13,7 @@ import BottomTabs from "./BottomTabs";
import BecomeOrg from "../screens/profile/BecomeOrg";
import EditGroupScreen from "../screens/management/EditGroupScreen";
import YourContacts from "../screens/management/YourContacts";
import Transaction from "../screens/profile/Transaction";
const Stack = createNativeStackNavigator();
export type RootStackParamList = {
@@ -64,6 +65,7 @@ export default function AppNavigator() {
<Stack.Screen name="GroupReview" component={GroupReview} options={{ headerShown: false }} />
<Stack.Screen name="BecomeOrg" component={BecomeOrg} options={{ headerShown: false }} />
<Stack.Screen name="YourContacts" component={YourContacts} options={{ headerShown: false }} />
<Stack.Screen name="Transaction" component={Transaction} options={{ headerShown: false }} />
{/* <Stack.Screen name="EditGroup" component={EditGroupScreen} options={{ headerShown: false }} /> */}
</Stack.Navigator>
</NavigationContainer>
+55 -41
View File
@@ -11,6 +11,7 @@ import {
Image,
ScrollView,
Alert,
RefreshControl,
} from "react-native";
import { FAB } from "react-native-paper";
import { Ionicons } from "@react-native-vector-icons/ionicons";
@@ -20,7 +21,7 @@ import { StackNavigationProp } from "@react-navigation/stack";
import { RootStackParamList } from "../navigation/AppNavigator";
import AppView from "../components/AppView";
import { apiCall } from "../utils/ApiHelper";
import { BASE_URL, JOIN_GROUP_URL } from "../utils/ApiUrls";
import { BASE_URL, JOIN_GROUP_URL, PUT_USER_STATUS } from "../utils/ApiUrls";
import colors from "../components/colors";
import { ApiResponse } from "./home/UserProfileStatus";
import * as Keychain from "react-native-keychain";
@@ -92,6 +93,7 @@ export default function GroupScreen() {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [role, setRole] = useState<string | null>(null);
const [refreshing, setRefreshing] = useState<boolean>(false)
const fetchGroups = async () => {
if (loading) return;
@@ -140,56 +142,64 @@ export default function GroupScreen() {
Alert.alert("Error", "An unexpected error occurred.");
}
};
const userStatus = async () => {
try {
const credentials = await Keychain.getGenericPassword();
if (!credentials) {
Alert.alert("Error", "You are not logged in");
return;
}
const token = credentials.password;
const userStatus = async () => {
try {
const credentials = await Keychain.getGenericPassword();
if (!credentials) {
Alert.alert("Error", "You are not logged in");
return;
}
const token = credentials.password;
setLoading(true);
setError(null);
const response = await fetch(`${BASE_URL}user/profile/status`, {
method: "GET",
headers: {
Accept: "*/*",
Authorization: `Bearer ${token}`,
},
});
setLoading(true);
setError(null);
const response = await fetch(PUT_USER_STATUS, {
method: "GET",
headers: {
Accept: "*/*",
Authorization: `Bearer ${token}`,
},
});
const json: ApiResponse = await response.json();
const json: ApiResponse = await response.json();
console.log("👤 Profile Status Response:", json);
if (json.status === "success") {
setRole(json.data.role);
console.log("👤 Profile Status Response:", json);
if (json.status === "success") {
setRole(json.data.role);
if (json.data.profileStatus === false) {
if (json.data.profileStatus === false) {
}
} else {
setError(json.message || "Failed to fetch status");
}
} catch (err) {
setError("Something went wrong. Please try again.");
} finally {
setLoading(false);
}
};
} else {
setError(json.message || "Failed to fetch status");
}
} catch (err) {
setError("Something went wrong. Please try again.");
} finally {
setLoading(false);
}
};
useFocusEffect(
useCallback(() => {
userStatus();
}, [])
);
useFocusEffect(
useCallback(() => {
userStatus();
}, [])
);
const handleViewGroup = (group: Group) => {
// navigation.navigate('GroupDetails', { group });
Alert.alert("View Group", `Viewing details for ${group.groupName}`);
};
const onRefresh = () => {
setRefreshing(true)
fetchGroups()
setTimeout(() => {
setRefreshing(false)
}, 20000);
}
const renderContent = () => {
let data: Group[];
switch (activeTab) {
@@ -226,6 +236,10 @@ export default function GroupScreen() {
)}
columnWrapperStyle={isGridView ? { justifyContent: 'space-between' } : null}
contentContainerStyle={{ paddingBottom: 150 }}
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}
ListFooterComponent={<ActivityIndicator size={'large'} color={colors.Group}/>}
/>
);
};
@@ -265,7 +279,7 @@ export default function GroupScreen() {
<TouchableOpacity key={tab} style={[styles.segmentButton, activeTab === tab && styles.segmentButtonActive]} onPress={() => setActiveTab(tab)}>
<Text style={[styles.segmentText, activeTab === tab && styles.segmentTextActive]}>{tab}</Text>
</TouchableOpacity>
))) }
)))}
</View>
<TouchableOpacity onPress={() => setIsGridView(!isGridView)} style={styles.layoutToggleButton}>
<Ionicons name={isGridView ? "list" : "grid"} size={22} color="#555" />
@@ -289,7 +303,7 @@ const styles = StyleSheet.create({
searchContainer: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#fff', borderRadius: 12, paddingHorizontal: 10, elevation: 2, marginVertical: 20 },
searchIcon: { marginRight: 8 },
searchInput: { flex: 1, height: 45, fontSize: 16, color: '#333' },
sectionTitle: { fontSize: 20, fontWeight: 'bold', color: '#333', marginBottom: 12, paddingHorizontal: 16 },
sectionTitle: { fontSize: 20, fontWeight: 'bold', color: colors.Group, marginBottom: 12, paddingHorizontal: 16 },
featuredList: { paddingLeft: 16, marginBottom: 20 },
featuredCard: { width: width * 0.45, marginRight: 15, backgroundColor: '#fff', borderRadius: 12, elevation: 3, overflow: 'hidden' },
featuredImage: { width: '100%', height: 100 },
+2 -2
View File
@@ -4,7 +4,7 @@ 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 { BASE_URL, PUT_USER_STATUS } from "../utils/ApiUrls";
import { useDispatch, useSelector } from "react-redux";
import { setUserData } from "../redux/userSlice";
import colors from "../components/colors";
@@ -30,7 +30,7 @@ const SplashScreen = () => {
}
const token = credentials.password;
const response = await fetch(`${BASE_URL}user/profile/status`, {
const response = await fetch(PUT_USER_STATUS, {
method: "GET",
headers: {
Accept: "*/*",
+2 -2
View File
@@ -10,7 +10,7 @@ import {
} from "react-native";
import * as Keychain from "react-native-keychain";
import { useFocusEffect, useNavigation } from "@react-navigation/native";
import { BASE_URL } from "../../utils/ApiUrls";
import { BASE_URL, PUT_USER_STATUS } from "../../utils/ApiUrls";
import colors from "../../components/colors";
export type ApiResponse = {
@@ -44,7 +44,7 @@ const UserProfileStatus: React.FC = () => {
setLoading(true);
setError(null);
const response = await fetch(`${BASE_URL}user/profile/status`, {
const response = await fetch(PUT_USER_STATUS, {
method: "GET",
headers: {
Accept: "*/*",
+5 -4
View File
@@ -15,6 +15,7 @@ import {
Alert,
} from "react-native";
import AppView from "../../components/AppView";
import colors from "../../components/colors";
const { ContactsModule } = NativeModules;
@@ -187,7 +188,7 @@ const styles = StyleSheet.create({
width: 45,
height: 45,
borderRadius: 25,
backgroundColor: "#25D366",
backgroundColor: colors.pastelOrange,
justifyContent: "center",
alignItems: "center",
marginRight: 12,
@@ -213,10 +214,10 @@ const styles = StyleSheet.create({
paddingVertical: 6,
borderRadius: 8,
borderWidth: 1,
borderColor: "#25D366",
borderColor: colors.Settings,
},
inviteText: {
color: "#25D366",
color: colors.Settings,
fontWeight: "bold",
},
modalOverlay: {
@@ -264,7 +265,7 @@ const styles = StyleSheet.create({
marginLeft: 10,
paddingVertical: 10,
borderRadius: 8,
backgroundColor: "#25D366",
backgroundColor: colors.pastelOrange,
alignItems: "center",
},
sendText: {
+1 -1
View File
@@ -81,7 +81,7 @@ const BecomeOrg = () => {
<TouchableOpacity onPress={() => navigation.replace("Home" as never)} >
<Ionicons name="arrow-back" size={24} color={'#000'} />
</TouchableOpacity>
<Text style={styles.headerTitle}>User Profile</Text>
<Text style={styles.headerTitle}>Become Organizer</Text>
</View>
<KeyboardAvoidingView
+30 -29
View File
@@ -22,13 +22,11 @@ import colors from "../../components/colors";
import SwitchNavigator from "./SwitchNavigator";
import { useFocusEffect, useNavigation } from "@react-navigation/native";
import { ApiResponse } from "../home/UserProfileStatus";
import { BASE_URL } from "../../utils/ApiUrls";
import { BASE_URL, PUT_USER_PROFILE, PUT_USER_PROFILE_IMG, PUT_USER_STATUS } from "../../utils/ApiUrls";
import AppView from "../../components/AppView";
import { useDispatch } from "react-redux";
import { setUserData } from "../../redux/userSlice";
type UserProfile = {
id: string;
userId: number;
@@ -85,27 +83,27 @@ const Profile = () => {
console.log("👤 Profile Response:", result);
if (result.status === "success") {
setUser(result.data);
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
}));
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
}));
} else {
Alert.alert("Error", "Failed to fetch user profile");
}
@@ -127,7 +125,7 @@ const Profile = () => {
const token = credentials.password;
const response = await fetch(
`${BASE_URL}user/profile/update`,
PUT_USER_PROFILE,
{
method: "PUT",
headers: {
@@ -198,7 +196,7 @@ const Profile = () => {
} as any);
const response = await fetch(
`${BASE_URL}user/update/userImg`,
PUT_USER_PROFILE_IMG,
{
method: "PUT",
headers: {
@@ -245,7 +243,7 @@ const Profile = () => {
setLoading(true);
setError(null);
const response = await fetch(`${BASE_URL}user/profile/status`, {
const response = await fetch(PUT_USER_STATUS, {
method: "GET",
headers: {
Accept: "*/*",
@@ -350,7 +348,7 @@ const Profile = () => {
<View style={styles.header}>
<Text style={styles.headerTitle}>User Profile</Text>
<TouchableOpacity onPress={() => confirmLogout(navigation)} style={styles.refreshButton}>
<Ionicons name="log-out-outline" size={24} color={'#000'} />
<Ionicons name="log-out-outline" size={24} color={colors.Profile} />
</TouchableOpacity>
</View>
<KeyboardAvoidingView
@@ -426,6 +424,9 @@ const Profile = () => {
</View> */}
</View>
<View>
<TouchableOpacity onPress={()=>navigation.navigate('Transaction')}>
<Text>View Transaction</Text>
</TouchableOpacity>
<CustomButton
title="Edit Profile"
onPress={() => setEditing(true)}
@@ -692,7 +693,7 @@ const styles = StyleSheet.create({
paddingHorizontal: 8,
},
editSection: {
marginBottom: '40%',
marginBottom: '100%',
flex: 1,
},
editButtons: {
+17
View File
@@ -0,0 +1,17 @@
import { StyleSheet, Text, View } from 'react-native'
import React from 'react'
import AppView from '../../components/AppView'
const Transaction = () => {
return (
<AppView barStyle='dark-content'>
<Text>Transaction</Text>
</AppView>
)
}
export default Transaction
const styles = StyleSheet.create({
})
+8 -8
View File
@@ -6,11 +6,11 @@ export const GROUP_CREATION_URL = `${BASE_URL}fund/groups/{organizerId}`
export const PROFILE_URL =`${BASE_URL}user/profile/view`
export const PUBLIC_GROUPS_URL =`${BASE_URL}fund/user/public`
export const JOIN_GROUP_URL = `${BASE_URL}fund/`;
export const MY_GROUPS_URL =`https://api.godemo.in/FundCollect/api/fund/getAll/my/groups`
export const REQUESTS_URL =`https://api.godemo.in/FundCollect/api/fund/group/pending/request`
//https://api.godemo.in/FundCollect/api/fund/groups/2a80cdaa-8532-4b8a-87f0-9c1023d18a7f/join/64
export const APPROVE_REQUEST_URL =`https://api.godemo.in/FundCollect/api/fund/requests/`
export const DECLINE_REQUEST_URL =`https://api.godemo.in/FundCollect/api/fund/user/my/groups`
// https://api.godemo.in/FundCollect/api/fund/groups/b89f56a1-952d-41b3-ab8d-3c28c91697f5/join/100005
export const GET_JOINED_GROUP_URL = `https://api.godemo.in/FundCollect/api/fund/my/join/groups`
export const MY_GROUPS_URL =`${BASE_URL}fund/getAll/my/groups`
export const REQUESTS_URL =`${BASE_URL}fund/group/pending/request`
export const APPROVE_REQUEST_URL =`${BASE_URL}fund/requests/`
export const DECLINE_REQUEST_URL =`${BASE_URL}fund/user/my/groups`
export const GET_JOINED_GROUP_URL = `${BASE_URL}fund/my/join/groups`
export const PUT_USER_PROFILE_IMG = `${BASE_URL}user/update/userImg`
export const PUT_USER_PROFILE = `${BASE_URL}user/profile/update`
export const PUT_USER_STATUS = `${BASE_URL}user/profile/status`