Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
anawork-mobile-v2
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
dungtnguyen
anawork-mobile-v2
Commits
6a8e5bdb
Commit
6a8e5bdb
authored
Oct 13, 2024
by
dungtnguyen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
change user info
parent
49289102
Changes
20
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
397 additions
and
571 deletions
+397
-571
app-release-final.apk
android/app/release/app-release-final.apk
+0
-0
app-release.dm
android/app/release/baselineProfiles/0/app-release.dm
+0
-0
app-release.dm
android/app/release/baselineProfiles/1/app-release.dm
+0
-0
output-metadata.json
android/app/release/output-metadata.json
+37
-0
authAPI.js
src/api/authAPI.js
+1
-1
onLeaveApi.js
src/api/onLeaveApi.js
+1
-1
profileAPI.js
src/api/profileAPI.js
+4
-0
index.js
src/config/index.js
+5
-1
authSlice.js
src/screens/authentication/authSlice.js
+19
-0
LoginContainer.js
src/screens/authentication/login/LoginContainer.js
+2
-3
ConfirmDateContainer.js
src/screens/confirm_date/ConfirmDateContainer.js
+5
-0
OnLeaveContainer.js
src/screens/onleave/OnLeaveContainer.js
+6
-0
onLeaveSlice.js
src/screens/onleave/onLeaveSlice.js
+1
-1
style.js
src/screens/onleave/style.js
+2
-2
ProfileContainer.js
src/screens/profile/ProfileContainer.js
+80
-284
profilePropsProvider.js
src/screens/profile/profilePropsProvider.js
+6
-67
profileSlice.js
src/screens/profile/profileSlice.js
+36
-0
ProfileMainView.js
src/screens/profile/template/ProfileMainView.js
+19
-175
DetailInformation.js
src/screens/profile/template/components/DetailInformation.js
+86
-18
PersonalInformation.js
...creens/profile/template/components/PersonalInformation.js
+87
-18
No files found.
android/app/release/app-release-final.apk
0 → 100644
View file @
6a8e5bdb
File added
android/app/release/baselineProfiles/0/app-release.dm
0 → 100644
View file @
6a8e5bdb
File added
android/app/release/baselineProfiles/1/app-release.dm
0 → 100644
View file @
6a8e5bdb
File added
android/app/release/output-metadata.json
0 → 100644
View file @
6a8e5bdb
{
"version"
:
3
,
"artifactType"
:
{
"type"
:
"APK"
,
"kind"
:
"Directory"
},
"applicationId"
:
"com.anawork_mobile"
,
"variantName"
:
"release"
,
"elements"
:
[
{
"type"
:
"SINGLE"
,
"filters"
:
[],
"attributes"
:
[],
"versionCode"
:
1
,
"versionName"
:
"1.0"
,
"outputFile"
:
"app-release.apk"
}
],
"elementType"
:
"File"
,
"baselineProfiles"
:
[
{
"minApi"
:
28
,
"maxApi"
:
30
,
"baselineProfiles"
:
[
"baselineProfiles/1/app-release.dm"
]
},
{
"minApi"
:
31
,
"maxApi"
:
2147483647
,
"baselineProfiles"
:
[
"baselineProfiles/0/app-release.dm"
]
}
],
"minSdkVersionForDexing"
:
23
}
\ No newline at end of file
src/api/authAPI.js
View file @
6a8e5bdb
...
...
@@ -14,7 +14,7 @@ const authAPI = {
`authenticate/authenticate?username=
${
username
}
&password=
${
password
}
`
,
),
requestLogout
:
(
{
token
})
=>
axiosClient
.
post
(
'authenticate/logout'
,
{
token
}
),
requestLogout
:
(
)
=>
axiosClient
.
post
(
'authenticate/logout'
),
requestGetMyInfo
:
()
=>
axiosClient
.
get
(
'authenticate/getMyInfo'
),
requestGetCompanyLogo
:
()
=>
axiosClient
.
get
(
'companyInfo'
),
...
...
src/
network/
api/onLeaveApi.js
→
src/api/onLeaveApi.js
View file @
6a8e5bdb
import
axiosClient
from
'../axios'
;
import
axiosClient
from
'../
network/
axios'
;
export
default
{
requestGetLeavesDay
:
({
filter
,
sort
,
page
,
pageSize
})
=>
axiosClient
.
get
(
...
...
src/api/profileAPI.js
0 → 100644
View file @
6a8e5bdb
import
axiosClient
from
'../network/axios'
;
export
default
{
requestChangeUserInfo
:
({
id
,
body
})
=>
axiosClient
.
put
(
`users/
${
id
}
`
,
body
),
};
src/config/index.js
View file @
6a8e5bdb
...
...
@@ -2,7 +2,10 @@ const storageKey = {
AUTH
:
'auth'
,
LANGUAGE
:
'language'
,
};
const
profileField
=
{
PERSONAL_INFO
:
'Personal Information'
,
DETAIL_INFO
:
'Detail Information'
,
};
export
default
{
apiEndpoint
:
'https://gateway.dev.meu-solutions.com/staginganawork/api/'
,
//apiEndpoint: 'https://gateway.dev.meu-solutions.com/techport/api/',
...
...
@@ -11,4 +14,5 @@ export default {
ONE_SIGNAL_KEY
:
'6f4f8bd1-9b43-4067-8175-c0052140e891'
,
axiosTimeout
:
10000
,
storageKey
,
profileField
,
};
src/screens/authentication/authSlice.js
View file @
6a8e5bdb
...
...
@@ -52,6 +52,19 @@ export const getCompanyInfo = createAsyncThunk(
});
},
);
export
const
logout
=
createAsyncThunk
(
'auth/logout'
,
async
(
data
,
thunkAPI
)
=>
{
return
serviceRequest
({
dispatch
:
thunkAPI
.
dispatch
,
serviceMethod
:
authAPI
.
requestLogout
,
payload
:
data
,
options
:
{
skipLoader
:
false
,
},
});
},
);
const
authSlice
=
createSlice
({
name
:
'auth'
,
initialState
:
initialState
,
...
...
@@ -71,6 +84,12 @@ const authSlice = createSlice({
state
.
userInfo
=
user
;
}
});
builder
.
addCase
(
logout
.
fulfilled
,
(
state
,
action
)
=>
{
const
{
success
}
=
Utils
.
getValues
(
action
,
'payload'
,
false
);
if
(
success
)
{
Utils
.
removeData
(
config
.
storageKey
.
AUTH
);
}
});
},
});
...
...
src/screens/authentication/login/LoginContainer.js
View file @
6a8e5bdb
/* eslint-disable prettier/prettier */
import
React
,
{
useState
}
from
'react'
;
import
RootNavigation
from
'../../../navigation/RootNavigation'
;
import
LoginScreen
from
'./LoginScreen'
;
...
...
@@ -7,11 +6,10 @@ import {useTranslation} from 'react-i18next';
import
OneSignal
from
'react-native-onesignal'
;
import
{
useDispatch
,
useSelector
}
from
'react-redux'
;
import
{
loaderSelector
}
from
'../../../app/selectors'
;
import
{
getMyInfo
}
from
'../../../store/actions/CommonAction'
;
import
Utils
from
'../../../utils'
;
import
{
APP_NAVIGATE_SCREEN
}
from
'../../../utils/constant'
;
import
{
ToastMessage
}
from
'../../../utils/MessageUtil'
;
import
{
authenticate
}
from
'../authSlice'
;
import
{
authenticate
,
getMyInfo
}
from
'../authSlice'
;
const
LoginContainer
=
props
=>
{
// console.log("props: ", props)
const
dispatch
=
useDispatch
();
...
...
@@ -66,6 +64,7 @@ const LoginContainer = props => {
}),
).
then
(
response
=>
{
const
{
success
}
=
Utils
.
getValues
(
response
,
'payload'
,
false
);
dispatch
(
getMyInfo
());
if
(
success
)
{
ToastMessage
({
title
:
'Hệ thống'
,
...
...
src/screens/confirm_date/ConfirmDateContainer.js
View file @
6a8e5bdb
...
...
@@ -380,6 +380,11 @@ const ConfirmDateContainer = props => {
};
const
handleSubmitConfirmWorkingDayRequest
=
()
=>
{
if
(
directManagersList
?.
length
===
0
)
{
ToastMessage
({
title
:
'Hệ thống'
,
message
:
'Bạn đã là cấp trên không thể gửi yêu cầu !!!'
,
type
:
'error'
,
});
return
false
;
}
const
isSelectedManager
=
directManagersList
.
filter
(
item
=>
item
.
isChecked
);
...
...
src/screens/onleave/OnLeaveContainer.js
View file @
6a8e5bdb
...
...
@@ -334,6 +334,12 @@ const OnLeaveContainer = props => {
};
const
handleSubmitLeaveRequest
=
()
=>
{
if
(
directManagersList
?.
length
===
0
)
{
ToastMessage
({
title
:
'Hệ thống'
,
message
:
'Bạn đã là cấp trên không thể gửi yêu cầu !!!'
,
type
:
'info'
,
timeVisible
:
5000
,
});
return
false
;
}
const
isSelectedManager
=
directManagersList
.
filter
(
item
=>
item
.
isChecked
);
...
...
src/screens/onleave/onLeaveSlice.js
View file @
6a8e5bdb
...
...
@@ -2,7 +2,7 @@ import {createAsyncThunk, createSlice} from '@reduxjs/toolkit';
import
serviceRequest
from
'../../app/serviceRequest'
;
import
onLeaveApi
from
'../../
network/
api/onLeaveApi'
;
import
onLeaveApi
from
'../../api/onLeaveApi'
;
import
Utils
from
'../../utils'
;
const
initialHome
=
{
...
...
src/screens/onleave/style.js
View file @
6a8e5bdb
...
...
@@ -428,9 +428,9 @@ export const leavesModalStyles = StyleSheet.create({
shadowOpacity
:
0.25
,
shadowRadius
:
4
,
elevation
:
5
,
marginTop
:
80
,
height
:
windowHeight
,
marginTop
:
100
,
width
:
'100%'
,
height
:
windowHeight
,
},
button
:
{
...
...
src/screens/profile/ProfileContainer.js
View file @
6a8e5bdb
...
...
@@ -4,67 +4,38 @@ import {launchImageLibrary} from 'react-native-image-picker';
import
Toast
from
'react-native-toast-message'
;
import
{
useDispatch
}
from
'react-redux'
;
import
RootNavigation
from
'../../navigation/RootNavigation'
;
import
{
logoutApp
}
from
'../../store/actions/CommonAction'
;
import
{
addContactUser
,
changeAvatar
,
changeContactUser
,
changeCoverAvatar
,
changeUserInfo
,
deleteContactUser
,
getContactUser
,
}
from
'../../store/actions/UserAction'
;
import
{
changeAvatar
,
changeCoverAvatar
}
from
'../../store/actions/UserAction'
;
import
Utils
from
'../../utils'
;
import
{
APP_NAVIGATE_SCREEN
}
from
'../../utils/constant'
;
import
{
logout
}
from
'../authentication/authSlice'
;
import
profilePropsProvider
from
'./profilePropsProvider'
;
import
ProfileMainView
from
'./template/ProfileMainView'
;
import
{
ToastMessage
}
from
'../../utils/MessageUtil'
;
import
config
from
'../../config'
;
import
{
changeUserInfo
}
from
'./profileSlice'
;
const
ProfileContainer
=
props
=>
{
const
{
userInfo
}
=
props
;
const
dispatch
=
useDispatch
();
const
[
modalVisible
,
setModalVisible
]
=
useState
(
false
);
const
[
isEditField
,
setEditField
]
=
useState
({
detail_info
:
false
,
contact_info
:
false
,
personal_info
:
false
,
avatar
:
false
,
});
const
[
btnAvailable
,
setBtnAvailable
]
=
useState
({
personalBtn
:
false
,
contactBtn
:
false
,
detailBtn
:
false
,
});
const
[
infoUser
,
setInfoUser
]
=
useState
(
userInfo
);
const
[
contactUser
,
setContactUser
]
=
useState
([]);
const
[
defaultContact
,
setDefaultContact
]
=
useState
([]);
const
[
userInputContact
,
setUserInputContact
]
=
useState
({
type
:
''
,
text
:
''
,
const
[
editUserInfo
,
setEditUserInfo
]
=
useState
({
personalInfo
:
false
,
detailInfo
:
false
,
});
const
[
avatar
,
setAvatar
]
=
useState
();
const
[
visibleMenu
,
setVisibleMenu
]
=
useState
(
false
);
const
[
isSlideShow
,
setSlideShow
]
=
useState
(
false
);
const
[
dateTimePicker
,
setDateTimePicker
]
=
useState
({
birthday
:
false
,
id_card_issue_date
:
false
,
});
const
[
showAlert
,
setShowAlert
]
=
useState
({
isError
:
false
,
title
:
''
,
message
:
''
,
});
const
[
deleteItem
,
setDelItem
]
=
useState
([]);
const
hideMenu
=
()
=>
setVisibleMenu
(
false
);
const
showMenu
=
()
=>
setVisibleMenu
(
true
);
const
hideDateTimePicker
=
()
=>
{
setDateTimePicker
({
birthday
:
false
,
id_card_issue_date
:
false
,
});
};
const
openGallery
=
()
=>
{
hideMenu
();
...
...
@@ -113,30 +84,63 @@ const ProfileContainer = props => {
);
};
const
showFullScreen
=
()
=>
{
setSlideShow
(
true
);
hideMenu
();
};
const
hideFullScreen
=
()
=>
{
//console.log("hide")
setSlideShow
(
false
);
const
onSubmitChangeInfo
=
async
values
=>
{
console
.
log
(
'values'
,
values
);
if
(
userInfo
)
{
const
{
first_name
,
middle_name
,
last_name
,
cell_phone
,
gender
,
birthday
,
birthplace
,
nationality
,
id_card_number
,
id_card_issue_date
,
id_card_issue_palce
,
ethnic
,
religion
,
domicile
,
personal_tax_code
,
address
,
permanent_address
,
}
=
values
;
const
payload
=
{
first_name
:
first_name
||
userInfo
?.
first_name
,
middle_name
:
middle_name
||
userInfo
?.
middle_name
,
last_name
:
last_name
||
userInfo
?.
last_name
,
cell_phone
:
cell_phone
||
userInfo
?.
cell_phone
,
gender
:
gender
===
'Nam'
,
birthday
:
birthday
||
userInfo
?.
birthday
,
birthplace
:
birthplace
||
userInfo
?.
birthplace
,
nationality
:
nationality
||
userInfo
?.
nationality
,
id_card_number
:
id_card_number
||
userInfo
?.
id_card_number
,
id_card_issue_date
:
id_card_issue_date
||
userInfo
?.
id_card_issue_date
,
id_card_issue_palce
:
id_card_issue_palce
||
userInfo
?.
id_card_issue_palce
,
ethnic
:
ethnic
||
userInfo
?.
ethnic
,
religion
:
religion
||
userInfo
?.
religion
,
domicile
:
domicile
||
userInfo
?.
domicile
,
personal_tax_code
:
personal_tax_code
||
userInfo
?.
personal_tax_code
,
address
:
address
||
userInfo
?.
address
,
permanent_address
:
permanent_address
||
userInfo
?.
permanent_address
,
};
const
onSaveInfo
=
async
()
=>
{
if
(
!!
compareInfoUser
)
{
const
res
=
await
dispatch
(
changeUserInfo
(
userInfo
.
id
,
infoUser
));
if
(
res
)
{
Toast
.
show
({
type
:
'success'
,
text1
:
'Hệ thống'
,
text2
:
'Thay đổi thông tin thành công 💖'
,
});
}
else
{
Toast
.
show
({
type
:
'error'
,
text1
:
'Hệ thống'
,
text2
:
'Thay đổi thông tin thất bại 💔'
,
dispatch
(
changeUserInfo
({
id
:
userInfo
.
id
,
body
:
payload
})).
then
(
response
=>
{
const
{
success
}
=
Utils
.
getValues
(
response
,
'payload'
,
false
);
success
&&
onEditUserInfo
();
ToastMessage
({
title
:
'Hệ thống'
,
message
:
`Thay đổi thông tin
${
success
?
'thành công 💖'
:
'thất bại 💔'
}
`
,
type
:
success
?
'success'
:
'error'
,
});
}
},
);
}
};
const
onDeniedAvatar
=
()
=>
{
...
...
@@ -154,246 +158,38 @@ const ProfileContainer = props => {
});
}
};
const
navigateMain
=
()
=>
{
RootNavigation
.
navigate
(
APP_NAVIGATE_SCREEN
.
MAIN
);
};
const
compareInfoUser
=
()
=>
{
// check user have change info
if
(
JSON
.
stringify
(
infoUser
)
==
JSON
.
stringify
(
userInfo
))
return
true
;
return
false
;
};
const
compareContactUser
=
()
=>
{
// check user have change info
// console.log("defaultContact", defaultContact)
if
(
JSON
.
stringify
(
defaultContact
)
===
JSON
.
stringify
(
contactUser
))
return
false
;
return
true
;
};
const
getContactSocialUser
=
async
()
=>
{
const
res
=
await
dispatch
(
getContactUser
(
userInfo
.
id
));
//console.log(res)
if
(
res
.
length
>
0
)
{
let
arrContact
=
[];
res
.
map
((
item
,
index
)
=>
{
arrContact
.
push
(
item
);
});
setContactUser
(
arrContact
);
setDefaultContact
(
JSON
.
parse
(
JSON
.
stringify
(
arrContact
)));
}
};
const
onChangeDropDownContactUser
=
(
selectedItem
,
index
)
=>
{
const
clone
=
[...
contactUser
];
clone
[
index
].
type
=
selectedItem
;
setContactUser
(
clone
);
//console.log("clone", clone)
};
const
onChangeInputContactUser
=
(
selectedItem
,
index
)
=>
{
const
clone
=
[...
contactUser
];
clone
[
index
].
contact_unique_id
=
selectedItem
;
setContactUser
(
clone
);
//console.log("clone", clone)
};
const
checkValidDropdown
=
()
=>
{
var
isValid
=
contactUser
.
map
(
a
=>
a
.
type
);
//console.log(isValid.some((a, index) => isValid.indexOf(a) !== index))
return
isValid
.
some
((
a
,
index
)
=>
isValid
.
indexOf
(
a
)
!==
index
);
};
const
onSubmitChangeContactUser
=
async
(
contact_unique_id
,
type
)
=>
{
const
isChange
=
compareContactUser
();
//console.log("defaultContact", defaultContact)
const
isValid
=
checkValidDropdown
();
if
(
!
isValid
)
{
if
(
isChange
)
{
//console.log("compareEmailContactUser", isChange)
const
resultsChange
=
contactUser
.
filter
(
({
type
:
t1
,
contact_unique_id
:
cui_1
})
=>
!
defaultContact
.
some
(
({
type
:
t2
,
contact_unique_id
:
cui_2
})
=>
t2
===
t1
&&
cui_1
===
cui_2
,
),
);
//console.log("results", resultsChange)
const
res
=
await
dispatch
(
changeContactUser
(
resultsChange
[
0
].
id
,
resultsChange
[
0
].
contact_unique_id
,
resultsChange
[
0
].
type
,
),
);
if
(
res
.
success
)
{
Toast
.
show
({
type
:
'success'
,
text1
:
'Hệ thống'
,
text2
:
'Thay đổi liên lạc thành công 💖'
,
});
setEditField
(
prev
=>
({...
prev
,
contact_info
:
false
}));
setBtnAvailable
(
prev
=>
({...
prev
,
contactBtn
:
false
}));
}
else
{
Toast
.
show
({
type
:
'error'
,
text1
:
'Hệ thống'
,
text2
:
'Thay đổi liên lạc thất bại 💔'
,
});
}
}
else
{
setEditField
(
prev
=>
({...
prev
,
contact_info
:
false
}));
setBtnAvailable
(
prev
=>
({...
prev
,
contactBtn
:
false
}));
}
}
else
{
Toast
.
show
({
type
:
'error'
,
text1
:
'Hệ thống'
,
text2
:
'Vui lòng chọn social khác nhau'
,
});
}
};
const
onPressDeleteItem
=
item
=>
{
// console.log("item", item)
setShowAlert
({
isError
:
true
,
title
:
'Hệ thống'
,
message
:
'Bạn có chắc chắn muốn xóa dòng dữ liệu này?'
,
});
setDelItem
(
item
);
};
const
onPressAddItem
=
()
=>
{
setModalVisible
(
true
);
};
const
onConfirmDeleteAlert
=
async
()
=>
{
const
clone
=
contactUser
.
filter
(
i
=>
i
!==
deleteItem
);
const
res
=
await
dispatch
(
deleteContactUser
(
deleteItem
.
id
));
if
(
res
)
{
Toast
.
show
({
type
:
'success'
,
text1
:
'Hệ thống'
,
text2
:
'Xoá thành công '
,
});
setContactUser
(
clone
);
setDefaultContact
(
clone
);
setShowAlert
({
isError
:
false
,
title
:
''
,
message
:
''
,
});
}
else
{
Toast
.
show
({
type
:
'error'
,
text1
:
'Hệ thống'
,
text2
:
'Xoá thất bại'
,
});
setShowAlert
({
isError
:
false
,
title
:
''
,
message
:
''
,
});
const
navigateToLogout
=
()
=>
{
dispatch
(
logout
()).
then
(
response
=>
{
const
{
success
}
=
Utils
.
getValues
(
response
,
'payload'
,
false
);
if
(
success
)
{
RootNavigation
.
replace
(
APP_NAVIGATE_SCREEN
.
LOGIN
);
}
// console.log("clone", clone)
};
const
onCancelAlert
=
()
=>
{
setShowAlert
({
isError
:
false
,
title
:
''
,
message
:
''
,
});
};
// submit add new contact
const
onSubmitCreateNew
=
async
()
=>
{
if
(
userInputContact
.
text
.
length
>
0
&&
userInputContact
.
type
.
length
>
0
)
{
// had social network type
const
duplicateSocial
=
contactUser
.
find
(
item
=>
item
.
type
===
userInputContact
.
type
,
);
//console.log("duplicateSocial", duplicateSocial)
if
(
duplicateSocial
===
undefined
)
{
const
res
=
await
dispatch
(
addContactUser
(
userInfo
.
id
,
userInputContact
.
text
,
userInputContact
.
type
,
),
);
if
(
res
.
success
)
{
Toast
.
show
({
type
:
'success'
,
text1
:
'Hệ thống'
,
text2
:
'Thêm contact thành công'
,
const
onEditUserInfo
=
field
=>
{
setEditUserInfo
({
personalInfo
:
field
===
config
.
profileField
.
PERSONAL_INFO
,
detailInfo
:
field
===
config
.
profileField
.
DETAIL_INFO
,
});
setEditField
(
prev
=>
({...
prev
,
contact_info
:
false
}));
setBtnAvailable
(
prev
=>
({...
prev
,
contactBtn
:
false
}));
setModalVisible
(
false
);
setUserInputContact
({
type
:
''
,
text
:
''
,
});
getContactSocialUser
();
}
else
{
Toast
.
show
({
type
:
'error'
,
text1
:
'Hệ thống'
,
text2
:
'Thêm contact thất bại'
,
});
}
}
else
{
Toast
.
show
({
type
:
'error'
,
text1
:
'Hệ thống'
,
text2
:
'Đã social này đã tổn tài'
,
});
}
}
};
const
navigateToLogout
=
()
=>
{
dispatch
(
logoutApp
());
};
useEffect
(()
=>
{
getContactSocialUser
();
},
[]);
const
profileProps
=
{
userInfo
,
isEditField
,
btnAvailable
,
infoUser
,
avatar
,
visibleMenu
,
isSlideShow
,
dateTimePicker
,
contactUser
,
showAlert
,
modalVisible
,
userInputContact
,
setAvatar
,
setInfoUser
,
navigateMain
,
setEditField
,
setBtnAvailable
,
onSaveInfo
,
editUserInfo
,
onDeniedAvatar
,
onConfirmAvatar
,
showMenu
,
openGallery
,
showFullScreen
,
hideFullScreen
,
hideMenu
,
hideDateTimePicker
,
setDateTimePicker
,
onSubmitChangeContactUser
,
setContactUser
,
onChangeDropDownContactUser
,
onChangeInputContactUser
,
onPressDeleteItem
,
onPressAddItem
,
onConfirmDeleteAlert
,
onCancelAlert
,
setUserInputContact
,
onSubmitCreateNew
,
setModalVisible
,
navigateToLogout
,
onChangeCoverAvatar
,
onEditUserInfo
,
onSubmitChangeInfo
,
};
return
<
ProfileMainView
{...
profilePropsProvider
(
profileProps
)}
/>
;
...
...
src/screens/profile/profilePropsProvider.js
View file @
6a8e5bdb
...
...
@@ -2,86 +2,24 @@ export default function profilePropsProvider(props) {
const
{
userInfo
,
isEditField
,
btnAvailable
,
infoUser
,
avatar
,
visibleMenu
,
isSlideShow
,
dateTimePicker
,
contactUser
,
showAlert
,
modalVisible
,
userInputContact
,
setAvatar
,
setInfoUser
,
navigateMain
,
setEditField
,
setBtnAvailable
,
onSaveInfo
,
onDeniedAvatar
,
onConfirmAvatar
,
showMenu
,
openGallery
,
showFullScreen
,
hideFullScreen
,
hideMenu
,
hideDateTimePicker
,
setDateTimePicker
,
onSubmitChangeContactUser
,
setContactUser
,
onChangeDropDownContactUser
,
onChangeInputContactUser
,
onPressDeleteItem
,
onPressAddItem
,
onConfirmDeleteAlert
,
onCancelAlert
,
setUserInputContact
,
onSubmitCreateNew
,
setModalVisible
,
navigateToLogout
,
onChangeCoverAvatar
,
onEditUserInfo
,
editUserInfo
,
onSubmitChangeInfo
,
}
=
props
;
return
{
userInfo
,
isEditField
,
btnAvailable
,
infoUser
,
avatar
,
visibleMenu
,
isSlideShow
,
dateTimePicker
,
contactUser
,
showAlert
,
modalVisible
,
userInputContact
,
setAvatar
,
setInfoUser
,
navigateMain
,
setEditField
,
setBtnAvailable
,
onSaveInfo
,
onDeniedAvatar
,
onConfirmAvatar
,
showMenu
,
openGallery
,
showFullScreen
,
hideFullScreen
,
hideMenu
,
hideDateTimePicker
,
setDateTimePicker
,
onSubmitChangeContactUser
,
setContactUser
,
onChangeDropDownContactUser
,
onChangeInputContactUser
,
onPressDeleteItem
,
onPressAddItem
,
onConfirmDeleteAlert
,
onCancelAlert
,
setUserInputContact
,
onSubmitCreateNew
,
setModalVisible
,
navigateToLogout
,
onChangeCoverAvatar
,
onEditUserInfo
,
editUserInfo
,
introduceUserProps
:
{
userInfo
,
isEditField
,
...
...
@@ -94,5 +32,6 @@ export default function profilePropsProvider(props) {
openGallery
,
onChangeCoverAvatar
,
},
onSubmitChangeInfo
,
};
}
src/screens/profile/profileSlice.js
View file @
6a8e5bdb
import
{
createAsyncThunk
,
createSlice
}
from
'@reduxjs/toolkit'
;
import
serviceRequest
from
'../../app/serviceRequest'
;
import
Utils
from
'../../utils'
;
import
profileAPI
from
'../../api/profileAPI'
;
const
initialState
=
{};
export
const
changeUserInfo
=
createAsyncThunk
(
'profile/changeUserInfo'
,
async
(
data
,
thunkAPI
)
=>
{
return
serviceRequest
({
dispatch
:
thunkAPI
.
dispatch
,
serviceMethod
:
profileAPI
.
requestChangeUserInfo
,
payload
:
data
,
options
:
{
skipLoader
:
false
,
},
});
},
);
const
profileSlice
=
createSlice
({
name
:
'profile'
,
initialState
:
initialState
,
reducers
:
{},
extraReducers
:
builder
=>
{
builder
.
addCase
(
changeUserInfo
.
fulfilled
,
(
state
,
action
)
=>
{
const
{
success
}
=
Utils
.
getValues
(
action
,
'payload'
,
false
);
});
},
});
const
{
reducer
}
=
profileSlice
;
export
default
reducer
;
src/screens/profile/template/ProfileMainView.js
View file @
6a8e5bdb
import
Moment
from
'moment'
;
import
React
from
'react'
;
import
{
Animated
,
Image
,
ImageBackground
,
Modal
,
SafeAreaView
,
ScrollView
,
TextInput
,
TouchableOpacity
,
View
,
}
from
'react-native'
;
import
Alert
from
'react-native-awesome-alerts'
;
import
{
GestureHandlerRootView
,
Swipeable
}
from
'react-native-gesture-handler'
;
import
{
Menu
,
MenuItem
}
from
'react-native-material-menu'
;
import
DateTimePickerModal
from
'react-native-modal-datetime-picker'
;
import
SelectDropdown
from
'react-native-select-dropdown'
;
import
Swiper
from
'react-native-swiper'
;
import
AppText
from
'../../../components/AppText'
;
import
{
SafeAreaView
,
ScrollView
,
View
}
from
'react-native'
;
import
ButtonComponent
from
'../../../components/ButtonComponent'
;
import
TextInputComponent
from
'../../../components/TextInputComponent'
;
import
{
IMAGES
,
IcNotificationList
,
IconProfile
,
IconSocial
,
}
from
'../../../values/images'
;
import
{
default
as
string
,
default
as
strings
}
from
'../../../values/string'
;
import
{
IMAGES
}
from
'../../../values/images'
;
import
styles
from
'../style'
;
import
colors
from
'../../../values/colors'
;
import
config
from
'../../../config'
;
import
IntroduceUser
from
'./components/IntroduceUser'
;
import
DetailInformation
from
'./components/DetailInformation'
;
import
GeneralInformation
from
'./components/GeneralInformation'
;
import
IntroduceUser
from
'./components/IntroduceUser'
;
import
PersonalInformation
from
'./components/PersonalInformation'
;
import
DetailInformation
from
'./components/DetailInformation'
;
const
Socials
=
[
'FACEBOOK'
,
'EMAIL'
,
'SKYPE'
,
'LINKEDIN'
,
'TWITTER'
,
'INSTAGRAM'
,
'WHATSAPP'
,
'VIPER'
,
'SNAPCHAT'
,
'TELEGRAM'
,
'APPLE'
,
'YOUTUBE'
,
'PINTEREST'
,
];
const
gender
=
[
'Nam'
,
'Nữ'
];
const
ProfileMainView
=
({
userInfo
,
contactUser
,
btnAvailable
,
isEditField
,
navigateMain
,
setEditField
,
setBtnAvailable
,
infoUser
,
setInfoUser
,
onSaveInfo
,
avatar
=
[],
onDeniedAvatar
,
onConfirmAvatar
,
showMenu
,
hideMenu
,
visibleMenu
,
openGallery
,
isSlideShow
,
showFullScreen
,
hideFullScreen
,
dateTimePicker
,
hideDateTimePicker
,
setDateTimePicker
,
showAlert
,
onSubmitChangeContactUser
,
onChangeDropDownContactUser
,
onChangeInputContactUser
,
onPressDeleteItem
,
onPressAddItem
,
onCancelAlert
,
modalVisible
,
setModalVisible
,
setUserInputContact
,
userInputContact
,
onSubmitCreateNew
,
onConfirmDeleteAlert
,
navigateToLogout
,
onChangeCoverAvatar
,
introduceUserProps
,
onEditUserInfo
,
editUserInfo
,
onSubmitChangeInfo
,
})
=>
{
return
(
<
SafeAreaView
style
=
{
styles
.
container
}
>
...
...
@@ -100,9 +24,19 @@ const ProfileMainView = ({
{
/* General information */
}
<
GeneralInformation
userInfo
=
{
userInfo
}
/
>
{
/* personal information */
}
<
PersonalInformation
userInfo
=
{
userInfo
}
/
>
<
PersonalInformation
userInfo
=
{
userInfo
}
onEditUserInfo
=
{
onEditUserInfo
}
editUserInfo
=
{
editUserInfo
}
handleSubmitChangeInfo
=
{
onSubmitChangeInfo
}
/
>
{
/* detail information */
}
<
DetailInformation
userInfo
=
{
userInfo
}
/
>
<
DetailInformation
userInfo
=
{
userInfo
}
onEditUserInfo
=
{
onEditUserInfo
}
editUserInfo
=
{
editUserInfo
}
handleSubmitChangeInfo
=
{
onSubmitChangeInfo
}
/
>
{
/* Logout Btn */
}
<
View
style
=
{{
...
...
@@ -118,96 +52,6 @@ const ProfileMainView = ({
onPress
=
{
navigateToLogout
}
/
>
<
/View
>
{
/* <View style={styles.centeredView}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
setModalVisible(!modalVisible);
}}>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<View style={{flexDirection: 'row'}}>
<View style={{flex: 1}}>
<SelectDropdown
data={Socials}
dropdownIconPosition={'right'}
defaultButtonText={'Loại liên hệ'}
buttonStyle={styles.dropdown1BtnStyle}
onSelect={(selectedItem, item_index) =>
setUserInputContact(prev => ({
...prev,
type: selectedItem,
}))
}
dropdownStyle={styles.dropdown1DropdownStyle}
rowStyle={styles.dropdown1RowStyle}
rowTextStyle={styles.dropdown1RowTxtStyle}
buttonTextStyle={styles.dropdown1BtnTxtStyle}
renderDropdownIcon={isOpened => {
return (
<Image
source={
isOpened ? IMAGES.IcUpArrow : IMAGES.IcDownArrow
}
style={{width: 20, height: 20}}
/>
);
}}
/>
{userInputContact.type.length <= 0 && (
<AppText style={{fontSize: 12, color: 'red'}}>
{' '}
Vui lòng chọn liên hệ
</AppText>
)}
</View>
<View style={{flex: 1}}>
<TextInput
style={{borderBottomWidth: 0.2}}
placeholder={'Nhập F'}
keyboardType={'email-address'}
autoCapitalize="none"
value={userInputContact.text}
onChangeText={text =>
setUserInputContact(prev => ({
...prev,
text: text,
}))
}
/>
{userInputContact.text.length <= 0 && (
<AppText style={{fontSize: 12, color: 'red'}}>
{' '}
Vui lòng nhập liên hệ
</AppText>
)}
</View>
</View>
<View style={{flexDirection: 'row', marginTop: 20}}>
<ButtonComponent
text={'Đóng'}
textStyle={styles.textStyle}
style={[
styles.button,
styles.buttonClose,
{marginRight: 15},
]}
onPress={() => setModalVisible(!modalVisible)}
/>
<ButtonComponent
text={'Thêm mới'}
textStyle={styles.textStyle}
style={[styles.button, styles.buttonClose]}
onPress={onSubmitCreateNew}
/>
</View>
</View>
</View>
</Modal>
</View> */
}
<
/ScrollView
>
<
/SafeAreaView
>
);
...
...
src/screens/profile/template/components/DetailInformation.js
View file @
6a8e5bdb
...
...
@@ -6,9 +6,14 @@ import string from '../../../../values/string';
import
styles
from
'../../style'
;
import
commonStyles
from
'../../../../styles/commonStyles'
;
import
moment
from
'moment'
;
import
config
from
'../../../../config'
;
import
{
Formik
}
from
'formik'
;
import
TextInputComponent
from
'../../../../components/TextInputComponent'
;
import
ButtonComponent
from
'../../../../components/ButtonComponent'
;
import
colors
from
'../../../../values/colors'
;
const
DetailInformation
=
React
.
memo
(
({
userInfo
})
=>
{
({
userInfo
,
editUserInfo
,
onEditUserInfo
,
handleSubmitChangeInfo
})
=>
{
const
personalInfo
=
[
{
name
:
'Số CMND'
,
...
...
@@ -74,7 +79,7 @@ const DetailInformation = React.memo(
name
:
'Địa chỉ liên hệ'
,
value
:
userInfo
?.
address
||
''
,
icon
:
IMAGES
.
IcLocationGray
,
width
:
'
5
0%'
,
width
:
'
10
0%'
,
},
{
name
:
'Địa chỉ thường trú'
,
...
...
@@ -90,13 +95,21 @@ const DetailInformation = React.memo(
{
string
.
PERSONAL_INFORMATION
}
<
/AppText
>
<
View
>
<
TouchableOpacity
>
{
!
editUserInfo
?.
detailInfo
?
(
<
TouchableOpacity
onPress
=
{()
=>
onEditUserInfo
(
config
.
profileField
.
DETAIL_INFO
)}
>
<
Image
source
=
{
IMAGES
.
IcEdit
}
style
=
{{
height
:
30
,
width
:
30
}}
/
>
<
/TouchableOpacity
>
)
:
(
<
TouchableOpacity
onPress
=
{()
=>
onEditUserInfo
()}
>
<
Image
source
=
{
IMAGES
.
IcReject
}
/
>
<
/TouchableOpacity
>
)}
<
/View
>
<
/View
>
<
View
style
=
{[
commonStyles
.
row
,
{
flexWrap
:
'wrap'
}]}
>
{
personalInfo
.
map
(
item
=>
(
{
!
editUserInfo
?.
detailInfo
?
(
personalInfo
.
map
(
item
=>
(
<
View
key
=
{
item
.
name
}
style
=
{[
styles
.
infoView
,
{
width
:
item
.
width
}]}
>
...
...
@@ -106,14 +119,69 @@ const DetailInformation = React.memo(
<
AppText
isSubText
>
{
item
?.
value
}
<
/AppText
>
<
/View
>
<
/View
>
))}
))
)
:
(
<
Formik
initialValues
=
{{
id_card_number
:
userInfo
?.
id_card_number
||
''
,
id_card_issue_date
:
userInfo
?.
id_card_issue_date
||
''
,
id_card_issue_palce
:
userInfo
?.
id_card_issue_palce
||
''
,
birthday
:
userInfo
?.
birthday
?
'Nam'
:
'Nữ'
,
domicile
:
userInfo
?.
domicile
||
''
,
birthplace
:
userInfo
?.
birthplace
||
''
,
religion
:
userInfo
?.
religion
||
''
,
ethnic
:
userInfo
?.
ethnic
||
''
,
personal_tax_code
:
userInfo
?.
personal_tax_code
||
''
,
nationality
:
userInfo
?.
personal_tax_code
||
''
,
address
:
userInfo
?.
address
||
''
,
permanent_address
:
userInfo
?.
permanent_address
||
''
,
}}
onSubmit
=
{
values
=>
handleSubmitChangeInfo
(
values
)}
>
{({
handleChange
,
handleBlur
,
handleSubmit
,
values
})
=>
(
<
View
style
=
{[
commonStyles
.
row
,
{
flexWrap
:
'wrap'
}]}
>
{
personalInfo
.
map
((
item
,
index
)
=>
{
return
(
<
View
key
=
{
item
.
name
}
style
=
{{
width
:
item
.
width
,
paddingHorizontal
:
5
,
}}
>
<
TextInputComponent
value
=
{
Object
.
values
(
values
)[
index
]}
label
=
{
item
.
name
}
placeholder
=
{
`Vui lòng nhập
${
item
.
name
}
của bạn`
}
styleAreaInput
=
{{
backgroundColor
:
colors
.
white
,
width
:
'100%'
,
}}
autoCompleteType
=
{
'postal-address'
}
keyboardType
=
{
'email'
}
onChangeText
=
{
handleChange
(
Object
.
keys
(
values
)[
index
],
)}
/
>
<
/View
>
);
})}
<
ButtonComponent
style
=
{[
styles
.
btnSubmit
]}
text
=
{
'Đồng ý'
}
textStyle
=
{{
color
:
colors
.
white
}}
onPress
=
{
handleSubmit
}
/
>
<
/View
>
)}
<
/Formik
>
)}
<
/View
>
<
/View
>
);
},
function
(
prevProps
,
nextProps
)
{
return
prevProps
.
userInfo
===
nextProps
.
userInfo
;
},
//
function (prevProps, nextProps) {
//
return prevProps.userInfo === nextProps.userInfo;
//
},
);
export
default
memo
(
DetailInformation
);
src/screens/profile/template/components/PersonalInformation.js
View file @
6a8e5bdb
import
{
Formik
}
from
'formik'
;
import
React
,
{
memo
}
from
'react'
;
import
{
Image
,
TouchableOpacity
,
View
}
from
'react-native'
;
import
AppText
from
'../../../../components/AppText'
;
import
ButtonComponent
from
'../../../../components/ButtonComponent'
;
import
TextInputComponent
from
'../../../../components/TextInputComponent'
;
import
config
from
'../../../../config'
;
import
commonStyles
from
'../../../../styles/commonStyles'
;
import
{
IMAGES
}
from
'../../../../values/images'
;
import
string
from
'../../../../values/string'
;
import
styles
from
'../../style'
;
import
co
mmonStyles
from
'../../../../styles/commonStyle
s'
;
import
co
lors
from
'../../../../values/color
s'
;
const
PersonalInformation
=
React
.
memo
(
({
userInfo
})
=>
{
({
userInfo
,
onEditUserInfo
,
editUserInfo
,
handleSubmitChangeInfo
})
=>
{
const
personalInfo
=
[
{
name
:
'Họ'
,
...
...
@@ -53,13 +58,23 @@ const PersonalInformation = React.memo(
{
string
.
PERSONAL_INFORMATION
}
<
/AppText
>
<
View
>
<
TouchableOpacity
>
{
!
editUserInfo
?.
personalInfo
?
(
<
TouchableOpacity
onPress
=
{()
=>
onEditUserInfo
(
config
.
profileField
.
PERSONAL_INFO
)
}
>
<
Image
source
=
{
IMAGES
.
IcEdit
}
style
=
{{
height
:
30
,
width
:
30
}}
/
>
<
/TouchableOpacity
>
)
:
(
<
TouchableOpacity
onPress
=
{()
=>
onEditUserInfo
()}
>
<
Image
source
=
{
IMAGES
.
IcReject
}
/
>
<
/TouchableOpacity
>
)}
<
/View
>
<
/View
>
<
View
style
=
{[
commonStyles
.
row
,
{
flexWrap
:
'wrap'
}]}
>
{
personalInfo
.
map
(
item
=>
(
{
!
editUserInfo
?.
personalInfo
?
(
personalInfo
.
map
(
item
=>
(
<
View
key
=
{
item
.
name
}
style
=
{[
styles
.
infoView
,
{
width
:
item
.
width
}]}
>
...
...
@@ -69,14 +84,68 @@ const PersonalInformation = React.memo(
<
AppText
isSubText
>
{
item
?.
value
}
<
/AppText
>
<
/View
>
<
/View
>
))}
))
)
:
(
<
Formik
initialValues
=
{{
first_name
:
userInfo
?.
first_name
||
''
,
middle_name
:
userInfo
?.
middle_name
||
''
,
last_name
:
userInfo
?.
last_name
||
''
,
gender
:
userInfo
?.
gender
?
'Nam'
:
'Nữ'
,
cell_phone
:
userInfo
?.
cell_phone
||
''
,
}}
onSubmit
=
{
values
=>
handleSubmitChangeInfo
(
values
)}
>
{({
handleChange
,
handleBlur
,
handleSubmit
,
values
})
=>
(
<
View
style
=
{[
commonStyles
.
row
,
{
flexWrap
:
'wrap'
}]}
>
{
personalInfo
.
map
((
item
,
index
)
=>
{
if
(
index
===
personalInfo
.
length
-
1
)
{
return
null
;
}
return
(
<
View
key
=
{
item
.
name
}
style
=
{{
width
:
item
.
width
,
paddingHorizontal
:
5
,
}}
>
<
TextInputComponent
value
=
{
Object
.
values
(
values
)[
index
]}
label
=
{
item
.
name
}
placeholder
=
{
`Vui lòng nhập
${
item
.
name
}
của bạn`
}
styleAreaInput
=
{{
backgroundColor
:
colors
.
white
,
width
:
'100%'
,
}}
autoCompleteType
=
{
'postal-address'
}
keyboardType
=
{
'email'
}
onChangeText
=
{
handleChange
(
Object
.
keys
(
values
)[
index
],
)}
/
>
<
/View
>
);
})}
<
ButtonComponent
style
=
{[
styles
.
btnSubmit
]}
text
=
{
'Đồng ý'
}
textStyle
=
{{
color
:
colors
.
white
}}
onPress
=
{
handleSubmit
}
/
>
<
/View
>
)}
<
/Formik
>
)}
<
/View
>
<
/View
>
);
},
function
(
prevProps
,
nextProps
)
{
return
prevProps
.
userInfo
===
nextProps
.
userInfo
;
},
// function (prevProps, nextProps) {
// return (
// prevProps.userInfo === nextProps.userInfo ||
// prevProps.editUserInfo === nextProps.editUserInfo ||
// prevProps.onEditUserInfo() === nextProps.onEditUserInfo()
// );
// },
);
export
default
memo
(
PersonalInformation
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment