From 381bd5fa32fceacbfca8e5426dde446524472cb2 Mon Sep 17 00:00:00 2001 From: Nurmuhammet Allanov Date: Tue, 8 Jul 2025 11:42:33 +0500 Subject: [PATCH] loan order store not bad --- src/components/ImageInput.js | 18 ++-- src/components/SelectInput.js | 6 +- src/screens/Loan/CreateLoanOrderScreen.js | 110 ++++++++++++++-------- 3 files changed, 85 insertions(+), 49 deletions(-) diff --git a/src/components/ImageInput.js b/src/components/ImageInput.js index b4aeddf..fb80586 100644 --- a/src/components/ImageInput.js +++ b/src/components/ImageInput.js @@ -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 ( {label && {label}} - + {image ? ( ) : ( @@ -90,6 +85,9 @@ const styles = StyleSheet.create({ height: '100%', borderRadius: 12, }, + error: { + borderColor: COLORS.error, + }, }); export default ImageInput; \ No newline at end of file diff --git a/src/components/SelectInput.js b/src/components/SelectInput.js index a185bbf..fbf33dd 100644 --- a/src/components/SelectInput.js +++ b/src/components/SelectInput.js @@ -29,6 +29,7 @@ const SelectInput = ({ onValueChange, placeholder = 'Select', disabled = false, + error = false, }) => { const [modalVisible, setModalVisible] = useState(false); @@ -53,7 +54,7 @@ const SelectInput = ({ {label && {label}} @@ -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)', diff --git a/src/screens/Loan/CreateLoanOrderScreen.js b/src/screens/Loan/CreateLoanOrderScreen.js index cbe3712..f413079 100644 --- a/src/screens/Loan/CreateLoanOrderScreen.js +++ b/src/screens/Loan/CreateLoanOrderScreen.js @@ -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() }]);