Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
AppUms_Student
Overview
Overview
Details
Activity
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
tungnq
AppUms_Student
Commits
80e80822
Commit
80e80822
authored
Sep 23, 2025
by
tungnq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
TODO: Bổ sung thư viện lấy ảnh từ thiết bị
parent
f1e4487a
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
57 additions
and
9 deletions
+57
-9
AndroidManifest.xml
android/app/src/main/AndroidManifest.xml
+3
-0
Info.plist
ios/AppUms_Student/Info.plist
+6
-0
package.json
package.json
+2
-1
Functions.js
src/config/Functions.js
+1
-0
card_button.js
src/screens/certificate_registration/card_button.js
+14
-2
index.js
src/screens/certificate_registration/index.js
+26
-1
style.js
src/screens/certificate_registration/style.js
+3
-3
view.js
src/screens/certificate_registration/view.js
+2
-2
yarn.lock
yarn.lock
+0
-0
No files found.
android/app/src/main/AndroidManifest.xml
View file @
80e80822
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.CAMERA"
/>
<uses-permission
android:name=
"android.permission.READ_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
<application
<application
android:name=
".MainApplication"
android:name=
".MainApplication"
...
...
ios/AppUms_Student/Info.plist
View file @
80e80822
...
@@ -23,6 +23,12 @@
...
@@ -23,6 +23,12 @@
<
k
e
y
>
CFBundleVersion
<
/k
e
y
>
<
k
e
y
>
CFBundleVersion
<
/k
e
y
>
<
string
>
$
(
CURRENT_PROJECT_VERSION
)<
/string
>
<
string
>
$
(
CURRENT_PROJECT_VERSION
)<
/string
>
<
k
e
y
>
LSRequiresIPhoneOS
<
/k
e
y
>
<
k
e
y
>
LSRequiresIPhoneOS
<
/k
e
y
>
<
k
e
y
>
NSPhotoLibraryUsageDescription
<
/k
e
y
>
<
string
>
Cho
ph
é
p
ứ
ng
d
ụ
ng
truy
c
ậ
p
th
ư
vi
ệ
n
ả
nh
c
ủ
a
b
ạ
n
<
/string
>
<
k
e
y
>
NSCameraUsageDescription
<
/k
e
y
>
<
string
>
Cho
ph
é
p
ứ
ng
d
ụ
ng
s
ử
d
ụ
ng
camera
c
ủ
a
b
ạ
n
<
/string
>
<
k
e
y
>
NSMicrophoneUsageDescription
<
/k
e
y
>
<
string
>
Cho
ph
é
p
ứ
ng
d
ụ
ng
s
ử
d
ụ
ng
microphone
c
ủ
a
b
ạ
n
<
/string
>
<
tru
e
/
>
<
tru
e
/
>
<
k
e
y
>
NSAppTransportSecurity
<
/k
e
y
>
<
k
e
y
>
NSAppTransportSecurity
<
/k
e
y
>
<
d
i
c
t
>
<
d
i
c
t
>
...
...
package.json
View file @
80e80822
...
@@ -40,6 +40,7 @@
...
@@ -40,6 +40,7 @@
"
react-native-gifted-charts
"
:
"^1.2.41"
,
"
react-native-gifted-charts
"
:
"^1.2.41"
,
"
react-native-i18n
"
:
"^2.0.15"
,
"
react-native-i18n
"
:
"^2.0.15"
,
"
react-native-image-crop-picker
"
:
"^0.36.2"
,
"
react-native-image-crop-picker
"
:
"^0.36.2"
,
"
react-native-image-picker
"
:
"^8.2.1"
,
"
react-native-indicators
"
:
"^0.17.0"
,
"
react-native-indicators
"
:
"^0.17.0"
,
"
react-native-linear-gradient
"
:
"^2.6.2"
,
"
react-native-linear-gradient
"
:
"^2.6.2"
,
"
react-native-material-textfield
"
:
"^0.16.1"
,
"
react-native-material-textfield
"
:
"^0.16.1"
,
...
@@ -49,8 +50,8 @@
...
@@ -49,8 +50,8 @@
"
react-native-permissions
"
:
"^3.6.1"
,
"
react-native-permissions
"
:
"^3.6.1"
,
"
react-native-progress
"
:
"^5.0.0"
,
"
react-native-progress
"
:
"^5.0.0"
,
"
react-native-qrcode-scanner
"
:
"^1.5.5"
,
"
react-native-qrcode-scanner
"
:
"^1.5.5"
,
"
react-native-reanimated-table
"
:
"^0.0.2"
,
"
react-native-reanimated
"
:
"3.12.1"
,
"
react-native-reanimated
"
:
"3.12.1"
,
"
react-native-reanimated-table
"
:
"^0.0.2"
,
"
react-native-rename
"
:
"^2.9.0"
,
"
react-native-rename
"
:
"^2.9.0"
,
"
react-native-render-html
"
:
"^6.1.0"
,
"
react-native-render-html
"
:
"^6.1.0"
,
"
react-native-responsive-fontsize
"
:
"^0.5.1"
,
"
react-native-responsive-fontsize
"
:
"^0.5.1"
,
...
...
src/config/Functions.js
View file @
80e80822
...
@@ -25,6 +25,7 @@ import {sha256, sha224} from 'js-sha256';
...
@@ -25,6 +25,7 @@ import {sha256, sha224} from 'js-sha256';
import
{
RFValue
}
from
'react-native-responsive-fontsize'
;
import
{
RFValue
}
from
'react-native-responsive-fontsize'
;
var
Sound
=
require
(
'react-native-sound'
);
var
Sound
=
require
(
'react-native-sound'
);
export
const
soundStart
=
()
=>
{
export
const
soundStart
=
()
=>
{
var
whoosh
=
new
Sound
(
'sond_noti.mp3'
,
Sound
.
MAIN_BUNDLE
,
error
=>
{
var
whoosh
=
new
Sound
(
'sond_noti.mp3'
,
Sound
.
MAIN_BUNDLE
,
error
=>
{
if
(
error
)
{
if
(
error
)
{
...
...
src/screens/certificate_registration/card_button.js
View file @
80e80822
...
@@ -7,23 +7,35 @@ const CardButtonImage = ({
...
@@ -7,23 +7,35 @@ const CardButtonImage = ({
text
=
'Tải ảnh ở đây'
,
text
=
'Tải ảnh ở đây'
,
width
,
width
,
height
=
150
,
height
=
150
,
image
,
disabled
=
false
,
disabled
=
false
,
})
=>
{
})
=>
{
return
(
return
(
<
TouchableOpacity
<
TouchableOpacity
style
=
{[
style
=
{[
styles
.
container_image
,
styles
.
container_image
,
{
width
,
height
},
{
width
,
height
,
borderStyle
:
'dashed'
,
borderColor
:
R
.
colors
.
gray150
,
},
disabled
&&
styles
.
disabled
,
disabled
&&
styles
.
disabled
,
]}
]}
onPress
=
{
onPress
}
onPress
=
{
onPress
}
disabled
=
{
disabled
}
disabled
=
{
disabled
}
activeOpacity
=
{
0.7
}
>
activeOpacity
=
{
0.7
}
>
{
image
?
(
<
Image
source
=
{{
uri
:
image
}}
style
=
{{
width
:
'100%'
,
height
:
'100%'
}}
resizeMode
=
"contain"
/>
)
:
(
<
View
style
=
{{
justifyContent
:
'center'
,
alignItems
:
'center'
}}
>
<
View
style
=
{
styles
.
image_placeholder
}
><
/View
>
<
View
style
=
{
styles
.
image_placeholder
}
><
/View
>
<
View
>
<
View
>
<
Image
source
=
{
R
.
images
.
icImageDownload
}
style
=
{
styles
.
image
}
/
>
<
Image
source
=
{
R
.
images
.
icImageDownload
}
style
=
{
styles
.
image
}
/
>
<
/View
>
<
/View
>
<
Text
style
=
{
styles
.
placeholder_text
}
>
{
text
}
<
/Text
>
<
Text
style
=
{
styles
.
placeholder_text
}
>
{
text
}
<
/Text
>
<
/View
>
)}
<
/TouchableOpacity
>
<
/TouchableOpacity
>
);
);
};
};
...
...
src/screens/certificate_registration/index.js
View file @
80e80822
import
React
,
{
useState
,
useMemo
}
from
'react'
;
import
React
,
{
useState
,
useMemo
}
from
'react'
;
import
{
Text
,
View
,
StyleSheet
}
from
'react-native'
;
import
{
Text
,
View
,
StyleSheet
}
from
'react-native'
;
import
CertificateRegistrationView
from
'./view'
;
import
CertificateRegistrationView
from
'./view'
;
import
{
launchCamera
,
launchImageLibrary
}
from
'react-native-image-picker'
;
const
CertificateRegistration
=
(
props
)
=>
{
const
CertificateRegistration
=
(
props
)
=>
{
const
[
titleHeader
,
setTitleHeader
]
=
useState
(
'CertificateRegisitor'
)
const
[
titleHeader
,
setTitleHeader
]
=
useState
(
'CertificateRegisitor'
)
const
[
isSelected
,
setSelection
]
=
useState
(
false
);
const
[
isSelected
,
setSelection
]
=
useState
(
false
);
const
[
selectedValue
,
setSelectedValue
]
=
useState
(
null
);
const
[
selectedValue
,
setSelectedValue
]
=
useState
(
null
);
const
[
image
,
setImage
]
=
useState
(
null
);
const
[
dataListCertificate
,
setdataListCertificate
]
=
useState
([
const
[
dataListCertificate
,
setdataListCertificate
]
=
useState
([
{
{
id
:
1
,
id
:
1
,
...
@@ -78,6 +79,28 @@ const CertificateRegistration = (props) => {
...
@@ -78,6 +79,28 @@ const CertificateRegistration = (props) => {
setSelectedValue
(
item
.
value
);
setSelectedValue
(
item
.
value
);
};
};
const
openImagePicker
=
()
=>
{
const
options
=
{
mediaType
:
'photo'
,
quality
:
1
,
};
launchImageLibrary
(
options
,(
res
)
=>
{
if
(
res
.
didCancel
)
{
console
.
log
(
'User cancelled image picker'
);
}
else
if
(
res
.
errorCode
)
{
console
.
log
(
'ImagePicker Error: '
,
res
.
errorCode
);
}
else
{
// Lấy URI từ asset đầu tiên
const
imageUri
=
res
.
assets
&&
res
.
assets
[
0
]
?
res
.
assets
[
0
].
uri
:
null
;
// Lưu URI vào state
setImage
(
imageUri
);
}
})
};
return
(
return
(
<
CertificateRegistrationView
<
CertificateRegistrationView
titleHeader
=
{
titleHeader
}
titleHeader
=
{
titleHeader
}
...
@@ -86,6 +109,8 @@ const CertificateRegistration = (props) => {
...
@@ -86,6 +109,8 @@ const CertificateRegistration = (props) => {
onSelect
=
{
handleSelect
}
onSelect
=
{
handleSelect
}
isSelected
=
{
isSelected
}
isSelected
=
{
isSelected
}
setSelection
=
{
setSelection
}
setSelection
=
{
setSelection
}
image
=
{
image
}
openImagePicker
=
{
openImagePicker
}
/
>
/
>
);
);
};
};
...
...
src/screens/certificate_registration/style.js
View file @
80e80822
...
@@ -54,11 +54,11 @@ const styles = StyleSheet.create({
...
@@ -54,11 +54,11 @@ const styles = StyleSheet.create({
marginTop
:
3
,
marginTop
:
3
,
marginBottom
:
15
,
marginBottom
:
15
,
borderWidth
:
1
,
borderWidth
:
1
,
borderRadius
:
10
,
paddingVertical
:
5
,
borderColor
:
R
.
colors
.
blue500
,
borderColor
:
R
.
colors
.
blue500
,
borderStyle
:
'dashed'
,
borderRadius
:
15
,
backgroundColor
:
R
.
colors
.
white
,
backgroundColor
:
R
.
colors
.
white
,
padding
:
16
,
flexDirection
:
'row'
,
flexDirection
:
'row'
,
flex
:
1
,
flex
:
1
,
},
},
...
...
src/screens/certificate_registration/view.js
View file @
80e80822
...
@@ -11,7 +11,7 @@ import CustomTextInput from '../../components/Input/TextFieldCus';
...
@@ -11,7 +11,7 @@ import CustomTextInput from '../../components/Input/TextFieldCus';
import
styles
from
'./style'
;
import
styles
from
'./style'
;
const
CertificateRegistrationView
=
props
=>
{
const
CertificateRegistrationView
=
props
=>
{
const
{
titleHeader
,
dataList
,
isSelected
,
setSelection
}
=
props
;
const
{
titleHeader
,
dataList
,
isSelected
,
setSelection
,
image
,
openImagePicker
}
=
props
;
const
renderBody
=
()
=>
{
const
renderBody
=
()
=>
{
return
(
return
(
<
ScrollView
<
ScrollView
...
@@ -121,7 +121,7 @@ const CertificateRegistrationView = props => {
...
@@ -121,7 +121,7 @@ const CertificateRegistrationView = props => {
<
Text
style
=
{
styles
.
text_title_register
}
>
<
Text
style
=
{
styles
.
text_title_register
}
>
Ả
nh
ch
ứ
ng
ch
ỉ
<
Text
style
=
{{
color
:
'red'
,}}
>*<
/Text
>
Ả
nh
ch
ứ
ng
ch
ỉ
<
Text
style
=
{{
color
:
'red'
,}}
>*<
/Text
>
<
/Text
>
<
/Text
>
<
CardButtonImage
/>
<
CardButtonImage
onPress
=
{
openImagePicker
}
image
=
{
image
}
/
>
<
View
style
=
{
styles
.
footer
}
>
<
View
style
=
{
styles
.
footer
}
>
<
CheckBox
<
CheckBox
...
...
yarn.lock
View file @
80e80822
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