with helper funtion
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { NativeStackScreenProps } from '@react-navigation/native-stack';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
@@ -30,282 +30,251 @@ export interface GroupDetails {
|
||||
startDate: [number, number, number];
|
||||
endDate: [number, number, number] | null;
|
||||
contributionAmount: number;
|
||||
minParticipants: number;
|
||||
maxParticipants: number;
|
||||
latePaymentCharge: number | null;
|
||||
cycleType: 'QUARTERLY' | 'MONTHLY' | 'WEEKLY' | 'CUSTOM';
|
||||
status: 'PENDING' | 'ACTIVE' | 'COMPLETED';
|
||||
visibility: 'PUBLIC' | 'PRIVATE';
|
||||
organizerFirstName: string;
|
||||
organizerLastName: string;
|
||||
customCycleDays: number;
|
||||
status: string;
|
||||
totalParticipants: number;
|
||||
participants: Participant[];
|
||||
}
|
||||
|
||||
export interface EditGroupPayload {
|
||||
groupName: string;
|
||||
description: string;
|
||||
visibility: 'PUBLIC' | 'PRIVATE';
|
||||
cycleType: 'QUARTERLY' | 'MONTHLY' | 'WEEKLY' | 'CUSTOM';
|
||||
contributionAmount: number;
|
||||
maxParticipants: number;
|
||||
latePaymentCharge: number;
|
||||
customCycleDays: number;
|
||||
startDate: string;
|
||||
endDate: string | null;
|
||||
groupName?: string;
|
||||
description?: string;
|
||||
maxParticipants?: number;
|
||||
}
|
||||
|
||||
type EditGroupScreenProps = NativeStackScreenProps<RootStackParamList, 'EditGroup'>;
|
||||
type EditingSection = 'details' | 'financials' | null;
|
||||
|
||||
// --- Helper Components for Read-Only View ---
|
||||
const InfoRow: React.FC<{ label: string; value: string | number; isStatus?: boolean }> = ({ label, value, isStatus = false }) => (
|
||||
<View style={styles.infoRow}>
|
||||
<Text style={styles.infoLabel}>{label}</Text>
|
||||
<Text
|
||||
style={[
|
||||
styles.infoValue,
|
||||
isStatus && { color: value === 'ACTIVE' ? '#059669' : '#D97706' } // Green for Active, Amber for others
|
||||
]}
|
||||
>
|
||||
{value}
|
||||
</Text>
|
||||
</View>
|
||||
// --- Helper Components ---
|
||||
const InfoRow: React.FC<{ label: string; value: string | number | null; isStatus?: boolean }> = ({ label, value, isStatus = false }) => (
|
||||
<View style={styles.infoRow}>
|
||||
<Text style={styles.infoLabel}>{label}</Text>
|
||||
<Text style={[styles.infoValue, isStatus && { color: value === 'ACTIVE' ? '#22c55e' : '#f97316' }]}>
|
||||
{value ?? 'N/A'}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
const ParticipantRow: React.FC<{ participant: Participant }> = ({ participant }) => (
|
||||
<View style={styles.participantRow}>
|
||||
<View>
|
||||
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
||||
<Text style={styles.participantName}>{`${participant.firstName} ${participant.lastName || ''}`.trim()}</Text>
|
||||
{participant.role === 'ORGANIZER' && (
|
||||
<View style={styles.organizerBadge}>
|
||||
<Text style={styles.organizerBadgeText}>Organizer</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
<Text style={styles.participantMobile}>{participant.mobile}</Text>
|
||||
<View style={styles.participantRow}>
|
||||
<View>
|
||||
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
||||
<Text style={styles.participantName}>{`${participant.firstName} ${participant.lastName || ''}`.trim()}</Text>
|
||||
{participant.role === 'ORGANIZER' && (
|
||||
<View style={styles.organizerBadge}><Text style={styles.organizerBadgeText}>Organizer</Text></View>
|
||||
)}
|
||||
</View>
|
||||
<Text style={styles.participantMobile}>{participant.mobile}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
const FormInput: React.FC<{ label: string; value: string; onChangeText: (text: string) => void; multiline?: boolean; keyboardType?: 'default' | 'numeric' }> =
|
||||
({ label, value, onChangeText, multiline = false, keyboardType = 'default' }) => (
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.inputLabel}>{label}</Text>
|
||||
<TextInput
|
||||
style={[styles.input, multiline && styles.textArea]}
|
||||
value={value}
|
||||
onChangeText={onChangeText}
|
||||
multiline={multiline}
|
||||
keyboardType={keyboardType}
|
||||
placeholderTextColor="#9CA3AF"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
// --- Main Screen Component ---
|
||||
const EditGroupScreen: React.FC<EditGroupScreenProps> = ({ route, navigation }) => {
|
||||
const { groupId } = route.params;
|
||||
const EditGroupScreen: React.FC<EditGroupScreenProps> = ({ route }) => {
|
||||
const { groupId } = route.params;
|
||||
|
||||
// --- State Management ---
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const [groupDetails, setGroupDetails] = useState<GroupDetails | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [editingSection, setEditingSection] = useState<EditingSection>(null);
|
||||
const [groupDetails, setGroupDetails] = useState<GroupDetails | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
// --- Form State ---
|
||||
const [groupName, setGroupName] = useState('');
|
||||
const [description, setDescription] = useState('');
|
||||
const [contributionAmount, setContributionAmount] = useState('');
|
||||
const [maxParticipants, setMaxParticipants] = useState('');
|
||||
const [latePaymentCharge, setLatePaymentCharge] = useState('');
|
||||
const [groupName, setGroupName] = useState('');
|
||||
const [description, setDescription] = useState('');
|
||||
const [maxParticipants, setMaxParticipants] = useState('');
|
||||
|
||||
// --- Data Fetching ---
|
||||
const fetchGroupDetails = async () => {
|
||||
if (!groupId) {
|
||||
setError("Group ID not provided.");
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
try {
|
||||
console.log(`Fetching details for group ID: ${groupId}`);
|
||||
const response = await apiCall(
|
||||
`https://api.godemo.in/FundCollect/api/fund/group/details?groupId=${groupId}`,
|
||||
'GET',
|
||||
) as { status: string; data?: GroupDetails; message?: string };
|
||||
|
||||
if (response.status === 'success' && response.data) {
|
||||
setGroupDetails(response.data);
|
||||
// Populate form state immediately
|
||||
const data = response.data;
|
||||
setGroupName(data.groupName);
|
||||
setDescription(data.description);
|
||||
setContributionAmount(data.contributionAmount.toString());
|
||||
setMaxParticipants(data.maxParticipants.toString());
|
||||
setLatePaymentCharge((data.latePaymentCharge || 0).toString());
|
||||
} else {
|
||||
throw new Error(response.message || 'Failed to fetch group data.');
|
||||
}
|
||||
} catch (e: any) {
|
||||
setError(e.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
const fetchGroupDetails = useCallback(async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const response = await apiCall(`https://api.godemo.in/FundCollect/api/fund/group/details?groupId=${groupId}`, 'GET') as { status: string; data?: GroupDetails; message?: string };
|
||||
if (response.status === 'success' && response.data) {
|
||||
setGroupDetails(response.data);
|
||||
setGroupName(response.data.groupName);
|
||||
setDescription(response.data.description);
|
||||
setMaxParticipants(response.data.maxParticipants.toString());
|
||||
} else {
|
||||
throw new Error(response.message || 'Failed to fetch group data.');
|
||||
}
|
||||
} catch (e: any) {
|
||||
setError(e.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [groupId]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchGroupDetails();
|
||||
}, [groupId]);
|
||||
useEffect(() => {
|
||||
fetchGroupDetails();
|
||||
}, [fetchGroupDetails]);
|
||||
|
||||
// --- Action Handlers ---
|
||||
const handleCancelEdit = () => {
|
||||
// Re-populate state from original details to discard any changes
|
||||
if (groupDetails) {
|
||||
setGroupName(groupDetails.groupName);
|
||||
setDescription(groupDetails.description);
|
||||
setContributionAmount(groupDetails.contributionAmount.toString());
|
||||
setMaxParticipants(groupDetails.maxParticipants.toString());
|
||||
setLatePaymentCharge((groupDetails.latePaymentCharge || 0).toString());
|
||||
}
|
||||
setIsEditing(false);
|
||||
};
|
||||
|
||||
const handleSaveChanges = async () => {
|
||||
if (!groupDetails) return;
|
||||
setSaving(true);
|
||||
const payload: EditGroupPayload = {
|
||||
groupName,
|
||||
description,
|
||||
visibility: groupDetails.visibility, // Assuming these are not editable
|
||||
cycleType: groupDetails.cycleType,
|
||||
contributionAmount: parseFloat(contributionAmount) || 0,
|
||||
maxParticipants: parseInt(maxParticipants, 10) || 0,
|
||||
latePaymentCharge: parseFloat(latePaymentCharge) || 0,
|
||||
customCycleDays: groupDetails.customCycleDays,
|
||||
startDate: new Date(groupDetails.startDate.join('-')).toISOString().split('T')[0],
|
||||
endDate: groupDetails.endDate ? new Date(groupDetails.endDate.join('-')).toISOString().split('T')[0] : null,
|
||||
const handleCancel = () => {
|
||||
if (groupDetails) {
|
||||
setGroupName(groupDetails.groupName);
|
||||
setDescription(groupDetails.description);
|
||||
setMaxParticipants(groupDetails.maxParticipants.toString());
|
||||
}
|
||||
setEditingSection(null);
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await apiCall(
|
||||
`https://api.godemo.in/FundCollect/api/fund/groups/${groupDetails.id}/edit`, 'PUT', payload
|
||||
) as { status: string; message?: string };
|
||||
const handleSave = async (section: EditingSection) => {
|
||||
if (!groupDetails || !section) return;
|
||||
|
||||
if (response.status === 'success') {
|
||||
Alert.alert('Success', 'Group details have been updated.');
|
||||
setIsEditing(false);
|
||||
await fetchGroupDetails(); // Refresh data to show updated view
|
||||
} else {
|
||||
throw new Error(response.message || 'Failed to save changes.');
|
||||
}
|
||||
} catch (e: any) {
|
||||
Alert.alert('Save Error', e.message);
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
};
|
||||
let payload: EditGroupPayload = {};
|
||||
if (section === 'details') {
|
||||
payload = { groupName, description };
|
||||
} else if (section === 'financials') {
|
||||
const newMaxParticipants = parseInt(maxParticipants, 10);
|
||||
if (newMaxParticipants < groupDetails.totalParticipants) {
|
||||
Alert.alert('Invalid Input', `Max participants cannot be less than the current count (${groupDetails.totalParticipants}).`);
|
||||
return;
|
||||
}
|
||||
payload = { maxParticipants: newMaxParticipants };
|
||||
}
|
||||
|
||||
// --- Render Logic ---
|
||||
if (loading) return <View style={styles.centered}><ActivityIndicator size="large" color="#4F46E5" /></View>;
|
||||
if (error) return <View style={styles.centered}><Text style={styles.errorText}>{error}</Text></View>;
|
||||
if (!groupDetails) return null;
|
||||
|
||||
return (
|
||||
<AppView paddingHorizontal={0}>
|
||||
<ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}>
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.headerTitle}>Group Overview</Text>
|
||||
{!isEditing && groupDetails.status !== 'ACTIVE' ? (
|
||||
<TouchableOpacity style={styles.editButton} onPress={() => setIsEditing(true)}>
|
||||
<Text style={styles.editButtonText}>Edit</Text>
|
||||
</TouchableOpacity>
|
||||
) : isEditing ? (
|
||||
<TouchableOpacity onPress={handleCancelEdit}>
|
||||
<Text style={styles.cancelButtonText}>Cancel</Text>
|
||||
</TouchableOpacity>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
{/* --- Main Details Card --- */}
|
||||
<View style={styles.card}>
|
||||
{isEditing ? (
|
||||
<>
|
||||
<Text style={styles.inputLabel}>Group Name</Text>
|
||||
<TextInput style={styles.input} value={groupName} onChangeText={setGroupName} />
|
||||
<Text style={styles.inputLabel}>Description</Text>
|
||||
<TextInput style={[styles.input, styles.textArea]} value={description} onChangeText={setDescription} multiline />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Text style={styles.groupNameView}>{groupDetails.groupName}</Text>
|
||||
<Text style={styles.descriptionView}>{groupDetails.description}</Text>
|
||||
</>
|
||||
)}
|
||||
<View style={styles.divider} />
|
||||
<View style={styles.row}>
|
||||
<View style={styles.column}>
|
||||
<Text style={styles.inputLabel}>Contribution</Text>
|
||||
<Text style={styles.dataText}>{`₹${groupDetails.contributionAmount.toLocaleString('en-IN')}`}</Text>
|
||||
</View>
|
||||
<View style={styles.column}>
|
||||
<Text style={styles.inputLabel}>Cycle</Text>
|
||||
<Text style={styles.dataText}>{groupDetails.cycleType}</Text>
|
||||
</View>
|
||||
setSaving(true);
|
||||
try {
|
||||
await apiCall(`https://api.godemo.in/FundCollect/api/fund/groups/${groupDetails.id}/edit`, 'PUT', payload);
|
||||
Alert.alert('Success', 'Group has been updated.');
|
||||
setEditingSection(null);
|
||||
await fetchGroupDetails();
|
||||
} catch (e: any) {
|
||||
Alert.alert('Save Error', e.message || 'An unexpected error occurred.');
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
const CardActionButtons: React.FC<{ section: EditingSection }> = ({ section }) => (
|
||||
<View style={styles.cardActions}>
|
||||
<TouchableOpacity style={[styles.button, styles.cancelButton]} onPress={handleCancel} disabled={saving}>
|
||||
<Text style={[styles.buttonText, { color: '#374151' }]}>Cancel</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={[styles.button, styles.saveButton]} onPress={() => handleSave(section)} disabled={saving}>
|
||||
{saving ? <ActivityIndicator color="#FFFFFF" size="small" /> : <Text style={styles.buttonText}>Save</Text>}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* --- Participants Card --- */}
|
||||
<View style={styles.card}>
|
||||
<Text style={styles.cardTitle}>Participants ({groupDetails.totalParticipants}/{groupDetails.maxParticipants})</Text>
|
||||
{groupDetails.participants.map(p => <ParticipantRow key={`${p.id}-${p.mobile}`} participant={p} />)}
|
||||
</View>
|
||||
);
|
||||
|
||||
{/* --- Other Details Card (Always Read-Only) --- */}
|
||||
<View style={styles.card}>
|
||||
<InfoRow label="Group Status" value={groupDetails.status} isStatus />
|
||||
<InfoRow label="Visibility" value={groupDetails.visibility} />
|
||||
<InfoRow label="Start Date" value={new Date(groupDetails.startDate.join('-')).toLocaleDateString()} />
|
||||
</View>
|
||||
|
||||
{isEditing && (
|
||||
<TouchableOpacity style={styles.saveButton} onPress={handleSaveChanges} disabled={saving}>
|
||||
{saving ? <ActivityIndicator color="#FFFFFF" /> : <Text style={styles.saveButtonText}>Save Changes</Text>}
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</ScrollView>
|
||||
</AppView>
|
||||
);
|
||||
if (loading) return <View style={styles.centered}><ActivityIndicator size="large" color="#4F46E5" /></View>;
|
||||
if (error) return <View style={styles.centered}><Text style={styles.errorText}>{error}</Text></View>;
|
||||
if (!groupDetails) return null;
|
||||
|
||||
const isEditable = groupDetails.status === 'PENDING';
|
||||
|
||||
return (
|
||||
<AppView paddingHorizontal={0}>
|
||||
<ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}>
|
||||
<Text style={styles.headerTitle}>Group Overview</Text>
|
||||
|
||||
<View style={styles.card}>
|
||||
<View style={styles.cardHeader}>
|
||||
<Text style={styles.cardTitle}>Group Details</Text>
|
||||
{isEditable && editingSection !== 'details' && (
|
||||
<TouchableOpacity onPress={() => setEditingSection('details')}><Text style={styles.editButtonText}>Edit</Text></TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
{editingSection === 'details' ? (
|
||||
<>
|
||||
<FormInput label="Group Name" value={groupName} onChangeText={setGroupName} />
|
||||
<FormInput label="Description" value={description} onChangeText={setDescription} multiline />
|
||||
<CardActionButtons section="details" />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Text style={styles.groupNameView}>{groupDetails.groupName}</Text>
|
||||
<Text style={styles.descriptionView}>{groupDetails.description}</Text>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View style={styles.card}>
|
||||
<View style={styles.cardHeader}>
|
||||
<Text style={styles.cardTitle}>Financial Rules</Text>
|
||||
{isEditable && editingSection !== 'financials' && (
|
||||
<TouchableOpacity onPress={() => setEditingSection('financials')}><Text style={styles.editButtonText}>Edit</Text></TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
<InfoRow label="Contribution" value={`₹${groupDetails.contributionAmount.toLocaleString('en-IN')}`} />
|
||||
{editingSection === 'financials' ? (
|
||||
<>
|
||||
<FormInput label="Max Participants" value={maxParticipants} onChangeText={setMaxParticipants} keyboardType="numeric" />
|
||||
<CardActionButtons section="financials" />
|
||||
</>
|
||||
) : (
|
||||
<InfoRow label="Participants" value={`${groupDetails.totalParticipants} / ${groupDetails.maxParticipants}`} />
|
||||
)}
|
||||
<InfoRow label="Payment Cycle" value={groupDetails.cycleType} />
|
||||
<InfoRow label="Group Status" value={groupDetails.status} isStatus />
|
||||
</View>
|
||||
|
||||
<View style={styles.card}>
|
||||
<Text style={styles.cardTitle}>Participants ({groupDetails.totalParticipants})</Text>
|
||||
{groupDetails.participants.length > 0 ? (
|
||||
groupDetails.participants.map(p => <ParticipantRow key={p.id} participant={p} />)
|
||||
) : (
|
||||
<Text style={styles.noParticipantsText}>No participants have joined yet.</Text>
|
||||
)}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</AppView>
|
||||
);
|
||||
};
|
||||
|
||||
// --- Styles ---
|
||||
const styles = StyleSheet.create({
|
||||
container: { flex: 1, backgroundColor: '#F3F4F6' },
|
||||
contentContainer: { paddingVertical: 20, paddingHorizontal: 16 },
|
||||
centered: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F3F4F6' },
|
||||
errorText: { color: '#EF4444', fontSize: 16, textAlign: 'center' },
|
||||
|
||||
header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 },
|
||||
headerTitle: { fontSize: 26, fontWeight: 'bold', color: '#111827' },
|
||||
editButton: { backgroundColor: '#E0E7FF', paddingHorizontal: 16, paddingVertical: 8, borderRadius: 20 },
|
||||
editButtonText: { color: '#4338CA', fontSize: 14, fontWeight: '600' },
|
||||
cancelButtonText: { fontSize: 16, color: '#6B7280', fontWeight: '500' },
|
||||
|
||||
card: { backgroundColor: '#FFFFFF', borderRadius: 16, padding: 20, marginBottom: 16, elevation: 1, shadowColor: '#374151', shadowOpacity: 0.05, shadowRadius: 10, shadowOffset: { width: 0, height: 4 } },
|
||||
cardTitle: { fontSize: 18, fontWeight: '600', color: '#1F2937', marginBottom: 10 },
|
||||
|
||||
groupNameView: { fontSize: 22, fontWeight: '700', color: '#1F2937', marginBottom: 8 },
|
||||
descriptionView: { fontSize: 16, color: '#6B7280', lineHeight: 24 },
|
||||
|
||||
divider: { height: 1, backgroundColor: '#E5E7EB', marginVertical: 20 },
|
||||
|
||||
row: { flexDirection: 'row', gap: 20 },
|
||||
column: { flex: 1 },
|
||||
|
||||
inputLabel: { fontSize: 14, color: '#6B7280', marginBottom: 8, fontWeight: '500' },
|
||||
input: { backgroundColor: '#F9FAFB', borderWidth: 1, borderColor: '#D1D5DB', borderRadius: 10, paddingHorizontal: 14, paddingVertical: 12, fontSize: 16, color: '#111827', marginBottom: 16 },
|
||||
textArea: { height: 80, textAlignVertical: 'top' },
|
||||
dataText: { fontSize: 18, fontWeight: '600', color: '#111827' },
|
||||
|
||||
infoRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingVertical: 12, borderBottomWidth: 1, borderBottomColor: '#F3F4F6' },
|
||||
infoLabel: { fontSize: 16, color: '#6B7280' },
|
||||
infoValue: { fontSize: 16, color: '#1F2937', fontWeight: '600' },
|
||||
|
||||
participantRow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingVertical: 10, borderBottomWidth: 1, borderBottomColor: '#F3F4F6' },
|
||||
participantName: { fontSize: 16, fontWeight: '600', color: '#111827' },
|
||||
participantMobile: { fontSize: 14, color: '#6B7280', marginTop: 4 },
|
||||
organizerBadge: { backgroundColor: '#FEF3C7', paddingHorizontal: 8, paddingVertical: 3, borderRadius: 12, marginLeft: 10 },
|
||||
organizerBadgeText: { color: '#92400E', fontSize: 12, fontWeight: '500' },
|
||||
|
||||
saveButton: { backgroundColor: '#4F46E5', borderRadius: 12, paddingVertical: 16, alignItems: 'center', marginTop: 10, elevation: 2 },
|
||||
saveButtonText: { color: '#FFFFFF', fontSize: 16, fontWeight: '600' },
|
||||
container: { flex: 1, backgroundColor: '#F3F4F6' },
|
||||
contentContainer: { padding: 16, paddingBottom: 40 },
|
||||
centered: { flex: 1, justifyContent: 'center', alignItems: 'center' },
|
||||
errorText: { color: '#EF4444', fontSize: 16, textAlign: 'center' },
|
||||
headerTitle: { fontSize: 28, fontWeight: 'bold', color: '#111827', marginBottom: 20 },
|
||||
|
||||
card: { backgroundColor: '#FFFFFF', borderRadius: 16, padding: 20, marginBottom: 16, shadowColor: '#374151', shadowOpacity: 0.05, shadowRadius: 10 },
|
||||
cardHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: '#E5E7EB', paddingBottom: 10, marginBottom: 16 },
|
||||
cardTitle: { fontSize: 18, fontWeight: 'bold', color: '#1F2937' },
|
||||
editButtonText: { color: '#4F46E5', fontSize: 15, fontWeight: '600' },
|
||||
|
||||
groupNameView: { fontSize: 22, fontWeight: '700', color: '#1F2937', marginBottom: 8 },
|
||||
descriptionView: { fontSize: 16, color: '#6B7280', lineHeight: 24 },
|
||||
|
||||
inputContainer: { marginBottom: 16 },
|
||||
inputLabel: { fontSize: 14, color: '#6B7280', marginBottom: 8, fontWeight: '500' },
|
||||
input: { backgroundColor: '#F9FAFB', borderWidth: 1, borderColor: '#D1D5DB', borderRadius: 10, padding: 14, fontSize: 16 },
|
||||
textArea: { height: 100, textAlignVertical: 'top' },
|
||||
|
||||
infoRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingVertical: 14, borderBottomWidth: 1, borderBottomColor: '#F3F4F6' },
|
||||
infoLabel: { fontSize: 16, color: '#6B7280' },
|
||||
infoValue: { fontSize: 16, fontWeight: '600', textTransform: 'capitalize' },
|
||||
|
||||
participantRow: { paddingVertical: 12, borderBottomWidth: 1, borderBottomColor: '#F3F4F6' },
|
||||
participantName: { fontSize: 16, fontWeight: '600', color: '#111827' },
|
||||
participantMobile: { fontSize: 14, color: '#6B7280', marginTop: 4 },
|
||||
organizerBadge: { backgroundColor: '#FEF3C7', paddingHorizontal: 8, paddingVertical: 3, borderRadius: 12, marginLeft: 10 },
|
||||
organizerBadgeText: { color: '#92400E', fontSize: 12, fontWeight: '500' },
|
||||
noParticipantsText: { fontSize: 15, color: '#6B7280', textAlign: 'center', paddingVertical: 20 },
|
||||
|
||||
cardActions: { flexDirection: 'row', justifyContent: 'flex-end', marginTop: 20, borderTopWidth: 1, borderTopColor: '#E5E7EB', paddingTop: 16 },
|
||||
button: { borderRadius: 10, paddingVertical: 10, paddingHorizontal: 20, marginLeft: 10, minWidth: 80, alignItems: 'center' },
|
||||
saveButton: { backgroundColor: '#4F46E5' },
|
||||
cancelButton: { backgroundColor: '#E5E7EB' },
|
||||
buttonText: { color: '#FFFFFF', fontSize: 15, fontWeight: '600' },
|
||||
});
|
||||
|
||||
export default EditGroupScreen;
|
||||
|
||||
Reference in New Issue
Block a user