optimization leave screen

parent 32fb9014
...@@ -7,6 +7,7 @@ const confirmDateAPI = { ...@@ -7,6 +7,7 @@ const confirmDateAPI = {
axiosClient.get( axiosClient.get(
`myAbsentApprovalRequests?Filters=${filter}&Sorts=${sort}&Page=${page}&PageSize=${pageSize}`, `myAbsentApprovalRequests?Filters=${filter}&Sorts=${sort}&Page=${page}&PageSize=${pageSize}`,
), ),
requestGetAbsentChart: () => axiosClient.get('myAbsentRequests/statistic'),
}; };
export default confirmDateAPI; export default confirmDateAPI;
import Moment from 'moment'; import Moment from 'moment';
import React, {useEffect, useState} from 'react'; import React, {useCallback, useEffect, useState} from 'react';
import {useDispatch} from 'react-redux'; import {useDispatch} from 'react-redux';
import RootNavigation from '../../navigation/RootNavigation'; import RootNavigation from '../../navigation/RootNavigation';
import {getAbsentChart} from '../../store/actions/UserAction';
import {APP_NAVIGATE_SCREEN} from '../../utils/constant'; import {APP_NAVIGATE_SCREEN} from '../../utils/constant';
import ConfirmModalAddNew from './confirm-modals/ConfirmModalAddNew'; import ConfirmModalAddNew from './confirm-modals/ConfirmModalAddNew';
import ConfirmModalDetails from './confirm-modals/ConfirmModalDetails'; import ConfirmModalDetails from './confirm-modals/ConfirmModalDetails';
import {getConfirmApprovedDate, getUserConfirmDay} from './confirmDateSlice'; import {
getAbsentChart,
getConfirmApprovedDate,
getUserConfirmDay,
} from './confirmDateSlice';
import ConfirmDateMainView from './template/ConfirmMainView'; import ConfirmDateMainView from './template/ConfirmMainView';
import confirmDatePropsProvider from './confirmDatePropsProvider'; import confirmDatePropsProvider from './confirmDatePropsProvider';
import Utils from '../../utils';
const ConfirmDateContainer = props => { const ConfirmDateContainer = props => {
const {confirmDateList, confirmApprovedDateList, userInfo} = props; const {confirmDateList, confirmApprovedDateList, userInfo} = props;
const dispatch = useDispatch(); const dispatch = useDispatch();
...@@ -19,11 +23,7 @@ const ConfirmDateContainer = props => { ...@@ -19,11 +23,7 @@ const ConfirmDateContainer = props => {
totalRequestApproveArr: 0, totalRequestApproveArr: 0,
totalConfirmArr: 0, totalConfirmArr: 0,
}); });
const [showAlert, setShowAlert] = useState({
isError: false,
title: '',
message: '',
});
// approveConfirmList payload // approveConfirmList payload
const [approveReqPayload, setApproveReqPayload] = useState({ const [approveReqPayload, setApproveReqPayload] = useState({
type: 'Tất cả', type: 'Tất cả',
...@@ -39,104 +39,32 @@ const ConfirmDateContainer = props => { ...@@ -39,104 +39,32 @@ const ConfirmDateContainer = props => {
pageSize: 5, pageSize: 5,
isRefresh: false, isRefresh: false,
}); });
const [isDisableLoadMore, setDisableLoadMore] = useState({
approveRequestBtn: false,
confirmBtn: false,
});
const [dataChart, setDataChart] = useState({ const [dataChart, setDataChart] = useState({
month: new Date().getMonth() + 1, month: new Date().getMonth() + 1,
data: {}, data: {},
}); });
const [modalContent, setModalContent] = useState(null); const [modalRequestConfirmWorkingDays, setModalRequestConfirmWorkingDays] =
useState({
visible: false,
});
const [dayPress, setDayPress] = useState(); const [dayPress, setDayPress] = useState();
// open the modal // open the modal
const onOpenDetailModal = detailItem => {}; const onOpenDetailModal = detailItem => {};
const onOpenAddModal = () => { const onOpenModalRequestConfirmWorkingDays = () => {
setModalContent( setModalRequestConfirmWorkingDays({userinfo: userInfo, visible: true});
<ConfirmModalAddNew
userDetails={userInfo}
onClose={onCloseModal}
alertMessage={alertMessage}
/>,
);
}; };
const onCloseModal = () => { const onCloseModalRequestConfirmWorkingDays = () => {
setModalContent(null); setModalRequestConfirmWorkingDays({userinfo: null, visible: false});
}; };
// main function // main function
const navigateToDayWage = () => { const navigateToDayWage = () => {
RootNavigation.navigate(APP_NAVIGATE_SCREEN.DAY_WAGE); 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 = () => { const onLoadMoreRequestApprove = () => {
setApproveReqPayload(prev => ({ setApproveReqPayload(prev => ({
...prev, ...prev,
...@@ -151,46 +79,7 @@ const ConfirmDateContainer = props => { ...@@ -151,46 +79,7 @@ const ConfirmDateContainer = props => {
isRefresh: false, 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 // refresh onClick event
const onRefreshApproveList = () => { const onRefreshApproveList = () => {
//console.log('onRefreshApproveList'); //console.log('onRefreshApproveList');
...@@ -255,7 +144,10 @@ const ConfirmDateContainer = props => { ...@@ -255,7 +144,10 @@ const ConfirmDateContainer = props => {
// fetchDataChart(parseInt(arr[1], 10)); // fetchDataChart(parseInt(arr[1], 10));
setDataChart(prev => ({ setDataChart(prev => ({
...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 => { const onChangeDayPressInChart = selectedItem => {
...@@ -294,69 +186,101 @@ const ConfirmDateContainer = props => { ...@@ -294,69 +186,101 @@ const ConfirmDateContainer = props => {
format.sort((a, b) => Moment(a.created_at) < Moment(b.created_at)); format.sort((a, b) => Moment(a.created_at) < Moment(b.created_at));
setRequestApproveArr(format); setRequestApproveArr(format);
}; };
const fetchDataChart = async month => {
//console.log('fetchDataChart') //=============================== FETCH DATA ================================//
const res = await dispatch(getAbsentChart()); const fetchAbsentApprovalRequests = async () => {
if (res && res.length > 0) { const res = await dispatch(
let filterByMonth = res.filter( getConfirmApprovedDate({
item => new Date(item.date).getMonth() + 1 === parseInt(month) && item, 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 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 = []; let formatData = [];
filterByMonth.forEach(item => { filterByMonth.forEach(item => {
//console.log(Moment(item.date).format('YYYY-MM-DD')); //console.log(Moment(item.date).format('YYYY-MM-DD'));
const objDay = Moment(item.date).format('YYYY-MM-DD'); const objDay = Moment(item.date).format('YYYY-MM-DD');
if (parseInt(item.absent_hours) > 0) { if (parseInt(item.absent_hours, 10) > 0) {
formatData.push({ formatData.push({
[objDay]: { [objDay]: {
selected: true, selected: true,
selectedColor: selectedColor:
(parseInt(item.absent_hours) > 8 && '#7d93ff') || (parseInt(item.absent_hours, 10) > 8 && '#7d93ff') ||
(parseInt(item.absent_hours) >= 6 && (parseInt(item.absent_hours, 10) >= 6 &&
parseInt(item.absent_hours) <= 8 && parseInt(item.absent_hours, 10) <= 8 &&
'#7d93ff') || '#7d93ff') ||
(parseInt(item.absent_hours) >= 4 && (parseInt(item.absent_hours, 10) >= 4 &&
parseInt(item.absent_hours) <= 6 && parseInt(item.absent_hours, 10) <= 6 &&
'#7d93ff') || '#7d93ff') ||
'#dfe4ff', '#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 => ({ setDataChart(prev => ({
...prev, ...prev,
data: filterByMonth, data: filterByMonth,
})); }));
} }
}; });
const minutesToHours = (start, finish) => { }, [dataChart.month, dispatch]);
//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
// useEffect
useEffect(() => { useEffect(() => {
confirmDateList && formatDataConfirmListFromApi(); confirmDateList && formatDataConfirmListFromApi();
}, [confirmDateList]); }, [confirmDateList]);
useEffect(() => { useEffect(() => {
dataChart.month && fetchDataChart(dataChart.month); dataChart.month && fetchStatisticsConfirmWorkingDays();
}, [dataChart.month]); }, [dataChart.month]);
// useEffect(() => {
// dataChart.data && console.log(dataChart.data);
// }, [dataChart.data]);
useEffect(() => { useEffect(() => {
confirmApprovedDateList && confirmApprovedDateList &&
formatDataApproveConfirmListFromApi(confirmApprovedDateList); formatDataApproveConfirmListFromApi(confirmApprovedDateList);
...@@ -365,36 +289,30 @@ const ConfirmDateContainer = props => { ...@@ -365,36 +289,30 @@ const ConfirmDateContainer = props => {
useEffect(() => { useEffect(() => {
approveReqPayload && fetchAbsentApprovalRequests(); approveReqPayload && fetchAbsentApprovalRequests();
}, [approveReqPayload]); }, [approveReqPayload]);
useEffect(() => { useEffect(() => {
userConfirmPayload && loadDataConfirmDay(); userConfirmPayload && loadDataConfirmDay();
}, [userConfirmPayload]); }, [userConfirmPayload]);
useEffect(() => {
checkVisibleLoadMore();
}, [requestApproveArr, confirmList, totalArr]);
const confirmProps = { const confirmProps = {
userInfo, userInfo,
showAlert,
requestApproveArr, requestApproveArr,
confirmList, confirmList,
isDisableLoadMore,
dataChart, dataChart,
modalContent,
approveReqPayload, approveReqPayload,
dayPress, dayPress,
modalRequestConfirmWorkingDays,
onChangeDayPressInChart, onChangeDayPressInChart,
onOpenDetailModal, onOpenDetailModal,
onOpenAddModal,
onLoadMoreConfirmList, onLoadMoreConfirmList,
onHideAlert,
navigateToDayWage, navigateToDayWage,
alertMessage,
onLoadMoreRequestApprove, onLoadMoreRequestApprove,
onRefreshApproveList, onRefreshApproveList,
onRefreshConfirmList, onRefreshConfirmList,
onChangeSelectFilter, onChangeSelectFilter,
onChangeMonthFilter, onChangeMonthFilter,
minutesToHours, onCloseModalRequestConfirmWorkingDays,
onOpenModalRequestConfirmWorkingDays,
}; };
return <ConfirmDateMainView {...confirmDatePropsProvider(confirmProps)} />; return <ConfirmDateMainView {...confirmDatePropsProvider(confirmProps)} />;
}; };
......
...@@ -31,6 +31,7 @@ import { ...@@ -31,6 +31,7 @@ import {
deleteApproveConfirmDay, deleteApproveConfirmDay,
} from '../../../store/actions/UserAction'; } from '../../../store/actions/UserAction';
import AppText from '../../../components/AppText'; import AppText from '../../../components/AppText';
import Utils from '../../../utils';
const windowWidth = Dimensions.get('window').width; const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height; const windowHeight = Dimensions.get('window').height;
const ConfirmModalAddNew = ({ const ConfirmModalAddNew = ({
...@@ -174,13 +175,7 @@ const ConfirmModalAddNew = ({ ...@@ -174,13 +175,7 @@ const ConfirmModalAddNew = ({
} }
//console.log('deleteItem', detailItem); //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(() => { useEffect(() => {
onOpenDetail(detailItem); onOpenDetail(detailItem);
}, []); }, []);
...@@ -271,7 +266,7 @@ const ConfirmModalAddNew = ({ ...@@ -271,7 +266,7 @@ const ConfirmModalAddNew = ({
Thi gian ngh Thi gian ngh
</AppText> </AppText>
<AppText> <AppText>
{minutesToHours( {Utils.minutesToHours(
confirmDateDetail.start, confirmDateDetail.start,
confirmDateDetail.finish, confirmDateDetail.finish,
)} )}
......
export default function confirmDatePropsProvider(props) { export default function confirmDatePropsProvider(props) {
const { const {
userInfo, userInfo,
showAlert,
requestApproveArr, requestApproveArr,
confirmList, confirmList,
isDisableLoadMore,
dataChart, dataChart,
modalContent,
approveReqPayload, approveReqPayload,
dayPress, dayPress,
modalRequestConfirmWorkingDays,
onChangeDayPressInChart, onChangeDayPressInChart,
onOpenDetailModal, onOpenDetailModal,
onOpenAddModal,
onLoadMoreConfirmList, onLoadMoreConfirmList,
onHideAlert,
navigateToDayWage, navigateToDayWage,
alertMessage,
onLoadMoreRequestApprove, onLoadMoreRequestApprove,
onRefreshApproveList, onRefreshApproveList,
onRefreshConfirmList, onRefreshConfirmList,
onChangeSelectFilter, onChangeSelectFilter,
onChangeMonthFilter, onChangeMonthFilter,
minutesToHours, onCloseModalRequestConfirmWorkingDays,
onOpenModalRequestConfirmWorkingDays,
} = props; } = props;
return { return {
userInfo, userInfo,
showAlert,
requestApproveArr, requestApproveArr,
confirmList, confirmList,
isDisableLoadMore,
dataChart, dataChart,
modalContent,
approveReqPayload, approveReqPayload,
dayPress, dayPress,
modalRequestConfirmWorkingDays,
onChangeDayPressInChart, onChangeDayPressInChart,
onOpenDetailModal, onOpenDetailModal,
onOpenAddModal,
onLoadMoreConfirmList, onLoadMoreConfirmList,
onHideAlert,
navigateToDayWage, navigateToDayWage,
alertMessage,
onLoadMoreRequestApprove, onLoadMoreRequestApprove,
onRefreshApproveList, onRefreshApproveList,
onRefreshConfirmList, onRefreshConfirmList,
onChangeSelectFilter, onChangeSelectFilter,
onChangeMonthFilter, onChangeMonthFilter,
minutesToHours, approveRequestWorkingDaysProps: {
approveReqPayload,
onChangeSelectFilter,
requestApproveArr,
onOpenDetailModal,
},
onCloseModalRequestConfirmWorkingDays,
onOpenModalRequestConfirmWorkingDays,
}; };
} }
...@@ -33,6 +33,20 @@ export const getConfirmApprovedDate = createAsyncThunk( ...@@ -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({ const authSlice = createSlice({
name: 'confirmDate', name: 'confirmDate',
initialState: initialState, initialState: initialState,
......
...@@ -67,49 +67,42 @@ const styles = StyleSheet.create({ ...@@ -67,49 +67,42 @@ const styles = StyleSheet.create({
marginRight: 5, marginRight: 5,
}, },
view: { view: {
width: windowWidth, width: windowWidth - 20,
alignSelf: 'center',
borderWidth: 1,
backgroundColor: colors.white, backgroundColor: colors.white,
borderColor: colors.white, borderColor: colors.white,
padding: 10, padding: 10,
marginTop: 10, marginHorizontal: 10,
borderRadius: 5,
}, },
btnConfirm: { btnConfirm: {
backgroundColor: '#5d78ff', backgroundColor: colors.purple_blue,
alignItems: 'center', borderRadius: 5,
justifyContent: 'center',
borderWidth: 1,
borderColor: '#5d78ff',
borderRadius: 8,
width: windowWidth - 100,
height: 35,
flexDirection: 'row', flexDirection: 'row',
padding: 10,
}, },
whiteTxt: { whiteTxt: {
color: colors.white, color: colors.white,
fontWeight: '500', fontWeight: '500',
}, },
blueTxt: { blueTxt: {
color: '#5d78ff', color: colors.purple_blue,
fontWeight: '500', fontWeight: '500',
}, },
iconPlus: { iconPlus: {
width: 20, width: 20,
height: 20, height: 20,
marginRight: 10, marginRight: 5,
}, },
primary_blue: { primary_blue: {
color: '#5d78ff', color: colors.purple_blue,
}, },
item: { item: {
padding: 20, padding: 10,
marginVertical: 8, margin: 8,
marginHorizontal: 16,
borderWidth: 1, borderWidth: 1,
borderBottomColor: '#f2f2f2', borderBottomColor: colors.gray95,
borderTopColor: '#f2f2f2', borderTopColor: colors.gray95,
borderRightColor: '#f2f2f2', borderRightColor: colors.gray95,
borderTopLeftRadius: 10, borderTopLeftRadius: 10,
borderBottomLeftRadius: 10, borderBottomLeftRadius: 10,
borderLeftWidth: 5, borderLeftWidth: 5,
...@@ -203,7 +196,7 @@ const styles = StyleSheet.create({ ...@@ -203,7 +196,7 @@ const styles = StyleSheet.create({
width: 50, width: 50,
}, },
btnSubmit: { btnSubmit: {
backgroundColor: '#5d78ff', backgroundColor: colors.purple_blue,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
height: 40, height: 40,
...@@ -336,7 +329,7 @@ const styles = StyleSheet.create({ ...@@ -336,7 +329,7 @@ const styles = StyleSheet.create({
paddingHorizontal: 8, paddingHorizontal: 8,
}, },
wrapperComment: { wrapperComment: {
borderColor: '#5d78ff', borderColor: colors.purple_blue,
borderStyle: 'dashed', borderStyle: 'dashed',
borderWidth: 0.5, borderWidth: 0.5,
borderRadius: 4, borderRadius: 4,
...@@ -351,7 +344,7 @@ const styles = StyleSheet.create({ ...@@ -351,7 +344,7 @@ const styles = StyleSheet.create({
flexDirection: 'row', flexDirection: 'row',
paddingHorizontal: 8, paddingHorizontal: 8,
paddingVertical: 12, paddingVertical: 12,
backgroundColor: '#5d78ff', backgroundColor: colors.purple_blue,
borderRadius: 4, borderRadius: 4,
}, },
btnReject: { btnReject: {
...@@ -381,7 +374,7 @@ const styles = StyleSheet.create({ ...@@ -381,7 +374,7 @@ const styles = StyleSheet.create({
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'center', alignItems: 'center',
borderBottomWidth: 1, borderBottomWidth: 1,
borderBottomColor: '#5d78ff', borderBottomColor: colors.purple_blue,
paddingBottom: 5, paddingBottom: 5,
paddingLeft: 10, paddingLeft: 10,
paddingRight: 15, paddingRight: 15,
...@@ -395,6 +388,19 @@ const styles = StyleSheet.create({ ...@@ -395,6 +388,19 @@ const styles = StyleSheet.create({
borderColor: '#7d93ff', borderColor: '#7d93ff',
paddingTop: 15, 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({ export const statisticsConfirmWorkdaysStyles = StyleSheet.create({
container: { container: {
......
...@@ -17,160 +17,130 @@ import SelectDropdown from 'react-native-select-dropdown'; ...@@ -17,160 +17,130 @@ import SelectDropdown from 'react-native-select-dropdown';
import AppText from '../../../components/AppText'; import AppText from '../../../components/AppText';
import StatisticsConfirmWorkdays from './components/StatisticsConfirmWorkdays'; import StatisticsConfirmWorkdays from './components/StatisticsConfirmWorkdays';
import commonStyles from '../../../styles/commonStyles'; 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 = ({ const approveWorkingDayStatus = [
isDisableLoadMore, {label: 'Tất cả', value: 'Tất cả'},
showAlert, {label: 'Chưa duyệt', value: 'Chưa duyệt'},
onHideAlert, {label: 'Đã duyệt', value: 'Đã duyệt'},
navigateToDayWage, {label: 'Đã từ chối', value: 'Đã từ chối'},
onLoadMoreRequestApprove, ];
onLoadMoreConfirmList,
requestApproveArr, const ConfirmWorkingDaysSession = React.memo(
confirmList, ({onOpenModalRequestConfirmWorkingDays, navigateToDayWage}) => {
onRefreshConfirmList,
modalContent,
onOpenDetailModal,
onOpenRequestLeavesModal,
approveReqPayload,
onChangeSelectFilter,
minutesToHours,
dataChart,
onChangeMonthFilter,
dayPress,
}) => {
return ( return (
<SafeAreaView>
<ScrollView nestedScrollEnabled={true}>
<StatisticsConfirmWorkdays
dataChart={dataChart}
onChangeMonthFilter={onChangeMonthFilter}
dayPress={dayPress}
/>
<View style={[styles.view, commonStyles.baseShadow]}> <View style={[styles.view, commonStyles.baseShadow]}>
<AppText style={{fontWeight: '500', marginBottom: 10}}> <AppText style={{fontWeight: '500', marginBottom: 10}}>
Xác nhn ngày công ca bn:{' '} Xác nhn ngày công ca bn:
</AppText> </AppText>
<View style={{alignItems: 'center', justifyContent: 'center'}}> <View style={{alignItems: 'center', justifyContent: 'center'}}>
<ButtonComponent <ButtonComponent
style={styles.btnConfirm} style={styles.btnConfirm}
onPress={onOpenRequestLeavesModal} onPress={onOpenModalRequestConfirmWorkingDays}
leftIcon={IMAGES.IcBtnAdd} leftIcon={IMAGES.IcBtnAdd}
styleIcon={styles.iconPlus} styleIcon={styles.iconPlus}
text={'XÁC NHẬN NGÀY CÔNG'} text={'XÁC NHẬN NGÀY CÔNG'}
textStyle={styles.whiteTxt} textStyle={styles.whiteTxt}
/> />
</View> </View>
<AppText style={{fontWeight: '500', marginBottom: 10, marginTop: 10}}> <AppText style={{fontWeight: '500'}}>Liên kết nhanh: </AppText>
Liên kết nhanh:{' '} <TouchableOpacity style={commonStyles.row} onPress={navigateToDayWage}>
</AppText>
<TouchableOpacity
style={{flexDirection: 'row'}}
onPress={navigateToDayWage}>
<Image source={IMAGES.IcTask} style={styles.iconPlus} /> <Image source={IMAGES.IcTask} style={styles.iconPlus} />
<AppText style={styles.primary_blue}> <AppText style={styles.primary_blue}>Bng chm công ca tôi</AppText>
Bng chm công ca tôi
</AppText>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
{requestApproveArr && ( );
<View style={[styles.view]}> },
{requestApproveArr && ( function (prevProps, nextProps) {
return (
prevProps.onOpenRequestLeavesModal === nextProps.onOpenRequestLeavesModal
);
},
);
const ApproveRequestWorkingDays = React.memo(
props => {
const {
approveReqPayload,
onChangeSelectFilter,
requestApproveArr,
onOpenDetailModal,
} = props;
return (
<View <View
style={{ style={[
flexDirection: 'row', styles.view,
}}> commonStyles.baseShadow,
commonStyles.marginVertical10,
]}>
<View style={[commonStyles.row, commonStyles.spaceBetweenCenter]}>
<AppText <AppText
style={{ style={{
fontWeight: 'bold', fontWeight: 'bold',
marginBottom: 4,
fontSize: 17, fontSize: 17,
flex: 1,
alignSelf: 'center',
}}> }}>
Duyt ngày công{' '} Duyt ngày công
</AppText> </AppText>
<SelectDropdownComponent
<View value={approveReqPayload?.type}
style={{ selectData={approveWorkingDayStatus}
alignItems: 'flex-end', setValue={onChangeSelectFilter}
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> </View>
)}
{requestApproveArr?.length > 0 && {requestApproveArr.map((item, index) => (
// requestApproveArr[0]?.approver_id == userDetails.id &&
requestApproveArr.map((item, index) => (
<TouchableOpacity <TouchableOpacity
onPress={() => onOpenDetailModal(item)} onPress={() => onOpenDetailModal(item)}
key={index} key={index}
style={[ style={[
styles.item, styles.item,
commonStyles.spaceBetweenCenter,
{ {
borderLeftColor: item.extend_approved_status_color, borderLeftColor: item?.extend_approved_status_color,
}, },
]}> ]}>
<View style={{flexDirection: 'row', flex: 2}}> <View style={commonStyles.row}>
<Image <Image
source={{ source={
uri: item?.extend_creator_avatar
'https://meu.anawork.com' + ? {
item.extend_creator_avatar, uri: config.imageEndPoint + item.extend_creator_avatar,
}} }
: IMAGES.IcAvatarDefault
}
style={{width: 35, height: 35, marginRight: 5}} style={{width: 35, height: 35, marginRight: 5}}
/> />
<View> <View>
<AppText style={styles.title}> <AppText style={styles.title}>
{item.extend_creator_full_name} {item?.extend_creator_full_name?.length > 20
? item?.extend_creator_full_name.slice(0, 15) + '...'
: item?.extend_creator_full_name}
</AppText> </AppText>
<AppText> <AppText isSubText>
{Moment(item.start).format('DD/MM/YYYY')} {Moment(item.start).format('DD/MM/YYYY')}
</AppText> </AppText>
</View> </View>
</View> </View>
<View <View
style={{ style={{
flex: 1,
justifyContent: 'flex-end',
alignItems: 'flex-end', alignItems: 'flex-end',
marginLeft: 10,
}}> }}>
<AppText> <AppText>
{item.reason.length > 20 {item.reason.length > 20
? item.reason.slice(0, 15) + '...' ? item.reason.slice(0, 15) + '...'
: item.reason} : item.reason}
</AppText> </AppText>
<AppText>{minutesToHours(item.start, item.finish)}</AppText> <AppText isSubText>
{Utils.minutesToHours(item?.start, item?.finish)}
</AppText>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
))} ))}
{!isDisableLoadMore.approveRequestBtn && {/* {!isDisableLoadMore.approveRequestBtn &&
requestApproveArr?.length > 0 && ( requestApproveArr?.length > 0 && (
<ButtonComponent <ButtonComponent
style={{ style={{
...@@ -182,49 +152,42 @@ const ConfirmDateMainView = ({ ...@@ -182,49 +152,42 @@ const ConfirmDateMainView = ({
textStyle={{color: '#5d78ff'}} textStyle={{color: '#5d78ff'}}
onPress={onLoadMoreRequestApprove} onPress={onLoadMoreRequestApprove}
/> />
)} )} */}
</View> </View>
)} );
<View style={[styles.view, {marginBottom: 30}]}> },
function (prevProps, nextProps) {
return prevProps.requestApproveArr === nextProps.requestApproveArr;
},
);
const ConfirmWorkingDays = React.memo(
({confirmList, onOpenDetailModal, onRefreshConfirmList}) => {
return (
<View <View
style={{ style={[
flexDirection: 'row', styles.view,
}}> commonStyles.baseShadow,
commonStyles.marginVertical10,
]}>
<View style={[commonStyles.row, commonStyles.spaceBetweenCenter]}>
<AppText <AppText
isBold
style={{ style={{
fontWeight: 'bold',
marginBottom: 4,
fontSize: 17, fontSize: 17,
alignSelf: 'center',
flex: 2,
}}> }}>
Xác nhn ngày công ca tôi{' '} Xác nhn ngày công ca tôi
</AppText> </AppText>
<View style={{alignItems: 'flex-end', flex: 1, paddingRight: 20}}>
<ButtonComponent <ButtonComponent
text={'Tải lại'} text={'Tải lại'}
textStyle={{color: '#5d78ff'}} textStyle={{color: colors.purple_blue}}
style={{ style={styles.refreshBtn}
justifyContent: 'center',
alignItems: 'center',
padding: 10,
flexDirection: 'row',
}}
onPress={onRefreshConfirmList} onPress={onRefreshConfirmList}
leftIcon={IMAGES.IcRefresh} leftIcon={IMAGES.IcRefresh}
styleIcon={{width: 20, height: 20}} styleIcon={{width: 20, height: 20}}
/> />
</View> </View>
</View>
{confirmList.length === 0 && ( {confirmList.length === 0 && (
<View <View style={styles.emptyConfirmWorkingDays}>
style={{
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white',
marginTop: 10,
padding: 20,
}}>
<AppText style={{textAlign: 'center'}}> <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 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é! trên nhé!
...@@ -264,11 +227,13 @@ const ConfirmDateMainView = ({ ...@@ -264,11 +227,13 @@ const ConfirmDateMainView = ({
? item.reason.slice(0, 15) + '...' ? item.reason.slice(0, 15) + '...'
: item.reason} : item.reason}
</AppText> </AppText>
<AppText>{minutesToHours(item.start, item.finish)}</AppText> <AppText>
{Utils.minutesToHours(item.start, item.finish)}
</AppText>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
))} ))}
{confirmList.length > 0 && !isDisableLoadMore.confirmBtn && ( {/* {confirmList.length > 0 && !isDisableLoadMore.confirmBtn && (
<ButtonComponent <ButtonComponent
style={{ style={{
justifyContent: 'center', justifyContent: 'center',
...@@ -279,22 +244,58 @@ const ConfirmDateMainView = ({ ...@@ -279,22 +244,58 @@ const ConfirmDateMainView = ({
textStyle={{color: '#5d78ff'}} textStyle={{color: '#5d78ff'}}
onPress={onLoadMoreConfirmList} onPress={onLoadMoreConfirmList}
/> />
)} )} */}
</View> </View>
<Alert );
show={showAlert.isError} },
showProgress={false} function (prevProps, nextProps) {
title={showAlert.title} return prevProps.confirmList === nextProps.confirmList;
message={showAlert.message} },
closeOnTouchOutside={true} );
closeOnHardwareBackPress={false} const ConfirmDateMainView = ({
showConfirmButton={true} navigateToDayWage,
confirmText="Đóng" requestApproveArr = [],
confirmButtonColor="#DD6B55" confirmList,
onConfirmPressed={onHideAlert} 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> </ScrollView>
{modalRequestConfirmWorkingDays?.visible && (
<ModalRequestConfirmWorkingDays
userinfo={modalRequestConfirmWorkingDays?.userinfo}
onClose={onCloseModalRequestConfirmWorkingDays}
/>
)}
</SafeAreaView> </SafeAreaView>
); );
}; };
......
import Moment from 'moment'; import Moment from 'moment';
import React, {memo} from 'react'; import React, {memo} from 'react';
import {Image, View} from 'react-native'; import {View} from 'react-native';
import {IMAGES} from '../../../../values/images';
import styles, {statisticsConfirmWorkdaysStyles} from '../../style'; import styles, {statisticsConfirmWorkdaysStyles} from '../../style';
import SelectDropdown from 'react-native-select-dropdown';
import AppText from '../../../../components/AppText'; import AppText from '../../../../components/AppText';
import SelectDropdownComponent from '../../../../components/Select'; import SelectDropdownComponent from '../../../../components/Select';
import commonStyles from '../../../../styles/commonStyles'; 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 => { ...@@ -250,14 +250,6 @@ const OnLeaveContainer = props => {
setLeaveRequestList([...format]); 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 getAndOpenModal = async id => {
const res = await dispatch(getUserLeavesById(id)); const res = await dispatch(getUserLeavesById(id));
if (res) { if (res) {
...@@ -478,7 +470,6 @@ const OnLeaveContainer = props => { ...@@ -478,7 +470,6 @@ const OnLeaveContainer = props => {
onOpenRequestLeavesModal, onOpenRequestLeavesModal,
onCloseModal, onCloseModal,
onChangeSelectFilter, onChangeSelectFilter,
minutesToHours,
onSubmitLeaveRequest, onSubmitLeaveRequest,
onSelectManagerLeaveRequest, onSelectManagerLeaveRequest,
onSubmitApproveLeaveRequest, onSubmitApproveLeaveRequest,
......
...@@ -23,7 +23,6 @@ export default function onLeavePropsProvider(props) { ...@@ -23,7 +23,6 @@ export default function onLeavePropsProvider(props) {
onOpenRequestLeavesModal, onOpenRequestLeavesModal,
onCloseModal, onCloseModal,
onChangeSelectFilter, onChangeSelectFilter,
minutesToHours,
leavesDaysModal, leavesDaysModal,
leaveCategory, leaveCategory,
directManagersList, directManagersList,
...@@ -65,7 +64,6 @@ export default function onLeavePropsProvider(props) { ...@@ -65,7 +64,6 @@ export default function onLeavePropsProvider(props) {
onOpenRequestLeavesModal, onOpenRequestLeavesModal,
onCloseModal, onCloseModal,
onChangeSelectFilter, onChangeSelectFilter,
minutesToHours,
approveRequestLeavesDaysProps: { approveRequestLeavesDaysProps: {
payloadApproveRequestLeavesDays, payloadApproveRequestLeavesDays,
onChangeSelectFilter, onChangeSelectFilter,
......
...@@ -2,23 +2,170 @@ ...@@ -2,23 +2,170 @@
import CheckBox from '@react-native-community/checkbox'; import CheckBox from '@react-native-community/checkbox';
import Moment from 'moment'; import Moment from 'moment';
import React, {useMemo} from 'react'; import React, {useMemo} from 'react';
import { import {Image, Modal, ScrollView, TouchableOpacity, View} from 'react-native';
Image,
Modal,
ScrollView,
TextInput,
TouchableOpacity,
View,
} from 'react-native';
import DateTimePickerModal from 'react-native-modal-datetime-picker'; import DateTimePickerModal from 'react-native-modal-datetime-picker';
import AppText from '../../../../components/AppText'; import AppText from '../../../../components/AppText';
import ButtonComponent from '../../../../components/ButtonComponent'; import ButtonComponent from '../../../../components/ButtonComponent';
import SelectDropdownComponent from '../../../../components/Select'; import SelectDropdownComponent from '../../../../components/Select';
import TextInputComponent from '../../../../components/TextInputComponent';
import config from '../../../../config'; import config from '../../../../config';
import {IMAGES} from '../../../../values/images'; import {IMAGES} from '../../../../values/images';
import {leavesModalStyles} from '../../style'; 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 RequestLeavesDays = props => {
const { const {
userInfo, userInfo,
...@@ -71,25 +218,7 @@ const RequestLeavesDays = props => { ...@@ -71,25 +218,7 @@ const RequestLeavesDays = props => {
Nghỉ phép mới Nghỉ phép mới
</AppText> </AppText>
</View> </View>
<View style={{flexDirection: 'row', marginVertical: 10}}> <UserHeader userInfo={userInfo} fullName={fullName} />
<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>
<View> <View>
<AppText style={leavesModalStyles.modalTitle}> <AppText style={leavesModalStyles.modalTitle}>
Thông tin chung Thông tin chung
...@@ -299,7 +428,12 @@ const RequestLeavesDays = props => { ...@@ -299,7 +428,12 @@ const RequestLeavesDays = props => {
/> />
</View> </View>
</View> </View>
<View style={leavesModalStyles.rowView}> <Attachments
leaveRequestImage={leaveRequestImage}
onDeleteLeaveRequestImage={onDeleteLeaveRequestImage}
openGallery={openGallery}
/>
{/* <View style={leavesModalStyles.rowView}>
<AppText>Tệp đính kèm</AppText> <AppText>Tệp đính kèm</AppText>
<View style={{flexDirection: 'row'}}> <View style={{flexDirection: 'row'}}>
{leaveRequestImage.length > 0 && {leaveRequestImage.length > 0 &&
...@@ -328,7 +462,7 @@ const RequestLeavesDays = props => { ...@@ -328,7 +462,7 @@ const RequestLeavesDays = props => {
/> />
)} )}
</View> </View>
</View> </View> */}
{isRequest && directManagersList.length > 0 && ( {isRequest && directManagersList.length > 0 && (
<View style={{marginTop: 10}}> <View style={{marginTop: 10}}>
<AppText <AppText
...@@ -385,36 +519,13 @@ const RequestLeavesDays = props => { ...@@ -385,36 +519,13 @@ const RequestLeavesDays = props => {
</View> </View>
)} )}
</View> </View>
<View <ButtonAction
style={{ onCloseModal={onCloseModal}
flexDirection: 'row', isRequest={isRequest}
justifyContent: 'flex-end', userInfo={userInfo}
marginTop: 20, onSubmitLeaveRequest={onSubmitLeaveRequest}
}}> onSubmitApproveLeaveRequest={onSubmitApproveLeaveRequest}
<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>
</View> </View>
</ScrollView> </ScrollView>
</Modal> </Modal>
......
...@@ -275,12 +275,6 @@ const OvertimeContainer = props => { ...@@ -275,12 +275,6 @@ const OvertimeContainer = props => {
RootNavigation.navigate(APP_NAVIGATE_SCREEN.ON_LEAVE); 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 => { const onChangeSelectFilter = selectedItem => {
if (selectedItem === 'Tất cả') { if (selectedItem === 'Tất cả') {
setPayloadOtApproveList({ setPayloadOtApproveList({
...@@ -409,7 +403,6 @@ const OvertimeContainer = props => { ...@@ -409,7 +403,6 @@ const OvertimeContainer = props => {
onLoadMoreOtList, onLoadMoreOtList,
setShowAlert, setShowAlert,
setMonth, setMonth,
minutesToHours,
navigateToConfirmDate, navigateToConfirmDate,
navigateToOnLeave, navigateToOnLeave,
onLoadMoreOtApproveReqList, 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 React from 'react';
import { import {
Image, Image,
...@@ -21,6 +17,7 @@ import FastImage from 'react-native-fast-image'; ...@@ -21,6 +17,7 @@ import FastImage from 'react-native-fast-image';
import AppText from '../../components/AppText'; import AppText from '../../components/AppText';
import ButtonComponent from '../../components/ButtonComponent'; import ButtonComponent from '../../components/ButtonComponent';
import styles from './style'; import styles from './style';
import Utils from '../../utils';
const OvertimeScreen = ({ const OvertimeScreen = ({
userDetails, userDetails,
otVoucherList, otVoucherList,
...@@ -32,7 +29,6 @@ const OvertimeScreen = ({ ...@@ -32,7 +29,6 @@ const OvertimeScreen = ({
showAlert, showAlert,
setShowAlert, setShowAlert,
setMonth, setMonth,
minutesToHours,
isDisableLoadMore, isDisableLoadMore,
onLoadMoreOtList, onLoadMoreOtList,
onLoadMoreOtApproveReqList, onLoadMoreOtApproveReqList,
...@@ -336,7 +332,7 @@ const OvertimeScreen = ({ ...@@ -336,7 +332,7 @@ const OvertimeScreen = ({
}}> }}>
<AppText>{''}</AppText> <AppText>{''}</AppText>
<AppText style={{textAlign: 'right'}}> <AppText style={{textAlign: 'right'}}>
{minutesToHours(item.start, item.finish)} {Utils.minutesToHours(item.start, item.finish)}
</AppText> </AppText>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
......
...@@ -17,5 +17,12 @@ const commonStyles = StyleSheet.create({ ...@@ -17,5 +17,12 @@ const commonStyles = StyleSheet.create({
elevation: 5, elevation: 5,
}, },
row: {
flexDirection: 'row',
},
spaceBetweenCenter: {justifyContent: 'space-between', alignItems: 'center'},
marginVertical10: {
marginVertical: 10,
},
}); });
export default commonStyles; export default commonStyles;
...@@ -168,7 +168,14 @@ const formatCurrency = price => { ...@@ -168,7 +168,14 @@ const formatCurrency = price => {
const getCategoryNotification = category => { const getCategoryNotification = category => {
return Object.keys(config.categoryNotification).find(el => el === 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 = { const Utils = {
storeData, storeData,
getData, getData,
...@@ -180,5 +187,6 @@ const Utils = { ...@@ -180,5 +187,6 @@ const Utils = {
formatMonthVietNamLanguage, formatMonthVietNamLanguage,
formatCurrency, formatCurrency,
getCategoryNotification, getCategoryNotification,
minutesToHours,
}; };
export default Utils; export default Utils;
...@@ -31,6 +31,7 @@ const colors = { ...@@ -31,6 +31,7 @@ const colors = {
blue5c: '#5c65dc', blue5c: '#5c65dc',
gray59: '#595959', gray59: '#595959',
grayE9: '#e9eaf9', grayE9: '#e9eaf9',
gray95: '#f2f2f2',
textColor: '#202121', textColor: '#202121',
baseShadowColor: '#000', 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