217 lines
6.8 KiB
TypeScript
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,
|
|
},
|
|
});
|