loan order store not bad

This commit is contained in:
2025-07-08 11:42:33 +05:00
parent 7e6a0846dd
commit 381bd5fa32
3 changed files with 85 additions and 49 deletions

View File

@@ -4,7 +4,7 @@ import * as ImagePicker from 'expo-image-picker';
import { Ionicons } from '@expo/vector-icons';
import { COLORS } from '../constants/colors';
const ImageInput = ({ label, image, onChange }) => {
const ImageInput = ({ label, image, onChange, error = false }) => {
const [hasPermission, setHasPermission] = useState(null);
useEffect(() => {
@@ -22,25 +22,20 @@ const ImageInput = ({ label, image, onChange }) => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaType,
quality: 0.7,
base64: true,
quality: 0.8,
base64: false,
});
if (!result.canceled && result.assets && result.assets.length > 0) {
const asset = result.assets[0];
const fileObj = {
uri: asset.uri,
name: asset.fileName || `photo_${Date.now()}.jpg`,
type: asset.mimeType || 'image/jpeg',
};
onChange && onChange(fileObj);
onChange && onChange(asset.uri);
}
};
return (
<View style={styles.container}>
{label && <Text style={styles.label}>{label}</Text>}
<TouchableOpacity style={styles.box} activeOpacity={0.8} onPress={pickImage}>
<TouchableOpacity style={[styles.box, error && styles.error]} activeOpacity={0.8} onPress={pickImage}>
{image ? (
<Image source={{ uri: image.uri ? image.uri : image }} style={styles.preview} />
) : (
@@ -90,6 +85,9 @@ const styles = StyleSheet.create({
height: '100%',
borderRadius: 12,
},
error: {
borderColor: COLORS.error,
},
});
export default ImageInput;

View File

@@ -29,6 +29,7 @@ const SelectInput = ({
onValueChange,
placeholder = 'Select',
disabled = false,
error = false,
}) => {
const [modalVisible, setModalVisible] = useState(false);
@@ -53,7 +54,7 @@ const SelectInput = ({
<View style={styles.container}>
{label && <Text style={styles.label}>{label}</Text>}
<TouchableOpacity
style={[styles.selectBox, disabled && styles.disabled]}
style={[styles.selectBox, disabled && styles.disabled, error && styles.error]}
onPress={openModal}
activeOpacity={0.7}
>
@@ -128,6 +129,9 @@ const styles = StyleSheet.create({
backgroundColor: COLORS.gray[100],
opacity: 0.6,
},
error: {
borderColor: COLORS.error,
},
modalOverlay: {
flex: 1,
backgroundColor: 'rgba(0,0,0,0.3)',

View File

@@ -12,6 +12,7 @@ import { useAuth } from '../../contexts/AuthContext';
import { useBaseEnums } from '../../contexts/BaseEnumsContext';
import { StatusBar } from 'expo-status-bar';
import ImageInput from '../../components/ImageInput';
import authService from '../../services/authService';
const CreateLoanOrderScreen = () => {
const navigation = useNavigation();
@@ -139,47 +140,80 @@ const CreateLoanOrderScreen = () => {
return;
}
const payload = {
loan_type: parseInt(loanType),
loan_amount: parseInt(loanAmount),
region,
branch_id: parseInt(branchId),
customer_name: customerName,
customer_surname: customerSurname,
customer_patronic_name: customerPatro || null,
education,
marriage_status: marriageStatus,
passport_address: passportAddress,
real_address: realAddress,
passport_serie: passportSerie,
passport_id: passportId.trim(),
passport_given_at: passportGivenAt,
passport_given_by: passportGivenBy,
born_place: bornPlace,
born_at: bornAt,
phone: parseInt(phone),
email: email || null,
phone_additional: phoneAdditional ? parseInt(phoneAdditional) : null,
phone_home: phoneHome || null,
work_company: workCompany || null,
work_company_accountant_number: workCompanyAccNum || null,
work_region: workRegion || null,
work_province_id: workProvinceId ? parseInt(workProvinceId) : null,
work_position: workPosition || null,
work_salary: workSalary ? parseInt(workSalary) : null,
work_started_at: workStartedAt || null,
card_number: rawCardNumber,
card_name: cardName,
card_month: cardMonth,
card_year: cardYear,
passport_one: passportOne,
passport_two: passportTwo,
passport_three: passportThree,
passport_four: passportFour,
const formData = new FormData();
const appendField = (key, value) => {
if (value !== null && value !== undefined && value !== '') {
formData.append(key, String(value));
}
};
appendField('loan_type', parseInt(loanType));
appendField('loan_amount', parseInt(loanAmount));
appendField('region', region);
appendField('branch_id', parseInt(branchId));
appendField('customer_name', customerName);
appendField('customer_surname', customerSurname);
appendField('customer_patronic_name', customerPatro || '');
appendField('education', education);
appendField('marriage_status', marriageStatus);
appendField('passport_address', passportAddress);
appendField('real_address', realAddress);
appendField('passport_serie', passportSerie);
appendField('passport_id', passportId.trim());
appendField('passport_given_at', passportGivenAt);
appendField('passport_given_by', passportGivenBy);
appendField('born_place', bornPlace);
appendField('born_at', bornAt);
appendField('phone', parseInt(phone));
if (email) appendField('email', email);
if (phoneAdditional) appendField('phone_additional', parseInt(phoneAdditional));
if (phoneHome) appendField('phone_home', phoneHome);
if (workCompany) appendField('work_company', workCompany);
if (workCompanyAccNum) appendField('work_company_accountant_number', workCompanyAccNum);
if (workRegion) appendField('work_region', workRegion);
if (workProvinceId) appendField('work_province_id', parseInt(workProvinceId));
if (workPosition) appendField('work_position', workPosition);
if (workSalary) appendField('work_salary', parseInt(workSalary));
if (workStartedAt) appendField('work_started_at', workStartedAt);
appendField('card_number', rawCardNumber);
appendField('card_name', cardName);
appendField('card_month', cardMonth);
appendField('card_year', cardYear);
const addImage = (field, uri) => {
if (!uri) return;
const fileName = uri.split('/').pop();
const fileTypeMatch = fileName.match(/\.([a-zA-Z0-9]+)$/);
const type = fileTypeMatch ? `image/${fileTypeMatch[1]}` : 'image/jpeg';
formData.append(field, { uri, name: fileName || `${field}.jpg`, type });
};
addImage('passport_one', passportOne);
addImage('passport_two', passportTwo);
addImage('passport_three', passportThree);
addImage('passport_four', passportFour);
setLoading(true);
const res = await apiService.createLoanOrder(payload);
let res;
try {
const token = await authService.getStoredToken();
const response = await fetch(`${API_CONFIG.BASE_URL}/loan-order`, {
method: 'POST',
headers: {
...(token ? { Authorization: `Bearer ${token}` } : {}),
Accept: 'application/json',
},
body: formData,
});
const json = await response.json();
console.log('[LoanOrder] API status:', response.status, response.ok);
console.log('[LoanOrder] API response:', json);
res = { success: response.ok, ...(response.ok ? { message: json.message } : { error: json.message }) };
} catch (e) {
console.error('[LoanOrder] API error', e);
res = { success: false, error: e.message };
}
setLoading(false);
if (res.success) {
Alert.alert('Success', res.message || 'Order created', [{ text: 'OK', onPress: () => navigation.goBack() }]);