import React, { useEffect, useState } from 'react'; import { View, Text, TouchableOpacity, StyleSheet, Image, ActivityIndicator, ScrollView } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import { Colors } from 'src/theme'; import { Input } from 'src/components'; import { storage, StoreType } from 'src/storage'; import { PostCreateGroup, usePostCreateGroupMutation } from '@api/chat'; import { API_HOST } from 'src/constants'; import { AvatarWithInitials } from 'src/components'; import * as ImagePicker from 'expo-image-picker'; import * as yup from 'yup'; import { FlashList } from '@shopify/flash-list'; import { useSheetRouter } from 'react-native-actions-sheet'; import { getFontSize } from 'src/utils'; import CloseIcon from 'assets/icons/close.svg'; import CameraIcon from 'assets/icons/messages/camera.svg'; import { Formik } from 'formik'; import { useGroupChatStore } from 'src/stores/groupChatStore'; import { NAVIGATION_PAGES } from 'src/types'; const ProfileSchema = yup.object({ name: yup .string() .required('name is required') .min(3, 'group name should be at least 3 characters'), description: yup.string().optional().max(8000, 'description should not exceed 8000 characters'), users: yup.array().min(2, 'select at least 2 members').required('members are required') }); const RouteAddGroup = () => { const router = useSheetRouter('search-modal'); const token = storage.get('token', StoreType.STRING) as string; const navigation = useNavigation(); const { selectedUsers, removeUser, image, setImage, groupName, setGroupName, description, setDescription, clearStore } = useGroupChatStore(); const [isSubmitting, setIsSubmitting] = useState(false); const { mutate: createGroup } = usePostCreateGroupMutation(); const pickImage = async () => { let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, aspect: [4, 3], quality: 1 }); if (!result.canceled) { setImage(result.assets[0]); } }; const renderUserItem = ({ item }: { item: any }) => { return ( removeUser(item.user_id)} style={styles.removeIcon}> {item.avatar ? ( ) : ( )} ); }; return ( { setIsSubmitting(true); const groupData: PostCreateGroup = { token, name: values.name, description: values.description, users: selectedUsers.map((user) => +user.user_id), admins: [] }; if (image && image.uri) { groupData.group_avatar = { type: image.type || 'image', uri: image.uri, name: image.uri.split('/').pop()! }; } await createGroup(groupData, { onSuccess: (res) => { console.log('res', res); setIsSubmitting(false); navigation.navigate( ...([ NAVIGATION_PAGES.CHAT, { id: 8948, name: 'Test Name', avatar: null, userType: 'normal' } ] as never) ); router?.close(); }, onError: (err) => { console.log('err', err); setIsSubmitting(false); } }); }} > {(props) => { useEffect(() => { props.setFieldValue('users', selectedUsers); }, [selectedUsers]); return ( { router?.goBack(); }} style={{ paddingTop: 16, paddingBottom: 6, paddingHorizontal: 6 }} > Back {isSubmitting ? ( ) : ( props.handleSubmit()} > Save )} {!image && ( <> Add photo )} {image && ( <> Change photo )} { props.handleChange('name')(text); setGroupName(text); }} onBlur={props.handleBlur('name')} header="Group name" formikError={props.touched.name && props.errors.name} /> { props.handleChange('description')(text); setDescription(text); }} onBlur={props.handleBlur('description')} header="Description" multiline height={58} formikError={props.touched.description && props.errors.description} /> {selectedUsers.length > 0 ? ( item.user_id.toString()} estimatedItemSize={100} extraData={selectedUsers} showsVerticalScrollIndicator={false} contentContainerStyle={styles.selectedUsersList} numColumns={4} /> ) : null} {props.errors.users && ( 0 ? { marginTop: -32 } : {}]} > select at least 2 members )} ); }} ); }; const styles = StyleSheet.create({ container: { gap: 16, height: '100%', backgroundColor: Colors.WHITE }, header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }, headerText: { color: Colors.DARK_BLUE, fontSize: getFontSize(14), fontWeight: '700' }, photoContainer: { alignItems: 'center', gap: 8 }, groupPhoto: { width: 80, height: 80, borderRadius: 40, alignItems: 'center', justifyContent: 'center' }, photoText: { color: Colors.DARK_BLUE, fontSize: 12, fontWeight: '700' }, input: { marginBottom: 12 }, userItem: { flexDirection: 'row', alignItems: 'center', paddingVertical: 8, paddingHorizontal: 12, backgroundColor: Colors.FILL_LIGHT, gap: 8, borderRadius: 8, marginBottom: 6 }, avatar: { width: 36, height: 36, borderRadius: 18, borderWidth: 1, borderColor: Colors.LIGHT_GRAY }, userName: { color: Colors.DARK_BLUE, fontSize: getFontSize(14), fontFamily: 'montserrat-700' }, userSubtitle: { color: Colors.DARK_BLUE, fontSize: 14, fontFamily: 'montserrat-500' }, userNM: { color: Colors.DARK_BLUE, fontSize: 14, fontFamily: 'montserrat-700', marginRight: 12 }, unselectedCircle: { width: 20, height: 20, borderRadius: 10, borderWidth: 1, borderColor: Colors.LIGHT_GRAY, justifyContent: 'center', alignItems: 'center' }, selectedUsersList: { paddingTop: 12 }, selectedUserContainer: { position: 'relative', width: '100%', alignItems: 'center', paddingBottom: 12 }, userContainer: {}, selectedAvatar: { width: 60, height: 60, borderRadius: 30, borderWidth: 1, borderColor: Colors.LIGHT_GRAY }, removeIcon: { position: 'absolute', top: -4, right: -4, width: 22, height: 22, borderRadius: 11, borderWidth: 1, borderColor: Colors.WHITE, backgroundColor: Colors.RED, justifyContent: 'center', alignItems: 'center', zIndex: 1 }, usersRow: { flex: 1, backgroundColor: Colors.FILL_LIGHT, borderRadius: 8, marginBottom: 24 }, textError: { color: Colors.RED, fontSize: getFontSize(12), fontFamily: 'redhat-600', marginTop: 5 } }); export default RouteAddGroup;