From 812f30c0c436d32f06c666cba85f42eb288a6d59 Mon Sep 17 00:00:00 2001 From: Abin Toppo Date: Tue, 16 Sep 2025 10:30:15 +0530 Subject: [PATCH] explore Groups --- src/components/AppView.tsx | 20 +- src/navigation/BottomTabs.tsx | 10 +- src/screens/GroupDetails.tsx | 0 src/screens/GroupReview.tsx | 296 ++++++++++++------------- src/screens/GroupScreen.tsx | 392 +++++++++++++++++++++------------- src/utils/ApiUrls.tsx | 5 +- 6 files changed, 394 insertions(+), 329 deletions(-) create mode 100644 src/screens/GroupDetails.tsx diff --git a/src/components/AppView.tsx b/src/components/AppView.tsx index a304a69..7a84206 100644 --- a/src/components/AppView.tsx +++ b/src/components/AppView.tsx @@ -1,17 +1,23 @@ import React from "react"; -import { StatusBar, StyleSheet, View } from "react-native"; +import { StatusBar, StyleSheet, View, ViewStyle } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; type AppViewProps = { children: React.ReactNode; backgroundColor?: string; barStyle?: "default" | "light-content" | "dark-content"; + paddingHorizontal?: number; + paddingTop?: number; + style?: ViewStyle; }; export default function AppView({ children, backgroundColor = "#f5f5f5", barStyle = "dark-content", + paddingHorizontal = 16, // default + paddingTop = 8, // default + style, }: AppViewProps) { return ( @@ -20,7 +26,15 @@ export default function AppView({ backgroundColor={backgroundColor} barStyle={barStyle} /> - {children} + + {children} + ); } @@ -31,7 +45,5 @@ const styles = StyleSheet.create({ }, container: { flex: 1, - paddingHorizontal: 16, - paddingTop: 8, }, }); diff --git a/src/navigation/BottomTabs.tsx b/src/navigation/BottomTabs.tsx index 8339caa..9b10493 100644 --- a/src/navigation/BottomTabs.tsx +++ b/src/navigation/BottomTabs.tsx @@ -12,7 +12,7 @@ const TAB_CONFIG = { inactiveColor: "#8e8e93", backgroundColor: "#fff", height: 70, - iconSize: 26, + iconSize: 28, }; // 1. Define a color map for active tabs @@ -28,7 +28,7 @@ const activeIconColors: { [key: string]: string } = { Home: "#333", Profile: "#333", Group: "#333", - Settings: "#e17055", + Settings: "#333", } @@ -128,14 +128,14 @@ const styles = StyleSheet.create({ marginHorizontal: 10, }, label: { + paddingVertical: 5, fontSize: 12, - marginBottom: 5, }, iconContainer: { justifyContent: "center", alignItems: "center", - width: 50, // Reduced size for a sleeker look - height: 50, // Reduced size + width: 80, // Reduced size for a sleeker look + height: 60, // Reduced size marginTop: 10, borderRadius: 15, }, diff --git a/src/screens/GroupDetails.tsx b/src/screens/GroupDetails.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/screens/GroupReview.tsx b/src/screens/GroupReview.tsx index 242ac46..e65dd92 100644 --- a/src/screens/GroupReview.tsx +++ b/src/screens/GroupReview.tsx @@ -1,51 +1,104 @@ -import React from "react"; -import { View, Text, StyleSheet, TouchableOpacity, ScrollView } from "react-native"; -import {Ionicons} from "@react-native-vector-icons/ionicons"; +import React, { useState, useEffect } from "react"; +import { View, Text, StyleSheet, TouchableOpacity, ScrollView, Modal, ActivityIndicator } from "react-native"; +import { Ionicons } from "@react-native-vector-icons/ionicons"; import AppView from "../components/AppView"; import { apiCall } from "../utils/ApiHelper"; import { GROUP_CREATION_URL } from "../utils/ApiUrls"; -import CustomButton from "../components/CustomButton"; + +// --- Simplified Dialog Component --- +const ThemedDialog = ({ visible, isSuccess, onClose }: { visible: boolean; isSuccess: boolean; onClose: () => void; }) => { + if (!visible) return null; + + const dialogConfig = { + success: { + icon: "checkmark-circle" as const, + color: "#2ecc71", + title: "Success!", + message: "Your group has been created.", + buttonText: "Awesome!", + }, + failure: { + icon: "close-circle" as const, + color: "#e74c3c", + title: "Oops!", + message: "Something went wrong. Please try again.", + buttonText: "Try Again", + }, + }; + + const config = isSuccess ? dialogConfig.success : dialogConfig.failure; + + return ( + + + + + {config.title} + {config.message} + {/* Only show button for failure case */} + {!isSuccess && ( + + {config.buttonText} + + )} + + + + ); +}; export default function GroupReview({ route, navigation }: any) { const { form } = route.params; + const [isLoading, setIsLoading] = useState(false); + // --- Simplified State --- + const [isSuccess, setIsSuccess] = useState(false); + const [modalVisible, setModalVisible] = useState(false); + + // --- Automatic Navigation Effect --- + useEffect(() => { + // If the modal is visible and the operation was a success... + if (modalVisible && isSuccess) { + // ...wait for 2 seconds, then navigate. + const timer = setTimeout(() => { + setModalVisible(false); // Close the dialog + navigation.reset({ // Reset the navigation stack + index: 0, + routes: [{ name: 'Home',}], + }); + }, 2000); + + return () => clearTimeout(timer); // Cleanup timer on unmount + } + }, [modalVisible, isSuccess, navigation]); const handleSubmit = async () => { - const payload = { - ...form, - contributionAmount: Number(form.contributionAmount) || 0, - customCycleDays: Number(form.customCycleDays) || 0, - maxParticipants: Number(form.maxParticipants) || 0, - minParticipants: Number(form.minParticipants) || 0, - }; - await apiCall(GROUP_CREATION_URL, "POST", payload); + setIsLoading(true); + try { + const payload = { + ...form, + contributionAmount: Number(form.contributionAmount) || 0, + customCycleDays: Number(form.customCycleDays) || 0, + maxParticipants: Number(form.maxParticipants) || 0, + minParticipants: Number(form.minParticipants) || 0, + }; + const res = await apiCall(GROUP_CREATION_URL, "POST", payload) as { statusCode?: number }; + + if (res?.statusCode === 201) { + setIsSuccess(true); + } else { + throw new Error("Failed to create group."); + } + } catch (error) { + setIsSuccess(false); + } finally { + setIsLoading(false); + setModalVisible(true); // Show the dialog for both success and failure + } }; - const TimelineSection = ({ icon, title, children }: { icon: any; title: string; children: React.ReactNode }) => ( - - - - - - - - - {title} - - {children} - - - - ); - - const renderRow = (label: string, value: string | number) => { - if (!value && typeof value !== 'number') return null; - return ( - - {label} - {value} - - ); - }; + // --- UI COMPONENTS --- + const TimelineSection = ({ icon, title, children }: { icon: any; title: string; children: React.ReactNode }) => ( {title} {children} ); + const renderRow = (label: string, value: string | number) => { if (!value && typeof value !== 'number') return null; return ( {label} {value} ); }; return ( @@ -55,137 +108,50 @@ export default function GroupReview({ route, navigation }: any) { Confirm the details to launch your group. - - {renderRow("Name", form.groupName)} - {form.description ? ( - - Description - {form.description} - - ) : null} - - - - {renderRow("Visibility", form.visibility)} - {renderRow("Distribution", form.fundDistribution)} - {renderRow("Min Members", form.minParticipants)} - {renderRow("Max Members", form.maxParticipants)} - - - - {renderRow("Contribution", `${form.contributionAmount} INR`)} - {renderRow("Cycle", form.cycleType)} - {form.cycleType === "CUSTOM" && renderRow("Cycle Days", `${form.customCycleDays} days`)} - {renderRow("Start Date", form.startDate)} - - + {/* --- Timeline Sections --- */} + {renderRow("Name", form.groupName)}{form.description ? ( Description {form.description} ) : null} + {renderRow("Visibility", form.visibility)}{renderRow("Distribution", form.fundDistribution)}{renderRow("Min Members", form.minParticipants)}{renderRow("Max Members", form.maxParticipants)} + {renderRow("Contribution", `${form.contributionAmount} INR`)}{renderRow("Cycle", form.cycleType)}{form.cycleType === "CUSTOM" && renderRow("Cycle Days", `${form.customCycleDays} days`)}{renderRow("Start Date", form.startDate)} + + + {isLoading ? : ( <> Launch Group )} + + + {/* --- Simplified Dialog Call --- */} + setModalVisible(false)} + /> ); } const styles = StyleSheet.create({ - container: { - padding: 20, - backgroundColor: "#f5f6fa", - }, - header: { - marginBottom: 30, - alignItems: 'flex-start', - }, - title: { - fontSize: 28, - fontWeight: "bold", - color: "#333", - }, - subtitle: { - fontSize: 16, - color: "#666", - marginTop: 2, - }, - section: { - flexDirection: 'row', - marginBottom: 10, - }, - timeline: { - alignItems: 'center', - width: 40, - }, - timelineIcon: { - width: 40, - height: 40, - borderRadius: 20, - backgroundColor: '#83f5cc', - justifyContent: 'center', - alignItems: 'center', - elevation: 3, - }, - timelineLine: { - flex: 1, - width: 2, - backgroundColor: '#e0e0e0', - }, - content: { - flex: 1, - paddingLeft: 10, - paddingBottom: 20, - }, - sectionTitle: { - fontSize: 18, - fontWeight: 'bold', - color: '#444', - marginBottom: 10, - }, - card: { - backgroundColor: "#fff", - borderRadius: 12, - padding: 15, - elevation: 2, - }, - row: { - flexDirection: "row", - justifyContent: "space-between", - paddingVertical: 10, - borderBottomWidth: 1, - borderBottomColor: '#f5f5f5', - }, - label: { - fontSize: 15, - color: "#666", - fontWeight: "500", - }, - value: { - fontSize: 15, - color: "#333", - fontWeight: "600", - textAlign: 'right', - textTransform: 'capitalize', - }, - descriptionContainer: { - paddingVertical: 10, - }, - descriptionText: { - fontSize: 15, - color: '#333', - marginTop: 4, - lineHeight: 22, - }, - submitBtn: { - backgroundColor: "#83f5cc", - flexDirection: 'row', - justifyContent: 'center', - alignItems: "center", - paddingVertical: 16, - borderRadius: 12, - elevation: 3, - marginTop: 20, - borderWidth: 1.5, - borderColor: '#62b59a', - }, - btnText: { - color: "#333", - fontWeight: "bold", - fontSize: 18, - marginLeft: 10, - }, + // ... (All previous styles remain the same) + container: { padding: 20, backgroundColor: "#f5f6fa" }, + header: { marginBottom: 30, alignItems: 'flex-start' }, + title: { fontSize: 28, fontWeight: "bold", color: "#333" }, + subtitle: { fontSize: 16, color: "#666", marginTop: 2 }, + section: { flexDirection: 'row', marginBottom: 10 }, + timeline: { alignItems: 'center', width: 40 }, + timelineIcon: { width: 40, height: 40, borderRadius: 20, backgroundColor: '#83f5cc', justifyContent: 'center', alignItems: 'center', elevation: 3 }, + timelineLine: { flex: 1, width: 2, backgroundColor: '#e0e0e0' }, + content: { flex: 1, paddingLeft: 10, paddingBottom: 20 }, + sectionTitle: { fontSize: 18, fontWeight: 'bold', color: '#444', marginBottom: 10 }, + card: { backgroundColor: "#fff", borderRadius: 12, padding: 15, elevation: 2 }, + row: { flexDirection: "row", justifyContent: "space-between", paddingVertical: 10, borderBottomWidth: 1, borderBottomColor: '#f5f5f5' }, + label: { fontSize: 15, color: "#666", fontWeight: "500" }, + value: { fontSize: 15, color: "#333", fontWeight: "600", textAlign: 'right', textTransform: 'capitalize' }, + descriptionContainer: { paddingVertical: 10 }, + descriptionText: { fontSize: 15, color: '#333', marginTop: 4, lineHeight: 22 }, + submitBtn: { backgroundColor: "#83f5cc", flexDirection: 'row', justifyContent: 'center', alignItems: "center", paddingVertical: 16, borderRadius: 12, elevation: 3, marginTop: 20, borderWidth: 1.5, borderColor: '#62b59a' }, + btnText: { color: "#333", fontWeight: "bold", fontSize: 18, marginLeft: 10 }, + modalBackdrop: { flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.6)', justifyContent: 'center', alignItems: 'center' }, + dialogBox: { width: '85%', backgroundColor: 'white', borderRadius: 16, padding: 25, alignItems: 'center', elevation: 10 }, + dialogTitle: { fontSize: 22, fontWeight: 'bold', color: '#333', marginTop: 15, marginBottom: 5 }, + dialogMessage: { fontSize: 16, color: '#666', textAlign: 'center', marginBottom: 25 }, + dialogButton: { backgroundColor: '#83f5cc', paddingVertical: 12, paddingHorizontal: 40, borderRadius: 10 }, + dialogButtonText: { color: '#333', fontWeight: 'bold', fontSize: 16 }, }); diff --git a/src/screens/GroupScreen.tsx b/src/screens/GroupScreen.tsx index 25092b9..9c81fa2 100644 --- a/src/screens/GroupScreen.tsx +++ b/src/screens/GroupScreen.tsx @@ -1,180 +1,264 @@ -import React, { useState } from "react"; -import { View, Text, StyleSheet, FlatList, TouchableOpacity } from "react-native"; +import React, { useState, useEffect } from "react"; +import { + View, + Text, + StyleSheet, + FlatList, + TouchableOpacity, + TextInput, + Dimensions, + ActivityIndicator, + Image, + ScrollView, + Alert, +} from "react-native"; import { FAB } from "react-native-paper"; -import { MaterialIcons } from '@react-native-vector-icons/material-icons'; -import { useNavigation } from "@react-navigation/native"; +import { Ionicons } from "@react-native-vector-icons/ionicons"; +import { MaterialIcons } from "@react-native-vector-icons/material-icons"; +import { useNavigation, useFocusEffect } from "@react-navigation/native"; import { StackNavigationProp } from "@react-navigation/stack"; import { RootStackParamList } from "../navigation/AppNavigator"; import AppView from "../components/AppView"; +import { apiCall } from "../utils/ApiHelper"; +import { JOIN_GROUP_URL } from "../utils/ApiUrls"; -// --- Placeholder Data --- -const myGroupsData = [ - { id: '1', name: 'Family Savings', members: 5 }, - { id: '2', name: 'Office Lunch Club', members: 12 }, -]; -const joinedGroupsData = [ - { id: '3', name: 'Apartment Committee', members: 8 }, -]; -const publicGroupsData = [ - { id: '4', name: 'City Runners', members: 50 }, - { id: '5', name: 'Book Readers', members: 25 }, -]; +const { width } = Dimensions.get('window'); +const PUBLIC_GROUPS_URL = "https://api.godemo.in/FundCollect/api/fund/user/public"; -// --- Placeholder Group List Component --- -const GroupList = ({ data }: { data: any[] }) => { - if (data.length === 0) { - return No groups found.; - } + +// --- Types --- +interface Group { + id: string; + groupName: string; + description: string; + maxParticipants: number; + currentParticipants: number; + contributionAmount: number; + cycleType: string; + createdByName: string; +} + +// --- UI Components --- +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; return ( - item.id} - renderItem={({ item }) => ( - - {item.name} - {item.members} members - - )} - /> + + {item.groupName} + {item.description} + + {item.currentParticipants}/{item.maxParticipants} Members + {item.cycleType} + + + onView(item)}> + View + + onJoin(item.id)} + disabled={isFull} + > + {isFull ? "Full" : "Join"} + + + ); }; +const FeaturedGroupCard = ({ item }: { item: Group }) => ( + + + + {item.groupName} + by {item.createdByName} + + +); + export default function GroupScreen() { - const [activeTab, setActiveTab] = useState("My Groups"); + const [activeTab, setActiveTab] = useState("Public"); + const [searchQuery, setSearchQuery] = useState(""); + const [isGridView, setIsGridView] = useState(false); const navigation = useNavigation>(); - const renderContent = () => { - switch (activeTab) { - case "My Groups": - return ; - case "Joined": - return ; - case "Public": - return ; - default: - return null; + const [myGroups, setMyGroups] = useState([]); + const [joinedGroups, setJoinedGroups] = useState([]); + const [publicGroups, setPublicGroups] = useState([]); + const [featuredGroups, setFeaturedGroups] = useState([]); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + const fetchGroups = async () => { + if (loading) return; + setLoading(true); + setError(null); + try { + const res = await apiCall(PUBLIC_GROUPS_URL, "GET") as { data?: Group[] }; + if (res && res.data) { + setPublicGroups(res.data); + setFeaturedGroups(res.data.slice(0, 5)); + } else { + throw new Error("No data received"); + } + } catch (e) { + setError("Failed to fetch groups. Please try again."); + } finally { + setLoading(false); } }; + useFocusEffect(React.useCallback(() => { fetchGroups(); }, [])); + + const filterData = (data: Group[]) => { + if (!searchQuery.trim()) return data; + return data.filter(g => + g.groupName.toLowerCase().includes(searchQuery.toLowerCase()) + ); + }; + + const handleJoinGroup = async (groupId: string, userId: string) => { + console.log("Joining group:", groupId, "User:", userId); + try { + const url = `${JOIN_GROUP_URL}/groups/${groupId}/join/0`; + console.log("Joining group URL:", url); + const res = await apiCall(url, "POST") as { statusCode?: number; message?: string }; + + 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."); + } + } catch (error) { + console.error("Join Group Error:", error); + Alert.alert("Error", "An unexpected error occurred."); + } + }; + + + const handleViewGroup = (group: Group) => { + // navigation.navigate('GroupDetails', { group }); + Alert.alert("View Group", `Viewing details for ${group.groupName}`); + }; + + const renderContent = () => { + let data; + switch (activeTab) { + case "My Groups": data = myGroups; break; + case "Joined": data = joinedGroups; break; + case "Public": data = publicGroups; break; + default: data = []; + } + + if (loading && !publicGroups.length) return ; + if (error) return {error}; + + const filteredData = filterData(data); + if (filteredData.length === 0 && !loading) return No groups found.; + + return ( + item.id} + renderItem={({ item }) => ( + { }} + onView={handleViewGroup} + isGrid={isGridView} + /> + )} + columnWrapperStyle={isGridView ? { justifyContent: 'space-between' } : null} + contentContainerStyle={{ paddingBottom: 150 }} + /> + ); + }; + return ( - - - {/* --- Header and Segmented Control --- */} - Your Groups - - {["My Groups", "Joined", "Public"].map((tab) => ( - setActiveTab(tab)} - > - - {tab} - - - ))} + + {/* Fixed Header */} + + Explore Groups + + + - - {/* --- Dynamic Content Area --- */} - - {renderContent()} - - - } - onPress={() => navigation.navigate('GroupCreation')} - /> + + {/* Scrollable Content */} + + Featured + item.id} + renderItem={({ item }) => } + style={styles.featuredList} + ListEmptyComponent={!loading && featuredGroups.length === 0 ? No featured groups. : null} + /> + + + + {["My Groups", "Joined", "Public"].map((tab) => ( + setActiveTab(tab)}> + {tab} + + ))} + + setIsGridView(!isGridView)} style={styles.layoutToggleButton}> + + + + + {/* The list now renders inside a simple View, as FlatList handles its own scroll */} + {renderContent()} + + } onPress={() => navigation.navigate('GroupCreation')} /> ); } const styles = StyleSheet.create({ - container: { - flex: 1, - padding: 16, - paddingTop: 40, - backgroundColor: '#f5f6fa', - }, - title: { - fontSize: 26, - fontWeight: "bold", - color: "#333", - marginBottom: 20, - }, - segmentedControl: { - flexDirection: 'row', - backgroundColor: '#e0e0e0', - borderRadius: 10, - padding: 4, - marginBottom: 20, - }, - segmentButton: { - flex: 1, - paddingVertical: 8, - borderRadius: 8, - alignItems: 'center', - }, - segmentButtonActive: { - backgroundColor: '#fff', - elevation: 2, - shadowColor: '#000', - shadowOpacity: 0.1, - shadowRadius: 5, - }, - segmentText: { - fontSize: 14, - fontWeight: '600', - color: '#555', - }, - segmentTextActive: { - color: '#333', - }, - contentArea: { - flex: 1, - }, - fab: { - position: "absolute", - right: 20, - bottom: 90, - width: 70, - height: 70, - justifyContent: "center", - alignItems: "center", - backgroundColor: "#83f5cc", - borderRadius: 35, - elevation: 4, - }, - // --- Group List Styles --- - groupCard: { - backgroundColor: '#fff', - padding: 16, - borderRadius: 12, - marginBottom: 12, - elevation: 1, - }, - groupName: { - fontSize: 16, - fontWeight: 'bold', - color: '#333', - }, - groupMembers: { - fontSize: 14, - color: '#777', - marginTop: 4, - }, - emptyText: { - textAlign: 'center', - marginTop: 50, - fontSize: 16, - color: '#888', - }, + container: { flex: 1, backgroundColor: '#f5f6fa' }, + headerContainer: { backgroundColor: '#f5f6fa', paddingTop: 40, paddingHorizontal: 16 }, + title: { fontSize: 28, fontWeight: "bold", color: "#222", marginBottom: 10 }, + searchContainer: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#fff', borderRadius: 12, paddingHorizontal: 10, elevation: 2, marginBottom: 20 }, + searchIcon: { marginRight: 8 }, + searchInput: { flex: 1, height: 45, fontSize: 16, color: '#333' }, + sectionTitle: { fontSize: 20, fontWeight: 'bold', color: '#333', 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 }, + featuredContent: { padding: 10 }, + featuredName: { fontSize: 14, fontWeight: 'bold', color: '#333' }, + featuredCreator: { fontSize: 12, color: '#777', marginTop: 2 }, + tabHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingHorizontal: 16, marginBottom: 16 }, + segmentedControl: { flex: 1, flexDirection: 'row', backgroundColor: '#e9ecef', borderRadius: 10, padding: 4, marginRight: 10 }, + segmentButton: { flex: 1, paddingVertical: 10, borderRadius: 8, alignItems: 'center' }, + segmentButtonActive: { backgroundColor: '#fff', elevation: 2, shadowColor: '#000', shadowOpacity: 0.1, shadowRadius: 5 }, + segmentText: { fontSize: 14, fontWeight: '600', color: '#555' }, + segmentTextActive: { color: '#333' }, + layoutToggleButton: { padding: 8 }, + contentArea: { paddingHorizontal: 16 }, + fab: { position: "absolute", right: 20, bottom: 90, width: 60, height: 60, justifyContent: "center", alignItems: "center", backgroundColor: "#83f5cc", borderRadius: 30, elevation: 4 }, + 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 }, + 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' }, + emptyFeaturedText: { marginLeft: 20, color: '#888' }, + buttonContainer: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 8 }, + viewButton: { flex: 1, backgroundColor: '#e9ecef', paddingVertical: 10, borderRadius: 8, alignItems: 'center', marginRight: 5 }, + viewButtonText: { color: '#333', fontWeight: 'bold', fontSize: 14 }, + joinButton: { flex: 1, backgroundColor: '#83f5cc', paddingVertical: 10, borderRadius: 8, alignItems: 'center', marginLeft: 5 }, + joinButtonDisabled: { backgroundColor: '#bdc3c7' }, + joinButtonText: { color: '#333', fontWeight: 'bold', fontSize: 14 }, }); diff --git a/src/utils/ApiUrls.tsx b/src/utils/ApiUrls.tsx index 9802f90..d0df59b 100644 --- a/src/utils/ApiUrls.tsx +++ b/src/utils/ApiUrls.tsx @@ -2,5 +2,8 @@ export const BASE_URL = "https://api.godemo.in/FundCollect" export const LOGIN_URL = `${BASE_URL}/api/user/generate/otp?mobile=` export const VARIFY_OTP_URL = `${BASE_URL}/api/user/otp/verify` export const ORGRAGISTRATION = `${BASE_URL}/api/organizer/registration/apply` -export const GROUP_CREATION_URL = `${BASE_URL}/api/group/create` +export const GROUP_CREATION_URL = `${BASE_URL}/api/fund/groups/{organizerId}` export const PROFILE_URL =`${BASE_URL}/api/user/profile/view` +export const PUBLIC_GROUPS_URL =`${BASE_URL}/api/fund/user/public` +export const JOIN_GROUP_URL = `${BASE_URL}/api/fund`; +//https://api.godemo.in/FundCollect/api/fund/groups/2a80cdaa-8532-4b8a-87f0-9c1023d18a7f/join/64 \ No newline at end of file