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;
import Moment from 'moment';
import React, {useEffect, useState} from 'react';
import React, {useCallback, useEffect, useState} from 'react';
import {useDispatch} from 'react-redux';
import RootNavigation from '../../navigation/RootNavigation';
import {getAbsentChart} from '../../store/actions/UserAction';
import {APP_NAVIGATE_SCREEN} from '../../utils/constant';
import ConfirmModalAddNew from './confirm-modals/ConfirmModalAddNew';
import ConfirmModalDetails from './confirm-modals/ConfirmModalDetails';
import {getConfirmApprovedDate, getUserConfirmDay} from './confirmDateSlice';
import {
getAbsentChart,
getConfirmApprovedDate,
getUserConfirmDay,
} from './confirmDateSlice';
import ConfirmDateMainView from './template/ConfirmMainView';
import confirmDatePropsProvider from './confirmDatePropsProvider';
import Utils from '../../utils';
const ConfirmDateContainer = props => {
const {confirmDateList, confirmApprovedDateList, userInfo} = props;
const dispatch = useDispatch();
......@@ -19,11 +23,7 @@ const ConfirmDateContainer = props => {
totalRequestApproveArr: 0,
totalConfirmArr: 0,
});
const [showAlert, setShowAlert] = useState({
isError: false,
title: '',
message: '',
});
// approveConfirmList payload
const [approveReqPayload, setApproveReqPayload] = useState({
type: 'Tất cả',
......@@ -39,104 +39,32 @@ const ConfirmDateContainer = props => {
pageSize: 5,
isRefresh: false,
});
const [isDisableLoadMore, setDisableLoadMore] = useState({
approveRequestBtn: false,
confirmBtn: false,
});
const [dataChart, setDataChart] = useState({
month: new Date().getMonth() + 1,
data: {},
});
const [modalContent, setModalContent] = useState(null);
const [modalRequestConfirmWorkingDays, setModalRequestConfirmWorkingDays] =
useState({
visible: false,
});
const [dayPress, setDayPress] = useState();
// open the modal
const onOpenDetailModal = detailItem => {};
const onOpenAddModal = () => {
setModalContent(
<ConfirmModalAddNew
userDetails={userInfo}
onClose={onCloseModal}
alertMessage={alertMessage}
/>,
);
const onOpenModalRequestConfirmWorkingDays = () => {
setModalRequestConfirmWorkingDays({userinfo: userInfo, visible: true});
};
const onCloseModal = () => {
setModalContent(null);
const onCloseModalRequestConfirmWorkingDays = () => {
setModalRequestConfirmWorkingDays({userinfo: null, visible: false});
};
// main function
const navigateToDayWage = () => {
RootNavigation.navigate(APP_NAVIGATE_SCREEN.DAY_WAGE);
};
const alertMessage = message => {
// Toast.show({
// type: 'success',
// text1: `Thông báo`,
// text2: `${message}`,
// style: {zIndex: 1001},
// visibilityTime: 2000,
// });
setShowAlert({
isError: true,
title: 'Hệ thống',
message: message,
});
};
const onHideAlert = () => {
setShowAlert({
isError: false,
title: '',
message: '',
});
};
const fetchAbsentApprovalRequests = async () => {
const res = await dispatch(
getConfirmApprovedDate({
filter: approveReqPayload.filter,
sort: approveReqPayload.sorts,
page: approveReqPayload.page,
pageSize: approveReqPayload.pageSize,
}),
);
if (res.success) {
//console.log(res);
const {collection, total} = res.data;
// check if refresh
if (!collection || collection.length === 0) {
return;
}
if (approveReqPayload.isRefresh) {
setTotalArr(prev => ({...prev, totalRequestApproveArr: total}));
return;
}
setTotalArr(prev => ({...prev, totalRequestApproveArr: total}));
}
};
const loadDataConfirmDay = async () => {
//console.log('loadDataConfirmDay');
const res = await dispatch(
getUserConfirmDay(userConfirmPayload.page, userConfirmPayload.pageSize),
);
if (res.success) {
//console.log(res);
const {collection, total} = res.data;
if (!collection || collection.length === 0) {
return;
}
if (userConfirmPayload.isRefresh) {
setTotalArr(prev => ({...prev, totalConfirmArr: total}));
return;
}
setTotalArr(prev => ({...prev, totalConfirmArr: total}));
}
};
const onLoadMoreRequestApprove = () => {
setApproveReqPayload(prev => ({
...prev,
......@@ -151,46 +79,7 @@ const ConfirmDateContainer = props => {
isRefresh: false,
}));
};
// check avoid btn load more
const checkVisibleLoadMore = () => {
if (
requestApproveArr.length > 0 &&
requestApproveArr.length == totalArr.totalRequestApproveArr
) {
//console.log('checkVisibleLoadMore');
setDisableLoadMore(prev => ({
...prev,
approveRequestBtn: true,
}));
} else if (
requestApproveArr.length > 0 &&
requestApproveArr.length < totalArr.totalRequestApproveArr
) {
//console.log('checkVisibleLoadMore');
setDisableLoadMore(prev => ({
...prev,
approveRequestBtn: false,
}));
} else if (
confirmList.length > 0 &&
confirmList.length == totalArr.totalConfirmArr
) {
//console.log('checkVisibleLoadMore');
setDisableLoadMore(prev => ({
...prev,
confirmBtn: true,
}));
} else if (
confirmList.length > 0 &&
confirmList.length == totalArr.totalConfirmArr
) {
//console.log('checkVisibleLoadMore');
setDisableLoadMore(prev => ({
...prev,
confirmBtn: false,
}));
}
};
// refresh onClick event
const onRefreshApproveList = () => {
//console.log('onRefreshApproveList');
......@@ -255,7 +144,10 @@ const ConfirmDateContainer = props => {
// fetchDataChart(parseInt(arr[1], 10));
setDataChart(prev => ({
...prev,
month: parseInt(arr[1]) < 10 ? '0' + parseInt(arr[1]) : parseInt(arr[1]),
month:
parseInt(arr[1], 10) < 10
? '0' + parseInt(arr[1], 10)
: parseInt(arr[1], 10),
}));
};
const onChangeDayPressInChart = selectedItem => {
......@@ -294,69 +186,101 @@ const ConfirmDateContainer = props => {
format.sort((a, b) => Moment(a.created_at) < Moment(b.created_at));
setRequestApproveArr(format);
};
const fetchDataChart = async month => {
//console.log('fetchDataChart')
const res = await dispatch(getAbsentChart());
if (res && res.length > 0) {
let filterByMonth = res.filter(
item => new Date(item.date).getMonth() + 1 === parseInt(month) && item,
);
let formatData = [];
filterByMonth.forEach(item => {
//console.log(Moment(item.date).format('YYYY-MM-DD'));
const objDay = Moment(item.date).format('YYYY-MM-DD');
if (parseInt(item.absent_hours) > 0) {
formatData.push({
[objDay]: {
selected: true,
selectedColor:
(parseInt(item.absent_hours) > 8 && '#7d93ff') ||
(parseInt(item.absent_hours) >= 6 &&
parseInt(item.absent_hours) <= 8 &&
'#7d93ff') ||
(parseInt(item.absent_hours) >= 4 &&
parseInt(item.absent_hours) <= 6 &&
'#7d93ff') ||
'#dfe4ff',
},
});
}
});
// const monthArr = filterByMonth.filter(
// item => item.absent_hours > 0 && item,
// //console.log((item.date = Moment(item.date).format('dddd')));
// );
//console.log('month', month);
const convertObj = Object.assign({}, ...formatData);
//console.log('filterByMonth', ...formatData);
setDataChart(prev => ({
...prev,
data: filterByMonth,
}));
//=============================== FETCH DATA ================================//
const fetchAbsentApprovalRequests = async () => {
const res = await dispatch(
getConfirmApprovedDate({
filter: approveReqPayload.filter,
sort: approveReqPayload.sorts,
page: approveReqPayload.page,
pageSize: approveReqPayload.pageSize,
}),
);
if (res.success) {
//console.log(res);
const {collection, total} = res.data;
// check if refresh
if (!collection || collection.length === 0) {
return;
}
if (approveReqPayload.isRefresh) {
setTotalArr(prev => ({...prev, totalRequestApproveArr: total}));
return;
}
setTotalArr(prev => ({...prev, totalRequestApproveArr: total}));
}
};
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 loadDataConfirmDay = async () => {
//console.log('loadDataConfirmDay');
const res = await dispatch(
getUserConfirmDay(userConfirmPayload.page, userConfirmPayload.pageSize),
);
if (res.success) {
//console.log(res);
const {collection, total} = res.data;
if (!collection || collection.length === 0) {
return;
}
if (userConfirmPayload.isRefresh) {
setTotalArr(prev => ({...prev, totalConfirmArr: total}));
return;
}
setTotalArr(prev => ({...prev, totalConfirmArr: total}));
}
};
// useEffect
const fetchStatisticsConfirmWorkingDays = useCallback(() => {
dispatch(getAbsentChart()).then(response => {
const {success} = Utils.getValues(response, 'payload', false);
if (success) {
const {data} = Utils.getValues(response, 'payload', []);
let filterByMonth =
data.length > 0
? data.filter(
item =>
new Date(item.date).getMonth() + 1 ===
parseInt(dataChart.month, 10),
)
: [];
let formatData = [];
filterByMonth.forEach(item => {
//console.log(Moment(item.date).format('YYYY-MM-DD'));
const objDay = Moment(item.date).format('YYYY-MM-DD');
if (parseInt(item.absent_hours, 10) > 0) {
formatData.push({
[objDay]: {
selected: true,
selectedColor:
(parseInt(item.absent_hours, 10) > 8 && '#7d93ff') ||
(parseInt(item.absent_hours, 10) >= 6 &&
parseInt(item.absent_hours, 10) <= 8 &&
'#7d93ff') ||
(parseInt(item.absent_hours, 10) >= 4 &&
parseInt(item.absent_hours, 10) <= 6 &&
'#7d93ff') ||
'#dfe4ff',
},
});
}
});
setDataChart(prev => ({
...prev,
data: filterByMonth,
}));
}
});
}, [dataChart.month, dispatch]);
// useEffect
useEffect(() => {
confirmDateList && formatDataConfirmListFromApi();
}, [confirmDateList]);
useEffect(() => {
dataChart.month && fetchDataChart(dataChart.month);
dataChart.month && fetchStatisticsConfirmWorkingDays();
}, [dataChart.month]);
// useEffect(() => {
// dataChart.data && console.log(dataChart.data);
// }, [dataChart.data]);
useEffect(() => {
confirmApprovedDateList &&
formatDataApproveConfirmListFromApi(confirmApprovedDateList);
......@@ -365,36 +289,30 @@ const ConfirmDateContainer = props => {
useEffect(() => {
approveReqPayload && fetchAbsentApprovalRequests();
}, [approveReqPayload]);
useEffect(() => {
userConfirmPayload && loadDataConfirmDay();
}, [userConfirmPayload]);
useEffect(() => {
checkVisibleLoadMore();
}, [requestApproveArr, confirmList, totalArr]);
const confirmProps = {
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,
};
return <ConfirmDateMainView {...confirmDatePropsProvider(confirmProps)} />;
};
......
......@@ -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: {
......
......@@ -17,258 +17,131 @@ import SelectDropdown from 'react-native-select-dropdown';
import AppText from '../../../components/AppText';
import StatisticsConfirmWorkdays from './components/StatisticsConfirmWorkdays';
import commonStyles from '../../../styles/commonStyles';
import config from '../../../config';
import SelectDropdownComponent from '../../../components/Select';
import Utils from '../../../utils';
import colors from '../../../values/colors';
import ModalRequestConfirmWorkingDays from './subViews/ModalRequestConfirmWorkingDays';
const ConfirmDateMainView = ({
isDisableLoadMore,
showAlert,
onHideAlert,
navigateToDayWage,
onLoadMoreRequestApprove,
onLoadMoreConfirmList,
requestApproveArr,
confirmList,
onRefreshConfirmList,
modalContent,
onOpenDetailModal,
onOpenRequestLeavesModal,
approveReqPayload,
onChangeSelectFilter,
minutesToHours,
dataChart,
onChangeMonthFilter,
dayPress,
}) => {
return (
<SafeAreaView>
<ScrollView nestedScrollEnabled={true}>
<StatisticsConfirmWorkdays
dataChart={dataChart}
onChangeMonthFilter={onChangeMonthFilter}
dayPress={dayPress}
/>
<View style={[styles.view, commonStyles.baseShadow]}>
<AppText style={{fontWeight: '500', marginBottom: 10}}>
Xác nhn ngày công ca bn:{' '}
</AppText>
<View style={{alignItems: 'center', justifyContent: 'center'}}>
<ButtonComponent
style={styles.btnConfirm}
onPress={onOpenRequestLeavesModal}
leftIcon={IMAGES.IcBtnAdd}
styleIcon={styles.iconPlus}
text={'XÁC NHẬN NGÀY CÔNG'}
textStyle={styles.whiteTxt}
/>
</View>
<AppText style={{fontWeight: '500', marginBottom: 10, marginTop: 10}}>
Liên kết nhanh:{' '}
</AppText>
<TouchableOpacity
style={{flexDirection: 'row'}}
onPress={navigateToDayWage}>
<Image source={IMAGES.IcTask} style={styles.iconPlus} />
<AppText style={styles.primary_blue}>
Bng chm công ca tôi
</AppText>
</TouchableOpacity>
</View>
{requestApproveArr && (
<View style={[styles.view]}>
{requestApproveArr && (
<View
style={{
flexDirection: 'row',
}}>
<AppText
style={{
fontWeight: 'bold',
marginBottom: 4,
fontSize: 17,
flex: 1,
alignSelf: 'center',
}}>
Duyt ngày công{' '}
</AppText>
const approveWorkingDayStatus = [
{label: 'Tất cả', value: 'Tất cả'},
{label: 'Chưa duyệt', value: 'Chưa duyệt'},
{label: 'Đã duyệt', value: 'Đã duyệt'},
{label: 'Đã từ chối', value: 'Đã từ chối'},
];
<View
style={{
alignItems: 'flex-end',
flex: 1,
paddingRight: 20,
}}>
<SelectDropdown
data={['Tất cả', 'Chưa duyệt', 'Đã duyệt', 'Đã từ chối']}
dropdownIconPosition={'right'}
defaultButtonText={approveReqPayload?.type}
buttonStyle={styles.dropdown1BtnStyle}
onSelect={selectedItem =>
onChangeSelectFilter(selectedItem)
}
dropdownStyle={styles.dropdown1DropdownStyle}
rowStyle={styles.dropdown1RowStyle}
rowTextStyle={styles.dropdown1RowTxtStyle}
buttonTextStyle={styles.dropdown1BtnTxtStyle}
renderDropdownIcon={isOpened => {
return (
<Image
source={
isOpened ? IMAGES.IcUpArrow : IMAGES.IcArrowDown
}
style={{width: 20, height: 20}}
/>
);
}}
/>
</View>
</View>
)}
{requestApproveArr?.length > 0 &&
// requestApproveArr[0]?.approver_id == userDetails.id &&
requestApproveArr.map((item, index) => (
<TouchableOpacity
onPress={() => onOpenDetailModal(item)}
key={index}
style={[
styles.item,
{
borderLeftColor: item.extend_approved_status_color,
},
]}>
<View style={{flexDirection: 'row', flex: 2}}>
<Image
source={{
uri:
'https://meu.anawork.com' +
item.extend_creator_avatar,
}}
style={{width: 35, height: 35, marginRight: 5}}
/>
const ConfirmWorkingDaysSession = React.memo(
({onOpenModalRequestConfirmWorkingDays, navigateToDayWage}) => {
return (
<View style={[styles.view, commonStyles.baseShadow]}>
<AppText style={{fontWeight: '500', marginBottom: 10}}>
Xác nhn ngày công ca bn:
</AppText>
<View style={{alignItems: 'center', justifyContent: 'center'}}>
<ButtonComponent
style={styles.btnConfirm}
onPress={onOpenModalRequestConfirmWorkingDays}
leftIcon={IMAGES.IcBtnAdd}
styleIcon={styles.iconPlus}
text={'XÁC NHẬN NGÀY CÔNG'}
textStyle={styles.whiteTxt}
/>
</View>
<AppText style={{fontWeight: '500'}}>Liên kết nhanh: </AppText>
<TouchableOpacity style={commonStyles.row} onPress={navigateToDayWage}>
<Image source={IMAGES.IcTask} style={styles.iconPlus} />
<AppText style={styles.primary_blue}>Bng chm công ca tôi</AppText>
</TouchableOpacity>
</View>
);
},
function (prevProps, nextProps) {
return (
prevProps.onOpenRequestLeavesModal === nextProps.onOpenRequestLeavesModal
);
},
);
<View>
<AppText style={styles.title}>
{item.extend_creator_full_name}
</AppText>
<AppText>
{Moment(item.start).format('DD/MM/YYYY')}
</AppText>
</View>
</View>
<View
style={{
flex: 1,
justifyContent: 'flex-end',
alignItems: 'flex-end',
marginLeft: 10,
}}>
<AppText>
{item.reason.length > 20
? item.reason.slice(0, 15) + '...'
: item.reason}
</AppText>
<AppText>{minutesToHours(item.start, item.finish)}</AppText>
</View>
</TouchableOpacity>
))}
{!isDisableLoadMore.approveRequestBtn &&
requestApproveArr?.length > 0 && (
<ButtonComponent
style={{
justifyContent: 'center',
alignItems: 'center',
padding: 10,
}}
text={'Xem thêm'}
textStyle={{color: '#5d78ff'}}
onPress={onLoadMoreRequestApprove}
/>
)}
</View>
)}
<View style={[styles.view, {marginBottom: 30}]}>
<View
const ApproveRequestWorkingDays = React.memo(
props => {
const {
approveReqPayload,
onChangeSelectFilter,
requestApproveArr,
onOpenDetailModal,
} = props;
return (
<View
style={[
styles.view,
commonStyles.baseShadow,
commonStyles.marginVertical10,
]}>
<View style={[commonStyles.row, commonStyles.spaceBetweenCenter]}>
<AppText
style={{
flexDirection: 'row',
fontWeight: 'bold',
fontSize: 17,
}}>
<AppText
style={{
fontWeight: 'bold',
marginBottom: 4,
fontSize: 17,
alignSelf: 'center',
flex: 2,
}}>
Xác nhn ngày công ca tôi{' '}
</AppText>
<View style={{alignItems: 'flex-end', flex: 1, paddingRight: 20}}>
<ButtonComponent
text={'Tải lại'}
textStyle={{color: '#5d78ff'}}
style={{
justifyContent: 'center',
alignItems: 'center',
padding: 10,
flexDirection: 'row',
}}
onPress={onRefreshConfirmList}
leftIcon={IMAGES.IcRefresh}
styleIcon={{width: 20, height: 20}}
Duyt ngày công
</AppText>
<SelectDropdownComponent
value={approveReqPayload?.type}
selectData={approveWorkingDayStatus}
setValue={onChangeSelectFilter}
/>
</View>
{requestApproveArr.map((item, index) => (
<TouchableOpacity
onPress={() => onOpenDetailModal(item)}
key={index}
style={[
styles.item,
commonStyles.spaceBetweenCenter,
{
borderLeftColor: item?.extend_approved_status_color,
},
]}>
<View style={commonStyles.row}>
<Image
source={
item?.extend_creator_avatar
? {
uri: config.imageEndPoint + item.extend_creator_avatar,
}
: IMAGES.IcAvatarDefault
}
style={{width: 35, height: 35, marginRight: 5}}
/>
<View>
<AppText style={styles.title}>
{item?.extend_creator_full_name?.length > 20
? item?.extend_creator_full_name.slice(0, 15) + '...'
: item?.extend_creator_full_name}
</AppText>
<AppText isSubText>
{Moment(item.start).format('DD/MM/YYYY')}
</AppText>
</View>
</View>
</View>
{confirmList.length === 0 && (
<View
style={{
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white',
marginTop: 10,
padding: 20,
alignItems: 'flex-end',
}}>
<AppText style={{textAlign: 'center'}}>
Chưa có ngày công nào 😢 Bn vui lòng thêm ngày công ngay bên
trên nhé!
<AppText>
{item.reason.length > 20
? item.reason.slice(0, 15) + '...'
: item.reason}
</AppText>
<AppText isSubText>
{Utils.minutesToHours(item?.start, item?.finish)}
</AppText>
<FastImage
source={GifType.gifConfirm}
style={{width: '90%', height: 250}}
/>
</View>
)}
{confirmList &&
confirmList.map((item, index) => (
<TouchableOpacity
onPress={() => onOpenDetailModal(item)}
key={index}
style={[
styles.item,
{
borderLeftColor: item.extend_approved_status_color,
},
]}>
<View>
<AppText style={styles.title}>
{item.extend_creator_full_name}
</AppText>
<AppText>{Moment(item.start).format('DD/MM/YYYY')}</AppText>
</View>
<View
style={{
flex: 1,
justifyContent: 'flex-end',
alignItems: 'flex-end',
marginLeft: 10,
}}>
<AppText>
{item.reason.length > 20
? item.reason.slice(0, 15) + '...'
: item.reason}
</AppText>
<AppText>{minutesToHours(item.start, item.finish)}</AppText>
</View>
</TouchableOpacity>
))}
{confirmList.length > 0 && !isDisableLoadMore.confirmBtn && (
</TouchableOpacity>
))}
{/* {!isDisableLoadMore.approveRequestBtn &&
requestApproveArr?.length > 0 && (
<ButtonComponent
style={{
justifyContent: 'center',
......@@ -277,24 +150,152 @@ const ConfirmDateMainView = ({
}}
text={'Xem thêm'}
textStyle={{color: '#5d78ff'}}
onPress={onLoadMoreConfirmList}
onPress={onLoadMoreRequestApprove}
/>
)}
)} */}
</View>
);
},
function (prevProps, nextProps) {
return prevProps.requestApproveArr === nextProps.requestApproveArr;
},
);
const ConfirmWorkingDays = React.memo(
({confirmList, onOpenDetailModal, onRefreshConfirmList}) => {
return (
<View
style={[
styles.view,
commonStyles.baseShadow,
commonStyles.marginVertical10,
]}>
<View style={[commonStyles.row, commonStyles.spaceBetweenCenter]}>
<AppText
isBold
style={{
fontSize: 17,
}}>
Xác nhn ngày công ca tôi
</AppText>
<ButtonComponent
text={'Tải lại'}
textStyle={{color: colors.purple_blue}}
style={styles.refreshBtn}
onPress={onRefreshConfirmList}
leftIcon={IMAGES.IcRefresh}
styleIcon={{width: 20, height: 20}}
/>
</View>
<Alert
show={showAlert.isError}
showProgress={false}
title={showAlert.title}
message={showAlert.message}
closeOnTouchOutside={true}
closeOnHardwareBackPress={false}
showConfirmButton={true}
confirmText="Đóng"
confirmButtonColor="#DD6B55"
onConfirmPressed={onHideAlert}
{confirmList.length === 0 && (
<View style={styles.emptyConfirmWorkingDays}>
<AppText style={{textAlign: 'center'}}>
Chưa có ngày công nào 😢 Bn vui lòng thêm ngày công ngay bên
trên nhé!
</AppText>
<FastImage
source={GifType.gifConfirm}
style={{width: '90%', height: 250}}
/>
</View>
)}
{confirmList &&
confirmList.map((item, index) => (
<TouchableOpacity
onPress={() => onOpenDetailModal(item)}
key={index}
style={[
styles.item,
{
borderLeftColor: item.extend_approved_status_color,
},
]}>
<View>
<AppText style={styles.title}>
{item.extend_creator_full_name}
</AppText>
<AppText>{Moment(item.start).format('DD/MM/YYYY')}</AppText>
</View>
<View
style={{
flex: 1,
justifyContent: 'flex-end',
alignItems: 'flex-end',
marginLeft: 10,
}}>
<AppText>
{item.reason.length > 20
? item.reason.slice(0, 15) + '...'
: item.reason}
</AppText>
<AppText>
{Utils.minutesToHours(item.start, item.finish)}
</AppText>
</View>
</TouchableOpacity>
))}
{/* {confirmList.length > 0 && !isDisableLoadMore.confirmBtn && (
<ButtonComponent
style={{
justifyContent: 'center',
alignItems: 'center',
padding: 10,
}}
text={'Xem thêm'}
textStyle={{color: '#5d78ff'}}
onPress={onLoadMoreConfirmList}
/>
)} */}
</View>
);
},
function (prevProps, nextProps) {
return prevProps.confirmList === nextProps.confirmList;
},
);
const ConfirmDateMainView = ({
navigateToDayWage,
requestApproveArr = [],
confirmList,
onRefreshConfirmList,
onOpenDetailModal,
onOpenRequestLeavesModal,
dataChart,
onChangeMonthFilter,
dayPress,
approveRequestWorkingDaysProps,
modalRequestConfirmWorkingDays,
onCloseModalRequestConfirmWorkingDays,
onOpenModalRequestConfirmWorkingDays,
}) => {
return (
<SafeAreaView>
<ScrollView nestedScrollEnabled={true}>
<StatisticsConfirmWorkdays
dataChart={dataChart}
onChangeMonthFilter={onChangeMonthFilter}
dayPress={dayPress}
/>
<ConfirmWorkingDaysSession
navigateToDayWage={navigateToDayWage}
onOpenModalRequestConfirmWorkingDays={
onOpenModalRequestConfirmWorkingDays
}
/>
{requestApproveArr.length > 0 && (
<ApproveRequestWorkingDays {...approveRequestWorkingDaysProps} />
)}
<ConfirmWorkingDays
confirmList={confirmList}
onOpenDetailModal={onOpenDetailModal}
onRefreshConfirmList={onRefreshConfirmList}
/>
{modalContent}
</ScrollView>
{modalRequestConfirmWorkingDays?.visible && (
<ModalRequestConfirmWorkingDays
userinfo={modalRequestConfirmWorkingDays?.userinfo}
onClose={onCloseModalRequestConfirmWorkingDays}
/>
)}
</SafeAreaView>
);
};
......
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';
......
import React from 'react';
import {
Dimensions,
Image,
Modal,
SafeAreaView,
ScrollView,
StyleSheet,
TouchableOpacity,
View,
} from 'react-native';
import AppText from '../../../../components/AppText';
import config from '../../../../config';
import colors from '../../../../values/colors';
import {IMAGES} from '../../../../values/images';
const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;
const ModalRequestConfirmWorkingDays = ({userinfo, onClose}) => {
return (
<Modal
animationType="slide"
transparent={true}
visible={true}
onRequestClose={() => {
onClose(null);
}}>
<SafeAreaView>
<View style={styles.modalView}>
<AppText style={styles.modalTitle}>Xác nhn ngày công</AppText>
<View style={{flexDirection: 'row', marginTop: 10}}>
<Image
source={{uri: config.imageEndPoint + userinfo?.avatar}}
style={styles.ImgAvatar}
/>
<View style={{marginLeft: 15}}>
<AppText style={styles.modalTitle}>{`${userinfo?.first_name} ${
userinfo?.middle_name ? userinfo?.middle_name : ''
} ${userinfo?.last_name}`}</AppText>
<AppText>{userinfo?.position}</AppText>
</View>
</View>
<View style={styles.bodyHeightCreate}>
<ScrollView>
<View style={{marginTop: 20}}>
<AppText style={styles.modalTitle}>Thông tin xác nhận</AppText>
<View style={styles.rowView}>
<AppText style={{flex: 1}}>Từ ngày</AppText>
<View style={{flex: 1}}>
<TouchableOpacity
// onPress={() =>
// setOpenTimePicker(state => ({
// ...state,
// start: true,
// }))
// }
style={[
styles.dropdown1BtnStyle,
{
alignItems: 'flex-end',
flexDirection: 'row',
justifyContent: 'flex-end',
},
]}>
{/* <AppText>
{Moment(confirmDate.since).format('DD/MM/YYYY')}
</AppText> */}
<Image
source={IMAGES.IcCalendarGray}
style={{width: 20, height: 20}}
/>
</TouchableOpacity>
{/* <DateTimePickerModal
isVisible={openTimePicker.start}
mode="date"
date={confirmDate.start}
onConfirm={time => {
setOpenTimePicker(state => ({
...state,
start: false,
}));
setConfirm(state => ({
...state,
since: time,
}));
}}
onCancel={() => {
setOpenTimePicker(state => ({
...state,
start: false,
}));
}}
/> */}
</View>
</View>
<View style={styles.rowView}>
<AppText>Giờ</AppText>
<TouchableOpacity
// onPress={() =>
// setOpenTimePicker(state => ({
// ...state,
// hourSince: true,
// }))
// }
style={{flexDirection: 'row'}}>
{/* <AppText>
{Moment(confirmDate.hourSince).format('HH:mm')}
</AppText> */}
<Image
source={IMAGES.IcLockGrey}
style={{width: 20, height: 20}}
/>
</TouchableOpacity>
{/* <DateTimePickerModal
isVisible={openTimePicker.hourSince}
mode="time"
date={confirmDate.hourSince}
onConfirm={time => {
setOpenTimePicker(state => ({
...state,
hourSince: false,
}));
setConfirm(state => ({
...state,
hourSince: time,
}));
}}
onCancel={() => {
setOpenTimePicker(state => ({
...state,
hourSince: false,
}));
}}
/> */}
</View>
<View style={styles.rowView}>
<AppText style={{flex: 1}}>Đến ngày</AppText>
<View style={{flex: 1}}>
<TouchableOpacity
// onPress={() =>
// setOpenTimePicker(state => ({
// ...state,
// finish: true,
// }))
// }
// style={[
// styles.dropdown1BtnStyle,
// {
// alignItems: 'flex-end',
// flexDirection: 'row',
// justifyContent: 'flex-end',
// },
// ]}
>
{/* <AppText>
{Moment(confirmDate.finish).format('DD/MM/YYYY')}
</AppText> */}
<Image
source={IMAGES.IcCalendarGray}
style={{width: 20, height: 20}}
/>
</TouchableOpacity>
{/* <DateTimePickerModal
isVisible={openTimePicker.finish}
mode="date"
date={confirmDate.finish}
onConfirm={time => {
setOpenTimePicker(state => ({
...state,
finish: false,
}));
setConfirm(state => ({
...state,
finish: time,
}));
}}
onCancel={() => {
setOpenTimePicker(state => ({
...state,
finish: false,
}));
}}
/> */}
</View>
</View>
<View style={styles.rowView}>
<AppText>Giờ</AppText>
<TouchableOpacity
// onPress={() =>
// setOpenTimePicker(state => ({
// ...state,
// hourFinish: true,
// }))
// }
style={{flexDirection: 'row'}}>
{/* <AppText>
{Moment(confirmDate.hourFinish).format('HH:mm')}
</AppText> */}
<Image
source={IMAGES.IcLockGrey}
style={{width: 20, height: 20}}
/>
</TouchableOpacity>
{/* <DateTimePickerModal
isVisible={openTimePicker.hourFinish}
mode="time"
date={confirmDate.hourFinish}
onConfirm={time => {
setOpenTimePicker(state => ({
...state,
hourFinish: false,
}));
setConfirm(state => ({
...state,
hourFinish: time,
}));
}}
onCancel={() => {
setOpenTimePicker(state => ({
...state,
hourFinish: false,
}));
}}
/> */}
</View>
<View style={styles.rowView}>
{/* <AppText
style={{
flex: 1,
color: confirmDate.reason.length === 0 ? 'red' : 'grey',
}}>
{`Lý do (*)`}
</AppText> */}
{/* <View style={{flex: 1}}>
<TextInput
style={styles.inputText}
values={confirmDate.reason}
placeholder="Nhập lý do tại đây"
onChangeText={text => {
setConfirm(prev => ({
...prev,
reason: text,
}));
}}
/>
</View> */}
</View>
{/* <View style={styles.rowView}>
<AppText style={{flex: 1}}>Tệp đính kèm</AppText>
<View
style={{
flex: 2,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginTop: 10,
}}>
{postImage.length > 0 &&
postImage.map((item, index) => {
//console.log("item", item[0].uri)
return (
<View key={index}>
<ButtonComponent
iconSource={IMAGES.IcClose}
style={styles.btnClose}
onPress={() => onDeleteImage(index)}
/>
<Image
source={{uri: item.uri}}
style={[styles.imgUpload]}
/>
</View>
);
})}
{postImage.length < 3 && (
<ButtonComponent
style={styles.touchableOpacity}
onPress={openGallery}
iconSource={IMAGES.IcAddMoreImg}
/>
)}
</View>
</View> */}
{/* <View style={{marginTop: 20}}>
<AppText
style={[
styles.modalTitle,
{
marginBottom: 10,
},
]}>
Người duyệt
</AppText>
{userManagerList.map((item, index) => (
<View
key={index}
style={{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
}}>
<View style={{flexDirection: 'row'}}>
<Image
source={{
uri: 'https://meu.anawork.com' + item.avatar,
}}
style={{width: 60, height: 60, borderRadius: 10}}
/>
<View>
<AppText
style={{
fontSize: 16,
fontWeight: '500',
marginLeft: 10,
}}>{`${item.extend_user_full_name}`}</AppText>
<AppText
style={{
fontSize: 13,
fontWeight: '500',
marginLeft: 10,
}}>{`${item?.position} - ${item?.department}`}</AppText>
</View>
</View>
<CheckBox
disabled={false}
value={item.checked}
onValueChange={newValue =>
onSelectManager(newValue, index, item)
}
boxType="square"
animationDuration={0.3}
lineWidth={1}
key={index}
/>
</View>
))}
</View> */}
</View>
</ScrollView>
</View>
<View style={{flexDirection: 'row', justifyContent: 'flex-end'}}>
<TouchableOpacity
onPress={() => {
onClose(null);
}}
style={styles.btnCancel}>
<AppText style={styles.blueTxt}>Hủy</AppText>
</TouchableOpacity>
<TouchableOpacity
style={styles.btnSubmit}
// onPress={onSubmitConfirmDate}
>
<AppText style={styles.whiteTxt}>Gửi yêu cầu</AppText>
</TouchableOpacity>
</View>
</View>
</SafeAreaView>
</Modal>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
pieChartContainer: {
flexDirection: 'row',
},
pieChartView: {
borderWidth: 1,
borderColor: 'white',
borderRadius: 5,
backgroundColor: 'white',
marginTop: 10,
flexDirection: 'row',
marginLeft: 10,
marginRight: 10,
padding: 10,
},
pieItem: {
alignItems: 'center',
},
pieFill: {
position: 'absolute',
width: 100,
height: 200,
alignItems: 'center',
justifyContent: 'center',
},
pieFillTextAmount: {
fontSize: 15,
color: '#757575',
},
pieFillText: {
fontSize: 10,
lineHeight: 15,
},
boldTitle: {
fontWeight: '500',
marginBottom: 10,
fontSize: 14,
color: 'black',
marginLeft: 10,
},
h2: {
fontWeight: '500',
fontSize: 20,
color: 'black',
},
viewTextPie: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
bgLeftViewTextPie: {
width: 10,
height: 10,
},
bgRightViewTextPie: {
backgroundColor: '#0abb87',
width: 10,
height: 10,
marginRight: 5,
},
view: {
width: windowWidth,
alignSelf: 'center',
borderWidth: 1,
backgroundColor: colors.white,
borderColor: colors.white,
padding: 10,
marginTop: 10,
},
btnConfirm: {
backgroundColor: '#5d78ff',
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
borderColor: '#5d78ff',
borderRadius: 8,
width: windowWidth - 100,
height: 35,
flexDirection: 'row',
},
whiteTxt: {
color: colors.white,
fontWeight: '500',
},
blueTxt: {
color: '#5d78ff',
fontWeight: '500',
},
iconPlus: {
width: 20,
height: 20,
marginRight: 10,
},
primary_blue: {
color: '#5d78ff',
},
item: {
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
borderWidth: 1,
borderBottomColor: '#f2f2f2',
borderTopColor: '#f2f2f2',
borderRightColor: '#f2f2f2',
borderTopLeftRadius: 10,
borderBottomLeftRadius: 10,
borderLeftWidth: 5,
flexDirection: 'row',
},
title: {
fontWeight: '500',
fontSize: 14,
color: 'black',
},
centeredView: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
marginTop: 22,
},
modalView: {
backgroundColor: 'white',
borderRadius: 20,
padding: 20,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5,
marginTop: 20,
height: 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,
},
rowView: {
flexDirection: 'row',
marginTop: 10,
justifyContent: 'space-between',
alignItems: 'center',
},
inputText: {
backgroundColor: '#FFF',
borderBottomWidth: 0.2,
borderColor: '#444',
},
touchableOpacity: {
borderColor: colors.primary_blue,
borderStyle: 'dotted',
borderWidth: 2,
justifyContent: 'center',
alignItems: 'center',
height: 50,
padding: 10,
width: 50,
},
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: 80,
width: 80,
},
btnClose: {
width: 20,
height: 20,
position: 'absolute',
top: -10,
right: 0,
},
});
export default ModalRequestConfirmWorkingDays;
......@@ -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