import { useTheme } from '@/components/ThemeContext'; import { formatPhone, normalizeDigits } from '@/constants/formatPhone'; import * as ImagePicker from 'expo-image-picker'; import { Image as ImageIcon, Play, Video, 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 StepProps = { formData: any; updateForm: (key: string, value: any) => void }; type Errors = { title?: string; description?: string; phone?: string; media?: string; }; type MediaTabType = 'image' | 'video'; const MAX_MEDIA = 1; const StepOne = forwardRef(({ formData, updateForm }: StepProps, ref) => { const [phone, setPhone] = useState(formData.phone || ''); const [focused, setFocused] = useState(false); const [errors, setErrors] = useState({}); const [selectedMediaTab, setSelectedMediaTab] = useState('image'); 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 = '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 mediaType = selectedMediaTab === 'image' ? ImagePicker.MediaTypeOptions.Images : ImagePicker.MediaTypeOptions.Videos; const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: mediaType, allowsMultipleSelection: false, quality: 0.8, videoMaxDuration: 60, // 60 seconds max for video }); if (!result.canceled) { const asset = result.assets[0]; const mediaItem = { uri: asset.uri, type: selectedMediaTab, }; updateForm('media', [mediaItem]); } }; const handlePhone = useCallback( (text: string) => { const n = normalizeDigits(text); setPhone(n); updateForm('phone', n); }, [updateForm] ); const removeMedia = () => { updateForm('media', []); }; 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', tabActive: isDark ? '#2563eb' : '#3b82f6', tabInactive: isDark ? '#334155' : '#e2e8f0', }; 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 Type Tabs */} {t('Media turi')} setSelectedMediaTab('image')} activeOpacity={0.7} > {t('Rasm')} setSelectedMediaTab('video')} activeOpacity={0.7} > {/* Media Upload/Preview */} {formData.media.length === 0 ? ( {selectedMediaTab === 'image' ? ( ) : ( {selectedMediaTab === 'image' ? t('Rasm yuklash') : t('Video yuklash')} {selectedMediaTab === 'image' ? t('Rasm tanlang') : t('Video tanlang')} ) : ( {formData.media[0].type === 'video' && ( )} {formData.media[0].type === 'image' ? ( ) : ( )} {errors.media && ( {t(errors.media)} )} ); }); export default StepOne; const styles = StyleSheet.create({ stepContainer: { gap: 10 }, label: { fontWeight: '700', fontSize: 15 }, error: { fontSize: 13, marginLeft: 6 }, inputBox: { flexDirection: 'row', alignItems: 'center', borderRadius: 16, borderWidth: 1, paddingHorizontal: 16, height: 56, }, textArea: { height: 120, alignItems: 'flex-start', paddingVertical: 0 }, input: { flex: 1, fontSize: 16 }, prefixContainer: { flexDirection: 'row', alignItems: 'center', marginRight: 12, }, prefix: { fontSize: 16, fontWeight: '600', letterSpacing: 0.3, }, prefixFocused: {}, divider: { width: 1.5, height: 24, marginLeft: 12, }, // Media Tabs tabsContainer: { flexDirection: 'row', gap: 12, }, tab: { flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingVertical: 14, paddingHorizontal: 16, borderRadius: 16, borderWidth: 2, gap: 8, }, tabActive: { shadowColor: '#2563eb', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.3, shadowRadius: 4, elevation: 3, }, tabText: { fontSize: 15, fontWeight: '700', letterSpacing: 0.3, }, // Media Container mediaContainer: { marginTop: 4, }, uploadLarge: { height: 240, borderRadius: 20, borderWidth: 2, borderStyle: 'dashed', justifyContent: 'center', alignItems: 'center', gap: 12, }, uploadIconWrapper: { width: 72, height: 72, borderRadius: 36, justifyContent: 'center', alignItems: 'center', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.2, shadowRadius: 4, elevation: 3, }, uploadLargeText: { fontSize: 18, fontWeight: '700', marginTop: 4, }, uploadLargeSubtext: { fontSize: 14, fontWeight: '500', textAlign: 'center', paddingHorizontal: 32, }, previewLarge: { height: 240, borderRadius: 20, overflow: 'hidden', position: 'relative', }, imageLarge: { width: '100%', height: '100%', borderRadius: 20, }, playLarge: { position: 'absolute', top: '50%', left: '50%', transform: [{ translateX: -28 }, { translateY: -28 }], backgroundColor: 'rgba(0,0,0,.6)', padding: 14, borderRadius: 32, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.3, shadowRadius: 4, elevation: 3, }, removeLarge: { position: 'absolute', top: 12, right: 12, padding: 8, borderRadius: 12, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.3, shadowRadius: 4, elevation: 3, }, mediaTypeBadge: { position: 'absolute', bottom: 12, left: 12, flexDirection: 'row', alignItems: 'center', gap: 6, paddingVertical: 6, paddingHorizontal: 12, borderRadius: 10, }, mediaTypeBadgeText: { color: '#ffffff', fontSize: 13, fontWeight: '600', }, });