Commit 68139437 authored by dungtnguyen's avatar dungtnguyen

add restart app

parent f200630d
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
"react-native-pie-chart": "^3.0.2", "react-native-pie-chart": "^3.0.2",
"react-native-reanimated": "^3.15.3", "react-native-reanimated": "^3.15.3",
"react-native-responsive-screen": "^1.4.2", "react-native-responsive-screen": "^1.4.2",
"react-native-restart": "^0.0.27",
"react-native-safe-area-context": "^4.11.0", "react-native-safe-area-context": "^4.11.0",
"react-native-screens": "^3.34.0", "react-native-screens": "^3.34.0",
"react-native-select-dropdown": "^4.0.1", "react-native-select-dropdown": "^4.0.1",
...@@ -9597,6 +9598,16 @@ ...@@ -9597,6 +9598,16 @@
"react-native": ">=0.35" "react-native": ">=0.35"
} }
}, },
"node_modules/react-native-restart": {
"version": "0.0.27",
"resolved": "https://registry.npmjs.org/react-native-restart/-/react-native-restart-0.0.27.tgz",
"integrity": "sha512-8KScVICrXwcTSJ1rjWkqVTHyEKQIttm5AIMGSK1QG1+RS5owYlE4z/1DykOTdWfVl9l16FIk0w9Xzk9ZO6jxlA==",
"license": "MIT",
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-safe-area-context": { "node_modules/react-native-safe-area-context": {
"version": "4.11.0", "version": "4.11.0",
"license": "MIT", "license": "MIT",
......
import axiosClient from '../network/axios'; import axiosClient from '../network/axios';
import axiosFormData from '../network/axiosFormData';
export default { export default {
requestChangeUserInfo: ({id, body}) => axiosClient.put(`users/${id}`, body), requestChangeUserInfo: ({id, body}) => axiosClient.put(`users/${id}`, body),
requestChangeAvatar: ({id, file}) =>
axiosFormData.put(`users/${id}/uploadAvatar`, file),
requestChangeCoverAvatar: ({id, file}) =>
axiosFormData.put(`users/${id}/uploadCoverImage`, file),
}; };
import axios from 'axios';
import Utils from '../utils';
import config from '../config';
const axiosFormData = axios.create({
baseURL: config.apiEndpoint,
headers: {
'Content-Type': 'multipart/form-data',
},
timeout: config.axiosTimeout,
});
axiosFormData.interceptors.request.use(async configAxios => {
const auth = await Utils.getData(config.storageKey.AUTH);
if (auth) {
configAxios.headers.Authorization = `Bearer ${auth}`;
}
return configAxios;
});
axiosFormData.interceptors.response.use(
response => {
if (response?.data) {
return response.data;
}
return response;
},
error => {
throw error;
},
);
export default axiosFormData;
...@@ -6,13 +6,12 @@ import RootNavigation from '../../../navigation/RootNavigation'; ...@@ -6,13 +6,12 @@ import RootNavigation from '../../../navigation/RootNavigation';
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from '@react-native-async-storage/async-storage';
import {useTranslation} from 'react-i18next'; import {useTranslation} from 'react-i18next';
import {useDispatch} from 'react-redux'; import {useDispatch} from 'react-redux';
import config from '../../../config';
import Utils from '../../../utils';
import AsyncStorageKeys from '../../../utils/AsyncStorageKeys'; import AsyncStorageKeys from '../../../utils/AsyncStorageKeys';
import {APP_NAVIGATE_SCREEN} from '../../../utils/constant'; import {APP_NAVIGATE_SCREEN} from '../../../utils/constant';
import SplashScreen from './SplashScreen';
import Utils from '../../../utils';
import config from '../../../config';
import {getMyInfo} from '../authSlice'; import {getMyInfo} from '../authSlice';
import {resetCache} from '../../../../metro.config'; import SplashScreen from './SplashScreen';
const SplashContainer = () => { const SplashContainer = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const {t, i18n} = useTranslation(); const {t, i18n} = useTranslation();
......
...@@ -83,8 +83,7 @@ const OnLeaveContainer = props => { ...@@ -83,8 +83,7 @@ const OnLeaveContainer = props => {
reason: '', reason: '',
}); });
// open the modal // open the modal
const onOpenDetailModal = useCallback( const onOpenDetailModal = detail => {
detail => {
if (detail) { if (detail) {
const user = { const user = {
id: detail?.staff_id, id: detail?.staff_id,
...@@ -105,9 +104,7 @@ const OnLeaveContainer = props => { ...@@ -105,9 +104,7 @@ const OnLeaveContainer = props => {
isRequest: false, isRequest: false,
}); });
} }
}, };
[userInfo],
);
const onOpenRequestLeavesModal = userDetails => { const onOpenRequestLeavesModal = userDetails => {
setLeavesDaysModal({ setLeavesDaysModal({
......
...@@ -27,13 +27,12 @@ const selectDataDropDown = [ ...@@ -27,13 +27,12 @@ const selectDataDropDown = [
]; ];
const DataChartLeavesRestDays = React.memo( const DataChartLeavesRestDays = React.memo(
({dataChart}) => { ({dataChart = []}) => {
return ( return (
<View style={styles.pieChartContainer}> <View style={styles.pieChartContainer}>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false}> <ScrollView horizontal={true} showsHorizontalScrollIndicator={false}>
<View style={{flexDirection: 'row'}}> <View style={{flexDirection: 'row'}}>
{dataChart && {dataChart?.length > 0 &&
dataChart?.length &&
dataChart.map((item, index) => { dataChart.map((item, index) => {
return ( return (
<View <View
...@@ -54,8 +53,10 @@ const DataChartLeavesRestDays = React.memo( ...@@ -54,8 +53,10 @@ const DataChartLeavesRestDays = React.memo(
doughnut={true} doughnut={true}
widthAndHeight={100} widthAndHeight={100}
series={[ series={[
item.from ? item.from : 0, item.from < 0
item.to ? item.to : 1, ? Math.abs(item.from)
: item.from || 0,
item.to < 0 ? Math.abs(item.to) : item.to || 1,
]} ]}
sliceColor={sliceColorRight} sliceColor={sliceColorRight}
coverRadius={0.9} coverRadius={0.9}
......
...@@ -4,7 +4,6 @@ import {launchImageLibrary} from 'react-native-image-picker'; ...@@ -4,7 +4,6 @@ import {launchImageLibrary} from 'react-native-image-picker';
import Toast from 'react-native-toast-message'; import Toast from 'react-native-toast-message';
import {useDispatch} from 'react-redux'; import {useDispatch} from 'react-redux';
import RootNavigation from '../../navigation/RootNavigation'; import RootNavigation from '../../navigation/RootNavigation';
import {changeAvatar, changeCoverAvatar} from '../../store/actions/UserAction';
import Utils from '../../utils'; import Utils from '../../utils';
import {APP_NAVIGATE_SCREEN} from '../../utils/constant'; import {APP_NAVIGATE_SCREEN} from '../../utils/constant';
import {logout} from '../authentication/authSlice'; import {logout} from '../authentication/authSlice';
...@@ -12,7 +11,7 @@ import profilePropsProvider from './profilePropsProvider'; ...@@ -12,7 +11,7 @@ import profilePropsProvider from './profilePropsProvider';
import ProfileMainView from './template/ProfileMainView'; import ProfileMainView from './template/ProfileMainView';
import {ToastMessage} from '../../utils/MessageUtil'; import {ToastMessage} from '../../utils/MessageUtil';
import config from '../../config'; import config from '../../config';
import {changeUserInfo} from './profileSlice'; import {changeAvatar, changeCoverAvatar, changeUserInfo} from './profileSlice';
const ProfileContainer = props => { const ProfileContainer = props => {
const {userInfo} = props; const {userInfo} = props;
...@@ -30,6 +29,7 @@ const ProfileContainer = props => { ...@@ -30,6 +29,7 @@ const ProfileContainer = props => {
}); });
const [avatar, setAvatar] = useState(); const [avatar, setAvatar] = useState();
const [coverAvatar, setCoverAvatar] = useState();
const [visibleMenu, setVisibleMenu] = useState(false); const [visibleMenu, setVisibleMenu] = useState(false);
...@@ -64,18 +64,26 @@ const ProfileContainer = props => { ...@@ -64,18 +64,26 @@ const ProfileContainer = props => {
response => { response => {
//console.log('res', response); //console.log('res', response);
if (!response.didCancel) { if (!response.didCancel) {
//setCoverAvatar(response.assets); const {assets} = response;
const resChangeCoverAvatar = dispatch( setCoverAvatar(response.assets);
changeCoverAvatar(userInfo.id, response.assets), let uploadImage = new FormData();
); uploadImage.append('file', {
if (resChangeCoverAvatar) { uri: assets[0].uri,
name: assets[0].fileName,
type: assets[0].type,
});
dispatch(
changeCoverAvatar({id: userInfo.id, file: uploadImage}),
).then(result => {
const {success} = Utils.getValues(result, 'payload', false);
setEditField(prev => ({...prev, avatar: false})); setEditField(prev => ({...prev, avatar: false}));
Toast.show({ Toast.show({
type: 'success', type: success ? 'success' : 'error',
text1: 'Hệ thống', text1: 'Hệ thống',
text2: 'Thay ảnh bìa thành công 💖', text2: `Thay ảnh bìa ${success ? 'thành công 💖' : 'thất bại'} `,
}); });
} });
//setEditField(prev => ({...prev, avatar: true})); //setEditField(prev => ({...prev, avatar: true}));
// hideMenu(); // hideMenu();
//console.log(response.assets[0].uri) //console.log(response.assets[0].uri)
...@@ -85,8 +93,6 @@ const ProfileContainer = props => { ...@@ -85,8 +93,6 @@ const ProfileContainer = props => {
}; };
const onSubmitChangeInfo = async values => { const onSubmitChangeInfo = async values => {
console.log('values', values);
if (userInfo) { if (userInfo) {
const { const {
first_name, first_name,
...@@ -148,14 +154,26 @@ const ProfileContainer = props => { ...@@ -148,14 +154,26 @@ const ProfileContainer = props => {
setEditField(prev => ({...prev, avatar: false})); setEditField(prev => ({...prev, avatar: false}));
}; };
const onConfirmAvatar = () => { const onConfirmAvatar = () => {
const res = dispatch(changeAvatar(userInfo.id, avatar)); if (avatar) {
if (res) { let uploadImage = new FormData();
for (let i = 0; i < avatar.length; i++) {
uploadImage.append('file', {
uri: avatar[i].uri,
name: avatar[i].fileName,
type: avatar[i].type,
});
}
dispatch(changeAvatar({id: userInfo.id, file: uploadImage})).then(
response => {
const {success} = Utils.getValues(response, 'payload', false);
setEditField(prev => ({...prev, avatar: false})); setEditField(prev => ({...prev, avatar: false}));
Toast.show({ Toast.show({
type: 'success', type: success ? 'success' : 'error',
text1: 'Hệ thống', text1: 'Hệ thống',
text2: 'Thay avatar thành công 💖', text2: `Thay avatar ${success ? 'thành công 💖' : 'thất bại!!!'}`,
}); });
},
);
} }
}; };
...@@ -163,7 +181,7 @@ const ProfileContainer = props => { ...@@ -163,7 +181,7 @@ const ProfileContainer = props => {
dispatch(logout()).then(response => { dispatch(logout()).then(response => {
const {success} = Utils.getValues(response, 'payload', false); const {success} = Utils.getValues(response, 'payload', false);
if (success) { if (success) {
RootNavigation.replace(APP_NAVIGATE_SCREEN.LOGIN); Utils.restartApp();
} }
}); });
}; };
...@@ -181,6 +199,7 @@ const ProfileContainer = props => { ...@@ -181,6 +199,7 @@ const ProfileContainer = props => {
avatar, avatar,
visibleMenu, visibleMenu,
editUserInfo, editUserInfo,
coverAvatar,
onDeniedAvatar, onDeniedAvatar,
onConfirmAvatar, onConfirmAvatar,
showMenu, showMenu,
......
...@@ -14,6 +14,7 @@ export default function profilePropsProvider(props) { ...@@ -14,6 +14,7 @@ export default function profilePropsProvider(props) {
onEditUserInfo, onEditUserInfo,
editUserInfo, editUserInfo,
onSubmitChangeInfo, onSubmitChangeInfo,
coverAvatar,
} = props; } = props;
return { return {
userInfo, userInfo,
...@@ -24,6 +25,7 @@ export default function profilePropsProvider(props) { ...@@ -24,6 +25,7 @@ export default function profilePropsProvider(props) {
userInfo, userInfo,
isEditField, isEditField,
avatar, avatar,
coverAvatar,
onDeniedAvatar, onDeniedAvatar,
onConfirmAvatar, onConfirmAvatar,
showMenu, showMenu,
......
...@@ -20,7 +20,32 @@ export const changeUserInfo = createAsyncThunk( ...@@ -20,7 +20,32 @@ export const changeUserInfo = createAsyncThunk(
}); });
}, },
); );
export const changeAvatar = createAsyncThunk(
'profile/changeAvatar',
async (data, thunkAPI) => {
return serviceRequest({
dispatch: thunkAPI.dispatch,
serviceMethod: profileAPI.requestChangeAvatar,
payload: data,
options: {
skipLoader: false,
},
});
},
);
export const changeCoverAvatar = createAsyncThunk(
'profile/requestChangeCoverAvatar',
async (data, thunkAPI) => {
return serviceRequest({
dispatch: thunkAPI.dispatch,
serviceMethod: profileAPI.requestChangeCoverAvatar,
payload: data,
options: {
skipLoader: false,
},
});
},
);
const profileSlice = createSlice({ const profileSlice = createSlice({
name: 'profile', name: 'profile',
initialState: initialState, initialState: initialState,
......
...@@ -98,6 +98,7 @@ const IntroduceUser = props => { ...@@ -98,6 +98,7 @@ const IntroduceUser = props => {
visibleMenu, visibleMenu,
openGallery, openGallery,
onChangeCoverAvatar, onChangeCoverAvatar,
coverAvatar = [],
} = props; } = props;
return ( return (
<Swiper <Swiper
...@@ -109,7 +110,9 @@ const IntroduceUser = props => { ...@@ -109,7 +110,9 @@ const IntroduceUser = props => {
<View style={styles.viewImageProfile}> <View style={styles.viewImageProfile}>
<ImageBackground <ImageBackground
source={ source={
userInfo?.cover_image coverAvatar.length > 0
? {uri: coverAvatar[0].uri}
: userInfo?.cover_image
? { ? {
uri: config.imageEndPoint + userInfo?.cover_image, uri: config.imageEndPoint + userInfo?.cover_image,
} }
......
...@@ -2,6 +2,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; ...@@ -2,6 +2,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage';
import moment from 'moment'; import moment from 'moment';
import {Linking} from 'react-native'; import {Linking} from 'react-native';
import config from '../config'; import config from '../config';
import RNRestart from 'react-native-restart';
const storeData = async (storageKey, value) => { const storeData = async (storageKey, value) => {
try { try {
const jsonValue = JSON.stringify(value); const jsonValue = JSON.stringify(value);
...@@ -176,6 +177,7 @@ const minutesToHours = (start, finish) => { ...@@ -176,6 +177,7 @@ const minutesToHours = (start, finish) => {
var minutes = time % 60; var minutes = time % 60;
return `${Hours}:${minutes} gi`; return `${Hours}:${minutes} gi`;
}; };
const restartApp = () => RNRestart.Restart();
const Utils = { const Utils = {
storeData, storeData,
getData, getData,
...@@ -188,5 +190,6 @@ const Utils = { ...@@ -188,5 +190,6 @@ const Utils = {
formatCurrency, formatCurrency,
getCategoryNotification, getCategoryNotification,
minutesToHours, minutesToHours,
restartApp,
}; };
export default Utils; export default Utils;
...@@ -4642,6 +4642,11 @@ react-native-reanimated@^3.15.3: ...@@ -4642,6 +4642,11 @@ react-native-reanimated@^3.15.3:
react-native-responsive-screen@^1.4.2: react-native-responsive-screen@^1.4.2:
version "1.4.2" version "1.4.2"
react-native-restart@^0.0.27:
version "0.0.27"
resolved "https://registry.npmjs.org/react-native-restart/-/react-native-restart-0.0.27.tgz"
integrity sha512-8KScVICrXwcTSJ1rjWkqVTHyEKQIttm5AIMGSK1QG1+RS5owYlE4z/1DykOTdWfVl9l16FIk0w9Xzk9ZO6jxlA==
react-native-safe-area-context@*, react-native-safe-area-context@^4.11.0, "react-native-safe-area-context@>= 3.0.0": react-native-safe-area-context@*, react-native-safe-area-context@^4.11.0, "react-native-safe-area-context@>= 3.0.0":
version "4.11.0" version "4.11.0"
......
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