import { useTheme } from '@/components/ThemeContext'; import { formatPhone, normalizeDigits } from '@/constants/formatPhone'; import * as ImagePicker from 'expo-image-picker'; import { Camera, Play, X } from 'lucide-react-native'; import React, { forwardRef, useCallback, useImperativeHandle, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Image, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native'; type MediaType = { uri: string; type: 'image' | 'video' }; type StepProps = { formData: any; updateForm: (key: string, value: any) => void }; type Errors = { title?: string; description?: string; phone?: string; media?: string; }; const MAX_MEDIA = 10; const StepOne = forwardRef(({ formData, updateForm }: StepProps, ref) => { const [phone, setPhone] = useState(formData.phone || ''); const [focused, setFocused] = useState(false); const [errors, setErrors] = useState({}); const { isDark } = useTheme(); const { t } = useTranslation(); const validate = () => { const e: Errors = {}; if (!formData.title || formData.title.trim().length < 5) e.title = "Sarlavha kamida 5 ta belgidan iborat bo'lishi kerak"; if (!formData.description || formData.description.trim().length < 10) e.description = "Tavsif kamida 10 ta belgidan iborat bo'lishi kerak"; if (!formData.phone || formData.phone.length !== 9) e.phone = "Telefon raqam to'liq kiritilmadi"; if (!formData.media || formData.media.length === 0) e.media = 'Kamida bitta rasm yoki video yuklang'; setErrors(e); return Object.keys(e).length === 0; }; useImperativeHandle(ref, () => ({ validate })); const pickMedia = async () => { if (formData.media.length >= MAX_MEDIA) return; const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.All, allowsMultipleSelection: true, quality: 0.8, }); if (!result.canceled) { const assets = result.assets .slice(0, MAX_MEDIA - formData.media.length) .map((a) => ({ uri: a.uri, type: a.type as 'image' | 'video' })); updateForm('media', [...formData.media, ...assets]); } }; const handlePhone = useCallback( (text: string) => { const n = normalizeDigits(text); setPhone(n); updateForm('phone', n); }, [updateForm] ); const removeMedia = (i: number) => updateForm( 'media', formData.media.filter((_: any, idx: number) => idx !== i) ); const theme = { background: isDark ? '#0f172a' : '#ffffff', inputBg: isDark ? '#1e293b' : '#f1f5f9', inputBorder: isDark ? '#334155' : '#e2e8f0', text: isDark ? '#f8fafc' : '#0f172a', textSecondary: isDark ? '#cbd5e1' : '#475569', placeholder: isDark ? '#94a3b8' : '#94a3b8', error: '#ef4444', primary: '#2563eb', divider: isDark ? '#475569' : '#cbd5e1', }; return ( {/* Sarlavha */} {t('Sarlavha')} updateForm('title', t)} /> {errors.title && ( {t(errors.title)} )} {/* Tavsif */} {t('Tavsif')} updateForm('description', t)} /> {errors.description && ( {t(errors.description)} )} {/* Telefon */} {t('Telefon raqami')} +998 setFocused(true)} onBlur={() => setFocused(false)} keyboardType="phone-pad" placeholder="90 123 45 67" maxLength={12} placeholderTextColor={theme.placeholder} /> {errors.phone && ( {t(errors.phone)} )} {/* Media */} {t('Media')} ({formData.media.length}/{MAX_MEDIA}) {t('Yuklash')} {formData.media.map((m: MediaType, i: number) => ( {m.type === 'video' && ( )} removeMedia(i)} > ))} {errors.media && ( {t(errors.media)} )} ); }); export default StepOne; const styles = StyleSheet.create({ stepContainer: { gap: 10 }, label: { fontWeight: '700' }, error: { fontSize: 13, marginLeft: 6 }, inputBox: { flexDirection: 'row', alignItems: 'center', borderRadius: 16, borderWidth: 1, paddingHorizontal: 16, height: 56, }, textArea: { height: 120, alignItems: 'flex-start' }, input: { flex: 1, fontSize: 16 }, media: { flexDirection: 'row', flexWrap: 'wrap', gap: 10 }, upload: { width: 100, height: 100, borderRadius: 16, borderWidth: 2, borderStyle: 'dashed', justifyContent: 'center', alignItems: 'center', }, uploadText: { fontSize: 11, marginTop: 4 }, preview: { width: 100, height: 100 }, image: { width: '100%', height: '100%', borderRadius: 16 }, play: { position: 'absolute', top: '40%', left: '40%', backgroundColor: 'rgba(0,0,0,.5)', padding: 6, borderRadius: 20, }, remove: { position: 'absolute', top: -6, right: -6, padding: 4, borderRadius: 10, }, prefixContainer: { flexDirection: 'row', alignItems: 'center', marginRight: 12, }, prefix: { fontSize: 16, fontWeight: '600', letterSpacing: 0.3, }, prefixFocused: {}, divider: { width: 1.5, height: 24, marginLeft: 12, }, });