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
6 months ago
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
This diff is collapsed.
Click to expand it.
android/app/release/baselineProfiles/0/app-release.dm
0 → 100644
View file @
6a8e5bdb
File added
This diff is collapsed.
Click to expand it.
android/app/release/baselineProfiles/1/app-release.dm
0 → 100644
View file @
6a8e5bdb
File added
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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'
),
...
...
This diff is collapsed.
Click to expand it.
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
(
...
...
This diff is collapsed.
Click to expand it.
src/api/profileAPI.js
0 → 100644
View file @
6a8e5bdb
import
axiosClient
from
'../network/axios'
;
export
default
{
requestChangeUserInfo
:
({
id
,
body
})
=>
axiosClient
.
put
(
`users/
${
id
}
`
,
body
),
};
This diff is collapsed.
Click to expand it.
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
,
};
This diff is collapsed.
Click to expand it.
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
);
}
});
},
});
...
...
This diff is collapsed.
Click to expand it.
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'
,
...
...
This diff is collapsed.
Click to expand it.
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
);
...
...
This diff is collapsed.
Click to expand it.
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
);
...
...
This diff is collapsed.
Click to expand it.
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
=
{
...
...
This diff is collapsed.
Click to expand it.
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
:
{
...
...
This diff is collapsed.
Click to expand it.
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
)}
/>
;
...
...
This diff is collapsed.
Click to expand it.
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
,
};
}
This diff is collapsed.
Click to expand it.
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
;
This diff is collapsed.
Click to expand it.
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
>
);
...
...
This diff is collapsed.
Click to expand it.
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
);
This diff is collapsed.
Click to expand it.
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
);
This diff is collapsed.
Click to expand it.
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