Files
CBS-Mobile-App/src/modules/agent/screens/AddEditCustomerScreen.tsx
T

217 lines
6.8 KiB
TypeScript

import React, { useEffect } from 'react';
import { View, StyleSheet, Text } from 'react-native';
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import Ionicons from '@react-native-vector-icons/ionicons';
import Animated, { FadeInUp } from 'react-native-reanimated';
import { ScreenShell, Input, Button, KeyboardAwareScrollView } from '../../../components';
import { useTheme } from '../../../theme';
import { TAB_BAR_HEIGHT } from '../../../utils/layoutConstants';
import { useAppSelector } from '../../../app/hooks';
import { selectCustomerById } from '../store/agentSelectors';
import type { AgentCustomersStackParamList } from '../navigation/agentNavigationTypes';
import { useCustomerForm } from '../hooks/useCustomerForm';
type Props = NativeStackScreenProps<AgentCustomersStackParamList, 'AddEditCustomer'>;
const FormSection = ({ title, icon, children }: { title: string, icon: string, children: React.ReactNode }) => {
const theme = useTheme();
return (
<Animated.View entering={FadeInUp} style={[styles.section, { backgroundColor: theme.colors.surface, borderColor: theme.colors.cardBorder }]}>
<View style={styles.sectionHeader}>
<View style={[styles.sectionIcon, { backgroundColor: `${theme.colors.primary}15` }]}>
<Ionicons name={icon as any} size={18} color={theme.colors.primary} />
</View>
<Text style={[styles.sectionTitle, { color: theme.colors.textPrimary }]}>{title}</Text>
</View>
<View style={styles.sectionContent}>
{children}
</View>
</Animated.View>
);
};
export default function AddEditCustomerScreen({ route, navigation }: Props) {
const { customerId } = route.params;
const theme = useTheme();
const existingCustomer = useAppSelector(state =>
customerId ? selectCustomerById(customerId)(state) : null
);
const { data, errors, updateField, submit, isSubmitting } = useCustomerForm(existingCustomer || undefined);
const isEdit = !!existingCustomer;
const handleSubmit = async () => {
const res = await submit();
if (res) {
navigation.goBack();
}
};
return (
<ScreenShell title={isEdit ? 'Edit Customer' : 'Add New Customer'} scrollable={false} keyboardAware={false} withTabBar={false}>
<View style={styles.flexContainer}>
<KeyboardAwareScrollView contentContainerStyle={styles.scrollContent} style={styles.flex}>
<FormSection title="Personal Information" icon="person-outline">
<Input
label="Full Name"
placeholder="e.g. Amit Sharma"
value={data.name}
onChangeText={(v) => updateField('name', v)}
error={errors.name}
/>
<Input
label="Phone Number"
placeholder="10-digit number"
value={data.phone}
onChangeText={(v) => updateField('phone', v)}
keyboardType="number-pad"
maxLength={10}
error={errors.phone}
leftAccessory={<Text style={{ color: theme.colors.textPrimary, fontWeight: 'bold' }}>+91</Text>}
/>
<Input
label="Email Address (Optional)"
placeholder="e.g. amit@example.com"
value={data.email}
onChangeText={(v) => updateField('email', v)}
keyboardType="email-address"
autoCapitalize="none"
error={errors.email}
/>
</FormSection>
<FormSection title="KYC Details" icon="finger-print-outline">
<Input
label="Aadhaar Number"
placeholder="12-digit number"
value={data.aadhaarNumber}
onChangeText={(v) => updateField('aadhaarNumber', v)}
keyboardType="number-pad"
maxLength={12}
error={errors.aadhaarNumber}
/>
<Input
label="PAN Number"
placeholder="e.g. ABCDE1234F"
value={data.panNumber}
onChangeText={(v) => updateField('panNumber', v)}
autoCapitalize="characters"
maxLength={10}
error={errors.panNumber}
/>
</FormSection>
<FormSection title="Address" icon="location-outline">
<Input
label="Street Address"
placeholder="House/Flat No, Area"
value={data.address}
onChangeText={(v) => updateField('address', v)}
error={errors.address}
/>
<View style={styles.row}>
<View style={styles.col}>
<Input
label="City"
placeholder="e.g. Kolkata"
value={data.city}
onChangeText={(v) => updateField('city', v)}
error={errors.city}
/>
</View>
<View style={{ width: 12 }} />
<View style={styles.col}>
<Input
label="State"
placeholder="e.g. West Bengal"
value={data.state}
onChangeText={(v) => updateField('state', v)}
error={errors.state}
/>
</View>
</View>
<Input
label="Pincode"
placeholder="6-digit pincode"
value={data.pincode}
onChangeText={(v) => updateField('pincode', v)}
keyboardType="number-pad"
maxLength={6}
error={errors.pincode}
/>
</FormSection>
</KeyboardAwareScrollView>
<View style={[styles.footer, { backgroundColor: theme.colors.background, borderTopColor: theme.colors.cardBorder }]}>
<Button
title={isEdit ? 'Save Changes' : 'Add Customer'}
onPress={handleSubmit}
loading={isSubmitting}
/>
</View>
</View>
</ScreenShell>
);
}
const styles = StyleSheet.create({
flex: {
flex: 1,
},
flexContainer: {
flex: 1,
},
scrollContent: {
padding: 16,
paddingBottom: 24,
},
section: {
borderRadius: 16,
borderWidth: 1,
marginBottom: 24,
overflow: 'hidden',
},
sectionHeader: {
flexDirection: 'row',
alignItems: 'center',
padding: 16,
borderBottomWidth: 1,
borderBottomColor: 'rgba(0,0,0,0.05)',
},
sectionIcon: {
width: 32,
height: 32,
borderRadius: 8,
alignItems: 'center',
justifyContent: 'center',
marginRight: 12,
},
sectionTitle: {
fontSize: 15,
fontWeight: '700',
},
sectionContent: {
padding: 16,
paddingBottom: 16,
gap: 16,
},
row: {
flexDirection: 'row',
},
col: {
flex: 1,
},
footer: {
padding: 16,
paddingBottom: TAB_BAR_HEIGHT + 10,
borderTopWidth: 1,
},
});