fix confirm working day

parent 70c8ad5f
...@@ -8,6 +8,14 @@ const confirmDateAPI = { ...@@ -8,6 +8,14 @@ const confirmDateAPI = {
`myAbsentApprovalRequests?Filters=${filter}&Sorts=${sort}&Page=${page}&PageSize=${pageSize}`, `myAbsentApprovalRequests?Filters=${filter}&Sorts=${sort}&Page=${page}&PageSize=${pageSize}`,
), ),
requestGetAbsentChart: () => axiosClient.get('myAbsentRequests/statistic'), requestGetAbsentChart: () => axiosClient.get('myAbsentRequests/statistic'),
requestPostConfirmWorkingDay: payload =>
axiosClient.post('absentRequests', payload),
requestPostApproveConfirmWorkingDay: ({id}) =>
axiosClient.post(`absentRequests/${id}/approve?comment=&nextApproverId=`),
requestMyAbsentRequest: ({page, pageSize}) =>
axiosClient.get(
`myAbsentRequests?Filters=&Sorts=-start&Page=${page}&PageSize=${pageSize}`,
),
}; };
export default confirmDateAPI; export default confirmDateAPI;
...@@ -5,15 +5,7 @@ import colors from '../../values/colors'; ...@@ -5,15 +5,7 @@ import colors from '../../values/colors';
const FONT_FAMILY_BASE = fonts.beProLight; const FONT_FAMILY_BASE = fonts.beProLight;
const AppText = ({ const AppText = ({variant, children, style, onPress, color, isSubText}) => {
variant,
children,
style,
onPress,
color,
isSubText,
isBold,
}) => {
const defaultStyle = { const defaultStyle = {
fontFamily: FONT_FAMILY_BASE, fontFamily: FONT_FAMILY_BASE,
fontSize: isSubText ? 12 : 14, fontSize: isSubText ? 12 : 14,
......
...@@ -8,13 +8,27 @@ import ConfirmModalDetails from './confirm-modals/ConfirmModalDetails'; ...@@ -8,13 +8,27 @@ import ConfirmModalDetails from './confirm-modals/ConfirmModalDetails';
import { import {
getAbsentChart, getAbsentChart,
getConfirmApprovedDate, getConfirmApprovedDate,
getMyAbsentRequests,
getUserConfirmDay, getUserConfirmDay,
handleSelectManagersConfirmWorkingDayRequest,
postConfirmWorkingDay,
postSubmitApproveConfirmWorkingDayRequest,
} from './confirmDateSlice'; } from './confirmDateSlice';
import ConfirmDateMainView from './template/ConfirmMainView'; import ConfirmDateMainView from './template/ConfirmMainView';
import confirmDatePropsProvider from './confirmDatePropsProvider'; import confirmDatePropsProvider from './confirmDatePropsProvider';
import Utils from '../../utils'; import Utils from '../../utils';
import {launchImageLibrary} from 'react-native-image-picker';
import {handleSelectManagersLeaveRequest} from '../onleave/onLeaveSlice';
import {ToastMessage} from '../../utils/MessageUtil';
import moment from 'moment';
const ConfirmDateContainer = props => { const ConfirmDateContainer = props => {
const {confirmDateList, confirmApprovedDateList, userInfo} = props; const {
confirmDateList,
confirmApprovedDateList,
userInfo,
directManagersList,
myAbsentRequests,
} = props;
const dispatch = useDispatch(); const dispatch = useDispatch();
const [requestApproveArr, setRequestApproveArr] = useState([]); const [requestApproveArr, setRequestApproveArr] = useState([]);
...@@ -47,19 +61,59 @@ const ConfirmDateContainer = props => { ...@@ -47,19 +61,59 @@ const ConfirmDateContainer = props => {
const [modalRequestConfirmWorkingDays, setModalRequestConfirmWorkingDays] = const [modalRequestConfirmWorkingDays, setModalRequestConfirmWorkingDays] =
useState({ useState({
visible: false, visible: false,
userInfo: null,
isRequest: false,
}); });
const [dayPress, setDayPress] = useState(); const [dayPress, setDayPress] = useState();
// open the modal
const onOpenDetailModal = detailItem => {};
const onOpenModalRequestConfirmWorkingDays = () => { const [openTimePicker, setOpenTimePicker] = useState({
setModalRequestConfirmWorkingDays({userinfo: userInfo, visible: true}); startDate: false,
finishDate: false,
startTime: false,
finishTime: false,
});
const [confirmDateRequestImage, setConfirmDateRequestImage] = useState([]);
const [confirmDateRequestTicket, setConfirmDateRequestTicket] = useState({
startDate: new Date(),
finishDate: new Date(),
reason: '',
});
// open the modal
const onOpenModalRequestConfirmWorkingDays = userDetails => {
const user = {
id: userDetails?.staff_id,
avatar: userDetails?.extend_creator_avatar,
full_name: userDetails?.extend_creator_full_name,
employee_code: userDetails?.extend_creator_employee_code,
position: userDetails?.extend_creator_position,
isApprover: userDetails?.approver_id === userInfo?.id,
confirmStatus: userDetails?.extend_approved_status_name !== 'APPROVED',
confirm_working_id: userDetails?.id,
};
setModalRequestConfirmWorkingDays({
userInfo: userDetails ? user : userInfo,
visible: true,
isRequest: !userDetails ? true : false,
});
if (userDetails) {
setConfirmDateRequestTicket({
startDate: new Date(userDetails?.start),
finishDate: new Date(userDetails?.finish),
reason: userDetails?.reason,
});
}
}; };
const onCloseModalRequestConfirmWorkingDays = () => { const onCloseModalRequestConfirmWorkingDays = () => {
setModalRequestConfirmWorkingDays({userinfo: null, visible: false}); setModalRequestConfirmWorkingDays({
userInfo: null,
visible: false,
isRequest: false,
});
}; };
// main function // main function
const navigateToDayWage = () => { const navigateToDayWage = () => {
RootNavigation.navigate(APP_NAVIGATE_SCREEN.DAY_WAGE); RootNavigation.navigate(APP_NAVIGATE_SCREEN.DAY_WAGE);
...@@ -271,8 +325,126 @@ const ConfirmDateContainer = props => { ...@@ -271,8 +325,126 @@ const ConfirmDateContainer = props => {
} }
}); });
}, [dataChart.month, dispatch]); }, [dataChart.month, dispatch]);
const fetchMyAbsentRequests = () => {
dispatch(getMyAbsentRequests({page: 1, pageSize: 5}));
};
//============================= REQUEST CONFIRM WORKING DAYS =============================//
const openGallery = () => {
launchImageLibrary(
{
mediaType: 'photo',
includeBase64: true,
},
response => {
if (!response.didCancel) {
//console.log('AAA');
const {assets} = response;
setConfirmDateRequestImage(prev => [...prev, ...assets]);
//console.log(response.assets[0].uri)
}
},
);
};
const onDeleteConfirmDateRequestImage = index => {
const clone = [...confirmDateRequestImage];
clone.splice(index, 1);
setConfirmDateRequestImage([...clone]);
};
const onSelectManagerConfirmWorkingDayRequest = (index, value) => {
dispatch(handleSelectManagersLeaveRequest({index, value}));
};
const onSubmitConfirmWorkingDayRequest = () => {
if (handleSubmitConfirmWorkingDayRequest()) {
const approver = directManagersList.filter(item => item.isChecked);
const payload = {
start: confirmDateRequestTicket.startDate,
finish: confirmDateRequestTicket.finishDate,
approver_id: approver.length > 0 ? approver[0].id : null,
reason: confirmDateRequestTicket.reason,
timeStart: moment(confirmDateRequestTicket.startDate).format('HH:mm'),
timeFinish: moment(confirmDateRequestTicket.finishDate).format('HH:mm'),
};
dispatch(postConfirmWorkingDay(payload)).then(response => {
const {success} = Utils.getValues(response, 'payload', false);
success && fetchAbsentApprovalRequests();
ToastMessage({
title: 'Hệ thống',
message: `Đã gửi yêu cầu xác nhận ${
success ? 'thành công' : 'thất bại'
}`,
type: success ? 'success' : 'error',
});
onCloseModalRequestConfirmWorkingDays();
});
}
};
const handleSubmitConfirmWorkingDayRequest = () => {
if (directManagersList?.length === 0) {
return false;
}
const isSelectedManager = directManagersList.filter(item => item.isChecked);
if (confirmDateRequestTicket.reason.length === 0) {
ToastMessage({
title: 'Hệ thống',
message: 'Vui lòng nhập lý do',
type: 'error',
});
return false;
} else if (
moment(confirmDateRequestTicket.startDate) >
moment(confirmDateRequestTicket.finishDate)
) {
ToastMessage({
title: 'Hệ thống',
message: 'Vui lòng chọn ngày bắt đầu nhỏ hơn ngày kết thúc',
type: 'error',
timeVisible: 5000,
});
return false;
} else if (isSelectedManager.length === 0) {
ToastMessage({
title: 'Hệ thống',
message: 'Vui lòng chọn người duyệt!!!',
type: 'error',
timeVisible: 5000,
});
return false;
} else {
return true;
}
};
const onSubmitApproveConfirmWorkingDaysRequest = confirm_working_id => {
try {
dispatch(
postSubmitApproveConfirmWorkingDayRequest({id: confirm_working_id}),
).then(response => {
const {success} = Utils.getValues(response, 'payload', false);
if (success) {
fetchAbsentApprovalRequests();
onCloseModalRequestConfirmWorkingDays();
}
ToastMessage({
title: 'Hệ thống',
message: `Duyệt xác nhận ngày công ${
success ? 'thành công' : 'thất bại'
}`,
type: success ? 'success' : 'error',
});
});
} catch (err) {
ToastMessage({
title: 'Hệ thống',
message: 'Đã có lỗi xảy ra !!!',
type: 'error',
});
}
};
// useEffect // useEffect
useEffect(() => {
fetchMyAbsentRequests();
}, []);
useEffect(() => { useEffect(() => {
confirmDateList && formatDataConfirmListFromApi(); confirmDateList && formatDataConfirmListFromApi();
}, [confirmDateList]); }, [confirmDateList]);
...@@ -302,8 +474,15 @@ const ConfirmDateContainer = props => { ...@@ -302,8 +474,15 @@ const ConfirmDateContainer = props => {
approveReqPayload, approveReqPayload,
dayPress, dayPress,
modalRequestConfirmWorkingDays, modalRequestConfirmWorkingDays,
confirmDateRequestImage,
confirmDateRequestTicket,
openTimePicker,
directManagersList,
myAbsentRequests,
setOpenTimePicker,
setConfirmDateRequestTicket,
openGallery,
onChangeDayPressInChart, onChangeDayPressInChart,
onOpenDetailModal,
onLoadMoreConfirmList, onLoadMoreConfirmList,
navigateToDayWage, navigateToDayWage,
onLoadMoreRequestApprove, onLoadMoreRequestApprove,
...@@ -313,6 +492,10 @@ const ConfirmDateContainer = props => { ...@@ -313,6 +492,10 @@ const ConfirmDateContainer = props => {
onChangeMonthFilter, onChangeMonthFilter,
onCloseModalRequestConfirmWorkingDays, onCloseModalRequestConfirmWorkingDays,
onOpenModalRequestConfirmWorkingDays, onOpenModalRequestConfirmWorkingDays,
onDeleteConfirmDateRequestImage,
onSelectManagerConfirmWorkingDayRequest,
onSubmitConfirmWorkingDayRequest,
onSubmitApproveConfirmWorkingDaysRequest,
}; };
return <ConfirmDateMainView {...confirmDatePropsProvider(confirmProps)} />; return <ConfirmDateMainView {...confirmDatePropsProvider(confirmProps)} />;
}; };
......
...@@ -18,6 +18,18 @@ export default function confirmDatePropsProvider(props) { ...@@ -18,6 +18,18 @@ export default function confirmDatePropsProvider(props) {
onChangeMonthFilter, onChangeMonthFilter,
onCloseModalRequestConfirmWorkingDays, onCloseModalRequestConfirmWorkingDays,
onOpenModalRequestConfirmWorkingDays, onOpenModalRequestConfirmWorkingDays,
onDeleteConfirmDateRequestImage,
confirmDateRequestImage,
openGallery,
confirmDateRequestTicket,
setConfirmDateRequestTicket,
openTimePicker,
setOpenTimePicker,
directManagersList,
onSelectManagerConfirmWorkingDayRequest,
onSubmitConfirmWorkingDayRequest,
onSubmitApproveConfirmWorkingDaysRequest,
myAbsentRequests,
} = props; } = props;
return { return {
userInfo, userInfo,
...@@ -40,9 +52,26 @@ export default function confirmDatePropsProvider(props) { ...@@ -40,9 +52,26 @@ export default function confirmDatePropsProvider(props) {
approveReqPayload, approveReqPayload,
onChangeSelectFilter, onChangeSelectFilter,
requestApproveArr, requestApproveArr,
onOpenDetailModal, onOpenModalRequestConfirmWorkingDays,
},
modalRequestConfirmWorkingDaysProps: {
userInfo: modalRequestConfirmWorkingDays.userInfo,
onClose: onCloseModalRequestConfirmWorkingDays,
isRequest: modalRequestConfirmWorkingDays.isRequest,
confirmDateRequestImage,
onDeleteConfirmDateRequestImage,
openGallery,
setOpenTimePicker,
confirmDateRequestTicket,
openTimePicker,
directManagersList,
setConfirmDateRequestTicket,
onSelectManagerConfirmWorkingDayRequest,
onSubmitConfirmWorkingDayRequest,
onSubmitApproveConfirmWorkingDaysRequest,
}, },
onCloseModalRequestConfirmWorkingDays, onCloseModalRequestConfirmWorkingDays,
onOpenModalRequestConfirmWorkingDays, onOpenModalRequestConfirmWorkingDays,
myAbsentRequests,
}; };
} }
...@@ -2,10 +2,14 @@ import {createAsyncThunk, createSlice} from '@reduxjs/toolkit'; ...@@ -2,10 +2,14 @@ import {createAsyncThunk, createSlice} from '@reduxjs/toolkit';
import serviceRequest from '../../app/serviceRequest'; import serviceRequest from '../../app/serviceRequest';
import Utils from '../../utils';
import authAPI from '../../api/authAPI';
import confirmDateAPI from '../../api/confirmDateAPI'; import confirmDateAPI from '../../api/confirmDateAPI';
const initialState = {};
import Utils from '../../utils';
const initialState = {
confirmApprovedDateList: [],
myAbsentRequests: [],
};
export const getUserConfirmDay = createAsyncThunk( export const getUserConfirmDay = createAsyncThunk(
'confirmDate/getUserConfirmDay', 'confirmDate/getUserConfirmDay',
...@@ -33,6 +37,19 @@ export const getConfirmApprovedDate = createAsyncThunk( ...@@ -33,6 +37,19 @@ export const getConfirmApprovedDate = createAsyncThunk(
}); });
}, },
); );
export const getMyAbsentRequests = createAsyncThunk(
'confirmDate/getMyAbsentRequests',
async (data, thunkAPI) => {
return serviceRequest({
dispatch: thunkAPI.dispatch,
serviceMethod: confirmDateAPI.requestMyAbsentRequest,
payload: data,
options: {
skipLoader: false,
},
});
},
);
export const getAbsentChart = createAsyncThunk( export const getAbsentChart = createAsyncThunk(
'confirmDate/getAbsentChart', 'confirmDate/getAbsentChart',
async (data, thunkAPI) => { async (data, thunkAPI) => {
...@@ -46,7 +63,32 @@ export const getAbsentChart = createAsyncThunk( ...@@ -46,7 +63,32 @@ export const getAbsentChart = createAsyncThunk(
}); });
}, },
); );
export const postConfirmWorkingDay = createAsyncThunk(
'confirmDate/postConfirmWorkingDay',
async (data, thunkAPI) => {
return serviceRequest({
dispatch: thunkAPI.dispatch,
serviceMethod: confirmDateAPI.requestPostConfirmWorkingDay,
payload: data,
options: {
skipLoader: false,
},
});
},
);
export const postSubmitApproveConfirmWorkingDayRequest = createAsyncThunk(
'confirmDate/postSubmitApproveConfirmWorkingDayRequest',
async (data, thunkAPI) => {
return serviceRequest({
dispatch: thunkAPI.dispatch,
serviceMethod: confirmDateAPI.requestPostApproveConfirmWorkingDay,
payload: data,
options: {
skipLoader: false,
},
});
},
);
const authSlice = createSlice({ const authSlice = createSlice({
name: 'confirmDate', name: 'confirmDate',
initialState: initialState, initialState: initialState,
...@@ -54,7 +96,6 @@ const authSlice = createSlice({ ...@@ -54,7 +96,6 @@ const authSlice = createSlice({
extraReducers: builder => { extraReducers: builder => {
builder.addCase(getUserConfirmDay.fulfilled, (state, action) => { builder.addCase(getUserConfirmDay.fulfilled, (state, action) => {
const {success} = Utils.getValues(action, 'payload', false); const {success} = Utils.getValues(action, 'payload', false);
if (success) { if (success) {
state.confirmDateList = Utils.getValues( state.confirmDateList = Utils.getValues(
action, action,
...@@ -73,8 +114,19 @@ const authSlice = createSlice({ ...@@ -73,8 +114,19 @@ const authSlice = createSlice({
); );
} }
}); });
builder.addCase(getMyAbsentRequests.fulfilled, (state, action) => {
const {success} = Utils.getValues(action, 'payload', false);
if (success) {
state.myAbsentRequests = Utils.getValues(
action,
'payload.data.collection',
[],
);
}
});
}, },
}); });
const {reducer} = authSlice; const {reducer, actions} = authSlice;
export default reducer; export default reducer;
import React from 'react'; import React from 'react';
import {useSelector} from 'react-redux'; import {useSelector} from 'react-redux';
import {authSelector, confirmDateSelector} from '../../app/selectors'; import {
authSelector,
confirmDateSelector,
onLeaveSelector,
} from '../../app/selectors';
import ConfirmDateContainer from './ConfirmDateContainer'; import ConfirmDateContainer from './ConfirmDateContainer';
export default function ConfirmDateScreen() { export default function ConfirmDateScreen() {
const authSelect = useSelector(authSelector); const authSelect = useSelector(authSelector);
const confirmDateSelect = useSelector(confirmDateSelector); const confirmDateSelect = useSelector(confirmDateSelector);
const onLeaveSelect = useSelector(onLeaveSelector);
const {directManagersList = []} = onLeaveSelect;
const {userInfo} = authSelect; const {userInfo} = authSelect;
const {confirmDateList, confirmApprovedDateList} = confirmDateSelect; const {confirmDateList, confirmApprovedDateList, myAbsentRequests} =
confirmDateSelect;
const confirmScreenProps = { const confirmScreenProps = {
userInfo, userInfo,
confirmDateList, confirmDateList,
confirmApprovedDateList, confirmApprovedDateList,
directManagersList,
myAbsentRequests,
}; };
return <ConfirmDateContainer {...confirmScreenProps} />; return <ConfirmDateContainer {...confirmScreenProps} />;
} }
...@@ -120,10 +120,10 @@ const styles = StyleSheet.create({ ...@@ -120,10 +120,10 @@ const styles = StyleSheet.create({
marginTop: 22, marginTop: 22,
}, },
modalView: { modalView: {
backgroundColor: 'white', backgroundColor: colors.white,
borderRadius: 20, borderRadius: 20,
padding: 20, padding: 10,
shadowColor: '#000', shadowColor: colors.black1,
shadowOffset: { shadowOffset: {
width: 0, width: 0,
height: 2, height: 2,
...@@ -131,8 +131,9 @@ const styles = StyleSheet.create({ ...@@ -131,8 +131,9 @@ const styles = StyleSheet.create({
shadowOpacity: 0.25, shadowOpacity: 0.25,
shadowRadius: 4, shadowRadius: 4,
elevation: 5, elevation: 5,
marginTop: 20, marginTop: 80,
height: windowHeight, height: windowHeight,
width: '100%',
}, },
button: { button: {
borderRadius: 20, borderRadius: 20,
...@@ -151,7 +152,7 @@ const styles = StyleSheet.create({ ...@@ -151,7 +152,7 @@ const styles = StyleSheet.create({
textAlign: 'center', textAlign: 'center',
}, },
modalTitle: { modalTitle: {
fontWeight: '500', fontWeight: '800',
fontSize: 16, fontSize: 16,
}, },
dropdown1DropdownStyle: {backgroundColor: '#EFEFEF'}, dropdown1DropdownStyle: {backgroundColor: '#EFEFEF'},
...@@ -181,9 +182,8 @@ const styles = StyleSheet.create({ ...@@ -181,9 +182,8 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
}, },
inputText: { inputText: {
backgroundColor: '#FFF', backgroundColor: colors.white,
borderBottomWidth: 0.2, width: 200,
borderColor: '#444',
}, },
touchableOpacity: { touchableOpacity: {
borderColor: colors.primary_blue, borderColor: colors.primary_blue,
...@@ -201,7 +201,7 @@ const styles = StyleSheet.create({ ...@@ -201,7 +201,7 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
height: 40, height: 40,
borderRadius: 8, borderRadius: 8,
width: 100, paddingHorizontal: 10,
}, },
btnCancel: { btnCancel: {
backgroundColor: colors.white, backgroundColor: colors.white,
...@@ -411,4 +411,44 @@ export const statisticsConfirmWorkdaysStyles = StyleSheet.create({ ...@@ -411,4 +411,44 @@ export const statisticsConfirmWorkdaysStyles = StyleSheet.create({
borderRadius: 5, borderRadius: 5,
}, },
}); });
export const modalRequestConfirmWorkdaysStyles = StyleSheet.create({
avatarUser: {
width: 50,
height: 50,
borderRadius: 30,
},
btnCancel: {
backgroundColor: colors.white,
justifyContent: 'center',
alignItems: 'center',
height: 40,
borderRadius: 8,
width: 100,
},
rowView: {
flexDirection: 'row',
marginTop: 10,
justifyContent: 'space-between',
alignItems: 'center',
},
addConfirmDateRequestImageBtn: {
borderColor: colors.primary_blue,
borderStyle: 'dotted',
borderWidth: 2,
justifyContent: 'center',
alignItems: 'center',
height: 50,
padding: 10,
width: 50,
},
chooseTimeSection: {
alignItems: 'flex-end',
flexDirection: 'row',
justifyContent: 'space-between',
borderBottomWidth: 0.5,
height: 35,
width: 200,
borderColor: colors.grey444,
},
});
export default styles; export default styles;
...@@ -40,7 +40,7 @@ const ConfirmWorkingDaysSession = React.memo( ...@@ -40,7 +40,7 @@ const ConfirmWorkingDaysSession = React.memo(
<View style={{alignItems: 'center', justifyContent: 'center'}}> <View style={{alignItems: 'center', justifyContent: 'center'}}>
<ButtonComponent <ButtonComponent
style={styles.btnConfirm} style={styles.btnConfirm}
onPress={onOpenModalRequestConfirmWorkingDays} 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'}
...@@ -55,11 +55,6 @@ const ConfirmWorkingDaysSession = React.memo( ...@@ -55,11 +55,6 @@ const ConfirmWorkingDaysSession = React.memo(
</View> </View>
); );
}, },
function (prevProps, nextProps) {
return (
prevProps.onOpenRequestLeavesModal === nextProps.onOpenRequestLeavesModal
);
},
); );
const ApproveRequestWorkingDays = React.memo( const ApproveRequestWorkingDays = React.memo(
...@@ -67,8 +62,8 @@ const ApproveRequestWorkingDays = React.memo( ...@@ -67,8 +62,8 @@ const ApproveRequestWorkingDays = React.memo(
const { const {
approveReqPayload, approveReqPayload,
onChangeSelectFilter, onChangeSelectFilter,
requestApproveArr, requestApproveArr = [],
onOpenDetailModal, onOpenModalRequestConfirmWorkingDays,
} = props; } = props;
return ( return (
<View <View
...@@ -89,57 +84,60 @@ const ApproveRequestWorkingDays = React.memo( ...@@ -89,57 +84,60 @@ const ApproveRequestWorkingDays = React.memo(
value={approveReqPayload?.type} value={approveReqPayload?.type}
selectData={approveWorkingDayStatus} selectData={approveWorkingDayStatus}
setValue={onChangeSelectFilter} setValue={onChangeSelectFilter}
width={150}
/> />
</View> </View>
{requestApproveArr.map((item, index) => ( {requestApproveArr.length > 0 &&
<TouchableOpacity requestApproveArr.map((item, index) => (
onPress={() => onOpenDetailModal(item)} <TouchableOpacity
key={index} onPress={() => onOpenModalRequestConfirmWorkingDays(item)}
style={[ key={index}
styles.item, style={[
commonStyles.spaceBetweenCenter, styles.item,
{ commonStyles.spaceBetweenCenter,
borderLeftColor: item?.extend_approved_status_color, {
}, borderLeftColor: item?.extend_approved_status_color,
]}> },
<View style={commonStyles.row}> ]}>
<Image <View style={commonStyles.row}>
source={ <Image
item?.extend_creator_avatar source={
? { item?.extend_creator_avatar
uri: config.imageEndPoint + item.extend_creator_avatar, ? {
} uri:
: IMAGES.IcAvatarDefault config.imageEndPoint + item.extend_creator_avatar,
} }
style={{width: 35, height: 35, marginRight: 5}} : IMAGES.IcAvatarDefault
/> }
<View> style={{width: 35, height: 35, marginRight: 5}}
<AppText style={styles.title}> />
{item?.extend_creator_full_name?.length > 20 <View>
? item?.extend_creator_full_name.slice(0, 15) + '...' <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 isSubText>
{Moment(item.start).format('DD/MM/YYYY')}
</AppText>
</View>
</View>
<View
style={{
alignItems: 'flex-end',
}}>
<AppText>
{item.reason.length > 20
? item.reason.slice(0, 15) + '...'
: item.reason}
</AppText> </AppText>
<AppText isSubText> <AppText isSubText>
{Moment(item.start).format('DD/MM/YYYY')} {Utils.minutesToHours(item?.start, item?.finish)}
</AppText> </AppText>
</View> </View>
</View> </TouchableOpacity>
<View ))}
style={{
alignItems: 'flex-end',
}}>
<AppText>
{item.reason.length > 20
? item.reason.slice(0, 15) + '...'
: item.reason}
</AppText>
<AppText isSubText>
{Utils.minutesToHours(item?.start, item?.finish)}
</AppText>
</View>
</TouchableOpacity>
))}
{/* {!isDisableLoadMore.approveRequestBtn && {/* {!isDisableLoadMore.approveRequestBtn &&
requestApproveArr?.length > 0 && ( requestApproveArr?.length > 0 && (
<ButtonComponent <ButtonComponent
...@@ -161,7 +159,11 @@ const ApproveRequestWorkingDays = React.memo( ...@@ -161,7 +159,11 @@ const ApproveRequestWorkingDays = React.memo(
}, },
); );
const ConfirmWorkingDays = React.memo( const ConfirmWorkingDays = React.memo(
({confirmList, onOpenDetailModal, onRefreshConfirmList}) => { ({
myAbsentRequests,
onOpenModalRequestConfirmWorkingDays,
onRefreshConfirmList,
}) => {
return ( return (
<View <View
style={[ style={[
...@@ -186,7 +188,7 @@ const ConfirmWorkingDays = React.memo( ...@@ -186,7 +188,7 @@ const ConfirmWorkingDays = React.memo(
styleIcon={{width: 20, height: 20}} styleIcon={{width: 20, height: 20}}
/> />
</View> </View>
{confirmList.length === 0 && ( {myAbsentRequests.length === 0 ? (
<View style={styles.emptyConfirmWorkingDays}> <View style={styles.emptyConfirmWorkingDays}>
<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
...@@ -197,42 +199,45 @@ const ConfirmWorkingDays = React.memo( ...@@ -197,42 +199,45 @@ const ConfirmWorkingDays = React.memo(
style={{width: '90%', height: 250}} style={{width: '90%', height: 250}}
/> />
</View> </View>
) : (
<>
{myAbsentRequests.map((item, index) => (
<TouchableOpacity
onPress={() => onOpenModalRequestConfirmWorkingDays(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 &&
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 && ( {/* {confirmList.length > 0 && !isDisableLoadMore.confirmBtn && (
<ButtonComponent <ButtonComponent
style={{ style={{
...@@ -249,23 +254,20 @@ const ConfirmWorkingDays = React.memo( ...@@ -249,23 +254,20 @@ const ConfirmWorkingDays = React.memo(
); );
}, },
function (prevProps, nextProps) { function (prevProps, nextProps) {
return prevProps.confirmList === nextProps.confirmList; return prevProps.myAbsentRequests === nextProps.myAbsentRequests;
}, },
); );
const ConfirmDateMainView = ({ const ConfirmDateMainView = ({
navigateToDayWage, navigateToDayWage,
requestApproveArr = [], myAbsentRequests = [],
confirmList,
onRefreshConfirmList, onRefreshConfirmList,
onOpenDetailModal, onOpenModalRequestConfirmWorkingDays,
onOpenRequestLeavesModal,
dataChart, dataChart,
onChangeMonthFilter, onChangeMonthFilter,
dayPress, dayPress,
approveRequestWorkingDaysProps, approveRequestWorkingDaysProps,
modalRequestConfirmWorkingDays, modalRequestConfirmWorkingDays,
onCloseModalRequestConfirmWorkingDays, modalRequestConfirmWorkingDaysProps,
onOpenModalRequestConfirmWorkingDays,
}) => { }) => {
return ( return (
<SafeAreaView> <SafeAreaView>
...@@ -281,19 +283,18 @@ const ConfirmDateMainView = ({ ...@@ -281,19 +283,18 @@ const ConfirmDateMainView = ({
onOpenModalRequestConfirmWorkingDays onOpenModalRequestConfirmWorkingDays
} }
/> />
{requestApproveArr.length > 0 && ( <ApproveRequestWorkingDays {...approveRequestWorkingDaysProps} />
<ApproveRequestWorkingDays {...approveRequestWorkingDaysProps} />
)}
<ConfirmWorkingDays <ConfirmWorkingDays
confirmList={confirmList} myAbsentRequests={myAbsentRequests}
onOpenDetailModal={onOpenDetailModal} onOpenModalRequestConfirmWorkingDays={
onOpenModalRequestConfirmWorkingDays
}
onRefreshConfirmList={onRefreshConfirmList} onRefreshConfirmList={onRefreshConfirmList}
/> />
</ScrollView> </ScrollView>
{modalRequestConfirmWorkingDays?.visible && ( {modalRequestConfirmWorkingDays?.visible && (
<ModalRequestConfirmWorkingDays <ModalRequestConfirmWorkingDays
userinfo={modalRequestConfirmWorkingDays?.userinfo} {...modalRequestConfirmWorkingDaysProps}
onClose={onCloseModalRequestConfirmWorkingDays}
/> />
)} )}
</SafeAreaView> </SafeAreaView>
......
import React from 'react'; import React, {useMemo} from 'react';
import { import {
Dimensions,
Image, Image,
Modal, Modal,
SafeAreaView, SafeAreaView,
ScrollView, ScrollView,
StyleSheet,
TouchableOpacity, TouchableOpacity,
View, View,
} from 'react-native'; } from 'react-native';
import AppText from '../../../../components/AppText'; import AppText from '../../../../components/AppText';
import config from '../../../../config'; import config from '../../../../config';
import colors from '../../../../values/colors';
import {IMAGES} from '../../../../values/images'; import {IMAGES} from '../../../../values/images';
const windowWidth = Dimensions.get('window').width; import styles, {modalRequestConfirmWorkdaysStyles} from '../../style';
const windowHeight = Dimensions.get('window').height; import commonStyles from '../../../../styles/commonStyles';
const ModalRequestConfirmWorkingDays = ({userinfo, onClose}) => { import ButtonComponent from '../../../../components/ButtonComponent';
import CheckBox from '@react-native-community/checkbox';
import SelectDropdownComponent from '../../../../components/Select';
import moment from 'moment';
import DateTimePicker from 'react-native-modal-datetime-picker';
import TextInputComponent from '../../../../components/TextInputComponent';
const UserHeader = React.memo(
({userInfo, fullName}) => {
return (
<View style={[commonStyles.row, commonStyles.marginVertical10]}>
<Image
source={
userInfo?.avatar
? {
uri: config.imageEndPoint + userInfo?.avatar,
}
: IMAGES.IcAvatarDefault
}
style={modalRequestConfirmWorkdaysStyles.avatarUser}
/>
<View style={{marginLeft: 15}}>
<AppText
style={
styles.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(
({
confirmDateRequestImage = [],
onDeleteConfirmDateRequestImage,
openGallery,
}) => {
return (
<View style={modalRequestConfirmWorkdaysStyles.rowView}>
<AppText>Tệp đính kèm</AppText>
<View style={{flexDirection: 'row'}}>
{confirmDateRequestImage.length > 0 &&
confirmDateRequestImage.map((item, index) => {
//console.log("item", item[0].uri)
return (
<View key={index}>
<ButtonComponent
iconSource={IMAGES.IcReject}
style={styles.btnClose}
onPress={() => onDeleteConfirmDateRequestImage(index)}
/>
<Image source={{uri: item.uri}} style={styles.imgUpload} />
</View>
);
})}
{confirmDateRequestImage.length < 3 && (
<ButtonComponent
style={
modalRequestConfirmWorkdaysStyles.addConfirmDateRequestImageBtn
}
onPress={openGallery}
iconSource={IMAGES.IcAddMoreImg}
/>
)}
</View>
</View>
);
},
);
const DirectManagers = ({
directManagersList,
onSelectManagerConfirmWorkingDayRequest,
}) => {
return (
<View style={{marginTop: 10}}>
<AppText
style={[
styles.modalTitle,
{
marginBottom: 10,
},
]}>
Người duyệt
</AppText>
{directManagersList.map((item, index) => (
<View
key={index}
style={[commonStyles.row, commonStyles.spaceBetweenCenter]}>
<View
style={{
flexDirection: 'row',
alignItems: 'center',
paddingLeft: 18,
}}>
<Image
source={{
uri: config.imageEndPoint + item.avatar,
}}
style={styles.avatarApprove}
/>
<AppText
style={{
marginLeft: 10,
}}>{`${item.extend_user_full_name}`}</AppText>
</View>
<View style={{paddingRight: 10}}>
<CheckBox
disabled={false}
value={item.isChecked}
onValueChange={newValue =>
onSelectManagerConfirmWorkingDayRequest(index, newValue)
}
boxType={'square'}
animationDuration={0.3}
lineWidth={1}
key={index}
tintColors={'#9E663C'}
/>
</View>
</View>
))}
</View>
);
};
const ButtonAction = ({
onSubmitApproveConfirmWorkingDaysRequest,
isRequest,
onClose,
userInfo,
onSubmitConfirmWorkingDayRequest,
}) => {
return (
<View
style={[
commonStyles.row,
commonStyles.marginVertical20,
{
justifyContent: 'flex-end',
},
]}>
<TouchableOpacity onPress={onClose} style={styles.btnCancel}>
<AppText style={styles.blueTxt}>Hủy</AppText>
</TouchableOpacity>
{isRequest && (
<TouchableOpacity
style={styles.btnSubmit}
onPress={onSubmitConfirmWorkingDayRequest}>
<AppText style={styles.whiteTxt}>Gửi yêu cầu</AppText>
</TouchableOpacity>
)}
{userInfo?.isApprover && userInfo?.confirmStatus && (
<TouchableOpacity
style={styles.btnSubmit}
onPress={() =>
onSubmitApproveConfirmWorkingDaysRequest(
userInfo?.confirm_working_id,
)
}>
<AppText style={styles.whiteTxt}>Duyệt yêu cầu</AppText>
</TouchableOpacity>
)}
</View>
);
};
const ModalRequestConfirmWorkingDays = props => {
const {
userInfo,
onClose,
isRequest = false,
confirmDateRequestImage,
onDeleteConfirmDateRequestImage,
openGallery,
setOpenTimePicker,
confirmDateRequestTicket,
openTimePicker,
directManagersList,
setConfirmDateRequestTicket,
onSelectManagerConfirmWorkingDayRequest,
onSubmitConfirmWorkingDayRequest,
onSubmitApproveConfirmWorkingDaysRequest,
} = props;
const fullName = useMemo(() => {
return userInfo?.full_name
? userInfo?.full_name
: `${userInfo?.first_name} ${
userInfo?.middle_name ? userInfo?.middle_name : ''
} ${userInfo?.last_name}`;
}, [userInfo]);
return ( return (
<Modal <Modal
animationType="slide" animationType="slide"
...@@ -24,553 +219,251 @@ const ModalRequestConfirmWorkingDays = ({userinfo, onClose}) => { ...@@ -24,553 +219,251 @@ const ModalRequestConfirmWorkingDays = ({userinfo, onClose}) => {
onRequestClose={() => { onRequestClose={() => {
onClose(null); onClose(null);
}}> }}>
<SafeAreaView> <ScrollView>
<View style={styles.modalView}> <View style={styles.modalView}>
<AppText style={styles.modalTitle}>Xác nhận ngày công</AppText> <AppText style={styles.modalTitle}>Xác nhận ngày công</AppText>
<View style={{flexDirection: 'row', marginTop: 10}}> <UserHeader userInfo={userInfo} fullName={fullName} />
<Image <View>
source={{uri: config.imageEndPoint + userinfo?.avatar}} <AppText style={styles.modalTitle}>Thông tin chung</AppText>
style={styles.ImgAvatar} <View style={styles.rowView}>
/> <AppText>Từ ngày</AppText>
<View style={{marginLeft: 15}}> <View>
<AppText style={styles.modalTitle}>{`${userinfo?.first_name} ${ <TouchableOpacity
userinfo?.middle_name ? userinfo?.middle_name : '' disabled={!isRequest}
} ${userinfo?.last_name}`}</AppText> onPress={() =>
<AppText>{userinfo?.position}</AppText> setOpenTimePicker(state => ({
...state,
startDate: true,
}))
}
style={modalRequestConfirmWorkdaysStyles.chooseTimeSection}>
<AppText>
{moment(confirmDateRequestTicket?.startDate).format(
'DD/MM/YYYY',
)}
</AppText>
<Image
source={IMAGES.IcCalendarGray}
style={{width: 20, height: 20, marginLeft: 8}}
/>
</TouchableOpacity>
<DateTimePicker
isVisible={openTimePicker.startDate}
mode="date"
date={confirmDateRequestTicket?.startDate}
onConfirm={time => {
setConfirmDateRequestTicket(prev => ({
...prev,
startDate: time,
}));
setOpenTimePicker(state => ({
...state,
startDate: false,
}));
}}
onCancel={() => {
setOpenTimePicker(state => ({
...state,
startDate: false,
}));
}}
/>
</View>
</View> </View>
</View> <View style={styles.rowView}>
<View style={styles.bodyHeightCreate}> <AppText>Giờ</AppText>
<ScrollView> <View>
<View style={{marginTop: 20}}> <TouchableOpacity
<AppText style={styles.modalTitle}>Thông tin xác nhận</AppText> disabled={!isRequest}
<View style={styles.rowView}> onPress={() =>
<AppText style={{flex: 1}}>Từ ngày</AppText> setOpenTimePicker(state => ({
<View style={{flex: 1}}> ...state,
<TouchableOpacity startTime: true,
// onPress={() => }))
// setOpenTimePicker(state => ({ }
// ...state, style={modalRequestConfirmWorkdaysStyles.chooseTimeSection}>
// start: true, <AppText>
// })) {moment(confirmDateRequestTicket?.startDate).format(
// } 'HH:mm',
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> </AppText>
{userManagerList.map((item, index) => ( <Image
<View source={IMAGES.IcLeaveNoti}
key={index} style={{width: 20, height: 20}}
style={{ />
flexDirection: 'row', </TouchableOpacity>
justifyContent: 'space-between', <DateTimePicker
alignItems: 'center', isVisible={openTimePicker.startTime}
}}> mode="time"
<View style={{flexDirection: 'row'}}> date={confirmDateRequestTicket?.startDate}
<Image onConfirm={time => {
source={{ setConfirmDateRequestTicket(prev => ({
uri: 'https://meu.anawork.com' + item.avatar, ...prev,
}} startDate: time,
style={{width: 60, height: 60, borderRadius: 10}} }));
/> setOpenTimePicker(state => ({
<View> ...state,
<AppText startTime: false,
style={{ }));
fontSize: 16, }}
fontWeight: '500', onCancel={() => {
marginLeft: 10, setOpenTimePicker(state => ({
}}>{`${item.extend_user_full_name}`}</AppText> ...state,
<AppText startTime: false,
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> </View>
</ScrollView> </View>
</View> <View style={styles.rowView}>
<View style={{flexDirection: 'row', justifyContent: 'flex-end'}}> <AppText>Đến ngày</AppText>
<TouchableOpacity <View>
onPress={() => { <TouchableOpacity
onClose(null); disabled={!isRequest}
}} onPress={() =>
style={styles.btnCancel}> setOpenTimePicker(state => ({
<AppText style={styles.blueTxt}>Hủy</AppText> ...state,
</TouchableOpacity> finishDate: true,
<TouchableOpacity }))
style={styles.btnSubmit} }
// onPress={onSubmitConfirmDate} style={modalRequestConfirmWorkdaysStyles.chooseTimeSection}>
> <AppText>
<AppText style={styles.whiteTxt}>Gửi yêu cầu</AppText> {moment(confirmDateRequestTicket?.finishDate).format(
</TouchableOpacity> 'DD/MM/YYYY',
)}
</AppText>
<Image
source={IMAGES.IcCalendarGray}
style={{width: 20, height: 20, marginLeft: 8}}
/>
</TouchableOpacity>
<DateTimePicker
isVisible={openTimePicker.finishDate}
mode="date"
date={confirmDateRequestTicket?.finishDate}
onConfirm={time => {
setConfirmDateRequestTicket(prev => ({
...prev,
finishDate: time,
}));
setOpenTimePicker(state => ({
...state,
finishDate: false,
}));
}}
onCancel={() => {
setOpenTimePicker(state => ({
...state,
finishDate: false,
}));
}}
/>
</View>
</View>
<View style={styles.rowView}>
<AppText>Giờ</AppText>
<View>
<TouchableOpacity
disabled={!isRequest}
onPress={() =>
setOpenTimePicker(state => ({
...state,
finishTime: true,
}))
}
style={modalRequestConfirmWorkdaysStyles.chooseTimeSection}>
<AppText>
{moment(confirmDateRequestTicket?.finishDate).format(
'HH:mm',
)}
</AppText>
<Image
source={IMAGES.IcLeaveNoti}
style={{width: 20, height: 20}}
/>
</TouchableOpacity>
<DateTimePicker
isVisible={openTimePicker.finishTime}
mode="time"
date={confirmDateRequestTicket?.finishDate}
onConfirm={time => {
setConfirmDateRequestTicket(prev => ({
...prev,
finishDate: time,
}));
setOpenTimePicker(state => ({
...state,
finishTime: false,
}));
}}
onCancel={() => {
setOpenTimePicker(state => ({
...state,
finishTime: false,
}));
}}
/>
</View>
</View>
{/* <View style={styles.rowView}>
<AppText>{`Thi gian ngh (*)`}</AppText>
<View style={styles.takeTimeStyle}>
<AppText style={{paddingLeft: 18}}>
{durationLeave.stringTime}
</AppText>
</View>
</View> */}
<View style={styles.rowView}>
<AppText
style={{
color:
confirmDateRequestTicket?.reason?.length === 0
? 'red'
: 'grey',
}}>{`Lý do(*)`}</AppText>
<View>
<TextInputComponent
disable={isRequest}
styleAreaInput={styles.inputText}
value={confirmDateRequestTicket.reason}
placeholder="Nhập lý do tại đây"
onChangeText={text => {
setConfirmDateRequestTicket(state => ({
...state,
reason: text,
}));
}}
noBorder
/>
</View>
</View>
<Attachments
confirmDateRequestImage={confirmDateRequestImage}
onDeleteConfirmDateRequestImage={onDeleteConfirmDateRequestImage}
openGallery={openGallery}
/>
{isRequest && directManagersList.length > 0 && (
<DirectManagers
directManagersList={directManagersList}
onSelectManagerConfirmWorkingDayRequest={
onSelectManagerConfirmWorkingDayRequest
}
/>
)}
</View> </View>
<ButtonAction
onClose={onClose}
isRequest={isRequest}
userInfo={userInfo}
onSubmitConfirmWorkingDayRequest={onSubmitConfirmWorkingDayRequest}
onSubmitApproveConfirmWorkingDaysRequest={
onSubmitApproveConfirmWorkingDaysRequest
}
/>
</View> </View>
</SafeAreaView> </ScrollView>
</Modal> </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; export default ModalRequestConfirmWorkingDays;
/* eslint-disable prettier/prettier */
import CheckBox from '@react-native-community/checkbox';
import Moment from 'moment';
import React, {useEffect, useState} from 'react';
import {
Dimensions,
Image,
KeyboardAvoidingView,
Modal,
SafeAreaView,
ScrollView,
StyleSheet,
TextInput,
TouchableOpacity,
View,
} from 'react-native';
import Toast from 'react-native-toast-message';
import {useDispatch, useSelector} from 'react-redux';
import AppText from '../../../components/AppText';
import ButtonComponent from '../../../components/ButtonComponent';
import {
deleteLeaveTicket,
getCommentByCode,
getImageByCode,
getUserLeaveHistories,
postApproveLeaveDay,
postComment,
postRejectLeaveDay,
} from '../../../store/actions/UserAction';
import colors from '../../../values/colors';
import {IMAGES} from '../../../values/images';
const OnLeaveModalDetail = ({
alertMessage,
onClose,
detailItem,
userDetails,
setPayloadApproveLeaves,
}) => {
const dispatch = useDispatch();
//console.log('detailItem', detailItem);
const userDirectManagersList = useSelector(
state => state.MyDirectManagers.myDirectManagers,
);
const initStateLeave = {
id: '',
since: new Date(),
timeStart: '',
dateStart: '',
toDate: new Date(),
timeFinish: '',
dateFinish: '',
reason: '',
taken_hours: 0,
approved_date: new Date(),
approver_id: '',
};
const initComment = {
code: '',
content: '',
};
// STATE
const [detailImage, setDetailImage] = useState([]);
const [leave, setLeave] = useState(initStateLeave);
const [leaveDayDetail, setLeaveDayDetail] = useState(null);
const [leaveHistories, setLeaveHistories] = useState([]);
const [leaveComment, setLeaveComment] = useState([]);
const [comment, setComment] = useState(initComment);
const [userManagerList, setUserManagerList] = useState([]);
const [commentApprove, setCommentApprove] = useState('');
const [isNextApprover, setIsNextApprover] = useState(false);
const [nextApproverId, setNextApproverId] = useState('');
// main function
const onOpenDetailLeave = async () => {
const objectClone = JSON.parse(JSON.stringify(userDirectManagersList));
let obj = [];
objectClone.forEach(element => {
element.checked = false;
obj.push(element);
});
setUserManagerList(obj);
setLeaveDayDetail(detailItem);
if (detailItem) {
const responseHistories = await dispatch(
getUserLeaveHistories(detailItem.id),
);
setLeaveHistories(responseHistories);
const responseComment = await dispatch(getCommentByCode(detailItem.id));
setLeaveComment(responseComment);
const responseImage = await dispatch(getImageByCode(detailItem.id));
setDetailImage(responseImage);
}
};
const onSelectManager = async (value, index, item) => {
let userManagerListClone = [...userManagerList];
let elementFound = userManagerListClone.find(
element => element.id == item.id,
);
let indexElementFound = userManagerListClone.findIndex(
element => element.id == item.id,
);
userManagerListClone.splice(indexElementFound, 1, {
...elementFound,
checked: value,
});
setUserManagerList(userManagerListClone);
setLeave(state => ({
...state,
approver_id: item.id,
}));
if (isNextApprover) {
setNextApproverId(item.id);
} else {
setNextApproverId('');
setLeave(state => ({
...state,
approver_id: item.id,
}));
}
};
const onSubmitComment = async () => {
if (comment.content) {
const res = await dispatch(postComment(comment));
if (res) {
setComment(initComment);
const responseComment = await dispatch(getCommentByCode(comment.code));
setLeaveComment(responseComment);
return;
}
}
};
const onRejectRequest = async id => {
const res = await dispatch(postRejectLeaveDay(id, commentApprove));
if (res) {
Toast.show({
type: 'success',
text1: `Hệ thống`,
text2: `Thành công!`,
styles: {zIndex: 1000},
});
refreshAfterSubmit();
} else {
Toast.show({
type: 'success',
text1: `Hệ thống`,
text2: `Không thành công!`,
styles: {zIndex: 1000},
});
}
onClose(null);
};
const onApproveRequest = async id => {
const res = await dispatch(
postApproveLeaveDay(id, commentApprove, nextApproverId),
);
if (res) {
Toast.show({
type: 'success',
text1: `Hệ thống`,
text2: `Thành công!`,
styles: {zIndex: 1000},
});
refreshAfterSubmit();
} else {
Toast.show({
type: 'success',
text1: `Hệ thống`,
text2: `Không thành công!`,
styles: {zIndex: 1000},
});
}
onClose(null);
};
const refreshAfterSubmit = () => {
setLeave(initStateLeave);
setComment(initComment);
setCommentApprove('');
setDetailImage(null);
setLeaveDayDetail(null);
setIsNextApprover(false);
setUserManagerList([]);
setPayloadApproveLeaves(prev => ({...prev, isRefresh: true}));
};
const deleteItem = async () => {
const res = await dispatch(deleteLeaveTicket(detailItem.id));
if (res) {
onClose(null);
Toast.show({
type: 'success',
text1: `Hệ thống`,
text2: `Hủy yêu cầu thành công 💓`,
visibilityTime: 2000,
style: {zIndex: 1001},
});
} else {
onClose(null);
Toast.show({
type: 'error',
text1: `Hệ thống`,
text2: `Hủy yêu cầu thất bại 💔`,
visibilityTime: 2000,
style: {zIndex: 1001},
});
}
//console.log('deleteItem', detailItem);
};
useEffect(() => {
onOpenDetailLeave();
}, []);
return (
<Modal
animationType="slide"
transparent={true}
visible={true}
onRequestClose={() => onClose(null)}>
<SafeAreaView>
<ScrollView>
<View style={styles.modalViewEdit}>
<View style={styles.headerModalBottom}>
<AppText style={styles.titleModalBottom}>
Chi tiết ngh phép
</AppText>
<TouchableOpacity onPress={() => onClose(null)}>
<Image
style={{height: 20, width: 20}}
source={IMAGES.IcClose}
/>
</TouchableOpacity>
</View>
<View style={styles.bodyHeight}>
<View style={styles.bodyModal}>
<View style={{flexDirection: 'row'}}>
<Image
source={{
uri:
'https://meu.anawork.com' +
leaveDayDetail?.extend_creator_avatar,
}}
style={{width: 40, height: 40, borderRadius: 2}}
/>
<View
style={{
justifyContent: 'space-around',
marginLeft: 16,
}}>
<AppText style={{fontSize: 14, fontWeight: '600'}}>
{leaveDayDetail?.extend_creator_full_name} -{' '}
{leaveDayDetail?.extend_creator_employee_code}
</AppText>
<AppText>
{leaveDayDetail?.extend_creator_department}
</AppText>
</View>
</View>
{leaveDayDetail && (
<View style={{marginTop: 16}}>
<AppText
style={{
fontWeight: '500',
fontSize: 14,
marginBottom: 12,
}}>
Thông tin chung
</AppText>
<View style={styles.commonDetail}>
<AppText style={styles.textMediumGrey}>
Loi ngh phép
</AppText>
<AppText>{leaveDayDetail.extend_category_name}</AppText>
</View>
<View style={styles.commonDetail}>
<AppText style={styles.textMediumGrey}>T ngày</AppText>
<AppText>
{Moment(leaveDayDetail.start).format(
'DD/MM/YYYY hh:mm',
)}
</AppText>
</View>
<View style={styles.commonDetail}>
<AppText style={styles.textMediumGrey}>Đến ngày</AppText>
<AppText>
{Moment(leaveDayDetail.finish).format(
'DD/MM/YYYY hh:mm',
)}
</AppText>
</View>
<View style={styles.commonDetail}>
<AppText style={styles.textMediumGrey}>
Thi gian ngh
</AppText>
<AppText>{leaveDayDetail.extend_taken_days} ngày</AppText>
</View>
<View style={styles.commonDetail}>
<AppText style={styles.textMediumGrey}>Lý do</AppText>
<AppText style={[styles.reason]}>
{leaveDayDetail.reason}
</AppText>
</View>
<View style={styles.commonDetail}>
<AppText style={[styles.textMediumGrey, {fontSize: 12}]}>
Tp đính kèm
</AppText>
<View style={styles.attachment}>
{
//physical_path.slice(30)
detailImage?.length > 0 &&
detailImage.map((item, index) => (
<AppText
key={index}
numberOfLines={1}
style={{fontSize: 13, color: '#5d78ff'}}>
{item.file_name}
</AppText>
))
}
{detailImage?.length == 0 && (
<AppText style={{fontSize: 13, color: '#757575'}}>
Không có tp đính kèm
</AppText>
)}
</View>
</View>
</View>
)}
<View style={{marginTop: 16}}>
<AppText
style={{
fontWeight: '500',
fontSize: 14,
marginBottom: 12,
}}>
Lch s duyt
</AppText>
{leaveHistories.length > 0 &&
leaveHistories.map((item, index) => (
<View key={index} style={{flexDirection: 'row'}}>
<Image
source={{
uri:
'https://meu.anawork.com' +
item.extend_approver_avatar,
}}
style={styles.avatarApprove}
/>
<View>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
width: '83%',
}}>
<View
style={{
justifyContent: 'space-between',
marginLeft: 8,
}}>
<AppText>
{item.extend_approver_full_name}
</AppText>
<View style={{flexDirection: 'row'}}>
{item.extend_approved_status_name ==
'APPROVED' && (
<Image
style={{height: 16, width: 16}}
source={IMAGES.uCheck}
/>
)}
{item.extend_approved_status_name ==
'PENDING' && <Image source={IMAGES.uMinus} />}
{item.extend_approved_status_name ==
'REJECTED' && (
<Image
source={IMAGES.IcReject}
style={{
height: 12,
width: 12,
alignSelf: 'center',
}}
/>
)}
<AppText
style={{
color: item.extend_approved_status_color,
fontStyle: 'italic',
fontSize: 12,
}}>
{(item.extend_approved_status_name ==
'APPROVED' &&
'Đã duyệt') ||
(item.extend_approved_status_name ==
'PENDING' &&
'Đang chờ') ||
'Đã từ chối'}
</AppText>
</View>
</View>
<AppText style={{fontSize: 12, color: '#959595'}}>
{Moment(item.created_at).format('DD/MM/YYYY')}
</AppText>
</View>
<View style={{marginLeft: 8}}>
<AppText style={{fontSize: 13, color: '#757575'}}>
{item.comment ? item.comment : ''}
</AppText>
</View>
</View>
</View>
))}
{leaveDayDetail?.extend_approved_status_name == 'PENDING' &&
leaveDayDetail?.approver_id == userDetails.id && (
<View style={{flexDirection: 'row'}}>
<Image
source={{
uri: 'https://meu.anawork.com' + userDetails.avatar,
}}
style={styles.avatarApprove}
/>
<View>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
width: '83%',
}}>
<View
style={{
justifyContent: 'space-between',
marginLeft: 8,
}}>
<AppText>
{leaveDayDetail.extend_approver_full_name}
</AppText>
<View style={{flexDirection: 'row'}}>
{leaveDayDetail.extend_approved_status_name ==
'APPROVED' ? (
<Image
style={{height: 16, width: 16}}
source={IMAGES.uCheck}
/>
) : (
<Image source={IMAGES.uMinus} />
)}
<AppText
style={{
color:
leaveDayDetail.extend_approved_status_color,
fontStyle: 'italic',
fontSize: 12,
}}>
{(leaveDayDetail.extend_approved_status_name ==
'APPROVED' &&
'Đã duyệt') ||
(leaveDayDetail.extend_approved_status_name ==
'PENDING' &&
'Đang chờ') ||
'Đã từ chối'}
</AppText>
</View>
</View>
<AppText style={{fontSize: 12, color: '#959595'}}>
{Moment().format('DD/MM/YYYY')}
</AppText>
</View>
<View style={{marginLeft: 8}}>
<View style={styles.wrapperComment}>
<KeyboardAvoidingView
behavior={
Platform.OS === 'ios' ? 'padding' : 'height'
}>
<TextInput
placeholder="Nhập lý do tại đây"
style={styles.commentInput}
multiline
value={commentApprove}
onChangeText={text => {
setCommentApprove(text);
}}
/>
</KeyboardAvoidingView>
</View>
</View>
</View>
</View>
)}
</View>
{leaveDayDetail?.approver_id == userDetails.id && (
<View
style={{
marginTop: 12,
flexDirection: 'row',
alignItems: 'center',
}}>
<CheckBox
boxType="square"
animationDuration={0.3}
value={isNextApprover}
onValueChange={value => setIsNextApprover(value)}
/>
<AppText
style={{
fontSize: 14,
color: '#434349',
marginLeft: 4,
}}>
Chn người duyt tiếp theo
</AppText>
</View>
)}
{isNextApprover &&
userManagerList.map((item, index) => (
<View
key={index}
style={{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginTop: 12,
}}>
<Image
source={{
uri: 'https://meu.anawork.com' + item.avatar,
}}
style={styles.avatarApprove}
/>
<AppText
style={{
fontSize: 16,
fontWeight: '500',
marginLeft: 10,
}}>{`${item.extend_user_full_name}`}</AppText>
<CheckBox
disabled={false}
value={item.checked}
onValueChange={newValue =>
onSelectManager(newValue, index, item)
}
boxType="square"
animationDuration={0.3}
/>
</View>
))}
<View style={{marginTop: 16}}>
<AppText
style={{
fontWeight: '500',
fontSize: 14,
marginBottom: 12,
}}>
Bình lun
</AppText>
{/*others comment*/}
{leaveComment &&
leaveComment.map((item, index) => (
<View style={styles.commentHistories} key={index}>
<Image
source={{
uri:
'https://meu.anawork.com' +
item.extend_staff_avatar,
}}
style={styles.avatarComment}
/>
<View style={styles.commentBox}>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
}}>
<AppText
style={{
color: '#434349',
fontSize: 12,
fontWeight: '500',
}}>
{item.extend_staff_full_name}
</AppText>
<AppText style={{color: '#959595', fontSize: 10}}>
{Moment(item.created_at).format(
'DD/MM/YYYY hh:mm',
)}
</AppText>
</View>
<AppText
style={{
color: '#666666',
fontSize: 13,
marginTop: 8,
}}>
{item.content}
</AppText>
</View>
</View>
))}
{/*my comment*/}
<View style={[styles.commentHistories, {marginTop: 16}]}>
<Image
source={{
uri: 'https://meu.anawork.com' + userDetails.avatar,
}}
style={styles.avatarComment}
/>
<View style={{width: '88%', position: 'relative'}}>
<TextInput
style={styles.commentText}
multiline
placeholder="Nhập bình luận ở đây"
onChangeText={text => {
setComment({
content: text,
code: leaveDayDetail.id,
});
}}
value={comment.content}
/>
<View style={{position: 'absolute', right: 0, top: 10}}>
<TouchableOpacity onPress={onSubmitComment}>
<Image
style={{height: 16, width: 16, marginRight: 4}}
source={IMAGES.IcSend}
/>
</TouchableOpacity>
</View>
</View>
</View>
</View>
</View>
</View>
<View style={styles.bottomModal}>
<TouchableOpacity
style={styles.btnCancel}
onPress={() => onClose(null)}>
<AppText
style={{color: '#5d78ff', fontSize: 14, fontWeight: '500'}}>
Hy
</AppText>
</TouchableOpacity>
{leaveDayDetail &&
leaveDayDetail?.approver_id !== userDetails.id &&
detailItem.extend_approved_status_name === 'PENDING' && (
<ButtonComponent
style={{flexDirection: 'row', alignItems: 'center'}}
text={'Xóa yêu cầu'}
textStyle={{
color: '#ff0a3a',
fontSize: 14,
fontWeight: '500',
}}
leftIcon={IMAGES.IcReject}
styleIcon={{height: 15, width: 15, marginRight: 4}}
onPress={deleteItem}
/>
)}
{leaveDayDetail?.approver_id === userDetails.id &&
leaveDayDetail?.extend_approved_status_name == 'PENDING' && (
<View style={{flexDirection: 'row'}}>
<TouchableOpacity
style={styles.btnReject}
onPress={() => {
onRejectRequest(leaveDayDetail.id);
}}>
<Image
style={{height: 16, width: 16, marginRight: 4}}
source={IMAGES.IcReject}
/>
<AppText
style={{
color: '#ff0a3a',
fontSize: 14,
fontWeight: '500',
}}>
T chi
</AppText>
</TouchableOpacity>
<TouchableOpacity
style={styles.btnAccept}
onPress={() => {
onApproveRequest(leaveDayDetail.id);
}}>
<Image
style={{height: 16, width: 16, marginRight: 4}}
source={IMAGES.IcAccept}
/>
<AppText
style={{
color: 'white',
fontSize: 14,
fontWeight: '500',
}}>
Duyt yêu cu
</AppText>
</TouchableOpacity>
</View>
)}
</View>
</View>
</ScrollView>
</SafeAreaView>
</Modal>
);
};
const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;
const styles = StyleSheet.create({
container: {
flex: 1,
},
primary_blue: {
color: '#5d78ff',
},
item: {
padding: 20,
marginVertical: 2,
marginHorizontal: 16,
borderWidth: 1,
borderBottomColor: '#f2f2f2',
borderTopColor: '#f2f2f2',
borderRightColor: '#f2f2f2',
borderRadius: 8,
borderLeftWidth: 3,
flexDirection: 'row',
},
title: {
fontWeight: '500',
fontSize: 16,
color: 'black',
},
centeredView: {
justifyContent: 'center',
alignItems: 'center',
marginTop: 22,
},
modalView: {
backgroundColor: 'white',
borderRadius: 20,
padding: 16,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5,
marginTop: 20,
// height: windowHeight,
},
modalViewEdit: {
backgroundColor: 'white',
borderRadius: 20,
padding: 16,
// height: windowHeight,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5,
marginTop: 20,
minHeight: windowHeight,
},
button: {
borderRadius: 20,
padding: 10,
elevation: 2,
},
buttonOpen: {
backgroundColor: '#F194FF',
},
buttonClose: {
backgroundColor: '#2196F3',
},
textStyle: {
color: 'white',
fontWeight: 'bold',
textAlign: 'center',
},
modalTitle: {
fontWeight: '500',
fontSize: 16,
},
dropdown1DropdownStyle: {backgroundColor: '#EFEFEF'},
dropdown1RowStyle: {
backgroundColor: '#EFEFEF',
borderBottomColor: '#C5C5C5',
height: 38,
borderRadius: 4,
},
dropdown1RowTxtStyle: {color: '#444', textAlign: 'left', fontSize: 14},
dropdownSelectTimeText: {color: '#444', textAlign: 'left', fontSize: 14},
dropdown1BtnStyle: {
backgroundColor: '#FFF',
borderBottomWidth: 0.2,
height: 24,
width: '100%',
fontSize: 12,
borderColor: '#444',
},
dropdown1BtnTxtStyle: {color: '#000', fontSize: 14, textAlign: 'left'},
rowView: {
flexDirection: 'row',
marginTop: 10,
justifyContent: 'space-between',
alignItems: 'center',
},
inputText: {
backgroundColor: '#FFF',
paddingLeft: 18,
marginTop: 4,
},
touchableOpacity: {
borderColor: colors.primary_blue,
borderStyle: 'dotted',
borderWidth: 1,
justifyContent: 'center',
alignItems: 'center',
height: 100,
padding: 10,
width: '35%',
},
btnSubmit: {
backgroundColor: '#5d78ff',
justifyContent: 'center',
alignItems: 'center',
height: 40,
borderRadius: 8,
width: 100,
},
btnCancel: {
backgroundColor: colors.white,
justifyContent: 'center',
alignItems: 'center',
height: 40,
borderRadius: 8,
width: 100,
},
ImgAvatar: {
width: 50,
height: 50,
borderRadius: 30,
},
imgUpload: {
resizeMode: 'contain',
height: 90,
width: 100,
},
headerModalBottom: {
paddingRight: 10,
paddingLeft: 10,
flexDirection: 'row',
justifyContent: 'space-between',
},
titleModalBottom: {
fontSize: 16,
fontWeight: '500',
},
bodyModal: {
// flex: 1,
paddingHorizontal: 10,
marginTop: 16,
},
reason: {
width: windowWidth / 2 - 25,
textAlign: 'right',
},
textMediumGrey: {
color: '#757575',
},
commonDetail: {
flexDirection: 'row',
justifyContent: 'space-between',
fontSize: 14,
marginBottom: 12,
fontFamily: 'Roboto',
},
attachment: {
borderColor: '#c4c4c4',
borderStyle: 'dashed',
borderWidth: 0.5,
borderRadius: 4,
height: 60,
width: '50%',
justifyContent: 'center',
alignItems: 'center',
padding: 8,
},
checkbox: {
alignSelf: 'center',
height: 16,
width: 16,
marginRight: 4,
},
commentHistories: {
flexDirection: 'row',
marginBottom: 10,
},
avatarApprove: {
width: 32,
height: 32,
borderRadius: 4,
},
avatarComment: {
width: 32,
height: 32,
borderRadius: 32,
},
commentBox: {
backgroundColor: '#e5eaf0',
width: '88%',
marginLeft: 8,
paddingHorizontal: 12,
paddingVertical: 8,
borderTopRightRadius: 4,
borderBottomRightRadius: 4,
borderBottomLeftRadius: 4,
},
commentText: {
marginLeft: 8,
width: '100%',
color: '#959595',
fontSize: 12,
borderBottomColor: '#5c65dc',
borderBottomWidth: 1,
paddingLeft: 8,
paddingRight: 28,
paddingVertical: 10,
},
bottomModal: {
width: '100%',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 8,
marginTop: 20,
// flex: 1
},
bodyHeight: {
// flex: 2
},
btnAccept: {
flexDirection: 'row',
paddingHorizontal: 8,
paddingVertical: 12,
backgroundColor: '#5d78ff',
borderRadius: 4,
},
btnCancel: {
paddingHorizontal: 8,
paddingVertical: 12,
},
btnReject: {
flexDirection: 'row',
paddingHorizontal: 8,
paddingVertical: 12,
marginRight: 8,
},
wrapperComment: {
borderColor: '#5d78ff',
borderStyle: 'dashed',
borderWidth: 0.5,
borderRadius: 4,
height: 60,
width: '81%',
padding: 8,
},
commentInput: {
fontSize: 13,
},
takeTimeStyle: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'flex-end',
borderBottomColor: '#444',
borderBottomWidth: 0.2,
height: 24,
},
});
export default OnLeaveModalDetail;
...@@ -417,7 +417,7 @@ export const leavesModalStyles = StyleSheet.create({ ...@@ -417,7 +417,7 @@ export const leavesModalStyles = StyleSheet.create({
}, },
modalView: { modalView: {
backgroundColor: 'white', backgroundColor: colors.white,
borderRadius: 20, borderRadius: 20,
paddingHorizontal: 10, paddingHorizontal: 10,
shadowColor: colors.black1, shadowColor: colors.black1,
......
...@@ -24,5 +24,8 @@ const commonStyles = StyleSheet.create({ ...@@ -24,5 +24,8 @@ const commonStyles = StyleSheet.create({
marginVertical10: { marginVertical10: {
marginVertical: 10, marginVertical: 10,
}, },
marginVertical20: {
marginVertical: 20,
},
}); });
export default commonStyles; export default commonStyles;
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