diff --git a/src/components/JoinedGroupCard.tsx b/src/components/JoinedGroupCard.tsx index ba68137..e2f9a52 100644 --- a/src/components/JoinedGroupCard.tsx +++ b/src/components/JoinedGroupCard.tsx @@ -2,42 +2,207 @@ import React, { FC } from 'react'; import { View, Text, StyleSheet } from 'react-native'; -import { JoinedGroup } from '../types'; -interface JoinedGroupCardProps { - item: JoinedGroup; +// Update the type to match the full data structure +interface JoinedGroup { + id: string; + groupName: string; + description: string; + visibility: 'PUBLIC' | 'PRIVATE'; + createdByUserId: number; + createdByName: string; // Renamed from createdBy for clarity + startDate: [number, number, number] | null; + endDate: [number, number, number] | null; + minParticipants: number; + maxParticipants: number; + currentParticipants: number; + contributionAmount: number; + cycleType: 'MONTHLY' | 'WEEKLY' | 'QUARTERLY' | 'CUSTOM'; + status: 'ACTIVE' | 'PENDING' | 'COMPLETED'; } -export const JoinedGroupCard: FC = ({ item }) => ( - - - {item.groupName} - Created by {item.createdBy} +interface JoinedGroupCardProps { + item: JoinedGroup | any; +} + +// Helper function to format dates +const formatDate = (dateArray: [number, number, number] | null): string => { + if (!dateArray) return 'N/A'; + const date = new Date(dateArray[0], dateArray[1] - 1, dateArray[2]); + return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }); +}; + +// Helper to determine status color +const getStatusStyle = (status: JoinedGroup['status']) => { + switch (status) { + case 'ACTIVE': + return { + backgroundColor: '#D1FAE5', // Green tint + textColor: '#065F46', // Dark Green + }; + case 'PENDING': + return { + backgroundColor: '#FEF3C7', // Yellow tint + textColor: '#92400E', // Dark Yellow/Brown + }; + case 'COMPLETED': + return { + backgroundColor: '#E5E7EB', // Gray tint + textColor: '#4B5563', // Dark Gray + }; + default: + return { + backgroundColor: '#E5E7EB', + textColor: '#4B5563', + }; + } +}; + +export const JoinedGroupCard: FC = ({ item }) => { + const progress = (item.currentParticipants / item.maxParticipants) * 100; + const statusStyle = getStatusStyle(item.status); + + return ( + + {/* Header */} + + {item.groupName} + + {item.status} + + + Created by {item.createdByName} + + {/* Financial Info */} + + + Contribution + ₹{item.contributionAmount.toLocaleString('en-IN')} + + + Cycle + {item.cycleType} + + + + {/* Participants Progress */} + + + Participants + {item.currentParticipants} / {item.maxParticipants} + + + + + + + {/* Dates */} + + + {formatDate(item.startDate)} - {formatDate(item.endDate)} + + - -); + ); +}; const styles = StyleSheet.create({ card: { - backgroundColor: '#fff', - borderRadius: 12, - padding: 16, - marginBottom: 12, + backgroundColor: '#FFFFFF', + borderRadius: 16, + padding: 20, + marginBottom: 16, + shadowColor: '#374151', + shadowOpacity: 0.08, + shadowRadius: 10, + shadowOffset: { width: 0, height: 4 }, + elevation: 3, + }, + header: { flexDirection: 'row', - alignItems: 'center', justifyContent: 'space-between', - elevation: 2, - shadowColor: '#000', - shadowOpacity: 0.05, - shadowRadius: 4, + alignItems: 'flex-start', + marginBottom: 4, }, - cardTitle: { - fontSize: 17, + groupName: { + fontSize: 20, fontWeight: 'bold', - color: '#343a40', + color: '#1F2937', + flexShrink: 1, }, - cardSubtitle: { + createdBy: { fontSize: 14, - color: '#6c757d', + color: '#6B7280', + marginBottom: 16, + }, + statusBadge: { + paddingHorizontal: 10, + paddingVertical: 5, + borderRadius: 12, + }, + statusText: { + fontSize: 12, + fontWeight: '600', + textTransform: 'uppercase', + }, + infoRow: { + flexDirection: 'row', + justifyContent: 'space-between', + paddingVertical: 16, + borderTopWidth: 1, + borderBottomWidth: 1, + borderColor: '#F3F4F6', + marginBottom: 16, + }, + infoItem: { + alignItems: 'flex-start', + }, + infoLabel: { + fontSize: 14, + color: '#6B7280', + marginBottom: 4, + }, + infoValue: { + fontSize: 16, + fontWeight: '600', + color: '#111827', + textTransform: 'capitalize', + }, + progressContainer: { + marginBottom: 16, + }, + progressLabels: { + flexDirection: 'row', + justifyContent: 'space-between', + marginBottom: 8, + }, + participantText: { + fontSize: 14, + color: '#6B7280', + }, + participantCount: { + fontSize: 14, + fontWeight: '600', + color: '#111827', + }, + progressBarBackground: { + height: 8, + backgroundColor: '#E5E7EB', + borderRadius: 4, + overflow: 'hidden', + }, + progressBarFill: { + height: '100%', + backgroundColor: '#4F46E5', + borderRadius: 4, + }, + footer: { + alignItems: 'center', + marginTop: 8, + }, + dateText: { + fontSize: 14, + color: '#4B5563', + fontWeight: '500', }, }); diff --git a/src/components/common/Custom.tsx b/src/components/common/Custom.tsx index ae3f3ec..5855ceb 100644 --- a/src/components/common/Custom.tsx +++ b/src/components/common/Custom.tsx @@ -14,12 +14,14 @@ import colors from "../colors"; type CustomInputProps = TextInputProps & { label?: string; icon?: IoniconsIconName; + error?:string }; const CustomInput: React.FC = ({ label, icon, style, + error, ...rest }) => { return ( diff --git a/src/components/common/Header.tsx b/src/components/common/Header.tsx new file mode 100644 index 0000000..b2c63a8 --- /dev/null +++ b/src/components/common/Header.tsx @@ -0,0 +1,62 @@ +import React from "react"; +import { View, Text, TouchableOpacity, StyleSheet } from "react-native"; +import { useNavigation } from "@react-navigation/native"; +import { Ionicons } from "@react-native-vector-icons/ionicons" + +type HeaderProps = { + title: string; + showBack?: boolean; // optional, default true + onBackPress?: () => void; // optional custom back action +}; + +const Header: React.FC = ({ + title, + showBack = true, + onBackPress, +}) => { + const navigation = useNavigation(); + + const handleBack = () => { + if (onBackPress) { + onBackPress(); + } else { + navigation.goBack(); + } + }; + + return ( + + {showBack && ( + + + + )} + {title} + + ); +}; + +export default Header; + +const styles = StyleSheet.create({ + header: { + flexDirection: "row", + alignItems: "center", + paddingHorizontal: 16, + paddingVertical: 12, + backgroundColor: "#fff", + shadowColor: "#000", + shadowOpacity: 0.05, + shadowOffset: { width: 0, height: 2 }, + shadowRadius: 6, + elevation: 3, + }, + backButton: { + marginRight: 12, + }, + headerTitle: { + fontSize: 18, + fontWeight: "600", + color: "#000", + }, +}); diff --git a/src/navigation/AppNavigator.tsx b/src/navigation/AppNavigator.tsx index 59ba031..d7655da 100644 --- a/src/navigation/AppNavigator.tsx +++ b/src/navigation/AppNavigator.tsx @@ -1,7 +1,6 @@ import * as React from "react"; import { NavigationContainer } from "@react-navigation/native"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; -import { View, Text, Button } from "react-native"; import LoginScreen from "../screens/LoginScreen"; import OtpVerificationScreen from "../screens/OtpVarificationScreen"; import SplashScreen from "../screens/SplashScreen"; @@ -11,49 +10,42 @@ import GroupCreation from "../screens/GroupCreation"; import GroupReview from "../screens/GroupReview"; 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"; +import GroupDetails from "../screens/home/user-home/GroupDetails"; +import EditGroupScreen from "../screens/management/EditGroupScreen"; -const Stack = createNativeStackNavigator(); export type RootStackParamList = { + Splash: undefined; Login: undefined; OtpVarify: { mobile: string }; - Home: undefined - HomeTabs: undefined - splash: undefined - OrganizerRegister: undefined + Home: undefined; + HomeTabs: undefined; + OrganizerRegister: undefined; Profile: undefined; GroupCreation: undefined; GroupReview: undefined; - EditGroup: { groupId: string} - + EditGroup: { groupId: string | number }; + GroupDetails: { groupId: string | number }; + BecomeOrg: undefined; + YourContacts: undefined; + Transaction: undefined; }; -function HomeScreen() { - return ( - - Home Screen -