diff --git a/src/components/EditProfileModal.js b/src/components/EditProfileModal.js new file mode 100644 index 0000000..6a9fdaf --- /dev/null +++ b/src/components/EditProfileModal.js @@ -0,0 +1,470 @@ +import React, { useState, useRef } from 'react'; +import { + View, + Text, + Modal, + StyleSheet, + SafeAreaView, + TouchableOpacity, + Alert, + ActivityIndicator, + ScrollView, + TouchableWithoutFeedback, + Keyboard, +} from 'react-native'; +import { Ionicons } from '@expo/vector-icons'; +import Input from './Input'; +import Button from './Button'; +import { COLORS } from '../constants/colors'; + +const PASSPORT_SERIES = [ + 'I-AS', 'I-MR', 'II-MR', 'I-AH', 'II-AH', + 'I-LB', 'II-LB', 'I-BN', 'II-BN', 'I-DZ', 'II-DZ' +]; + +const EditProfileModal = ({ + visible, + onClose, + onSave, + initialData = {}, + isLoading = false +}) => { + const [formData, setFormData] = useState({ + name: initialData.name || '', + phone: initialData.phone ? initialData.phone.toString() : '', + password: '', + passport_serie: initialData.passport_serie || '', + passport_id: initialData.passport_id ? initialData.passport_id.toString() : '', + }); + + const [errors, setErrors] = useState({}); + const [showPassportPicker, setShowPassportPicker] = useState(false); + + const phoneInputRef = useRef(null); + const passwordInputRef = useRef(null); + const passportIdInputRef = useRef(null); + + const validateForm = () => { + const newErrors = {}; + + // Name validation (required, max 255 characters) + if (!formData.name.trim()) { + newErrors.name = 'At gerek'; + } else if (formData.name.length > 255) { + newErrors.name = 'At 255 harpdan köp bolmaly däl'; + } + + // Phone validation (required, should be number) + if (!formData.phone.trim()) { + newErrors.phone = 'Telefon belgisi gerek'; + } else if (!/^\d+$/.test(formData.phone)) { + newErrors.phone = 'Telefon belgisi diňe sanlardan durmalı'; + } else if (formData.phone.length < 8) { + newErrors.phone = 'Telefon belgisi azyndan 8 san bolmaly'; + } + + // Password validation (optional, but if provided should be strong) + if (formData.password && formData.password.length < 6) { + newErrors.password = 'Parol azyndan 6 harp bolmaly'; + } + + // Passport ID validation (optional, but if provided should be number) + if (formData.passport_id && !/^\d+$/.test(formData.passport_id)) { + newErrors.passport_id = 'Passport ID diňe sanlardan durmalı'; + } + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; + + const handleSave = () => { + if (!validateForm()) { + return; + } + + // Prepare data for API call + const updateData = { + name: formData.name.trim(), + phone: parseInt(formData.phone), + }; + + // Only include optional fields if they're provided + if (formData.password) { + updateData.password = formData.password; + } + + if (formData.passport_serie) { + updateData.passport_serie = formData.passport_serie; + } + + if (formData.passport_id) { + updateData.passport_id = parseInt(formData.passport_id); + } + + onSave(updateData); + }; + + const handleClose = () => { + // Reset form data and errors + setFormData({ + name: initialData.name || '', + phone: initialData.phone ? initialData.phone.toString() : '', + password: '', + passport_serie: initialData.passport_serie || '', + passport_id: initialData.passport_id ? initialData.passport_id.toString() : '', + }); + setErrors({}); + onClose(); + }; + + const updateFormData = (field, value) => { + setFormData(prev => ({ + ...prev, + [field]: value + })); + + // Clear error for this field if it exists + if (errors[field]) { + setErrors(prev => ({ + ...prev, + [field]: null + })); + } + }; + + const renderPassportSeriesPicker = () => { + if (!showPassportPicker) return null; + + return ( + setShowPassportPicker(false)} + > + setShowPassportPicker(false)}> + + + + Passport seriýasy + setShowPassportPicker(false)}> + Boldy + + + + { + updateFormData('passport_serie', ''); + setShowPassportPicker(false); + }} + > + + Saýlaň + + + {PASSPORT_SERIES.map((series) => ( + { + updateFormData('passport_serie', series); + setShowPassportPicker(false); + }} + > + + {series} + + + ))} + + + + + + ); + }; + + return ( + + + + + {/* Header */} + + + + + Şahsy maglumatlar + + + + {/* Form */} + + + Esasy maglumatlar + + updateFormData('name', value)} + error={errors.name} + maxLength={255} + returnKeyType="next" + onSubmitEditing={() => phoneInputRef.current?.focus()} + /> + + updateFormData('phone', value)} + error={errors.phone} + keyboardType="numeric" + maxLength={8} + returnKeyType="next" + onSubmitEditing={() => passwordInputRef.current?.focus()} + /> + + updateFormData('password', value)} + error={errors.password} + secureTextEntry + placeholder="Parol üýtgetmezlik üçin boş goýuň" + returnKeyType="next" + onSubmitEditing={() => passportIdInputRef.current?.focus()} + /> + + + + Passport maglumatlary + + + Passport seriýasy + setShowPassportPicker(true)} + > + + {formData.passport_serie || 'Saýlaň'} + + + + {errors.passport_serie && ( + {errors.passport_serie} + )} + + + updateFormData('passport_id', value)} + error={errors.passport_id} + keyboardType="numeric" + returnKeyType="done" + /> + + + + + + * belgisi bolan meýdanlar hökmany doldurulmaly + + + + + {/* Save Button */} + +