import { useTheme } from '@/components/ThemeContext'; import * as ImagePicker from 'expo-image-picker'; import { Camera, Play, X } from 'lucide-react-native'; import React, { forwardRef, 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; removeMedia: (index: number) => void; }; type Errors = { title?: string; description?: string; media?: string; }; const MAX_MEDIA = 10; const StepOneServices = forwardRef(({ formData, updateForm, removeMedia }: StepProps, ref) => { const { isDark } = useTheme(); const { t } = useTranslation(); const [errors, setErrors] = useState({}); const validate = () => { const e: Errors = {}; if (!formData.title || formData.title.trim().length < 5) e.title = t("Sarlavha kamida 5 ta belgidan iborat bo'lishi kerak"); if (!formData.description || formData.description.trim().length < 10) e.description = t("Tavsif kamida 10 ta belgidan iborat bo'lishi kerak"); if (!formData.media || formData.media.length === 0) e.media = t('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]); } }; return ( {/* Sarlavha */} {t('Sarlavha')} updateForm('title', t)} /> {errors.title && {errors.title}} {/* Tavsif */} {t('Tavsif')} updateForm('description', t)} /> {errors.description && {errors.description}} {/* Media */} {t('Media')} ({formData.media.length}/{MAX_MEDIA}) {t('Yuklash')} {formData.media.map((m: MediaType, i: number) => ( {m.type === 'video' && ( )} removeMedia(i)}> ))} {errors.media && {errors.media}} ); }); export default StepOneServices; const styles = StyleSheet.create({ stepContainer: { gap: 10 }, label: { fontWeight: '700', fontSize: 15 }, error: { color: '#ef4444', fontSize: 13, marginLeft: 6 }, inputBox: { flexDirection: 'row', alignItems: 'center', borderRadius: 16, borderWidth: 1, paddingHorizontal: 16, height: 56, }, textArea: { height: 120, alignItems: 'flex-start', paddingTop: 16 }, 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: { color: '#2563eb', fontSize: 11, marginTop: 4, fontWeight: '600' }, 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, backgroundColor: '#ef4444', padding: 4, borderRadius: 10, }, prefixContainer: { flexDirection: 'row', alignItems: 'center', marginRight: 12, }, prefix: { fontSize: 16, fontWeight: '600', letterSpacing: 0.3, }, prefixFocused: { color: '#fff', }, divider: { width: 1.5, height: 24, marginLeft: 12, }, });