Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
AppUms_Lecturer
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_Lecturer
Commits
27da74cf
Commit
27da74cf
authored
Aug 14, 2025
by
tungnq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
TODO: Đã hoàn thiện một số phần của giao diện tạo thông báo
parent
cdd4522a
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
404 additions
and
28 deletions
+404
-28
Dropdown.js
src/components/DropdownAlert/Dropdown.js
+92
-0
TextField.js
src/components/Input/TextField.js
+5
-1
TextMulti.js
src/components/Input/TextMulti.js
+2
-0
StackNavigation.js
src/routers/StackNavigation.js
+3
-1
index.js
src/screens/notification/add/index.js
+21
-2
style.js
src/screens/notification/add/style.js
+105
-0
view.js
src/screens/notification/add/view.js
+175
-16
index.js
src/screens/notification/detail/index.js
+1
-8
No files found.
src/components/DropdownAlert/Dropdown.js
0 → 100644
View file @
27da74cf
import
React
,
{
useState
}
from
'react'
;
import
{
View
,
Text
,
TouchableOpacity
,
StyleSheet
,
FlatList
,
Image
}
from
'react-native'
;
import
R
from
'../../assets/R'
;
const
Dropdown
=
({
items
,
placeholder
=
"Chọn..."
,
onSelect
})
=>
{
const
[
isOpen
,
setIsOpen
]
=
useState
(
false
);
const
[
selected
,
setSelected
]
=
useState
(
null
);
const
handleSelect
=
(
item
)
=>
{
setSelected
(
item
);
setIsOpen
(
false
);
if
(
onSelect
)
onSelect
(
item
);
};
return
(
<
View
style
=
{
styles
.
container
}
>
{
/* Nút hiển thị */
}
<
TouchableOpacity
style
=
{
styles
.
dropdownHeader
}
onPress
=
{()
=>
setIsOpen
(
!
isOpen
)}
>
<
Text
style
=
{
styles
.
dropdownHeaderText
}
>
{
selected
?
selected
.
label
:
placeholder
}
<
/Text
>
<
Image
source
=
{
R
.
images
.
icDrop
}
style
=
{
styles
.
imageIcon
}
/
>
<
/TouchableOpacity
>
{
/* Danh sách xổ xuống */
}
{
isOpen
&&
(
<
View
style
=
{[
styles
.
dropdownList
,
{
position
:
'absolute'
,
top
:
35
,
left
:
0
,
right
:
0
,
zIndex
:
999
}]}
>
<
FlatList
data
=
{
items
}
keyExtractor
=
{(
item
)
=>
item
.
id
.
toString
()}
renderItem
=
{({
item
})
=>
(
<
TouchableOpacity
style
=
{
styles
.
dropdownItem
}
onPress
=
{()
=>
handleSelect
(
item
)}
>
<
Text
style
=
{
styles
.
dropdownItemText
}
>
{
item
.
label
}
<
/Text
>
<
/TouchableOpacity
>
)}
/
>
<
/View
>
)}
<
/View
>
);
};
export
default
Dropdown
;
const
styles
=
StyleSheet
.
create
({
container
:
{
width
:
'100%'
,
},
dropdownHeader
:
{
flexDirection
:
'row'
,
justifyContent
:
'space-between'
,
alignItems
:
'center'
,
borderWidth
:
1
,
borderColor
:
'#ccc'
,
borderRadius
:
5
,
backgroundColor
:
'#fff'
,
height
:
35
,
paddingHorizontal
:
15
},
dropdownHeaderText
:
{
fontSize
:
12
,
color
:
'#333'
,
},
dropdownList
:
{
borderWidth
:
1
,
borderColor
:
'#ccc'
,
backgroundColor
:
'#fff'
,
},
dropdownItem
:
{
padding
:
5
,
borderBottomWidth
:
1
,
borderBottomColor
:
'#eee'
,
},
dropdownItemText
:
{
fontSize
:
12
,
color
:
'#333'
,
},
imageIcon
:{
width
:
20
,
height
:
20
,
resizeMode
:
'contain'
,
tintColor
:
'#333'
,
}
});
src/components/Input/TextField.js
View file @
27da74cf
...
@@ -21,6 +21,7 @@ const TextField = props => {
...
@@ -21,6 +21,7 @@ const TextField = props => {
color
,
color
,
required
,
required
,
containerMarginVertical
,
containerMarginVertical
,
containerMarginTop
,
containerMarginHorizontal
,
containerMarginHorizontal
,
containerMarginBottom
,
containerMarginBottom
,
containerBackgroundColor
,
containerBackgroundColor
,
...
@@ -31,7 +32,7 @@ const TextField = props => {
...
@@ -31,7 +32,7 @@ const TextField = props => {
};
};
return
(
return
(
<
View
style
=
{{
marginVertical
:
containerMarginVertical
,
marginHorizontal
:
containerMarginHorizontal
,
marginBottom
:
containerMarginBottom
,
backgroundColor
:
containerBackgroundColor
}}
>
<
View
style
=
{{
marginVertical
:
containerMarginVertical
,
marginHorizontal
:
containerMarginHorizontal
,
marginBottom
:
containerMarginBottom
,
backgroundColor
:
containerBackgroundColor
,
marginTop
:
containerMarginTop
}}
>
<
Text
<
Text
style
=
{{
style
=
{{
fontSize
:
fontSizeTitle
,
fontSize
:
fontSizeTitle
,
...
@@ -45,6 +46,7 @@ const TextField = props => {
...
@@ -45,6 +46,7 @@ const TextField = props => {
<
Text
style
=
{{
color
:
R
.
colors
.
red
}}
>
{
required
?
"*"
:
""
}
<
/Text
>
<
Text
style
=
{{
color
:
R
.
colors
.
red
}}
>
{
required
?
"*"
:
""
}
<
/Text
>
<
/Text
>
<
/Text
>
<
TextInput
<
TextInput
placeholder
=
{
placeholder
}
placeholder
=
{
placeholder
}
maxLength
=
{
maxLength
?
maxLength
:
256
}
maxLength
=
{
maxLength
?
maxLength
:
256
}
placeholderTextColor
=
{
R
.
colors
.
placeHolder
}
placeholderTextColor
=
{
R
.
colors
.
placeHolder
}
...
@@ -58,6 +60,8 @@ const TextField = props => {
...
@@ -58,6 +60,8 @@ const TextField = props => {
style
=
{{
style
=
{{
height
:
HEIGHT
(
35
),
height
:
HEIGHT
(
35
),
color
:
color
,
color
:
color
,
borderColor
:
R
.
colors
.
grayBorderInputTextHeader
,
borderWidth
:
1
,
borderRadius
:
HEIGHT
(
6
),
borderRadius
:
HEIGHT
(
6
),
fontSize
:
fontSize
,
fontSize
:
fontSize
,
paddingVertical
:
5
,
paddingVertical
:
5
,
...
...
src/components/Input/TextMulti.js
View file @
27da74cf
...
@@ -53,6 +53,8 @@ const TextField = props => {
...
@@ -53,6 +53,8 @@ const TextField = props => {
textAlign
:
'left'
,
textAlign
:
'left'
,
color
:
'black'
,
color
:
'black'
,
height
:
210
,
height
:
210
,
borderColor
:
R
.
colors
.
grayBorderInputTextHeader
,
borderWidth
:
1
,
width
:
'100%'
,
width
:
'100%'
,
borderRadius
:
7
,
borderRadius
:
7
,
fontSize
:
fontSizePlaceHolder
,
fontSize
:
fontSizePlaceHolder
,
...
...
src/routers/StackNavigation.js
View file @
27da74cf
...
@@ -5,6 +5,7 @@ import Home from '../screens/home';
...
@@ -5,6 +5,7 @@ import Home from '../screens/home';
import
NotificationDetail
from
'../screens/notification/detail'
;
import
NotificationDetail
from
'../screens/notification/detail'
;
import
TabNavigator
from
'./TabNavigation'
;
import
TabNavigator
from
'./TabNavigation'
;
import
*
as
ScreenName
from
'./ScreenNames'
;
import
*
as
ScreenName
from
'./ScreenNames'
;
import
NotificationAdd
from
'../screens/notification/add'
;
const
Stack
=
createStackNavigator
();
const
Stack
=
createStackNavigator
();
...
@@ -15,10 +16,11 @@ function MyStack(props) {
...
@@ -15,10 +16,11 @@ function MyStack(props) {
headerStatusBarHeight
:
0
,
headerStatusBarHeight
:
0
,
}}
}}
headerMode
=
{
'none'
}
headerMode
=
{
'none'
}
initialRouteName
=
{
ScreenName
.
DETAIL
NOTIFICATION
}
>
initialRouteName
=
{
ScreenName
.
ADD
NOTIFICATION
}
>
<
Stack
.
Screen
name
=
{
ScreenName
.
HOMESCREEN
}
component
=
{
Home
}
/
>
<
Stack
.
Screen
name
=
{
ScreenName
.
HOMESCREEN
}
component
=
{
Home
}
/
>
<
Stack
.
Screen
name
=
{
ScreenName
.
TABNAVIGATOR
}
component
=
{
TabNavigator
}
/
>
<
Stack
.
Screen
name
=
{
ScreenName
.
TABNAVIGATOR
}
component
=
{
TabNavigator
}
/
>
<
Stack
.
Screen
name
=
{
ScreenName
.
DETAILNOTIFICATION
}
component
=
{
NotificationDetail
}
/
>
<
Stack
.
Screen
name
=
{
ScreenName
.
DETAILNOTIFICATION
}
component
=
{
NotificationDetail
}
/
>
<
Stack
.
Screen
name
=
{
ScreenName
.
ADDNOTIFICATION
}
component
=
{
NotificationAdd
}
/
>
<
/Stack.Navigator
>
<
/Stack.Navigator
>
);
);
}
}
...
...
src/screens/notification/add/index.js
View file @
27da74cf
import
React
from
'react'
;
import
React
,
{
useState
}
from
'react'
;
import
{
Text
,
View
,
StyleSheet
}
from
'react-native'
;
import
{
Text
,
View
,
StyleSheet
}
from
'react-native'
;
import
NotificationAddView
from
'./view'
;
import
NotificationAddView
from
'./view'
;
const
NotificationAdd
=
(
props
)
=>
{
const
NotificationAdd
=
(
props
)
=>
{
const
[
selectedValue
,
setSelectedValue
]
=
useState
(
'1'
);
const
options
=
[
{
label
:
'Gửi cá nhân'
,
value
:
'1'
},
{
label
:
'Gửi tập thể lớp'
,
value
:
'2'
},
];
const
onValueChange
=
value
=>
{
setSelectedValue
(
value
);
};
const
items
=
[
{
id
:
1
,
label
:
'Option 1'
},
{
id
:
2
,
label
:
'Option 2'
},
{
id
:
3
,
label
:
'Option 3'
},
];
return
(
return
(
<
NotificationAddView
/>
<
NotificationAddView
options
=
{
options
}
selectedValue
=
{
selectedValue
}
onValueChange
=
{
onValueChange
}
items
=
{
items
}
/
>
);
);
};
};
...
...
src/screens/notification/add/style.js
View file @
27da74cf
import
{
StyleSheet
,
Platform
}
from
"react-native"
;
import
R
from
"../../../assets/R"
;
const
styles
=
StyleSheet
.
create
({
safeArea
:{
flex
:
1
,
backgroundColor
:
R
.
colors
.
white
,
},
container
:{
marginHorizontal
:
15
,
},
boxInput
:{
padding
:
7
,
borderColor
:
R
.
colors
.
grayBorderInputTextHeader
,
borderWidth
:
1
,
borderRadius
:
10
,
marginVertical
:
10
,
backgroundColor
:
R
.
colors
.
brown
,
},
txtInput
:{
color
:
R
.
colors
.
white
,
fontSize
:
R
.
fontsize
.
fontSizeLabel
,
fontFamily
:
R
.
fonts
.
fontMedium
,
fontWeight
:
'600'
,
},
containerRow
:{
flexDirection
:
'row'
,
alignItems
:
'center'
,
justifyContent
:
'center'
,
},
text
:{
fontSize
:
R
.
fontsize
.
fontSizeLabel
,
fontFamily
:
R
.
fonts
.
fontMedium
,
fontWeight
:
'600'
,
color
:
R
.
colors
.
black
,
},
//Item
chip
:
{
flexDirection
:
'row'
,
alignItems
:
'center'
,
// position: 'relative',
paddingLeft
:
10
,
height
:
25
,
borderRadius
:
10
,
marginBottom
:
10
,
marginHorizontal
:
5
,
// top: 10,
// left: 10,
backgroundColor
:
R
.
colors
.
blue2
,
alignSelf
:
'flex-start'
},
imageIcon
:
{
width
:
15
,
height
:
15
,
},
containerIcon
:
{
marginRight
:
2
,
},
text
:
{
fontSize
:
12
,
fontWeight
:
'300'
,
fontFamily
:
R
.
fonts
.
fontRegular
,
color
:
R
.
colors
.
blueTextChip
,
marginRight
:
10
},
//FlatList
flatList
:{
height
:
200
,
backgroundColor
:
R
.
colors
.
blue1
,
paddingHorizontal
:
10
,
borderRadius
:
10
,
paddingVertical
:
15
,
flexDirection
:
'row'
,
marginBottom
:
15
,
},
//ContainerBtn
containerBtn
:{
flexDirection
:
'row'
,
justifyContent
:
'space-between'
,
},
containerInput
:{
flex
:
10
,
},
txtSubtitle
:{
fontSize
:
R
.
fontsize
.
fontSizeSubTitle
,
fontFamily
:
R
.
fonts
.
fontMedium
,
fontWeight
:
'600'
,
color
:
R
.
colors
.
black
,
marginBottom
:
15
,
},
text
:{
fontSize
:
R
.
fontsize
.
fontSizeContent
,
fontFamily
:
R
.
fonts
.
fontRegular
,
fontWeight
:
'400'
,
color
:
R
.
colors
.
black
,
},
containerDropdown
:{
marginBottom
:
15
,
position
:
'relative'
,
zIndex
:
1000
},
});
export
default
styles
;
\ No newline at end of file
src/screens/notification/add/view.js
View file @
27da74cf
import
React
from
'react'
;
import
React
from
'react'
;
import
{
Text
,
View
,
TouchableOpacity
,
StyleSheet
}
from
'react-native'
;
import
{
Text
,
View
,
FlatList
,
ScrollView
}
from
'react-native'
;
import
styles
from
'./style'
;
import
Header
from
'../../../components/Header/Header'
;
import
TextField
from
'../../../components/Input/TextField'
;
import
R
from
'../../../assets/R'
;
import
TextMulti
from
'../../../components/Input/TextMulti'
;
import
RadioGroup
from
'../../../components/RadioButton/RadioGroup'
;
import
Button
from
'../../../components/Button'
;
import
Dropdown
from
'../../../components/DropdownAlert/Dropdown'
;
const
NotificationDetailView
=
props
=>
{
const
{
showWarning
,
title
,
onTitleChange
,
options
,
selectedValue
,
onValueChange
,
disabled
,
size
,
color
,
direction
,
dataList
,
items
,
}
=
props
;
const
renderItem
=
({
item
,
onPress
})
=>
{
return
(
<
View
style
=
{
styles
.
chip
}
>
{
/* <TouchableOpacity style={styles.containerIcon} onPress={onPress}>
<Image
resizeMode="cover"
source={R.images.icCancel}
style={styles.imageIcon}
/>
</TouchableOpacity> */
}
<
Text
style
=
{
styles
.
text
}
>
{
`
${
item
.
id
}
,
${
item
.
name
}
`
}
<
/Text
>
<
/View
>
);
};
const
NotificationAddView
=
(
props
)
=>
{
const
{
}
=
props
;
return
(
return
(
<
View
<
View
style
=
{
styles
.
safeArea
}
>
style
=
{{
<
Header
isBack
title
=
{
'Tạo mới thông báo'
}
/
>
flex
:
1
,
<
ScrollView
justifyContent
:
'center'
,
showsVerticalScrollIndicator
=
{
false
}
alignItems
:
'center'
,
contentContainerStyle
=
{{
paddingBottom
:
20
}}
>
}}
>
<
View
style
=
{
styles
.
container
}
>
<
TouchableOpacity
>
<
TextField
<
Text
>
NotificationAdd
<
/Text
>
containerMarginTop
=
{
15
}
<
/TouchableOpacity
>
title
=
"Tiêu đề thông báo"
value
=
{
title
}
onChangeText
=
{
onTitleChange
}
placeholder
=
"HS"
backgroundColor
=
{
R
.
colors
.
white
}
color
=
{
R
.
colors
.
white
}
fontSize
=
{
R
.
sizes
.
sm
}
onFocus
=
{()
=>
{}}
fontSizeTitle
=
{
R
.
sizes
.
sm
}
containerMarginBottom
=
{
15
}
required
/>
<
TextField
title
=
"Mã CBGV"
value
=
{
title
}
onChangeText
=
{
onTitleChange
}
backgroundColor
=
{
R
.
colors
.
grayBorderInputTextHeader
}
color
=
{
R
.
colors
.
white
}
fontSize
=
{
R
.
sizes
.
sm
}
onFocus
=
{()
=>
{}}
fontSizeTitle
=
{
R
.
sizes
.
sm
}
required
containerMarginBottom
=
{
15
}
editable
=
{
false
}
/
>
<
TextMulti
title
=
"Nội dung thông báo"
fontFamily
=
{
R
.
fonts
.
fontRegular
}
titleFontSize
=
{
R
.
sizes
.
sm
}
value
=
{
title
}
onChangeText
=
{
onTitleChange
}
color
=
{
R
.
colors
.
white
}
fontSize
=
{
R
.
sizes
.
sm
}
onFocus
=
{()
=>
{}}
fontSizeTitle
=
{
R
.
sizes
.
sm
}
fontSizePlaceHolder
=
{
R
.
sizes
.
sm
}
required
containerMarginBottom
=
{
15
}
editable
=
{
false
}
/
>
<
RadioGroup
options
=
{
options
}
selectedValue
=
{
selectedValue
}
onValueChange
=
{
onValueChange
}
disabled
=
{
false
}
size
=
{
20
}
backgroundBoxColor
=
{
R
.
colors
.
blue
}
borderBoxColor
=
{
R
.
colors
.
black
}
direction
=
{
'row'
}
marginBtnAndLabel
=
{
10
}
// justifyContent={'space-between'}
containerMarginRight
=
{
39
}
containerMarginBottom
=
{
15
}
editable
=
{
true
}
/
>
<
Text
style
=
{[
styles
.
text
]}
>
Ch
ọ
n
nh
ữ
ng
sinh
vi
ê
n
nh
ậ
n
th
ô
ng
b
á
o
<
Text
style
=
{{
color
:
R
.
colors
.
red
}}
>*<
/Text></
Text
>
<
View
style
=
{
styles
.
containerDropdown
}
>
<
Dropdown
items
=
{
items
}
placeholder
=
"Chọn tùy chọn"
onSelect
=
{
item
=>
console
.
log
(
'Bạn đã chọn:'
,
item
)}
/
>
<
/View
>
<
Text
style
=
{[
styles
.
text
]}
>
Danh
s
á
ch
đã
ch
ọ
n
:
<
/Text
>
<
View
>
<
/View
>
<
View
style
=
{
styles
.
containerBtn
}
>
<
View
style
=
{
styles
.
containerInput
}
>
<
TextField
title
=
"Ngày gửi"
value
=
{
title
}
onChangeText
=
{
onTitleChange
}
backgroundColor
=
{
R
.
colors
.
blue1
}
color
=
{
R
.
colors
.
white
}
fontSize
=
{
R
.
sizes
.
sm
}
onFocus
=
{()
=>
{}}
fontSizeTitle
=
{
R
.
sizes
.
sm
}
containerMarginBottom
=
{
15
}
editable
=
{
false
}
/
>
<
/View
>
<
View
style
=
{{
flex
:
1
}}
><
/View
>
<
View
style
=
{
styles
.
containerInput
}
>
<
TextField
title
=
"Thời gian gửi"
value
=
{
title
}
onChangeText
=
{
onTitleChange
}
backgroundColor
=
{
R
.
colors
.
blue1
}
color
=
{
R
.
colors
.
white
}
fontSize
=
{
R
.
sizes
.
sm
}
onFocus
=
{()
=>
{}}
fontSizeTitle
=
{
R
.
sizes
.
sm
}
containerMarginBottom
=
{
15
}
editable
=
{
false
}
/
>
<
/View
>
<
/View
>
<
Text
style
=
{[
styles
.
txtSubtitle
]}
>
T
à
i
li
ệ
u
đí
nh
k
è
m
<
/Text
>
<
View
>
<
Button
title
=
"Thêm tài liệu"
onPress
=
{()
=>
{}}
backgroundColor
=
{
R
.
colors
.
blue1
}
fontSize
=
{
R
.
sizes
.
sm
}
editable
=
{
false
}
height
=
{
25
}
width
=
{
176
}
borderRadius
=
{
10
}
textColor
=
{
R
.
colors
.
blue
}
fontWeight
=
{
'600'
}
fontFamily
=
{
R
.
fonts
.
fontMedium
}
icon
=
{
R
.
images
.
icDownload
}
iconStyle
=
{{
width
:
15
,
height
:
15
,
}}
containerStyle
=
{{
alignSelf
:
'flex-start'
,
}}
/
>
<
/View
>
<
/View
>
<
/ScrollView
>
<
/View
>
<
/View
>
);
);
};
};
export
default
NotificationAddView
;
export
default
NotificationDetailView
;
const
styles
=
StyleSheet
.
create
({})
\ No newline at end of file
src/screens/notification/detail/index.js
View file @
27da74cf
...
@@ -3,14 +3,7 @@ import {Text, View, StyleSheet} from 'react-native';
...
@@ -3,14 +3,7 @@ import {Text, View, StyleSheet} from 'react-native';
import
NotificationDetailView
from
'./view'
;
import
NotificationDetailView
from
'./view'
;
import
R
from
'../../../assets/R'
;
import
R
from
'../../../assets/R'
;
const
NotificationDetail
=
(
props
)
=>
{
const
NotificationDetail
=
(
props
)
=>
{
const
[
selectedValue
,
setSelectedValue
]
=
useState
(
'1'
);
const
options
=
[
{
label
:
'Gửi cá nhân'
,
value
:
'1'
},
{
label
:
'Gửi tập thể lớp'
,
value
:
'2'
},
];
const
onValueChange
=
value
=>
{
setSelectedValue
(
value
);
};
const
[
dataList
,
setDataList
]
=
useState
([
const
[
dataList
,
setDataList
]
=
useState
([
{
id
:
1
,
name
:
'Nguyễn Minh Đức'
},
{
id
:
1
,
name
:
'Nguyễn Minh Đức'
},
{
id
:
2
,
name
:
'Trần Văn Hùng'
},
{
id
:
2
,
name
:
'Trần Văn Hùng'
},
...
...
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