/* eslint-disable prettier/prettier */ import CheckBox from '@react-native-community/checkbox'; import Moment from 'moment'; import React, {useEffect, useState} from 'react'; import { Dimensions, Image, KeyboardAvoidingView, Modal, SafeAreaView, ScrollView, StyleSheet, TextInput, TouchableOpacity, View, } from 'react-native'; import Toast from 'react-native-toast-message'; import {useDispatch, useSelector} from 'react-redux'; import AppText from '../../../components/AppText'; import ButtonComponent from '../../../components/ButtonComponent'; import { deleteLeaveTicket, getCommentByCode, getImageByCode, getUserLeaveHistories, postApproveLeaveDay, postComment, postRejectLeaveDay, } from '../../../store/actions/UserAction'; import colors from '../../../values/colors'; import {IMAGES} from '../../../values/images'; const OnLeaveModalDetail = ({ alertMessage, onClose, detailItem, userDetails, setPayloadApproveLeaves, }) => { const dispatch = useDispatch(); //console.log('detailItem', detailItem); const userDirectManagersList = useSelector( state => state.MyDirectManagers.myDirectManagers, ); const initStateLeave = { id: '', since: new Date(), timeStart: '', dateStart: '', toDate: new Date(), timeFinish: '', dateFinish: '', reason: '', taken_hours: 0, approved_date: new Date(), approver_id: '', }; const initComment = { code: '', content: '', }; // STATE const [detailImage, setDetailImage] = useState([]); const [leave, setLeave] = useState(initStateLeave); const [leaveDayDetail, setLeaveDayDetail] = useState(null); const [leaveHistories, setLeaveHistories] = useState([]); const [leaveComment, setLeaveComment] = useState([]); const [comment, setComment] = useState(initComment); const [userManagerList, setUserManagerList] = useState([]); const [commentApprove, setCommentApprove] = useState(''); const [isNextApprover, setIsNextApprover] = useState(false); const [nextApproverId, setNextApproverId] = useState(''); // main function const onOpenDetailLeave = async () => { const objectClone = JSON.parse(JSON.stringify(userDirectManagersList)); let obj = []; objectClone.forEach(element => { element.checked = false; obj.push(element); }); setUserManagerList(obj); setLeaveDayDetail(detailItem); if (detailItem) { const responseHistories = await dispatch( getUserLeaveHistories(detailItem.id), ); setLeaveHistories(responseHistories); const responseComment = await dispatch(getCommentByCode(detailItem.id)); setLeaveComment(responseComment); const responseImage = await dispatch(getImageByCode(detailItem.id)); setDetailImage(responseImage); } }; const onSelectManager = async (value, index, item) => { let userManagerListClone = [...userManagerList]; let elementFound = userManagerListClone.find( element => element.id == item.id, ); let indexElementFound = userManagerListClone.findIndex( element => element.id == item.id, ); userManagerListClone.splice(indexElementFound, 1, { ...elementFound, checked: value, }); setUserManagerList(userManagerListClone); setLeave(state => ({ ...state, approver_id: item.id, })); if (isNextApprover) { setNextApproverId(item.id); } else { setNextApproverId(''); setLeave(state => ({ ...state, approver_id: item.id, })); } }; const onSubmitComment = async () => { if (comment.content) { const res = await dispatch(postComment(comment)); if (res) { setComment(initComment); const responseComment = await dispatch(getCommentByCode(comment.code)); setLeaveComment(responseComment); return; } } }; const onRejectRequest = async id => { const res = await dispatch(postRejectLeaveDay(id, commentApprove)); if (res) { Toast.show({ type: 'success', text1: `Hệ thống`, text2: `Thành công!`, styles: {zIndex: 1000}, }); refreshAfterSubmit(); } else { Toast.show({ type: 'success', text1: `Hệ thống`, text2: `Không thành công!`, styles: {zIndex: 1000}, }); } onClose(null); }; const onApproveRequest = async id => { const res = await dispatch( postApproveLeaveDay(id, commentApprove, nextApproverId), ); if (res) { Toast.show({ type: 'success', text1: `Hệ thống`, text2: `Thành công!`, styles: {zIndex: 1000}, }); refreshAfterSubmit(); } else { Toast.show({ type: 'success', text1: `Hệ thống`, text2: `Không thành công!`, styles: {zIndex: 1000}, }); } onClose(null); }; const refreshAfterSubmit = () => { setLeave(initStateLeave); setComment(initComment); setCommentApprove(''); setDetailImage(null); setLeaveDayDetail(null); setIsNextApprover(false); setUserManagerList([]); setPayloadApproveLeaves(prev => ({...prev, isRefresh: true})); }; const deleteItem = async () => { const res = await dispatch(deleteLeaveTicket(detailItem.id)); if (res) { onClose(null); Toast.show({ type: 'success', text1: `Hệ thống`, text2: `Hủy yêu cầu thành công 💓`, visibilityTime: 2000, style: {zIndex: 1001}, }); } else { onClose(null); Toast.show({ type: 'error', text1: `Hệ thống`, text2: `Hủy yêu cầu thất bại 💔`, visibilityTime: 2000, style: {zIndex: 1001}, }); } //console.log('deleteItem', detailItem); }; useEffect(() => { onOpenDetailLeave(); }, []); return ( <Modal animationType="slide" transparent={true} visible={true} onRequestClose={() => onClose(null)}> <SafeAreaView> <ScrollView> <View style={styles.modalViewEdit}> <View style={styles.headerModalBottom}> <AppText style={styles.titleModalBottom}> Chi tiết nghỉ phép </AppText> <TouchableOpacity onPress={() => onClose(null)}> <Image style={{height: 20, width: 20}} source={IMAGES.IcClose} /> </TouchableOpacity> </View> <View style={styles.bodyHeight}> <View style={styles.bodyModal}> <View style={{flexDirection: 'row'}}> <Image source={{ uri: 'https://meu.anawork.com' + leaveDayDetail?.extend_creator_avatar, }} style={{width: 40, height: 40, borderRadius: 2}} /> <View style={{ justifyContent: 'space-around', marginLeft: 16, }}> <AppText style={{fontSize: 14, fontWeight: '600'}}> {leaveDayDetail?.extend_creator_full_name} -{' '} {leaveDayDetail?.extend_creator_employee_code} </AppText> <AppText> {leaveDayDetail?.extend_creator_department} </AppText> </View> </View> {leaveDayDetail && ( <View style={{marginTop: 16}}> <AppText style={{ fontWeight: '500', fontSize: 14, marginBottom: 12, }}> Thông tin chung </AppText> <View style={styles.commonDetail}> <AppText style={styles.textMediumGrey}> Loại nghỉ phép </AppText> <AppText>{leaveDayDetail.extend_category_name}</AppText> </View> <View style={styles.commonDetail}> <AppText style={styles.textMediumGrey}>Từ ngày</AppText> <AppText> {Moment(leaveDayDetail.start).format( 'DD/MM/YYYY hh:mm', )} </AppText> </View> <View style={styles.commonDetail}> <AppText style={styles.textMediumGrey}>Đến ngày</AppText> <AppText> {Moment(leaveDayDetail.finish).format( 'DD/MM/YYYY hh:mm', )} </AppText> </View> <View style={styles.commonDetail}> <AppText style={styles.textMediumGrey}> Thời gian nghỉ </AppText> <AppText>{leaveDayDetail.extend_taken_days} ngày</AppText> </View> <View style={styles.commonDetail}> <AppText style={styles.textMediumGrey}>Lý do</AppText> <AppText style={[styles.reason]}> {leaveDayDetail.reason} </AppText> </View> <View style={styles.commonDetail}> <AppText style={[styles.textMediumGrey, {fontSize: 12}]}> Tệp đính kèm </AppText> <View style={styles.attachment}> { //physical_path.slice(30) detailImage?.length > 0 && detailImage.map((item, index) => ( <AppText key={index} numberOfLines={1} style={{fontSize: 13, color: '#5d78ff'}}> {item.file_name} </AppText> )) } {detailImage?.length == 0 && ( <AppText style={{fontSize: 13, color: '#757575'}}> Không có tệp đính kèm </AppText> )} </View> </View> </View> )} <View style={{marginTop: 16}}> <AppText style={{ fontWeight: '500', fontSize: 14, marginBottom: 12, }}> Lịch sử duyệt </AppText> {leaveHistories.length > 0 && leaveHistories.map((item, index) => ( <View key={index} style={{flexDirection: 'row'}}> <Image source={{ uri: 'https://meu.anawork.com' + item.extend_approver_avatar, }} style={styles.avatarApprove} /> <View> <View style={{ flexDirection: 'row', justifyContent: 'space-between', width: '83%', }}> <View style={{ justifyContent: 'space-between', marginLeft: 8, }}> <AppText> {item.extend_approver_full_name} </AppText> <View style={{flexDirection: 'row'}}> {item.extend_approved_status_name == 'APPROVED' && ( <Image style={{height: 16, width: 16}} source={IMAGES.uCheck} /> )} {item.extend_approved_status_name == 'PENDING' && <Image source={IMAGES.uMinus} />} {item.extend_approved_status_name == 'REJECTED' && ( <Image source={IMAGES.IcReject} style={{ height: 12, width: 12, alignSelf: 'center', }} /> )} <AppText style={{ color: item.extend_approved_status_color, fontStyle: 'italic', fontSize: 12, }}> {(item.extend_approved_status_name == 'APPROVED' && 'Đã duyệt') || (item.extend_approved_status_name == 'PENDING' && 'Đang chờ') || 'Đã từ chối'} </AppText> </View> </View> <AppText style={{fontSize: 12, color: '#959595'}}> {Moment(item.created_at).format('DD/MM/YYYY')} </AppText> </View> <View style={{marginLeft: 8}}> <AppText style={{fontSize: 13, color: '#757575'}}> {item.comment ? item.comment : ''} </AppText> </View> </View> </View> ))} {leaveDayDetail?.extend_approved_status_name == 'PENDING' && leaveDayDetail?.approver_id == userDetails.id && ( <View style={{flexDirection: 'row'}}> <Image source={{ uri: 'https://meu.anawork.com' + userDetails.avatar, }} style={styles.avatarApprove} /> <View> <View style={{ flexDirection: 'row', justifyContent: 'space-between', width: '83%', }}> <View style={{ justifyContent: 'space-between', marginLeft: 8, }}> <AppText> {leaveDayDetail.extend_approver_full_name} </AppText> <View style={{flexDirection: 'row'}}> {leaveDayDetail.extend_approved_status_name == 'APPROVED' ? ( <Image style={{height: 16, width: 16}} source={IMAGES.uCheck} /> ) : ( <Image source={IMAGES.uMinus} /> )} <AppText style={{ color: leaveDayDetail.extend_approved_status_color, fontStyle: 'italic', fontSize: 12, }}> {(leaveDayDetail.extend_approved_status_name == 'APPROVED' && 'Đã duyệt') || (leaveDayDetail.extend_approved_status_name == 'PENDING' && 'Đang chờ') || 'Đã từ chối'} </AppText> </View> </View> <AppText style={{fontSize: 12, color: '#959595'}}> {Moment().format('DD/MM/YYYY')} </AppText> </View> <View style={{marginLeft: 8}}> <View style={styles.wrapperComment}> <KeyboardAvoidingView behavior={ Platform.OS === 'ios' ? 'padding' : 'height' }> <TextInput placeholder="Nhập lý do tại đây" style={styles.commentInput} multiline value={commentApprove} onChangeText={text => { setCommentApprove(text); }} /> </KeyboardAvoidingView> </View> </View> </View> </View> )} </View> {leaveDayDetail?.approver_id == userDetails.id && ( <View style={{ marginTop: 12, flexDirection: 'row', alignItems: 'center', }}> <CheckBox boxType="square" animationDuration={0.3} value={isNextApprover} onValueChange={value => setIsNextApprover(value)} /> <AppText style={{ fontSize: 14, color: '#434349', marginLeft: 4, }}> Chọn người duyệt tiếp theo </AppText> </View> )} {isNextApprover && userManagerList.map((item, index) => ( <View key={index} style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginTop: 12, }}> <Image source={{ uri: 'https://meu.anawork.com' + item.avatar, }} style={styles.avatarApprove} /> <AppText style={{ fontSize: 16, fontWeight: '500', marginLeft: 10, }}>{`${item.extend_user_full_name}`}</AppText> <CheckBox disabled={false} value={item.checked} onValueChange={newValue => onSelectManager(newValue, index, item) } boxType="square" animationDuration={0.3} /> </View> ))} <View style={{marginTop: 16}}> <AppText style={{ fontWeight: '500', fontSize: 14, marginBottom: 12, }}> Bình luận </AppText> {/*others comment*/} {leaveComment && leaveComment.map((item, index) => ( <View style={styles.commentHistories} key={index}> <Image source={{ uri: 'https://meu.anawork.com' + item.extend_staff_avatar, }} style={styles.avatarComment} /> <View style={styles.commentBox}> <View style={{ flexDirection: 'row', justifyContent: 'space-between', }}> <AppText style={{ color: '#434349', fontSize: 12, fontWeight: '500', }}> {item.extend_staff_full_name} </AppText> <AppText style={{color: '#959595', fontSize: 10}}> {Moment(item.created_at).format( 'DD/MM/YYYY hh:mm', )} </AppText> </View> <AppText style={{ color: '#666666', fontSize: 13, marginTop: 8, }}> {item.content} </AppText> </View> </View> ))} {/*my comment*/} <View style={[styles.commentHistories, {marginTop: 16}]}> <Image source={{ uri: 'https://meu.anawork.com' + userDetails.avatar, }} style={styles.avatarComment} /> <View style={{width: '88%', position: 'relative'}}> <TextInput style={styles.commentText} multiline placeholder="Nhập bình luận ở đây" onChangeText={text => { setComment({ content: text, code: leaveDayDetail.id, }); }} value={comment.content} /> <View style={{position: 'absolute', right: 0, top: 10}}> <TouchableOpacity onPress={onSubmitComment}> <Image style={{height: 16, width: 16, marginRight: 4}} source={IMAGES.IcSend} /> </TouchableOpacity> </View> </View> </View> </View> </View> </View> <View style={styles.bottomModal}> <TouchableOpacity style={styles.btnCancel} onPress={() => onClose(null)}> <AppText style={{color: '#5d78ff', fontSize: 14, fontWeight: '500'}}> Hủy </AppText> </TouchableOpacity> {leaveDayDetail && leaveDayDetail?.approver_id !== userDetails.id && detailItem.extend_approved_status_name === 'PENDING' && ( <ButtonComponent style={{flexDirection: 'row', alignItems: 'center'}} text={'Xóa yêu cầu'} textStyle={{ color: '#ff0a3a', fontSize: 14, fontWeight: '500', }} leftIcon={IMAGES.IcReject} styleIcon={{height: 15, width: 15, marginRight: 4}} onPress={deleteItem} /> )} {leaveDayDetail?.approver_id === userDetails.id && leaveDayDetail?.extend_approved_status_name == 'PENDING' && ( <View style={{flexDirection: 'row'}}> <TouchableOpacity style={styles.btnReject} onPress={() => { onRejectRequest(leaveDayDetail.id); }}> <Image style={{height: 16, width: 16, marginRight: 4}} source={IMAGES.IcReject} /> <AppText style={{ color: '#ff0a3a', fontSize: 14, fontWeight: '500', }}> Từ chối </AppText> </TouchableOpacity> <TouchableOpacity style={styles.btnAccept} onPress={() => { onApproveRequest(leaveDayDetail.id); }}> <Image style={{height: 16, width: 16, marginRight: 4}} source={IMAGES.IcAccept} /> <AppText style={{ color: 'white', fontSize: 14, fontWeight: '500', }}> Duyệt yêu cầu </AppText> </TouchableOpacity> </View> )} </View> </View> </ScrollView> </SafeAreaView> </Modal> ); }; const windowWidth = Dimensions.get('window').width; const windowHeight = Dimensions.get('window').height; const styles = StyleSheet.create({ container: { flex: 1, }, primary_blue: { color: '#5d78ff', }, item: { padding: 20, marginVertical: 2, marginHorizontal: 16, borderWidth: 1, borderBottomColor: '#f2f2f2', borderTopColor: '#f2f2f2', borderRightColor: '#f2f2f2', borderRadius: 8, borderLeftWidth: 3, flexDirection: 'row', }, title: { fontWeight: '500', fontSize: 16, color: 'black', }, centeredView: { justifyContent: 'center', alignItems: 'center', marginTop: 22, }, modalView: { backgroundColor: 'white', borderRadius: 20, padding: 16, shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.25, shadowRadius: 4, elevation: 5, marginTop: 20, // height: windowHeight, }, modalViewEdit: { backgroundColor: 'white', borderRadius: 20, padding: 16, // height: windowHeight, shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.25, shadowRadius: 4, elevation: 5, marginTop: 20, minHeight: windowHeight, }, button: { borderRadius: 20, padding: 10, elevation: 2, }, buttonOpen: { backgroundColor: '#F194FF', }, buttonClose: { backgroundColor: '#2196F3', }, textStyle: { color: 'white', fontWeight: 'bold', textAlign: 'center', }, modalTitle: { fontWeight: '500', fontSize: 16, }, dropdown1DropdownStyle: {backgroundColor: '#EFEFEF'}, dropdown1RowStyle: { backgroundColor: '#EFEFEF', borderBottomColor: '#C5C5C5', height: 38, borderRadius: 4, }, dropdown1RowTxtStyle: {color: '#444', textAlign: 'left', fontSize: 14}, dropdownSelectTimeText: {color: '#444', textAlign: 'left', fontSize: 14}, dropdown1BtnStyle: { backgroundColor: '#FFF', borderBottomWidth: 0.2, height: 24, width: '100%', fontSize: 12, borderColor: '#444', }, dropdown1BtnTxtStyle: {color: '#000', fontSize: 14, textAlign: 'left'}, rowView: { flexDirection: 'row', marginTop: 10, justifyContent: 'space-between', alignItems: 'center', }, inputText: { backgroundColor: '#FFF', paddingLeft: 18, marginTop: 4, }, touchableOpacity: { borderColor: colors.primary_blue, borderStyle: 'dotted', borderWidth: 1, justifyContent: 'center', alignItems: 'center', height: 100, padding: 10, width: '35%', }, btnSubmit: { backgroundColor: '#5d78ff', justifyContent: 'center', alignItems: 'center', height: 40, borderRadius: 8, width: 100, }, btnCancel: { backgroundColor: colors.white, justifyContent: 'center', alignItems: 'center', height: 40, borderRadius: 8, width: 100, }, ImgAvatar: { width: 50, height: 50, borderRadius: 30, }, imgUpload: { resizeMode: 'contain', height: 90, width: 100, }, headerModalBottom: { paddingRight: 10, paddingLeft: 10, flexDirection: 'row', justifyContent: 'space-between', }, titleModalBottom: { fontSize: 16, fontWeight: '500', }, bodyModal: { // flex: 1, paddingHorizontal: 10, marginTop: 16, }, reason: { width: windowWidth / 2 - 25, textAlign: 'right', }, textMediumGrey: { color: '#757575', }, commonDetail: { flexDirection: 'row', justifyContent: 'space-between', fontSize: 14, marginBottom: 12, fontFamily: 'Roboto', }, attachment: { borderColor: '#c4c4c4', borderStyle: 'dashed', borderWidth: 0.5, borderRadius: 4, height: 60, width: '50%', justifyContent: 'center', alignItems: 'center', padding: 8, }, checkbox: { alignSelf: 'center', height: 16, width: 16, marginRight: 4, }, commentHistories: { flexDirection: 'row', marginBottom: 10, }, avatarApprove: { width: 32, height: 32, borderRadius: 4, }, avatarComment: { width: 32, height: 32, borderRadius: 32, }, commentBox: { backgroundColor: '#e5eaf0', width: '88%', marginLeft: 8, paddingHorizontal: 12, paddingVertical: 8, borderTopRightRadius: 4, borderBottomRightRadius: 4, borderBottomLeftRadius: 4, }, commentText: { marginLeft: 8, width: '100%', color: '#959595', fontSize: 12, borderBottomColor: '#5c65dc', borderBottomWidth: 1, paddingLeft: 8, paddingRight: 28, paddingVertical: 10, }, bottomModal: { width: '100%', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 8, marginTop: 20, // flex: 1 }, bodyHeight: { // flex: 2 }, btnAccept: { flexDirection: 'row', paddingHorizontal: 8, paddingVertical: 12, backgroundColor: '#5d78ff', borderRadius: 4, }, btnCancel: { paddingHorizontal: 8, paddingVertical: 12, }, btnReject: { flexDirection: 'row', paddingHorizontal: 8, paddingVertical: 12, marginRight: 8, }, wrapperComment: { borderColor: '#5d78ff', borderStyle: 'dashed', borderWidth: 0.5, borderRadius: 4, height: 60, width: '81%', padding: 8, }, commentInput: { fontSize: 13, }, takeTimeStyle: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-end', borderBottomColor: '#444', borderBottomWidth: 0.2, height: 24, }, }); export default OnLeaveModalDetail;