254 lines
7.6 KiB
TypeScript

import React, { useEffect, useMemo, useState } from 'react';
import {
View,
Text,
TouchableOpacity,
ScrollView,
KeyboardAvoidingView,
Platform,
Alert,
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import { getStyles } from './addLead.styles';
import { useTheme } from '@theme';
import { FormInput, FormPicker } from '@components';
import { RootState, useAppDispatch, useAppSelector } from '@store';
import { addLead, resetAddLeadState } from './thunk';
export const AddLeadScreen = () => {
const { theme: colors } = useTheme();
const styles = getStyles(colors);
const dispatch = useAppDispatch();
const userData = useAppSelector((state: RootState) => state.auth.user_data);
const { loading, successMessage, error } = useAppSelector(
(state: RootState) => state.addLead,
);
const { items: sourceItems } = useAppSelector(
(state: RootState) => state.sourceList,
);
const { items: statusItems } = useAppSelector(
(state: RootState) => state.statusList,
);
const { items: countryItems } = useAppSelector(
(state: RootState) => state.countryList,
);
const [company, setCompany] = useState('');
const [fullName, setFullName] = useState('');
const [email, setEmail] = useState('');
const [phone, setPhone] = useState('');
const [website, setWebsite] = useState('');
const [source, setSource] = useState('');
const [status, setStatus] = useState('');
const [address, setAddress] = useState('');
const [city, setCity] = useState('');
const [state, setState] = useState('');
const [zip, setZip] = useState('');
const [country, setCountry] = useState('');
const sourceOptions = useMemo(
() => sourceItems.map(s => ({ label: s.name, value: s.id })),
[sourceItems],
);
const statusOptions = useMemo(
() => statusItems.map(s => ({ label: s.name, value: s.id })),
[statusItems],
);
const countryOptions = useMemo(
() => countryItems.map(c => ({ label: c.short_name, value: c.country_id })),
[countryItems],
);
useEffect(() => {
if (successMessage) {
Alert.alert('Success', successMessage);
setCompany('');
setFullName('');
setEmail('');
setPhone('');
setWebsite('');
setSource('');
setStatus('');
setAddress('');
setCity('');
setState('');
setZip('');
setCountry('');
dispatch(resetAddLeadState());
} else if (error) {
Alert.alert('Error', error);
dispatch(resetAddLeadState());
}
}, [successMessage, error, dispatch]);
const handleSubmit = () => {
if (!fullName.trim() || !email.trim() || !source || !status) {
Alert.alert('Error', 'Full Name, Email, Source and Status are required.');
return;
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email.trim())) {
Alert.alert('Error', 'Please enter a valid email address.');
return;
}
const staffId = userData?.staffid || '';
if (!staffId) {
Alert.alert('Error', 'User session invalid. Please log in again.');
return;
}
dispatch(
addLead({
staff_id: staffId,
name: fullName,
company,
email,
phonenumber: phone,
website,
source,
status,
address,
city,
state,
zip,
country,
}),
);
};
return (
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={styles.container}>
<ScrollView
contentContainerStyle={styles.scrollContainer}
keyboardShouldPersistTaps="handled">
{/* Basic Info */}
<View style={styles.formCard}>
<Text style={styles.sectionHeader}>Basic Information</Text>
<FormInput
label="Company"
placeholder="Acme Corp"
value={company}
onChangeText={setCompany}
leftIcon={<Icon name="business-outline" size={18} color={colors.textSecondary} />}
/>
<FormInput
label="Full Name"
required
placeholder="John Doe"
value={fullName}
onChangeText={setFullName}
leftIcon={<Icon name="person-outline" size={18} color={colors.textSecondary} />}
/>
<FormInput
label="Email"
required
placeholder="john@acme.com"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
autoCapitalize="none"
leftIcon={<Icon name="mail-outline" size={18} color={colors.textSecondary} />}
/>
<FormInput
label="Phone Number"
placeholder="+1 (555) 000-0000"
value={phone}
onChangeText={setPhone}
keyboardType="phone-pad"
leftIcon={<Icon name="call-outline" size={18} color={colors.textSecondary} />}
/>
<FormInput
label="Website"
placeholder="https://acme.com"
value={website}
onChangeText={setWebsite}
keyboardType="url"
autoCapitalize="none"
leftIcon={<Icon name="globe-outline" size={18} color={colors.textSecondary} />}
/>
</View>
{/* Classification */}
<View style={[styles.formCard, styles.cardSpacing]}>
<Text style={styles.sectionHeader}>Classification</Text>
<FormPicker
label="Source"
required
value={source}
onValueChange={setSource}
options={sourceOptions}
placeholder="Select source..."
/>
<FormPicker
label="Status"
required
value={status}
onValueChange={setStatus}
options={statusOptions}
placeholder="Select status..."
/>
</View>
{/* Address */}
<View style={[styles.formCard, styles.cardSpacing]}>
<Text style={styles.sectionHeader}>Address</Text>
<FormInput
label="Address"
placeholder="123 Main Street"
value={address}
onChangeText={setAddress}
leftIcon={<Icon name="location-outline" size={18} color={colors.textSecondary} />}
/>
<View style={styles.row}>
<View style={styles.rowHalf}>
<FormInput label="City" placeholder="New York" value={city} onChangeText={setCity} />
</View>
<View style={styles.rowHalf}>
<FormInput label="State" placeholder="NY" value={state} onChangeText={setState} />
</View>
</View>
<FormInput
label="ZIP / Postal Code"
placeholder="10001"
value={zip}
onChangeText={setZip}
keyboardType="number-pad"
leftIcon={<Icon name="map-outline" size={18} color={colors.textSecondary} />}
/>
<FormPicker
label="Country"
value={country}
onValueChange={setCountry}
options={countryOptions}
placeholder="Select country..."
searchable
/>
</View>
{/* Submit */}
<TouchableOpacity
style={[styles.submitButton, loading && { opacity: 0.7 }]}
activeOpacity={0.8}
disabled={loading}
onPress={handleSubmit}>
<Icon name="checkmark-circle-outline" size={20} color="#FFFFFF" style={styles.buttonIcon} />
<Text style={styles.submitButtonText}>{loading ? 'Creating Lead...' : 'Create Lead'}</Text>
</TouchableOpacity>
</ScrollView>
</KeyboardAvoidingView>
);
};