optimization leave screen

parent 32fb9014
......@@ -7,6 +7,7 @@ const confirmDateAPI = {
axiosClient.get(
`myAbsentApprovalRequests?Filters=${filter}&Sorts=${sort}&Page=${page}&PageSize=${pageSize}`,
),
requestGetAbsentChart: () => axiosClient.get('myAbsentRequests/statistic'),
};
export default confirmDateAPI;
......@@ -31,6 +31,7 @@ import {
deleteApproveConfirmDay,
} from '../../../store/actions/UserAction';
import AppText from '../../../components/AppText';
import Utils from '../../../utils';
const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;
const ConfirmModalAddNew = ({
......@@ -174,13 +175,7 @@ const ConfirmModalAddNew = ({
}
//console.log('deleteItem', detailItem);
};
const minutesToHours = (start, finish) => {
//console.log(start, finish);
let time = Moment(finish).diff(Moment(start), 'minutes');
var Hours = Math.floor(time / 60);
var minutes = time % 60;
return `${Hours}:${minutes} giờ`;
};
useEffect(() => {
onOpenDetail(detailItem);
}, []);
......@@ -271,7 +266,7 @@ const ConfirmModalAddNew = ({
Thi gian ngh
</AppText>
<AppText>
{minutesToHours(
{Utils.minutesToHours(
confirmDateDetail.start,
confirmDateDetail.finish,
)}
......
export default function confirmDatePropsProvider(props) {
const {
userInfo,
showAlert,
requestApproveArr,
confirmList,
isDisableLoadMore,
dataChart,
modalContent,
approveReqPayload,
dayPress,
modalRequestConfirmWorkingDays,
onChangeDayPressInChart,
onOpenDetailModal,
onOpenAddModal,
onLoadMoreConfirmList,
onHideAlert,
navigateToDayWage,
alertMessage,
onLoadMoreRequestApprove,
onRefreshApproveList,
onRefreshConfirmList,
onChangeSelectFilter,
onChangeMonthFilter,
minutesToHours,
onCloseModalRequestConfirmWorkingDays,
onOpenModalRequestConfirmWorkingDays,
} = props;
return {
userInfo,
showAlert,
requestApproveArr,
confirmList,
isDisableLoadMore,
dataChart,
modalContent,
approveReqPayload,
dayPress,
modalRequestConfirmWorkingDays,
onChangeDayPressInChart,
onOpenDetailModal,
onOpenAddModal,
onLoadMoreConfirmList,
onHideAlert,
navigateToDayWage,
alertMessage,
onLoadMoreRequestApprove,
onRefreshApproveList,
onRefreshConfirmList,
onChangeSelectFilter,
onChangeMonthFilter,
minutesToHours,
approveRequestWorkingDaysProps: {
approveReqPayload,
onChangeSelectFilter,
requestApproveArr,
onOpenDetailModal,
},
onCloseModalRequestConfirmWorkingDays,
onOpenModalRequestConfirmWorkingDays,
};
}
......@@ -33,6 +33,20 @@ export const getConfirmApprovedDate = createAsyncThunk(
});
},
);
export const getAbsentChart = createAsyncThunk(
'confirmDate/getAbsentChart',
async (data, thunkAPI) => {
return serviceRequest({
dispatch: thunkAPI.dispatch,
serviceMethod: confirmDateAPI.requestGetAbsentChart,
payload: data,
options: {
skipLoader: false,
},
});
},
);
const authSlice = createSlice({
name: 'confirmDate',
initialState: initialState,
......
......@@ -67,49 +67,42 @@ const styles = StyleSheet.create({
marginRight: 5,
},
view: {
width: windowWidth,
alignSelf: 'center',
borderWidth: 1,
width: windowWidth - 20,
backgroundColor: colors.white,
borderColor: colors.white,
padding: 10,
marginTop: 10,
marginHorizontal: 10,
borderRadius: 5,
},
btnConfirm: {
backgroundColor: '#5d78ff',
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
borderColor: '#5d78ff',
borderRadius: 8,
width: windowWidth - 100,
height: 35,
backgroundColor: colors.purple_blue,
borderRadius: 5,
flexDirection: 'row',
padding: 10,
},
whiteTxt: {
color: colors.white,
fontWeight: '500',
},
blueTxt: {
color: '#5d78ff',
color: colors.purple_blue,
fontWeight: '500',
},
iconPlus: {
width: 20,
height: 20,
marginRight: 10,
marginRight: 5,
},
primary_blue: {
color: '#5d78ff',
color: colors.purple_blue,
},
item: {
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
padding: 10,
margin: 8,
borderWidth: 1,
borderBottomColor: '#f2f2f2',
borderTopColor: '#f2f2f2',
borderRightColor: '#f2f2f2',
borderBottomColor: colors.gray95,
borderTopColor: colors.gray95,
borderRightColor: colors.gray95,
borderTopLeftRadius: 10,
borderBottomLeftRadius: 10,
borderLeftWidth: 5,
......@@ -203,7 +196,7 @@ const styles = StyleSheet.create({
width: 50,
},
btnSubmit: {
backgroundColor: '#5d78ff',
backgroundColor: colors.purple_blue,
justifyContent: 'center',
alignItems: 'center',
height: 40,
......@@ -336,7 +329,7 @@ const styles = StyleSheet.create({
paddingHorizontal: 8,
},
wrapperComment: {
borderColor: '#5d78ff',
borderColor: colors.purple_blue,
borderStyle: 'dashed',
borderWidth: 0.5,
borderRadius: 4,
......@@ -351,7 +344,7 @@ const styles = StyleSheet.create({
flexDirection: 'row',
paddingHorizontal: 8,
paddingVertical: 12,
backgroundColor: '#5d78ff',
backgroundColor: colors.purple_blue,
borderRadius: 4,
},
btnReject: {
......@@ -381,7 +374,7 @@ const styles = StyleSheet.create({
justifyContent: 'space-between',
alignItems: 'center',
borderBottomWidth: 1,
borderBottomColor: '#5d78ff',
borderBottomColor: colors.purple_blue,
paddingBottom: 5,
paddingLeft: 10,
paddingRight: 15,
......@@ -395,6 +388,19 @@ const styles = StyleSheet.create({
borderColor: '#7d93ff',
paddingTop: 15,
},
refreshBtn: {
justifyContent: 'center',
alignItems: 'center',
padding: 10,
flexDirection: 'row',
},
emptyConfirmWorkingDays: {
justifyContent: 'center',
alignItems: 'center',
backgroundColor: colors.white,
marginTop: 10,
padding: 20,
},
});
export const statisticsConfirmWorkdaysStyles = StyleSheet.create({
container: {
......
import Moment from 'moment';
import React, {memo} from 'react';
import {Image, View} from 'react-native';
import {IMAGES} from '../../../../values/images';
import {View} from 'react-native';
import styles, {statisticsConfirmWorkdaysStyles} from '../../style';
import SelectDropdown from 'react-native-select-dropdown';
import AppText from '../../../../components/AppText';
import SelectDropdownComponent from '../../../../components/Select';
import commonStyles from '../../../../styles/commonStyles';
......
......@@ -250,14 +250,6 @@ const OnLeaveContainer = props => {
setLeaveRequestList([...format]);
};
const minutesToHours = (start, finish) => {
//console.log(start, finish);
let time = Moment(finish).diff(Moment(start), 'minutes');
var Hours = Math.floor(time / 60);
var minutes = time % 60;
return `${Hours}:${minutes} giờ`;
};
const getAndOpenModal = async id => {
const res = await dispatch(getUserLeavesById(id));
if (res) {
......@@ -478,7 +470,6 @@ const OnLeaveContainer = props => {
onOpenRequestLeavesModal,
onCloseModal,
onChangeSelectFilter,
minutesToHours,
onSubmitLeaveRequest,
onSelectManagerLeaveRequest,
onSubmitApproveLeaveRequest,
......
......@@ -23,7 +23,6 @@ export default function onLeavePropsProvider(props) {
onOpenRequestLeavesModal,
onCloseModal,
onChangeSelectFilter,
minutesToHours,
leavesDaysModal,
leaveCategory,
directManagersList,
......@@ -65,7 +64,6 @@ export default function onLeavePropsProvider(props) {
onOpenRequestLeavesModal,
onCloseModal,
onChangeSelectFilter,
minutesToHours,
approveRequestLeavesDaysProps: {
payloadApproveRequestLeavesDays,
onChangeSelectFilter,
......
......@@ -2,23 +2,170 @@
import CheckBox from '@react-native-community/checkbox';
import Moment from 'moment';
import React, {useMemo} from 'react';
import {
Image,
Modal,
ScrollView,
TextInput,
TouchableOpacity,
View,
} from 'react-native';
import {Image, Modal, ScrollView, TouchableOpacity, View} from 'react-native';
import DateTimePickerModal from 'react-native-modal-datetime-picker';
import AppText from '../../../../components/AppText';
import ButtonComponent from '../../../../components/ButtonComponent';
import SelectDropdownComponent from '../../../../components/Select';
import TextInputComponent from '../../../../components/TextInputComponent';
import config from '../../../../config';
import {IMAGES} from '../../../../values/images';
import {leavesModalStyles} from '../../style';
import TextInputComponent from '../../../../components/TextInputComponent';
import colors from '../../../../values/colors';
// const ButtonAction = React.memo(
// ({
// onCloseModal,
// onSubmitApproveLeaveRequest,
// isRequest,
// onSubmitLeaveRequest,
// userInfo,
// }) => {
// return (
// <View
// style={{
// flexDirection: 'row',
// justifyContent: 'flex-end',
// marginTop: 20,
// }}>
// <TouchableOpacity
// onPress={onCloseModal}
// style={leavesModalStyles.btnCancel}>
// <AppText style={leavesModalStyles.blueTxt}>Hủy</AppText>
// </TouchableOpacity>
// {isRequest && (
// <TouchableOpacity
// style={leavesModalStyles.btnSubmit}
// onPress={onSubmitLeaveRequest}>
// <AppText style={leavesModalStyles.whiteTxt}>Gửi yêu cầu</AppText>
// </TouchableOpacity>
// )}
// {userInfo?.isApprover && (
// <TouchableOpacity
// style={leavesModalStyles.btnSubmit}
// onPress={() => onSubmitApproveLeaveRequest(userInfo?.leave_id)}>
// <AppText style={leavesModalStyles.whiteTxt}>Duyệt yêu cầu</AppText>
// </TouchableOpacity>
// )}
// </View>
// );
// },
// function areEquals(prevProps, nextProps) {
// return (
// prevProps.isRequest === nextProps.isRequest ||
// prevProps.userInfo === nextProps.userInfo ||
// prevProps.onSubmitLeaveRequest === nextProps.onSubmitLeaveRequest ||
// prevProps.onCloseModal === nextProps.onCloseModal ||
// prevProps.onSubmitApproveLeaveRequest ===
// nextProps.onSubmitApproveLeaveRequest
// );
// },
// );
const UserHeader = React.memo(
({userInfo, fullName}) => {
return (
<View style={{flexDirection: 'row', marginVertical: 10}}>
<Image
source={
userInfo?.avatar
? {
uri: config.imageEndPoint + userInfo?.avatar,
}
: IMAGES.IcAvatarDefault
}
style={leavesModalStyles.ImgAvatar}
/>
<View style={{marginLeft: 15}}>
<AppText
style={
leavesModalStyles.modalTitle
}>{`${fullName} - ${userInfo?.employee_code}`}</AppText>
<AppText>{userInfo?.position}</AppText>
</View>
</View>
);
},
function areEqual(prevProps, nextProps) {
return (
prevProps.userInfo === nextProps.userInfo ||
prevProps.fullName === nextProps.fullName
);
},
);
const Attachments = React.memo(
({leaveRequestImage, onDeleteLeaveRequestImage, openGallery}) => {
return (
<View style={leavesModalStyles.rowView}>
<AppText>Tệp đính kèm</AppText>
<View style={{flexDirection: 'row'}}>
{leaveRequestImage.length > 0 &&
leaveRequestImage.map((item, index) => {
//console.log("item", item[0].uri)
return (
<View key={index}>
<ButtonComponent
iconSource={IMAGES.IcReject}
style={leavesModalStyles.btnClose}
onPress={() => onDeleteLeaveRequestImage(index)}
/>
<Image
source={{uri: item.uri}}
style={leavesModalStyles.imgUpload}
/>
</View>
);
})}
{leaveRequestImage.length < 3 && (
<ButtonComponent
style={leavesModalStyles.addLeaveRequestImageBtn}
onPress={openGallery}
iconSource={IMAGES.IcAddMoreImg}
/>
)}
</View>
</View>
);
},
);
const ButtonAction = ({
onCloseModal,
onSubmitApproveLeaveRequest,
isRequest,
onSubmitLeaveRequest,
userInfo,
}) => {
return (
<View
style={{
flexDirection: 'row',
justifyContent: 'flex-end',
marginTop: 20,
}}>
<TouchableOpacity
onPress={onCloseModal}
style={leavesModalStyles.btnCancel}>
<AppText style={leavesModalStyles.blueTxt}>Hủy</AppText>
</TouchableOpacity>
{isRequest && (
<TouchableOpacity
style={leavesModalStyles.btnSubmit}
onPress={onSubmitLeaveRequest}>
<AppText style={leavesModalStyles.whiteTxt}>Gửi yêu cầu</AppText>
</TouchableOpacity>
)}
{userInfo?.isApprover && (
<TouchableOpacity
style={leavesModalStyles.btnSubmit}
onPress={() => onSubmitApproveLeaveRequest(userInfo?.leave_id)}>
<AppText style={leavesModalStyles.whiteTxt}>Duyệt yêu cầu</AppText>
</TouchableOpacity>
)}
</View>
);
};
const RequestLeavesDays = props => {
const {
userInfo,
......@@ -71,25 +218,7 @@ const RequestLeavesDays = props => {
Nghỉ phép mới
</AppText>
</View>
<View style={{flexDirection: 'row', marginVertical: 10}}>
<Image
source={
userInfo?.avatar
? {
uri: config.imageEndPoint + userInfo?.avatar,
}
: IMAGES.IcAvatarDefault
}
style={leavesModalStyles.ImgAvatar}
/>
<View style={{marginLeft: 15}}>
<AppText
style={
leavesModalStyles.modalTitle
}>{`${fullName} - ${userInfo?.employee_code}`}</AppText>
<AppText>{userInfo?.position}</AppText>
</View>
</View>
<UserHeader userInfo={userInfo} fullName={fullName} />
<View>
<AppText style={leavesModalStyles.modalTitle}>
Thông tin chung
......@@ -299,7 +428,12 @@ const RequestLeavesDays = props => {
/>
</View>
</View>
<View style={leavesModalStyles.rowView}>
<Attachments
leaveRequestImage={leaveRequestImage}
onDeleteLeaveRequestImage={onDeleteLeaveRequestImage}
openGallery={openGallery}
/>
{/* <View style={leavesModalStyles.rowView}>
<AppText>Tệp đính kèm</AppText>
<View style={{flexDirection: 'row'}}>
{leaveRequestImage.length > 0 &&
......@@ -328,7 +462,7 @@ const RequestLeavesDays = props => {
/>
)}
</View>
</View>
</View> */}
{isRequest && directManagersList.length > 0 && (
<View style={{marginTop: 10}}>
<AppText
......@@ -385,36 +519,13 @@ const RequestLeavesDays = props => {
</View>
)}
</View>
<View
style={{
flexDirection: 'row',
justifyContent: 'flex-end',
marginTop: 20,
}}>
<TouchableOpacity
onPress={onCloseModal}
style={leavesModalStyles.btnCancel}>
<AppText style={leavesModalStyles.blueTxt}>Hủy</AppText>
</TouchableOpacity>
{isRequest && (
<TouchableOpacity
style={leavesModalStyles.btnSubmit}
onPress={onSubmitLeaveRequest}>
<AppText style={leavesModalStyles.whiteTxt}>
Gửi yêu cầu
</AppText>
</TouchableOpacity>
)}
{userInfo?.isApprover && (
<TouchableOpacity
style={leavesModalStyles.btnSubmit}
onPress={() => onSubmitApproveLeaveRequest(userInfo?.leave_id)}>
<AppText style={leavesModalStyles.whiteTxt}>
Duyệt yêu cầu
</AppText>
</TouchableOpacity>
)}
</View>
<ButtonAction
onCloseModal={onCloseModal}
isRequest={isRequest}
userInfo={userInfo}
onSubmitLeaveRequest={onSubmitLeaveRequest}
onSubmitApproveLeaveRequest={onSubmitApproveLeaveRequest}
/>
</View>
</ScrollView>
</Modal>
......
......@@ -275,12 +275,6 @@ const OvertimeContainer = props => {
RootNavigation.navigate(APP_NAVIGATE_SCREEN.ON_LEAVE);
};
const minutesToHours = (start, finish) => {
let time = Moment(finish).diff(Moment(start), 'minutes');
var Hours = Math.floor(time / 60);
var minutes = time % 60;
return `${Hours}:${minutes} giờ`;
};
const onChangeSelectFilter = selectedItem => {
if (selectedItem === 'Tất cả') {
setPayloadOtApproveList({
......@@ -409,7 +403,6 @@ const OvertimeContainer = props => {
onLoadMoreOtList,
setShowAlert,
setMonth,
minutesToHours,
navigateToConfirmDate,
navigateToOnLeave,
onLoadMoreOtApproveReqList,
......
/* eslint-disable prettier/prettier */
/* eslint-disable react/self-closing-comp */
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable react-native/no-inline-styles */
import React from 'react';
import {
Image,
......@@ -21,6 +17,7 @@ import FastImage from 'react-native-fast-image';
import AppText from '../../components/AppText';
import ButtonComponent from '../../components/ButtonComponent';
import styles from './style';
import Utils from '../../utils';
const OvertimeScreen = ({
userDetails,
otVoucherList,
......@@ -32,7 +29,6 @@ const OvertimeScreen = ({
showAlert,
setShowAlert,
setMonth,
minutesToHours,
isDisableLoadMore,
onLoadMoreOtList,
onLoadMoreOtApproveReqList,
......@@ -336,7 +332,7 @@ const OvertimeScreen = ({
}}>
<AppText>{''}</AppText>
<AppText style={{textAlign: 'right'}}>
{minutesToHours(item.start, item.finish)}
{Utils.minutesToHours(item.start, item.finish)}
</AppText>
</View>
</TouchableOpacity>
......
......@@ -17,5 +17,12 @@ const commonStyles = StyleSheet.create({
elevation: 5,
},
row: {
flexDirection: 'row',
},
spaceBetweenCenter: {justifyContent: 'space-between', alignItems: 'center'},
marginVertical10: {
marginVertical: 10,
},
});
export default commonStyles;
......@@ -168,7 +168,14 @@ const formatCurrency = price => {
const getCategoryNotification = category => {
return Object.keys(config.categoryNotification).find(el => el === category);
};
const minutesToHours = (start, finish) => {
//console.log(start, finish);
if (!start || !finish) return '00:00';
let time = moment(finish).diff(moment(start), 'minutes');
var Hours = Math.floor(time / 60);
var minutes = time % 60;
return `${Hours}:${minutes} gi`;
};
const Utils = {
storeData,
getData,
......@@ -180,5 +187,6 @@ const Utils = {
formatMonthVietNamLanguage,
formatCurrency,
getCategoryNotification,
minutesToHours,
};
export default Utils;
......@@ -31,6 +31,7 @@ const colors = {
blue5c: '#5c65dc',
gray59: '#595959',
grayE9: '#e9eaf9',
gray95: '#f2f2f2',
textColor: '#202121',
baseShadowColor: '#000',
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment