From 79905d7acbddf262147c4d5bdbbdfabb9d3374ed Mon Sep 17 00:00:00 2001 From: dungtnguyen <dungtnguyen@meu-solutions.com> Date: Thu, 10 Oct 2024 16:51:10 +0700 Subject: [PATCH] fix profile screen --- src/navigation/BottomTabNavigation.js | 6 +- src/screens/onleave/OnLeaveContainer.js | 23 +- src/screens/profile/ProfileContainer.js | 51 +- src/screens/profile/ProfileScreen.js | 1312 ----------------- src/screens/profile/index.js | 7 +- src/screens/profile/profilePropsProvider.js | 98 ++ src/screens/profile/profileSlice.js | 0 src/screens/profile/style.js | 27 +- .../profile/template/ProfileMainView.js | 216 +++ .../template/components/DetailInformation.js | 119 ++ .../template/components/GeneralInformation.js | 64 + .../template/components/IntroduceUser.js | 174 +++ .../components/PersonalInformation.js | 82 ++ src/styles/commonStyles.js | 1 + 14 files changed, 810 insertions(+), 1370 deletions(-) delete mode 100644 src/screens/profile/ProfileScreen.js create mode 100644 src/screens/profile/profilePropsProvider.js create mode 100644 src/screens/profile/profileSlice.js create mode 100644 src/screens/profile/template/ProfileMainView.js create mode 100644 src/screens/profile/template/components/DetailInformation.js create mode 100644 src/screens/profile/template/components/GeneralInformation.js create mode 100644 src/screens/profile/template/components/IntroduceUser.js create mode 100644 src/screens/profile/template/components/PersonalInformation.js diff --git a/src/navigation/BottomTabNavigation.js b/src/navigation/BottomTabNavigation.js index 4ee186e..e5fbfda 100644 --- a/src/navigation/BottomTabNavigation.js +++ b/src/navigation/BottomTabNavigation.js @@ -4,14 +4,12 @@ import {Image} from 'react-native'; import {useSelector} from 'react-redux'; import {authSelector} from '../app/selectors'; import HeaderComponent from '../components/header/HeaderComponent'; +import config from '../config'; import NotificationScreen from '../screens/notification/NotificationContainer'; -import ProfileScreen from '../screens/profile/ProfileContainer'; +import ProfileScreen from '../screens/profile'; import {APP_NAVIGATE_SCREEN} from '../utils/constant'; import {IconDrawer, IMAGES} from '../values/images'; -import DayWageNavigation from './DayWageTopTabNavigation'; import TopTabNavigation from './TopTabNavigation'; -import config from '../config'; -import HomeScreen from '../screens/home'; const {HOME, SHIFT, PROFILE, DAY_WAGE, Notification} = APP_NAVIGATE_SCREEN; diff --git a/src/screens/onleave/OnLeaveContainer.js b/src/screens/onleave/OnLeaveContainer.js index 85dda44..375312e 100644 --- a/src/screens/onleave/OnLeaveContainer.js +++ b/src/screens/onleave/OnLeaveContainer.js @@ -4,30 +4,25 @@ import Moment from 'moment'; import React, {useCallback, useEffect, useState} from 'react'; import {useDispatch} from 'react-redux'; import RootNavigation from '../../navigation/RootNavigation'; -import { - getUserLeaveDayApproveReq, - getUserLeavesById, -} from '../../store/actions/UserAction'; +import {getUserLeavesById} from '../../store/actions/UserAction'; import {APP_NAVIGATE_SCREEN} from '../../utils/constant'; -import OnLeaveModalAddNew from './template/subViews/RequestLeavesDays'; -import OnLeaveModalDetail from './modals/OnLeaveModalDetails'; +import moment from 'moment'; +import {launchImageLibrary} from 'react-native-image-picker'; +import Utils from '../../utils'; +import {ToastMessage} from '../../utils/MessageUtil'; +import onLeavePropsProvider from './onLeavePropsProvider'; import { - getUserLeavesDay, getApproveRequestLeavesDays, - getUserRestDay, - getLeaveCategory, getDirectManagers, + getLeaveCategory, + getUserLeavesDay, + getUserRestDay, handleSelectManagersLeaveRequest, postLeaveRequest, postSubmitApproveLeaveRequest, } from './onLeaveSlice'; import OnLeaveMainView from './template/OnLeaveMainView'; -import onLeavePropsProvider from './onLeavePropsProvider'; -import {launchImageLibrary} from 'react-native-image-picker'; -import {ToastMessage} from '../../utils/MessageUtil'; -import moment from 'moment'; -import Utils from '../../utils'; const initPayloadApprove = { type: 'Tất cả', diff --git a/src/screens/profile/ProfileContainer.js b/src/screens/profile/ProfileContainer.js index 76b1cf5..99b609f 100644 --- a/src/screens/profile/ProfileContainer.js +++ b/src/screens/profile/ProfileContainer.js @@ -1,25 +1,24 @@ -/* eslint-disable prettier/prettier */ import React, {useEffect, useState} from 'react'; -import ProfileScreen from './ProfileScreen'; -import {useDispatch, useSelector} from 'react-redux'; +import {launchImageLibrary} from 'react-native-image-picker'; +import Toast from 'react-native-toast-message'; +import {useDispatch} from 'react-redux'; import RootNavigation from '../../navigation/RootNavigation'; -import {APP_NAVIGATE_SCREEN} from '../../utils/constant'; +import {logoutApp} from '../../store/actions/CommonAction'; import { + addContactUser, changeAvatar, + changeContactUser, changeCoverAvatar, changeUserInfo, - getContactUser, - changeContactUser, deleteContactUser, - addContactUser, + getContactUser, } from '../../store/actions/UserAction'; -import {launchImageLibrary} from 'react-native-image-picker'; -import Toast from 'react-native-toast-message'; -import Moment from 'moment'; -import {logoutApp} from '../../store/actions/CommonAction'; +import {APP_NAVIGATE_SCREEN} from '../../utils/constant'; +import profilePropsProvider from './profilePropsProvider'; +import ProfileMainView from './template/ProfileMainView'; const ProfileContainer = props => { - const {userDetails} = props; + const {userInfo} = props; const dispatch = useDispatch(); const [modalVisible, setModalVisible] = useState(false); @@ -34,7 +33,7 @@ const ProfileContainer = props => { contactBtn: false, detailBtn: false, }); - const [infoUser, setInfoUser] = useState(userDetails); + const [infoUser, setInfoUser] = useState(userInfo); const [contactUser, setContactUser] = useState([]); const [defaultContact, setDefaultContact] = useState([]); @@ -96,7 +95,7 @@ const ProfileContainer = props => { if (!response.didCancel) { //setCoverAvatar(response.assets); const resChangeCoverAvatar = dispatch( - changeCoverAvatar(userDetails.id, response.assets), + changeCoverAvatar(userInfo.id, response.assets), ); if (resChangeCoverAvatar) { setEditField(prev => ({...prev, avatar: false})); @@ -124,7 +123,7 @@ const ProfileContainer = props => { }; const onSaveInfo = async () => { if (!!compareInfoUser) { - const res = await dispatch(changeUserInfo(userDetails.id, infoUser)); + const res = await dispatch(changeUserInfo(userInfo.id, infoUser)); if (res) { Toast.show({ type: 'success', @@ -145,7 +144,7 @@ const ProfileContainer = props => { setEditField(prev => ({...prev, avatar: false})); }; const onConfirmAvatar = () => { - const res = dispatch(changeAvatar(userDetails.id, avatar)); + const res = dispatch(changeAvatar(userInfo.id, avatar)); if (res) { setEditField(prev => ({...prev, avatar: false})); Toast.show({ @@ -160,7 +159,7 @@ const ProfileContainer = props => { }; const compareInfoUser = () => { // check user have change info - if (JSON.stringify(infoUser) == JSON.stringify(userDetails)) return true; + if (JSON.stringify(infoUser) == JSON.stringify(userInfo)) return true; return false; }; @@ -173,7 +172,7 @@ const ProfileContainer = props => { }; const getContactSocialUser = async () => { - const res = await dispatch(getContactUser(userDetails.id)); + const res = await dispatch(getContactUser(userInfo.id)); //console.log(res) if (res.length > 0) { let arrContact = []; @@ -312,7 +311,7 @@ const ProfileContainer = props => { if (duplicateSocial === undefined) { const res = await dispatch( addContactUser( - userDetails.id, + userInfo.id, userInputContact.text, userInputContact.type, ), @@ -354,11 +353,8 @@ const ProfileContainer = props => { getContactSocialUser(); }, []); - // useEffect(() => { - // infoUser && console.log("infoUser", infoUser) - // }, []) const profileProps = { - userDetails, + userInfo, isEditField, btnAvailable, infoUser, @@ -400,14 +396,7 @@ const ProfileContainer = props => { onChangeCoverAvatar, }; - // useEffect(() => { - // infoUser && userDetails && compareInfoUser() - // }, [userDetails, infoUser]) - // useEffect(() => { - // infoUser && console.log("infoUser", infoUser) - // }, []) - - return <ProfileScreen {...profileProps} />; + return <ProfileMainView {...profilePropsProvider(profileProps)} />; }; export default ProfileContainer; diff --git a/src/screens/profile/ProfileScreen.js b/src/screens/profile/ProfileScreen.js deleted file mode 100644 index f7620db..0000000 --- a/src/screens/profile/ProfileScreen.js +++ /dev/null @@ -1,1312 +0,0 @@ -/* eslint-disable prettier/prettier */ -import Moment from 'moment'; -import React from 'react'; -import { - Animated, - Image, - ImageBackground, - Modal, - SafeAreaView, - ScrollView, - TextInput, - TouchableOpacity, - View, -} from 'react-native'; -import Alert from 'react-native-awesome-alerts'; -import {GestureHandlerRootView, Swipeable} from 'react-native-gesture-handler'; -import {Menu, MenuItem} from 'react-native-material-menu'; -import DateTimePickerModal from 'react-native-modal-datetime-picker'; -import SelectDropdown from 'react-native-select-dropdown'; -import Swiper from 'react-native-swiper'; -import AppText from '../../components/AppText'; -import ButtonComponent from '../../components/ButtonComponent'; -import TextInputComponent from '../../components/TextInputComponent'; -import { - IMAGES, - IcNotificationList, - IconProfile, - IconSocial, -} from '../../values/images'; -import {default as string, default as strings} from '../../values/string'; -import styles from './style'; -const ProfileScreen = ({ - userDetails, - contactUser, - btnAvailable, - isEditField, - navigateMain, - setEditField, - setBtnAvailable, - infoUser, - setInfoUser, - onSaveInfo, - avatar, - onDeniedAvatar, - onConfirmAvatar, - showMenu, - hideMenu, - visibleMenu, - openGallery, - isSlideShow, - showFullScreen, - hideFullScreen, - dateTimePicker, - hideDateTimePicker, - setDateTimePicker, - showAlert, - onSubmitChangeContactUser, - onChangeDropDownContactUser, - onChangeInputContactUser, - onPressDeleteItem, - onPressAddItem, - onCancelAlert, - modalVisible, - setModalVisible, - setUserInputContact, - userInputContact, - onSubmitCreateNew, - onConfirmDeleteAlert, - navigateToLogout, - onChangeCoverAvatar, -}) => { - //console.log("userDetails", userDetails) - - const Socials = [ - 'FACEBOOK', - 'EMAIL', - 'SKYPE', - 'LINKEDIN', - 'TWITTER', - 'INSTAGRAM', - 'WHATSAPP', - 'VIPER', - 'SNAPCHAT', - 'TELEGRAM', - 'APPLE', - 'YOUTUBE', - 'PINTEREST', - ]; - const gender = ['Nam', 'Nữ']; - const renderRightActions = (dragX, item) => { - const trans = dragX.interpolate({ - inputRange: [0, 100], - outputRange: [0, 1], - extrapolate: 'clamp', - }); - return ( - <Animated.AppText - style={[ - styles.actionText, - { - transform: [{translateX: trans}], - }, - ]}> - <ButtonComponent - style={styles.hiddenItem} - onPress={() => onPressDeleteItem(item)} - iconSource={IcNotificationList.IcTrash} - styleIcon={{width: 20, height: 20}} - /> - </Animated.AppText> - ); - }; - return ( - <SafeAreaView style={styles.container}> - {isSlideShow && ( - <TouchableOpacity - onPress={hideFullScreen} - style={styles.viewFullScreen}> - <ButtonComponent - style={styles.btnClose} - iconSource={IconProfile.IcCloseBlack} - styleIcon={styles.imgClose} - onPress={hideFullScreen} - /> - {avatar ? ( - <Image - source={{uri: avatar[0].uri}} - style={styles.imgAvatarFullScreen} - /> - ) : ( - <Image - source={{uri: 'https://meu.anawork.com' + userDetails.avatar}} - style={styles.imgAvatarFullScreen} - /> - )} - </TouchableOpacity> - )} - <ScrollView nestedScrollEnabled={true}> - <Swiper - style={{height: 390, padding: 10}} - showsButtons={false} - loop={false} - showsPagination={true} - activeDot={ - <View - style={{ - backgroundColor: '#007aff', - width: 25, - height: 8, - borderRadius: 4, - }} - /> - }> - <View style={styles.viewImageProfile}> - <ImageBackground - source={ - (userDetails?.cover_image && { - uri: 'https://meu.anawork.com' + userDetails?.cover_image, - }) || - IMAGES.ImageCoverBg - } - style={styles.coverImage}> - <ButtonComponent - iconSource={IMAGES.IcChangeCoverImage} - styleIcon={{height: 20, width: 20}} - style={{marginRight: 15, marginBottom: 10}} - onPress={onChangeCoverAvatar} - /> - </ImageBackground> - <TouchableOpacity onPress={showMenu} style={styles.viewAvatar}> - {avatar ? ( - <Image source={{uri: avatar[0].uri}} style={styles.imgAvatar} /> - ) : ( - <Image - source={{uri: 'https://meu.anawork.com' + userDetails.avatar}} - style={styles.imgAvatar} - /> - )} - - {/* menu option */} - <View style={{justifyContent: 'center', alignItems: 'center'}}> - <Menu - visible={visibleMenu} - // anchor={<AppText onPress={showMenu}>Show menu</AppText>} - onRequestClose={hideMenu}> - <MenuItem onPress={showFullScreen}>Xem ảnh đại diện</MenuItem> - <MenuItem onPress={openGallery}>Äổi hình ná»n</MenuItem> - </Menu> - </View> - </TouchableOpacity> - {isEditField.avatar && ( - <View - style={{flexDirection: 'row', justifyContent: 'space-around'}}> - <TouchableOpacity onPress={onDeniedAvatar}> - <Image - source={IMAGES.IcDenied} - style={{width: 25, height: 25}} - /> - </TouchableOpacity> - <TouchableOpacity onPress={onConfirmAvatar}> - <Image - source={IMAGES.IcCheckMark} - style={{width: 25, height: 25}} - /> - </TouchableOpacity> - </View> - )} - <AppText style={{color: 'black', fontSize: 18}}> - {`${userDetails.first_name} ${ - userDetails.middle_name ? userDetails.middle_name : '' - } ${userDetails.last_name} (${userDetails.employee_code})`}{' '} - </AppText> - <AppText style={{marginBottom: 20}}>{userDetails.position}</AppText> - </View> - {/**Card Info */} - <ImageBackground - source={IMAGES.BgProfileCard} - style={[ - styles.viewCardProfile, - { - borderRadius: 10, - paddingTop: 20, - paddingBottom: 10, - }, - ]} - resizeMode="cover"> - <View style={{position: 'absolute', left: 15, top: 10}}> - <Image - source={IMAGES.ImageQrCode} - style={{height: 45, width: 45}} - /> - </View> - <ImageBackground source={IMAGES.BgFrame} style={styles.imgFrame}> - <Image - source={{uri: 'https://meu.anawork.com' + userDetails.avatar}} - style={{ - width: 100, - height: 100, - resizeMode: 'contain', - alignSelf: 'center', - borderRadius: 60, - zIndex: -100, - }} - /> - </ImageBackground> - <View style={{justifyContent: 'center', alignItems: 'center'}}> - <AppText style={{marginTop: 20}}>{userDetails.position}</AppText> - <AppText - style={{color: 'black', fontSize: 18, fontWeight: 'bold'}}> - {`${userDetails.first_name} ${ - userDetails.middle_name ? userDetails.middle_name : '' - } ${userDetails.last_name} `} - </AppText> - <View style={{flexDirection: 'row', marginTop: 10}}> - <View - style={{flex: 1, alignItems: 'flex-end', paddingRight: 5}}> - <Image - source={IMAGES.IconMailGrey} - style={{height: 25, width: 25}} - /> - </View> - <AppText style={{flex: 2, color: 'black'}}> - {userDetails.email} - </AppText> - </View> - <View style={{flexDirection: 'row', marginTop: 10}}> - <View - style={{flex: 1, alignItems: 'flex-end', paddingRight: 5}}> - <Image - source={IMAGES.IcPhoneGrey} - style={{height: 25, width: 25}} - /> - </View> - <AppText style={{flex: 2, color: 'black'}}> - {userDetails.cell_phone} - </AppText> - </View> - </View> - <View - style={{ - flexDirection: 'row', - justifyContent: 'space-evenly', - marginTop: 20, - }}> - <AppText style={{color: 'black', fontWeight: 'bold'}}> - #willing-to-do - </AppText> - <AppText style={{color: 'black', fontWeight: 'bold'}}> - #passion - </AppText> - <AppText style={{color: 'black', fontWeight: 'bold'}}> - #hard-working - </AppText> - </View> - </ImageBackground> - </Swiper> - - {/* General information */} - <View style={styles.viewInfo}> - <View style={styles.viewTitle}> - <AppText style={{color: 'black', fontSize: 18}}> - {strings.GENERAL_INFORMATION} - </AppText> - </View> - <View style={{flexDirection: 'row', justifyContent: 'space-between'}}> - <View style={{flexDirection: 'row'}}> - <Image source={IMAGES.IcUser} style={{height: 45, width: 45}} /> - <View style={{marginLeft: 5}}> - <AppText>{strings.USER_ID}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.employee_code} - </AppText> - </View> - </View> - <View style={{flexDirection: 'row'}}> - <Image source={IMAGES.IcCheck} style={{height: 45, width: 45}} /> - <View style={{marginLeft: 5}}> - <AppText>{strings.TIME_ATTENDANCE_CODE}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.employee_code} - </AppText> - </View> - </View> - </View> - <View style={{flexDirection: 'row', marginTop: 10}}> - <Image source={IMAGES.IcCalendar} style={{height: 45, width: 45}} /> - <View style={{marginLeft: 5}}> - <AppText>{strings.SHIFT}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - Meu Official working time - </AppText> - </View> - </View> - <View style={{flexDirection: 'row', marginTop: 10}}> - <Image source={IMAGES.IcUserTag} style={{height: 45, width: 45}} /> - <View style={{marginLeft: 5}}> - <AppText>{strings.STATUS}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - Nhân viên chÃnh thức - </AppText> - </View> - </View> - </View> - {/* personal information */} - <View style={[styles.viewInfo, styles.paddingView]}> - <View style={styles.viewTitle}> - <AppText style={{color: 'black', fontSize: 17}}> - {strings.PERSONAL_INFORMATION} - </AppText> - <View - style={{ - justifyContent: 'flex-end', - alignItems: 'flex-end', - flex: 1, - }}> - {!btnAvailable.personalBtn && ( - <TouchableOpacity - onPress={() => { - setEditField(prev => ({...prev, personal_info: true})); - setBtnAvailable(prev => ({...prev, personalBtn: true})); - }}> - <Image - source={IMAGES.IcEdit} - style={{height: 30, width: 30}} - /> - </TouchableOpacity> - )} - {btnAvailable.personalBtn && ( - <View style={{flexDirection: 'row'}}> - <TouchableOpacity - onPress={() => { - setEditField(prev => ({...prev, personal_info: false})); - setBtnAvailable(prev => ({...prev, personalBtn: false})); - }} - style={styles.btnCancel}> - <AppText style={styles.blueTxt}>Hủy</AppText> - </TouchableOpacity> - <TouchableOpacity - style={styles.btnSubmit} - onPress={() => { - onSaveInfo(); - setEditField(prev => ({...prev, personal_info: false})); - setBtnAvailable(prev => ({...prev, personalBtn: false})); - }}> - <AppText style={styles.whiteTxt}>LÆ°u</AppText> - </TouchableOpacity> - </View> - )} - </View> - </View> - {!isEditField.personal_info && ( - <View> - <View style={styles.viewItem}> - <View style={{flexDirection: 'row', flex: 1}}> - <Image source={IMAGES.IcInfoGuess} /> - <View style={{marginLeft: 5}}> - <AppText>{strings.LAST_NAME}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.first_name} - </AppText> - </View> - </View> - <View style={{flexDirection: 'row', flex: 1}}> - <Image source={IMAGES.IcInfoGuess} /> - <View style={{marginLeft: 5}}> - <AppText>{strings.MIDDLE_NAME}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.middle_name ? userDetails.middle_name : ''} - </AppText> - </View> - </View> - </View> - <View style={styles.viewItem}> - <View style={{flexDirection: 'row', flex: 1}}> - <Image source={IMAGES.IcInfoGuess} /> - <View style={{marginLeft: 5}}> - <AppText>{strings.FIRST_NAME}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.last_name} - </AppText> - </View> - </View> - <View style={{flexDirection: 'row', flex: 1}}> - <Image source={IMAGES.IcInfoGuess} /> - <View style={{marginLeft: 5}}> - <AppText>{strings.GENDER}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.gender ? 'Nam' : 'Nữ'} - </AppText> - </View> - </View> - </View> - <View style={styles.viewItem}> - <Image - source={IMAGES.IcPhone} - style={{height: 20, width: 20}} - /> - <View style={{marginLeft: 5}}> - <AppText>{strings.TELEPHONE}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.cell_phone} - </AppText> - </View> - </View> - <View style={styles.viewItem}> - <Image - source={IMAGES.IcMailGray} - style={{height: 20, width: 20}} - /> - <View style={{marginLeft: 5}}> - <AppText>{strings.EMAIL}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.email} - </AppText> - </View> - </View> - </View> - )} - {isEditField.personal_info && ( - <View> - {/* row 1 */} - <View style={{flexDirection: 'row'}}> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Há»</AppText> - <TextInputComponent - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Há»'} - keyboardType={'email-address'} - autoCapitalize="none" - value={infoUser.first_name} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - first_name: text, - })) - } - /> - </View> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Tên lót</AppText> - <TextInputComponent - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Tên lót'} - keyboardType={'email-address'} - autoCapitalize="none" - value={infoUser.middle_name} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - middle_name: text, - })) - } - /> - </View> - </View> - {/* row 2 */} - <View style={{flexDirection: 'row'}}> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Tên</AppText> - <TextInputComponent - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Tên'} - keyboardType={'email-address'} - autoCapitalize="none" - value={infoUser.last_name} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - last_name: text, - })) - } - /> - </View> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Giá»›i tÃnh</AppText> - <SelectDropdown - data={gender} - dropdownIconPosition={'right'} - defaultButtonText={ - infoUser.gender ? 'Nam' : 'Nữ' || 'Chá»n giá»›i tÃnh' - } - buttonStyle={styles.dropdown1BtnStyle} - onSelect={(selectedItem, item_index) => - setInfoUser(prev => ({ - ...prev, - gender: selectedItem === 'Nam' ? true : false, - })) - } - dropdownStyle={styles.dropdown1DropdownStyle} - rowStyle={styles.dropdown1RowStyle} - rowTextStyle={styles.dropdown1RowTxtStyle} - buttonTextStyle={styles.dropdown1BtnTxtStyle} - renderDropdownIcon={isOpened => { - return ( - <Image - source={ - isOpened ? IMAGES.IcUpArrow : IMAGES.IcDownArrow - } - style={{width: 20, height: 20}} - /> - ); - }} - /> - </View> - </View> - {/* row 3 */} - <View style={{paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Số Ä‘iện thoại</AppText> - <TextInputComponent - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Số Ä‘iện thoại'} - keyboardType={'phone-pad'} - autoCapitalize="none" - value={infoUser.cell_phone} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - cell_phone: text, - })) - } - /> - </View> - {/* row 4 */} - <View style={{paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Email</AppText> - <TextInputComponent - disable={true} - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Email'} - keyboardType={'email-address'} - autoCapitalize="none" - value={infoUser.email} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - email: text, - })) - } - /> - </View> - </View> - )} - </View> - {/* detail information */} - <View style={[styles.viewInfo, styles.paddingView]}> - <View style={styles.viewTitle}> - <AppText style={{color: 'black', fontSize: 18, flex: 1}}> - {strings.DETAIL_INFORMATION} - </AppText> - <View - style={{ - justifyContent: 'flex-end', - alignItems: 'flex-end', - flex: 1, - }}> - {!btnAvailable.detailBtn && ( - <TouchableOpacity - onPress={() => { - setEditField(prev => ({...prev, detail_info: true})); - setBtnAvailable(prev => ({...prev, detailBtn: true})); - }}> - <Image - source={IMAGES.IcEdit} - style={{height: 30, width: 30}} - /> - </TouchableOpacity> - )} - {btnAvailable.detailBtn && ( - <View style={{flexDirection: 'row'}}> - <TouchableOpacity - onPress={() => { - setEditField(prev => ({...prev, detail_info: false})); - setBtnAvailable(prev => ({...prev, detailBtn: false})); - }} - style={styles.btnCancel}> - <AppText style={styles.blueTxt}>Hủy</AppText> - </TouchableOpacity> - <TouchableOpacity - style={styles.btnSubmit} - onPress={() => { - onSaveInfo(); - setEditField(prev => ({...prev, detail_info: false})); - setBtnAvailable(prev => ({...prev, detailBtn: false})); - }}> - <AppText style={styles.whiteTxt}>LÆ°u</AppText> - </TouchableOpacity> - </View> - )} - </View> - </View> - {!isEditField.detail_info && ( - <View> - {/* row 1 */} - <View style={styles.viewItem}> - <View style={{flexDirection: 'row', flex: 1}}> - <Image source={IMAGES.IcInfoGuess} /> - <View style={{marginLeft: 5}}> - <AppText>{strings.IDENTITY_CARD}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.id_card_number} - </AppText> - </View> - </View> - <View style={styles.rightView}> - <Image - source={IMAGES.IcCalendarGray} - style={{height: 25, width: 25}} - /> - <View> - <AppText>{strings.DATE_IDENTITY_CARD}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.id_card_issue_date && - Moment(userDetails.id_card_issue_date).format( - 'DD/MM/YYYY', - )} - </AppText> - </View> - </View> - </View> - {/* row 2 */} - <View style={styles.viewItem}> - <View style={{flexDirection: 'row', flex: 1}}> - <Image source={IMAGES.IcInfoGuess} /> - <View style={{marginLeft: 5}}> - <AppText>{strings.ISSUED_BY}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.id_card_issue_palce} - </AppText> - </View> - </View> - <View style={styles.rightView}> - <Image - source={IMAGES.IcCalendarGray} - style={{height: 25, width: 25}} - /> - <View> - <AppText>{strings.DATE_OF_BIRTH}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {infoUser.birthday && - Moment(infoUser.birthday).format('DD/MM/YYYY')} - </AppText> - </View> - </View> - </View> - {/* row 3 */} - <View style={styles.viewItem}> - <View style={{flexDirection: 'row', flex: 1}}> - <Image source={IMAGES.IcInfoGuess} /> - <View style={{marginLeft: 5}}> - <AppText>{strings.PLACE_OF_COUNTRY}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.domicile} - </AppText> - </View> - </View> - <View style={styles.rightView}> - <Image - source={IMAGES.IcCalendarGray} - style={{height: 25, width: 25}} - /> - <View> - <AppText>NÆ¡i sinh</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.birthplace} - </AppText> - </View> - </View> - </View> - {/* row 4 */} - <View style={styles.viewItem}> - <View style={{flexDirection: 'row', flex: 1}}> - <Image source={IMAGES.IcInfoGuess} /> - <View style={{marginLeft: 5}}> - <AppText>{strings.NATIONALITY}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.nationality} - </AppText> - </View> - </View> - <View style={styles.rightView}> - <Image - source={IMAGES.IcCalendarGray} - style={{height: 25, width: 25}} - /> - <View> - <AppText>{string.ETHNIC}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.ethnic} - </AppText> - </View> - </View> - </View> - {/* row 5 */} - <View style={styles.viewItem}> - <View style={{flexDirection: 'row', flex: 1}}> - <Image source={IMAGES.IcInfoGuess} /> - <View style={{marginLeft: 5}}> - <AppText>{strings.RELIGION}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.religion} - </AppText> - </View> - </View> - <View style={styles.rightView}> - <Image - source={IMAGES.IcCalendarGray} - style={{height: 25, width: 25}} - /> - <View> - <AppText>{strings.MST}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.personal_tax_code} - </AppText> - </View> - </View> - </View> - {/* row 6 */} - <View style={styles.viewItem}> - <Image - source={IMAGES.IcLocationGray} - style={{height: 25, width: 25}} - /> - <View style={{marginLeft: 5}}> - <AppText>{strings.PERMANENT_ADDRESS}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.permanent_address} - </AppText> - </View> - </View> - {/* row 7 */} - <View style={styles.viewItem}> - <Image - source={IMAGES.IcLocationGray} - style={{height: 25, width: 25}} - /> - <View style={{marginLeft: 5}}> - <AppText>{strings.RESIDENTIAL_ADDRESS}</AppText> - <AppText style={{color: 'black', fontSize: 15}}> - {userDetails.address} - </AppText> - </View> - </View> - </View> - )} - {isEditField.detail_info && ( - <View> - {/* row 1 */} - <View style={{flexDirection: 'row'}}> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Số CMND</AppText> - <TextInputComponent - maxLength={12} - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Số CMND'} - keyboardType={'phone-pad'} - autoCapitalize="none" - value={infoUser.id_card_number} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - id_card_number: text, - })) - } - /> - </View> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <TouchableOpacity - onPress={() => - setDateTimePicker(prev => ({ - ...prev, - id_card_issue_date: true, - })) - }> - <AppText style={{fontSize: 12}}>Ngà y cấp CMND</AppText> - <TextInputComponent - disable={true} - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Ngà y cấp CMND'} - keyboardType={'email-address'} - autoCapitalize="none" - value={ - infoUser.id_card_issue_date && - Moment(infoUser.id_card_issue_date).format('DD/MM/YYYY') - } - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - id_card_issue_date: text, - })) - } - /> - <DateTimePickerModal - isVisible={dateTimePicker.id_card_issue_date} - mode="date" - date={new Date(infoUser.id_card_issue_date)} - onConfirm={time => { - setInfoUser(prev => ({ - ...prev, - id_card_issue_date: time, - })); - hideDateTimePicker(); - }} - onCancel={() => hideDateTimePicker()} - /> - </TouchableOpacity> - </View> - </View> - {/* row 2 */} - <View style={{flexDirection: 'row'}}> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>NÆ¡i cấp CMND</AppText> - <TextInputComponent - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'NÆ¡i cấp CMND'} - keyboardType={'email-address'} - autoCapitalize="none" - value={infoUser.id_card_issue_palce} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - id_card_issue_palce: text, - })) - } - /> - </View> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <TouchableOpacity - onPress={() => - setDateTimePicker(prev => ({ - ...prev, - birthday: true, - })) - }> - <AppText style={{fontSize: 12}}>Ngà y sinh</AppText> - <TextInputComponent - disable={true} - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Ngà y sinh'} - keyboardType={'email-address'} - autoCapitalize="none" - value={ - infoUser.birthday && - Moment(infoUser.birthday).format('DD/MM/YYYY') - } - /> - <DateTimePickerModal - isVisible={dateTimePicker.birthday} - mode="date" - date={new Date(infoUser.birthday)} - onConfirm={time => { - setInfoUser(prev => ({ - ...prev, - birthday: time, - })); - hideDateTimePicker(); - }} - onCancel={() => hideDateTimePicker()} - /> - </TouchableOpacity> - </View> - </View> - {/* row 3 */} - <View style={{flexDirection: 'row'}}> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Nguyên Quán</AppText> - <TextInputComponent - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Nguyên Quán'} - keyboardType={'email-address'} - autoCapitalize="none" - value={infoUser.domicile} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - domicile: text, - })) - } - /> - </View> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>NÆ¡i sinh</AppText> - <TextInputComponent - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'NÆ¡i sinh'} - keyboardType={'email-address'} - autoCapitalize="none" - value={infoUser.birthplace} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - birthplace: text, - })) - } - /> - </View> - </View> - {/* row 4 */} - <View style={{flexDirection: 'row'}}> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Quốc tịch</AppText> - <TextInputComponent - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Quốc tịch'} - keyboardType={'email-address'} - autoCapitalize="none" - value={infoUser.nationality} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - nationality: text, - })) - } - /> - </View> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Dân tá»™c</AppText> - <TextInputComponent - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Dân tá»™c'} - keyboardType={'email-address'} - autoCapitalize="none" - value={infoUser.ethnic} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - ethnic: text, - })) - } - /> - </View> - </View> - {/* row 5 */} - <View style={{flexDirection: 'row'}}> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Tôn giáo</AppText> - <TextInputComponent - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Tôn giáo'} - keyboardType={'email-address'} - autoCapitalize="none" - value={infoUser.religion} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - religion: text, - })) - } - /> - </View> - <View style={{flex: 1, paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Mã số thuế</AppText> - <TextInputComponent - maxLength={20} - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Mã số thuế'} - keyboardType={'email-address'} - autoCapitalize="none" - value={infoUser.personal_tax_code} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - personal_tax_code: text, - })) - } - /> - </View> - </View> - {/* row 6 */} - <View style={{paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Äịa chỉ thÆ°á»ng trú</AppText> - <TextInputComponent - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Äịa chỉ thÆ°á»ng trú'} - keyboardType={'email-address'} - autoCapitalize="none" - value={infoUser.permanent_address} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - permanent_address: text, - })) - } - /> - </View> - {/* row 7 */} - <View style={{paddingLeft: 10, paddingRight: 10}}> - <AppText style={{fontSize: 12}}>Äịa chỉ liên hệ</AppText> - <TextInputComponent - styleAreaInput={{backgroundColor: 'white'}} - placeholder={'Äịa chỉ liên hệ'} - keyboardType={'email-address'} - autoCapitalize="none" - value={infoUser.address} - onChangeText={text => - setInfoUser(prev => ({ - ...prev, - address: text, - })) - } - /> - </View> - </View> - )} - </View> - {/* contact information */} - <View style={[styles.viewInfo, styles.marginBottom]}> - {/* edit */} - <View style={styles.viewTitle}> - <AppText style={{color: 'black', fontSize: 18, flex: 1}}> - Thông tin liên lạc - </AppText> - <View - style={{ - justifyContent: 'flex-end', - alignItems: 'flex-end', - flex: 1, - }}> - {!btnAvailable.contactBtn && ( - <TouchableOpacity - onPress={() => { - setEditField(prev => ({...prev, contact_info: true})); - setBtnAvailable(prev => ({...prev, contactBtn: true})); - }}> - <Image - source={IMAGES.IcEdit} - style={{height: 30, width: 30}} - /> - </TouchableOpacity> - )} - {btnAvailable.contactBtn && ( - <View style={{flexDirection: 'row'}}> - <TouchableOpacity - onPress={() => { - setEditField(prev => ({...prev, contact_info: false})); - setBtnAvailable(prev => ({...prev, contactBtn: false})); - }} - style={styles.btnCancel}> - <AppText style={styles.blueTxt}>Hủy</AppText> - </TouchableOpacity> - <TouchableOpacity - style={styles.btnSubmit} - onPress={() => onSubmitChangeContactUser()}> - <AppText style={styles.whiteTxt}>LÆ°u</AppText> - </TouchableOpacity> - </View> - )} - </View> - </View> - {!isEditField.contact_info && - contactUser.map((item, index) => { - return ( - <View key={index} style={{flexDirection: 'row'}}> - <View style={{flexDirection: 'row'}}> - <Image - source={IconSocial[item.type]} - style={{height: 25, width: 25}} - /> - <View style={{marginLeft: 5, justifyContent: 'center'}}> - <AppText style={{color: 'black', fontSize: 15}}> - {item.contact_unique_id} - </AppText> - </View> - </View> - </View> - ); - })} - {isEditField.contact_info && - // <SwipeListView - // data={contactUser} - // renderItem={renderContactUser} - // renderHiddenItem={renderHiddenItem} - // rightOpenValue={-75} - // scrollEnabled={false} - // // onRefresh={onRefreshList} - // // onEndReached={onLoadMore} - // // onRowDidOpen={(item, index) => onDeleteNotification(item, index)} - // /> - contactUser.map((item, index) => { - return ( - <GestureHandlerRootView key={index}> - <Swipeable - renderRightActions={dragX => - renderRightActions(dragX, item) - }> - <View - style={{ - flexDirection: 'row', - flex: 1, - justifyContent: 'center', - }}> - <View style={{flex: 3}}> - <SelectDropdown - data={Socials} - dropdownIconPosition={'right'} - defaultButtonText={item.type} - buttonStyle={styles.dropdown1BtnStyle} - onSelect={(selectedItem, item_index) => - onChangeDropDownContactUser(selectedItem, index) - } - dropdownStyle={styles.dropdown1DropdownStyle} - rowStyle={styles.dropdown1RowStyle} - rowTextStyle={styles.dropdown1RowTxtStyle} - buttonTextStyle={styles.dropdown1BtnTxtStyle} - renderDropdownIcon={isOpened => { - return ( - <Image - source={ - isOpened - ? IMAGES.IcUpArrow - : IMAGES.IcDownArrow - } - style={{width: 20, height: 20}} - /> - ); - }} - /> - </View> - <View style={{flex: 5}}> - <TextInputComponent - styleAreaInput={{backgroundColor: 'white'}} - placeholder={`${item.type} contact`} - keyboardType={'email-address'} - autoCapitalize="none" - value={item.contact_unique_id} - onChangeText={text => - onChangeInputContactUser(text, index) - } - /> - </View> - </View> - </Swipeable> - </GestureHandlerRootView> - ); - })} - {isEditField.contact_info && ( - <View style={{justifyContent: 'flex-end', alignItems: 'flex-end'}}> - <ButtonComponent - style={{marginTop: -15}} - styleIcon={{width: 20, height: 20}} - iconSource={IMAGES.IcAdd} - onPress={onPressAddItem} - /> - </View> - )} - </View> - - {/* Logout Btn */} - <View - style={{ - justifyContent: 'center', - alignItems: 'center', - marginTop: 10, - }}> - <ButtonComponent - text={'Äăng xuất'} - style={{marginBottom: 10, flexDirection: 'row'}} - rightIcon={IMAGES.IcLogout} - styleIcon={{width: 20, height: 20, marginLeft: 10}} - onPress={navigateToLogout} - /> - </View> - <Alert - show={showAlert.isError} - showProgress={false} - title={showAlert.title} - message={showAlert.message} - closeOnTouchOutside={true} - closeOnHardwareBackPress={false} - showConfirmButton={true} - showCancelButton={true} - confirmText="Xóa" - cancelText="Không" - confirmButtonColor="#DD6B55" - onConfirmPressed={onConfirmDeleteAlert} - onCancelPressed={onCancelAlert} - /> - <View style={styles.centeredView}> - <Modal - animationType="slide" - transparent={true} - visible={modalVisible} - onRequestClose={() => { - Alert.alert('Modal has been closed.'); - setModalVisible(!modalVisible); - }}> - <View style={styles.centeredView}> - <View style={styles.modalView}> - <View style={{flexDirection: 'row'}}> - <View style={{flex: 1}}> - <SelectDropdown - data={Socials} - dropdownIconPosition={'right'} - defaultButtonText={'Loại liên hệ'} - buttonStyle={styles.dropdown1BtnStyle} - onSelect={(selectedItem, item_index) => - setUserInputContact(prev => ({ - ...prev, - type: selectedItem, - })) - } - dropdownStyle={styles.dropdown1DropdownStyle} - rowStyle={styles.dropdown1RowStyle} - rowTextStyle={styles.dropdown1RowTxtStyle} - buttonTextStyle={styles.dropdown1BtnTxtStyle} - renderDropdownIcon={isOpened => { - return ( - <Image - source={ - isOpened ? IMAGES.IcUpArrow : IMAGES.IcDownArrow - } - style={{width: 20, height: 20}} - /> - ); - }} - /> - {userInputContact.type.length <= 0 && ( - <AppText style={{fontSize: 12, color: 'red'}}> - {' '} - Vui lòng chá»n liên hệ - </AppText> - )} - </View> - <View style={{flex: 1}}> - <TextInput - style={{borderBottomWidth: 0.2}} - placeholder={'Nháºp F'} - keyboardType={'email-address'} - autoCapitalize="none" - value={userInputContact.text} - onChangeText={text => - setUserInputContact(prev => ({ - ...prev, - text: text, - })) - } - /> - {userInputContact.text.length <= 0 && ( - <AppText style={{fontSize: 12, color: 'red'}}> - {' '} - Vui lòng nháºp liên hệ - </AppText> - )} - </View> - </View> - <View style={{flexDirection: 'row', marginTop: 20}}> - <ButtonComponent - text={'Äóng'} - textStyle={styles.textStyle} - style={[ - styles.button, - styles.buttonClose, - {marginRight: 15}, - ]} - onPress={() => setModalVisible(!modalVisible)} - /> - <ButtonComponent - text={'Thêm má»›i'} - textStyle={styles.textStyle} - style={[styles.button, styles.buttonClose]} - onPress={onSubmitCreateNew} - /> - </View> - </View> - </View> - </Modal> - </View> - </ScrollView> - </SafeAreaView> - ); -}; - -export default ProfileScreen; diff --git a/src/screens/profile/index.js b/src/screens/profile/index.js index 699afc2..2f0806c 100644 --- a/src/screens/profile/index.js +++ b/src/screens/profile/index.js @@ -1,4 +1,3 @@ -/* eslint-disable prettier/prettier */ import React from 'react'; import {useSelector} from 'react-redux'; @@ -6,10 +5,10 @@ import {authSelector} from '../../app/selectors'; import ProfileContainer from './ProfileContainer'; export default function ProfileScreen() { - const userDetails = useSelector(authSelector); - + const authSelect = useSelector(authSelector); + const {userInfo} = authSelect; const profileScreenProps = { - userDetails, + userInfo, }; return <ProfileContainer {...profileScreenProps} />; } diff --git a/src/screens/profile/profilePropsProvider.js b/src/screens/profile/profilePropsProvider.js new file mode 100644 index 0000000..416cc77 --- /dev/null +++ b/src/screens/profile/profilePropsProvider.js @@ -0,0 +1,98 @@ +export default function profilePropsProvider(props) { + const { + userInfo, + isEditField, + btnAvailable, + infoUser, + avatar, + visibleMenu, + isSlideShow, + dateTimePicker, + contactUser, + showAlert, + modalVisible, + userInputContact, + setAvatar, + setInfoUser, + navigateMain, + setEditField, + setBtnAvailable, + onSaveInfo, + onDeniedAvatar, + onConfirmAvatar, + showMenu, + openGallery, + showFullScreen, + hideFullScreen, + hideMenu, + hideDateTimePicker, + setDateTimePicker, + onSubmitChangeContactUser, + setContactUser, + onChangeDropDownContactUser, + onChangeInputContactUser, + onPressDeleteItem, + onPressAddItem, + onConfirmDeleteAlert, + onCancelAlert, + setUserInputContact, + onSubmitCreateNew, + setModalVisible, + navigateToLogout, + onChangeCoverAvatar, + } = props; + return { + userInfo, + isEditField, + btnAvailable, + infoUser, + avatar, + visibleMenu, + isSlideShow, + dateTimePicker, + contactUser, + showAlert, + modalVisible, + userInputContact, + setAvatar, + setInfoUser, + navigateMain, + setEditField, + setBtnAvailable, + onSaveInfo, + onDeniedAvatar, + onConfirmAvatar, + showMenu, + openGallery, + showFullScreen, + hideFullScreen, + hideMenu, + hideDateTimePicker, + setDateTimePicker, + onSubmitChangeContactUser, + setContactUser, + onChangeDropDownContactUser, + onChangeInputContactUser, + onPressDeleteItem, + onPressAddItem, + onConfirmDeleteAlert, + onCancelAlert, + setUserInputContact, + onSubmitCreateNew, + setModalVisible, + navigateToLogout, + onChangeCoverAvatar, + introduceUserProps: { + userInfo, + isEditField, + avatar, + onDeniedAvatar, + onConfirmAvatar, + showMenu, + hideMenu, + visibleMenu, + openGallery, + onChangeCoverAvatar, + }, + }; +} diff --git a/src/screens/profile/profileSlice.js b/src/screens/profile/profileSlice.js new file mode 100644 index 0000000..e69de29 diff --git a/src/screens/profile/style.js b/src/screens/profile/style.js index 0ac9632..c9fccfc 100644 --- a/src/screens/profile/style.js +++ b/src/screens/profile/style.js @@ -6,6 +6,7 @@ const windowHeight = Dimensions.get('window').height; const styles = StyleSheet.create({ container: { flex: 1, + padding: 10, }, flexRow: { flexDirection: 'row', @@ -22,6 +23,7 @@ const styles = StyleSheet.create({ backgroundColor: colors.white, borderColor: colors.white, marginBottom: 10, + borderRadius: 5, }, viewCardProfile: { width: windowWidth - 20, @@ -29,7 +31,6 @@ const styles = StyleSheet.create({ borderWidth: 1, backgroundColor: colors.white, borderColor: colors.white, - marginBottom: 10, }, coverImage: { width: windowWidth - 20, @@ -83,9 +84,10 @@ const styles = StyleSheet.create({ height: windowHeight, }, viewInfo: { - width: windowWidth - 10, + width: '100%', alignSelf: 'center', borderWidth: 1, + borderRadius: 5, backgroundColor: colors.white, borderColor: colors.white, padding: 10, @@ -95,9 +97,10 @@ const styles = StyleSheet.create({ borderBottomColor: 'gray', borderBottomWidth: 1, marginBottom: 10, - padding: 10, + paddingHorizontal: 10, flexDirection: 'row', alignItems: 'center', + justifyContent: 'space-between', }, paddingView: { padding: 20, @@ -113,8 +116,7 @@ const styles = StyleSheet.create({ flexDirection: 'row', borderBottomWidth: 1, borderBottomColor: '#f6f6f6', - paddingBottom: 10, - paddingTop: 10, + paddingVertical: 10, }, btnSubmit: { backgroundColor: '#5d78ff', @@ -214,6 +216,21 @@ const styles = StyleSheet.create({ elevation: 5, flexDirection: 'row', }, + activeDot: { + backgroundColor: colors.purple_blue, + width: 25, + height: 8, + borderRadius: 4, + }, + avatarFrame: { + width: 100, + height: 100, + resizeMode: 'contain', + alignSelf: 'center', + borderRadius: 60, + zIndex: -100, + }, + infoView: {flexDirection: 'row', paddingVertical: 10}, }); export default styles; diff --git a/src/screens/profile/template/ProfileMainView.js b/src/screens/profile/template/ProfileMainView.js new file mode 100644 index 0000000..8176b9c --- /dev/null +++ b/src/screens/profile/template/ProfileMainView.js @@ -0,0 +1,216 @@ +import Moment from 'moment'; +import React from 'react'; +import { + Animated, + Image, + ImageBackground, + Modal, + SafeAreaView, + ScrollView, + TextInput, + TouchableOpacity, + View, +} from 'react-native'; +import Alert from 'react-native-awesome-alerts'; +import {GestureHandlerRootView, Swipeable} from 'react-native-gesture-handler'; +import {Menu, MenuItem} from 'react-native-material-menu'; +import DateTimePickerModal from 'react-native-modal-datetime-picker'; +import SelectDropdown from 'react-native-select-dropdown'; +import Swiper from 'react-native-swiper'; +import AppText from '../../../components/AppText'; +import ButtonComponent from '../../../components/ButtonComponent'; +import TextInputComponent from '../../../components/TextInputComponent'; +import { + IMAGES, + IcNotificationList, + IconProfile, + IconSocial, +} from '../../../values/images'; +import {default as string, default as strings} from '../../../values/string'; +import styles from '../style'; +import colors from '../../../values/colors'; +import config from '../../../config'; +import IntroduceUser from './components/IntroduceUser'; +import GeneralInformation from './components/GeneralInformation'; +import PersonalInformation from './components/PersonalInformation'; +import DetailInformation from './components/DetailInformation'; +const Socials = [ + 'FACEBOOK', + 'EMAIL', + 'SKYPE', + 'LINKEDIN', + 'TWITTER', + 'INSTAGRAM', + 'WHATSAPP', + 'VIPER', + 'SNAPCHAT', + 'TELEGRAM', + 'APPLE', + 'YOUTUBE', + 'PINTEREST', +]; +const gender = ['Nam', 'Nữ']; + +const ProfileMainView = ({ + userInfo, + contactUser, + btnAvailable, + isEditField, + navigateMain, + setEditField, + setBtnAvailable, + infoUser, + setInfoUser, + onSaveInfo, + avatar = [], + onDeniedAvatar, + onConfirmAvatar, + showMenu, + hideMenu, + visibleMenu, + openGallery, + isSlideShow, + showFullScreen, + hideFullScreen, + dateTimePicker, + hideDateTimePicker, + setDateTimePicker, + showAlert, + onSubmitChangeContactUser, + onChangeDropDownContactUser, + onChangeInputContactUser, + onPressDeleteItem, + onPressAddItem, + onCancelAlert, + modalVisible, + setModalVisible, + setUserInputContact, + userInputContact, + onSubmitCreateNew, + onConfirmDeleteAlert, + navigateToLogout, + onChangeCoverAvatar, + introduceUserProps, +}) => { + return ( + <SafeAreaView style={styles.container}> + <ScrollView nestedScrollEnabled={true}> + <IntroduceUser {...introduceUserProps} /> + + {/* General information */} + <GeneralInformation userInfo={userInfo} /> + {/* personal information */} + <PersonalInformation userInfo={userInfo} /> + {/* detail information */} + <DetailInformation userInfo={userInfo} /> + {/* Logout Btn */} + <View + style={{ + justifyContent: 'center', + alignItems: 'center', + marginTop: 10, + }}> + <ButtonComponent + text={'Äăng xuất'} + style={{marginBottom: 10, flexDirection: 'row'}} + rightIcon={IMAGES.IcLogout} + styleIcon={{width: 20, height: 20, marginLeft: 10}} + onPress={navigateToLogout} + /> + </View> + {/* <View style={styles.centeredView}> + <Modal + animationType="slide" + transparent={true} + visible={modalVisible} + onRequestClose={() => { + Alert.alert('Modal has been closed.'); + setModalVisible(!modalVisible); + }}> + <View style={styles.centeredView}> + <View style={styles.modalView}> + <View style={{flexDirection: 'row'}}> + <View style={{flex: 1}}> + <SelectDropdown + data={Socials} + dropdownIconPosition={'right'} + defaultButtonText={'Loại liên hệ'} + buttonStyle={styles.dropdown1BtnStyle} + onSelect={(selectedItem, item_index) => + setUserInputContact(prev => ({ + ...prev, + type: selectedItem, + })) + } + dropdownStyle={styles.dropdown1DropdownStyle} + rowStyle={styles.dropdown1RowStyle} + rowTextStyle={styles.dropdown1RowTxtStyle} + buttonTextStyle={styles.dropdown1BtnTxtStyle} + renderDropdownIcon={isOpened => { + return ( + <Image + source={ + isOpened ? IMAGES.IcUpArrow : IMAGES.IcDownArrow + } + style={{width: 20, height: 20}} + /> + ); + }} + /> + {userInputContact.type.length <= 0 && ( + <AppText style={{fontSize: 12, color: 'red'}}> + {' '} + Vui lòng chá»n liên hệ + </AppText> + )} + </View> + <View style={{flex: 1}}> + <TextInput + style={{borderBottomWidth: 0.2}} + placeholder={'Nháºp F'} + keyboardType={'email-address'} + autoCapitalize="none" + value={userInputContact.text} + onChangeText={text => + setUserInputContact(prev => ({ + ...prev, + text: text, + })) + } + /> + {userInputContact.text.length <= 0 && ( + <AppText style={{fontSize: 12, color: 'red'}}> + {' '} + Vui lòng nháºp liên hệ + </AppText> + )} + </View> + </View> + <View style={{flexDirection: 'row', marginTop: 20}}> + <ButtonComponent + text={'Äóng'} + textStyle={styles.textStyle} + style={[ + styles.button, + styles.buttonClose, + {marginRight: 15}, + ]} + onPress={() => setModalVisible(!modalVisible)} + /> + <ButtonComponent + text={'Thêm má»›i'} + textStyle={styles.textStyle} + style={[styles.button, styles.buttonClose]} + onPress={onSubmitCreateNew} + /> + </View> + </View> + </View> + </Modal> + </View> */} + </ScrollView> + </SafeAreaView> + ); +}; + +export default ProfileMainView; diff --git a/src/screens/profile/template/components/DetailInformation.js b/src/screens/profile/template/components/DetailInformation.js new file mode 100644 index 0000000..a9ba3d5 --- /dev/null +++ b/src/screens/profile/template/components/DetailInformation.js @@ -0,0 +1,119 @@ +import React, {memo} from 'react'; +import {Image, TouchableOpacity, View} from 'react-native'; +import AppText from '../../../../components/AppText'; +import {IMAGES} from '../../../../values/images'; +import string from '../../../../values/string'; +import styles from '../../style'; +import commonStyles from '../../../../styles/commonStyles'; +import moment from 'moment'; + +const DetailInformation = React.memo( + ({userInfo}) => { + const personalInfo = [ + { + name: 'Số CMND', + value: userInfo?.id_card_number || '', + icon: IMAGES.IcInfoGuess, + width: '50%', + }, + { + name: 'Ngà y cấp CMND', + value: moment(userInfo?.id_card_issue_date).format('dd/MM/YYYY') || '', + icon: IMAGES.IcInfoGuess, + width: '50%', + }, + { + name: 'NÆ¡i cấp CMND', + value: userInfo?.id_card_issue_palce || '', + icon: IMAGES.IcInfoGuess, + width: '50%', + }, + { + name: 'Ngà y sinh', + value: userInfo?.birthday ? 'Nam' : 'Nữ', + icon: IMAGES.IcInfoGuess, + width: '50%', + }, + { + name: 'Nguyên quán', + value: userInfo?.domicile || '', + icon: IMAGES.IcPhone, + width: '50%', + }, + { + name: 'NÆ¡i sinh', + value: userInfo?.birthplace || '', + icon: IMAGES.IcPhone, + width: '50%', + }, + { + name: 'Tôn giáo', + value: userInfo?.religion || '', + icon: IMAGES.IcMailGray, + width: '50%', + }, + { + name: 'Dân tá»™c', + value: userInfo?.ethnic || '', + icon: IMAGES.IcMailGray, + width: '50%', + }, + { + name: 'MST cá nhân', + value: userInfo?.personal_tax_code || '', + icon: IMAGES.IcCalendarGray, + width: '50%', + }, + { + name: 'Quốc tịch', + value: userInfo?.nationality || '', + icon: IMAGES.IcMailGray, + width: '50%', + }, + { + name: 'Äịa chỉ liên hệ', + value: userInfo?.address || '', + icon: IMAGES.IcLocationGray, + width: '50%', + }, + { + name: 'Äịa chỉ thÆ°á»ng trú', + value: userInfo?.permanent_address || '', + icon: IMAGES.IcLocationGray, + width: '100%', + }, + ]; + return ( + <View style={[styles.viewInfo]}> + <View style={styles.viewTitle}> + <AppText style={{fontSize: 17}}> + {string.PERSONAL_INFORMATION} + </AppText> + <View> + <TouchableOpacity> + <Image source={IMAGES.IcEdit} style={{height: 30, width: 30}} /> + </TouchableOpacity> + </View> + </View> + <View style={[commonStyles.row, {flexWrap: 'wrap'}]}> + {personalInfo.map(item => ( + <View + key={item.name} + style={[styles.infoView, {width: item.width}]}> + <Image source={item.icon} style={{width: 20, height: 20}} /> + <View style={{marginLeft: 5}}> + <AppText>{item.name}</AppText> + <AppText isSubText>{item?.value}</AppText> + </View> + </View> + ))} + </View> + </View> + ); + }, + function (prevProps, nextProps) { + return prevProps.userInfo === nextProps.userInfo; + }, +); + +export default memo(DetailInformation); diff --git a/src/screens/profile/template/components/GeneralInformation.js b/src/screens/profile/template/components/GeneralInformation.js new file mode 100644 index 0000000..31d2b99 --- /dev/null +++ b/src/screens/profile/template/components/GeneralInformation.js @@ -0,0 +1,64 @@ +import React, {memo} from 'react'; +import {Image, View} from 'react-native'; +import AppText from '../../../../components/AppText'; +import {IMAGES} from '../../../../values/images'; +import styles from '../../style'; +import string from '../../../../values/string'; +import commonStyles from '../../../../styles/commonStyles'; + +const GeneralInformation = React.memo( + ({userInfo}) => { + return ( + <View style={[styles.viewInfo, commonStyles.baseShadow]}> + <View style={styles.viewTitle}> + <AppText style={{color: 'black', fontSize: 18}}> + {string.GENERAL_INFORMATION} + </AppText> + </View> + <View style={{flexDirection: 'row', justifyContent: 'space-between'}}> + <View style={{flexDirection: 'row'}}> + <Image source={IMAGES.IcUser} style={{height: 45, width: 45}} /> + <View style={{marginLeft: 5}}> + <AppText>{string.USER_ID}</AppText> + <AppText style={{color: 'black', fontSize: 15}}> + {userInfo?.employee_code} + </AppText> + </View> + </View> + <View style={{flexDirection: 'row'}}> + <Image source={IMAGES.IcCheck} style={{height: 45, width: 45}} /> + <View style={{marginLeft: 5}}> + <AppText>{string.TIME_ATTENDANCE_CODE}</AppText> + <AppText style={{color: 'black', fontSize: 15}}> + {userInfo?.employee_code} + </AppText> + </View> + </View> + </View> + <View style={{flexDirection: 'row', marginTop: 10}}> + <Image source={IMAGES.IcCalendar} style={{height: 45, width: 45}} /> + <View style={{marginLeft: 5}}> + <AppText>{string.SHIFT}</AppText> + <AppText style={{color: 'black', fontSize: 15}}> + Meu Official working time + </AppText> + </View> + </View> + <View style={{flexDirection: 'row', marginTop: 10}}> + <Image source={IMAGES.IcUserTag} style={{height: 45, width: 45}} /> + <View style={{marginLeft: 5}}> + <AppText>{string.STATUS}</AppText> + <AppText style={{color: 'black', fontSize: 15}}> + Nhân viên chÃnh thức + </AppText> + </View> + </View> + </View> + ); + }, + function (prevProps, nextProps) { + return prevProps.userInfo === nextProps.userInfo; + }, +); + +export default memo(GeneralInformation); diff --git a/src/screens/profile/template/components/IntroduceUser.js b/src/screens/profile/template/components/IntroduceUser.js new file mode 100644 index 0000000..5e96755 --- /dev/null +++ b/src/screens/profile/template/components/IntroduceUser.js @@ -0,0 +1,174 @@ +import React from 'react'; +import {Image, ImageBackground, TouchableOpacity, View} from 'react-native'; +import {Menu, MenuItem} from 'react-native-material-menu'; +import Swiper from 'react-native-swiper'; +import AppText from '../../../../components/AppText'; +import ButtonComponent from '../../../../components/ButtonComponent'; +import config from '../../../../config'; +import colors from '../../../../values/colors'; +import {IMAGES} from '../../../../values/images'; +import styles from '../../style'; +import commonStyles from '../../../../styles/commonStyles'; + +const CardInfo = React.memo( + ({userInfo}) => { + return ( + <ImageBackground + source={IMAGES.BgProfileCard} + style={[ + styles.viewCardProfile, + { + borderRadius: 10, + paddingTop: 30, + }, + ]} + resizeMode="cover"> + <View style={{position: 'absolute', left: 15, top: 10}}> + <Image source={IMAGES.ImageQrCode} style={{height: 45, width: 45}} /> + </View> + <ImageBackground source={IMAGES.BgFrame} style={styles.imgFrame}> + <Image + source={ + userInfo?.avatar + ? {uri: config.imageEndPoint + userInfo?.avatar} + : IMAGES.IcAvatarDefault + } + style={styles.avatarFrame} + /> + </ImageBackground> + <View style={[commonStyles.centerView, commonStyles.marginVertical10]}> + {userInfo?.position && <AppText>{userInfo?.position}</AppText>} + <AppText style={{fontSize: 18, fontWeight: 'bold'}}> + {`${userInfo?.first_name} ${ + userInfo?.middle_name ? userInfo?.middle_name : '' + } ${userInfo?.last_name} `} + </AppText> + {userInfo?.email && ( + <View style={{flexDirection: 'row', marginTop: 10}}> + <View style={{flex: 1, alignItems: 'flex-end', paddingRight: 5}}> + <Image + source={IMAGES.IconMailGrey} + style={{height: 25, width: 25}} + /> + </View> + <AppText style={{flex: 2}}>{userInfo?.email}</AppText> + </View> + )} + {userInfo?.cell_phone && ( + <View style={{flexDirection: 'row', marginTop: 10}}> + <View style={{flex: 1, alignItems: 'flex-end', paddingRight: 5}}> + <Image + source={IMAGES.IcPhoneGrey} + style={{height: 25, width: 25}} + /> + </View> + <AppText style={{flex: 2, color: 'black'}}> + {userInfo?.cell_phone} + </AppText> + </View> + )} + </View> + <View + style={[ + commonStyles.row, + { + justifyContent: 'space-evenly', + }, + ]}> + <AppText style={{fontWeight: 'bold'}}>#willing-to-do</AppText> + <AppText style={{fontWeight: 'bold'}}>#passion</AppText> + <AppText style={{fontWeight: 'bold'}}>#hard-working</AppText> + </View> + </ImageBackground> + ); + }, + function (prevProps, nextProps) { + return prevProps.userInfo === nextProps.userInfo; + }, +); +const IntroduceUser = props => { + const { + userInfo, + isEditField, + avatar = [], + onDeniedAvatar, + onConfirmAvatar, + showMenu, + hideMenu, + visibleMenu, + openGallery, + onChangeCoverAvatar, + } = props; + return ( + <Swiper + style={[commonStyles.baseShadow, {height: 380}]} + showsButtons={false} + loop={false} + showsPagination={true} + activeDot={<View style={styles.activeDot} />}> + <View style={styles.viewImageProfile}> + <ImageBackground + source={ + userInfo?.cover_image + ? { + uri: config.imageEndPoint + userInfo?.cover_image, + } + : IMAGES.ImageCoverBg + } + style={styles.coverImage}> + <ButtonComponent + iconSource={IMAGES.IcChangeCoverImage} + styleIcon={{height: 20, width: 20}} + style={{marginRight: 15, marginBottom: 10}} + onPress={onChangeCoverAvatar} + /> + </ImageBackground> + <TouchableOpacity onPress={showMenu} style={styles.viewAvatar}> + {avatar.length > 0 ? ( + <Image source={{uri: avatar[0].uri}} style={styles.imgAvatar} /> + ) : ( + <Image + source={ + userInfo?.avatar + ? {uri: config.imageEndPoint + userInfo?.avatar} + : IMAGES.IcAvatarDefault + } + style={styles.imgAvatar} + /> + )} + + {/* menu option */} + <View style={{justifyContent: 'center', alignItems: 'center'}}> + <Menu visible={visibleMenu} onRequestClose={hideMenu}> + <MenuItem onPress={openGallery}> + <AppText>Äổi hình ná»n</AppText> + </MenuItem> + </Menu> + </View> + </TouchableOpacity> + {isEditField.avatar && ( + <View style={{flexDirection: 'row', justifyContent: 'space-around'}}> + <TouchableOpacity onPress={onDeniedAvatar}> + <Image source={IMAGES.IcDenied} style={{width: 25, height: 25}} /> + </TouchableOpacity> + <TouchableOpacity onPress={onConfirmAvatar}> + <Image + source={IMAGES.IcCheckMark} + style={{width: 25, height: 25}} + /> + </TouchableOpacity> + </View> + )} + <AppText style={{fontSize: 18}}> + {`${userInfo?.first_name} ${ + userInfo?.middle_name ? userInfo?.middle_name : '' + } ${userInfo?.last_name} (${userInfo?.employee_code})`}{' '} + </AppText> + <AppText style={{marginBottom: 20}}>{userInfo?.position}</AppText> + </View> + <CardInfo userInfo={userInfo} /> + </Swiper> + ); +}; + +export default IntroduceUser; diff --git a/src/screens/profile/template/components/PersonalInformation.js b/src/screens/profile/template/components/PersonalInformation.js new file mode 100644 index 0000000..36047c2 --- /dev/null +++ b/src/screens/profile/template/components/PersonalInformation.js @@ -0,0 +1,82 @@ +import React, {memo} from 'react'; +import {Image, TouchableOpacity, View} from 'react-native'; +import AppText from '../../../../components/AppText'; +import {IMAGES} from '../../../../values/images'; +import string from '../../../../values/string'; +import styles from '../../style'; +import commonStyles from '../../../../styles/commonStyles'; + +const PersonalInformation = React.memo( + ({userInfo}) => { + const personalInfo = [ + { + name: 'Há»', + value: userInfo?.first_name || '', + icon: IMAGES.IcInfoGuess, + width: '50%', + }, + { + name: 'Tên lót', + value: userInfo?.middle_name || '', + icon: IMAGES.IcInfoGuess, + width: '50%', + }, + { + name: 'Tên', + value: userInfo?.last_name || '', + icon: IMAGES.IcInfoGuess, + width: '50%', + }, + { + name: 'Giá»›i tÃnh', + value: userInfo?.gender ? 'Nam' : 'Nữ', + icon: IMAGES.IcInfoGuess, + width: '50%', + }, + { + name: 'Số Ä‘iện thoại', + value: userInfo?.cell_phone || '', + icon: IMAGES.IcPhone, + width: '100%', + }, + { + name: 'Email', + value: userInfo?.email || '', + icon: IMAGES.IcMailGray, + width: '100%', + }, + ]; + return ( + <View style={[styles.viewInfo]}> + <View style={styles.viewTitle}> + <AppText style={{fontSize: 17}}> + {string.PERSONAL_INFORMATION} + </AppText> + <View> + <TouchableOpacity> + <Image source={IMAGES.IcEdit} style={{height: 30, width: 30}} /> + </TouchableOpacity> + </View> + </View> + <View style={[commonStyles.row, {flexWrap: 'wrap'}]}> + {personalInfo.map(item => ( + <View + key={item.name} + style={[styles.infoView, {width: item.width}]}> + <Image source={item.icon} style={{width: 20, height: 20}} /> + <View style={{marginLeft: 5}}> + <AppText>{item.name}</AppText> + <AppText isSubText>{item?.value}</AppText> + </View> + </View> + ))} + </View> + </View> + ); + }, + function (prevProps, nextProps) { + return prevProps.userInfo === nextProps.userInfo; + }, +); + +export default memo(PersonalInformation); diff --git a/src/styles/commonStyles.js b/src/styles/commonStyles.js index 856c8cb..929b11f 100644 --- a/src/styles/commonStyles.js +++ b/src/styles/commonStyles.js @@ -27,5 +27,6 @@ const commonStyles = StyleSheet.create({ marginVertical20: { marginVertical: 20, }, + centerView: {justifyContent: 'center', alignItems: 'center'}, }); export default commonStyles; -- 2.18.1