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
329dacbc
Commit
329dacbc
authored
Aug 25, 2025
by
tungnq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
TODO: Bổ sung commit
parent
475e212d
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
81 additions
and
57 deletions
+81
-57
index.js
src/screens/class_schedule/index.js
+81
-57
No files found.
src/screens/class_schedule/index.js
View file @
329dacbc
...
@@ -2,16 +2,24 @@ import React, {useState, useMemo, useRef} from 'react';
...
@@ -2,16 +2,24 @@ import React, {useState, useMemo, useRef} from 'react';
import
{
Animated
,
PanResponder
,
Dimensions
}
from
'react-native'
;
import
{
Animated
,
PanResponder
,
Dimensions
}
from
'react-native'
;
import
ClassScheduleView
from
'./view'
;
import
ClassScheduleView
from
'./view'
;
// ==================== HẰNG SỐ ====================
const
{
height
:
screenHeight
}
=
Dimensions
.
get
(
'window'
);
const
{
height
:
screenHeight
}
=
Dimensions
.
get
(
'window'
);
const
BOTTOM_SHEET_HEIGHT
=
screenHeight
*
0.6
;
const
BOTTOM_SHEET_HEIGHT
=
screenHeight
*
0.6
;
const
ClassSchedule
=
({
events
=
[],
onDateSelect
,
onEventPress
})
=>
{
const
ClassSchedule
=
({
events
=
[],
onDateSelect
,
onEventPress
})
=>
{
const
[
currentDate
,
setCurrentDate
]
=
useState
(
new
Date
(
2025
,
7
,
1
));
// ==================== QUẢN LÝ STATE ====================
// B1: State ngày tháng và lịch
const
[
currentDate
,
setCurrentDate
]
=
useState
(
new
Date
());
const
[
selectedDate
,
setSelectedDate
]
=
useState
(
null
);
const
[
selectedDate
,
setSelectedDate
]
=
useState
(
null
);
// B2: State bottom sheet
const
[
showBottomSheet
,
setShowBottomSheet
]
=
useState
(
false
);
const
[
showBottomSheet
,
setShowBottomSheet
]
=
useState
(
false
);
// B3: Tham chiếu animation
const
bottomSheetTranslateY
=
useRef
(
new
Animated
.
Value
(
BOTTOM_SHEET_HEIGHT
)).
current
;
const
bottomSheetTranslateY
=
useRef
(
new
Animated
.
Value
(
BOTTOM_SHEET_HEIGHT
)).
current
;
// ==================== HÀM TIỆN ÍCH ====================
// T1: Định dạng ngày thành chuỗi
const
formatDateToString
=
(
date
)
=>
{
const
formatDateToString
=
(
date
)
=>
{
const
year
=
date
.
getFullYear
();
const
year
=
date
.
getFullYear
();
const
month
=
(
date
.
getMonth
()
+
1
).
toString
().
padStart
(
2
,
'0'
);
const
month
=
(
date
.
getMonth
()
+
1
).
toString
().
padStart
(
2
,
'0'
);
...
@@ -19,6 +27,22 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
...
@@ -19,6 +27,22 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
return
`
${
year
}
-
${
month
}
-
${
day
}
`
;
return
`
${
year
}
-
${
month
}
-
${
day
}
`
;
};
};
// T2: Định dạng ngày để hiển thị
const
formatDateToDisplay
=
(
date
)
=>
{
const
day
=
date
.
getDate
().
toString
().
padStart
(
2
,
'0'
);
const
month
=
(
date
.
getMonth
()
+
1
).
toString
().
padStart
(
2
,
'0'
);
const
year
=
date
.
getFullYear
();
return
`Lịch ngày
${
day
}
/
${
month
}
/
${
year
}
`
;
};
// T3: Chuyển đổi chuỗi thành ngày
const
parseLocalDate
=
(
dateString
)
=>
{
const
[
year
,
month
,
day
]
=
dateString
.
split
(
'-'
).
map
(
Number
);
return
new
Date
(
year
,
month
-
1
,
day
);
};
// ==================== QUẢN LÝ DỮ LIỆU ====================
// D1: Tạo dữ liệu sự kiện mẫu
const
createMockEvents
=
()
=>
{
const
createMockEvents
=
()
=>
{
const
today
=
new
Date
();
const
today
=
new
Date
();
const
todayStr
=
formatDateToString
(
today
);
const
todayStr
=
formatDateToString
(
today
);
...
@@ -147,32 +171,25 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
...
@@ -147,32 +171,25 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
];
];
};
};
// D2: Xử lý dữ liệu sự kiện
const
mockEvents
=
createMockEvents
();
const
mockEvents
=
createMockEvents
();
const
allEvents
=
[...
events
,
...
mockEvents
];
const
allEvents
=
[...
events
,
...
mockEvents
];
const
panResponder
=
useRef
(
// D3: Hàm truy vấn sự kiện
PanResponder
.
create
({
const
getEventsForDate
=
(
date
)
=>
{
onMoveShouldSetPanResponder
:
(
evt
,
gestureState
)
=>
{
const
dateStr
=
formatDateToString
(
date
);
return
Math
.
abs
(
gestureState
.
dy
)
>
10
;
return
allEvents
.
filter
(
event
=>
event
.
date
===
dateStr
);
},
};
onPanResponderMove
:
(
evt
,
gestureState
)
=>
{
if
(
gestureState
.
dy
>
0
)
{
const
getSelectedEvents
=
()
=>
{
bottomSheetTranslateY
.
setValue
(
gestureState
.
dy
);
if
(
!
selectedDate
)
return
[];
}
return
allEvents
},
.
filter
(
event
=>
event
.
date
===
selectedDate
)
onPanResponderRelease
:
(
evt
,
gestureState
)
=>
{
.
sort
((
a
,
b
)
=>
a
.
time
.
localeCompare
(
b
.
time
));
if
(
gestureState
.
dy
>
100
)
{
};
hideBottomSheetModal
();
}
else
{
Animated
.
spring
(
bottomSheetTranslateY
,
{
toValue
:
0
,
useNativeDriver
:
true
,
}).
start
();
}
},
})
).
current
;
// ==================== LOGIC LỊCH ====================
// L1: Tạo dữ liệu tháng
const
getMonthData
=
useMemo
(()
=>
{
const
getMonthData
=
useMemo
(()
=>
{
const
year
=
currentDate
.
getFullYear
();
const
year
=
currentDate
.
getFullYear
();
const
month
=
currentDate
.
getMonth
();
const
month
=
currentDate
.
getMonth
();
...
@@ -198,23 +215,7 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
...
@@ -198,23 +215,7 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
};
};
},
[
currentDate
]);
},
[
currentDate
]);
const
getEventsForDate
=
(
date
)
=>
{
// L2: Hàm kiểm tra ngày tháng
const
dateStr
=
formatDateToString
(
date
);
return
allEvents
.
filter
(
event
=>
event
.
date
===
dateStr
);
};
const
parseLocalDate
=
(
dateString
)
=>
{
const
[
year
,
month
,
day
]
=
dateString
.
split
(
'-'
).
map
(
Number
);
return
new
Date
(
year
,
month
-
1
,
day
);
};
const
formatDateToDisplay
=
(
date
)
=>
{
const
day
=
date
.
getDate
().
toString
().
padStart
(
2
,
'0'
);
const
month
=
(
date
.
getMonth
()
+
1
).
toString
().
padStart
(
2
,
'0'
);
const
year
=
date
.
getFullYear
();
return
`Lịch ngày
${
day
}
/
${
month
}
/
${
year
}
`
;
};
const
isCurrentMonth
=
(
date
)
=>
{
const
isCurrentMonth
=
(
date
)
=>
{
return
date
.
getMonth
()
===
currentDate
.
getMonth
();
return
date
.
getMonth
()
===
currentDate
.
getMonth
();
};
};
...
@@ -228,20 +229,32 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
...
@@ -228,20 +229,32 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
);
);
};
};
const
navigateMonth
=
(
direction
)
=>
{
// ==================== HỆ THỐNG ANIMATION ====================
const
newDate
=
new
Date
(
currentDate
);
// A1: Thiết lập PanResponder
if
(
direction
===
'prev'
)
{
const
panResponder
=
useRef
(
newDate
.
setMonth
(
newDate
.
getMonth
()
-
1
);
PanResponder
.
create
({
}
else
{
onMoveShouldSetPanResponder
:
(
evt
,
gestureState
)
=>
{
newDate
.
setMonth
(
newDate
.
getMonth
()
+
1
);
return
Math
.
abs
(
gestureState
.
dy
)
>
10
;
},
onPanResponderMove
:
(
evt
,
gestureState
)
=>
{
if
(
gestureState
.
dy
>
0
)
{
bottomSheetTranslateY
.
setValue
(
gestureState
.
dy
);
}
}
setCurrentDate
(
newDate
);
},
setSelectedDate
(
null
);
onPanResponderRelease
:
(
evt
,
gestureState
)
=>
{
if
(
showBottomSheet
)
{
if
(
gestureState
.
dy
>
100
)
{
hideBottomSheetModal
();
hideBottomSheetModal
();
}
else
{
Animated
.
spring
(
bottomSheetTranslateY
,
{
toValue
:
0
,
useNativeDriver
:
true
,
}).
start
();
}
}
};
},
})
).
current
;
// A2: Hàm animation Bottom Sheet
const
showBottomSheetModal
=
()
=>
{
const
showBottomSheetModal
=
()
=>
{
setShowBottomSheet
(
true
);
setShowBottomSheet
(
true
);
Animated
.
spring
(
bottomSheetTranslateY
,
{
Animated
.
spring
(
bottomSheetTranslateY
,
{
...
@@ -262,6 +275,23 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
...
@@ -262,6 +275,23 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
});
});
};
};
// ==================== XỬ LÝ SỰ KIỆN ====================
// X1: Xử lý điều hướng
const
navigateMonth
=
(
direction
)
=>
{
const
newDate
=
new
Date
(
currentDate
);
if
(
direction
===
'prev'
)
{
newDate
.
setMonth
(
newDate
.
getMonth
()
-
1
);
}
else
{
newDate
.
setMonth
(
newDate
.
getMonth
()
+
1
);
}
setCurrentDate
(
newDate
);
setSelectedDate
(
null
);
if
(
showBottomSheet
)
{
hideBottomSheetModal
();
}
};
// X2: Xử lý chọn ngày
const
handleDatePress
=
(
date
)
=>
{
const
handleDatePress
=
(
date
)
=>
{
const
dateStr
=
formatDateToString
(
date
);
const
dateStr
=
formatDateToString
(
date
);
const
dayEvents
=
getEventsForDate
(
date
);
const
dayEvents
=
getEventsForDate
(
date
);
...
@@ -274,6 +304,7 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
...
@@ -274,6 +304,7 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
}
}
};
};
// X3: Xử lý tương tác sự kiện
const
handleEventPress
=
(
event
)
=>
{
const
handleEventPress
=
(
event
)
=>
{
onEventPress
?.(
event
);
onEventPress
?.(
event
);
};
};
...
@@ -282,13 +313,6 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
...
@@ -282,13 +313,6 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
hideBottomSheetModal
();
hideBottomSheetModal
();
};
};
const
getSelectedEvents
=
()
=>
{
if
(
!
selectedDate
)
return
[];
return
allEvents
.
filter
(
event
=>
event
.
date
===
selectedDate
)
.
sort
((
a
,
b
)
=>
a
.
time
.
localeCompare
(
b
.
time
));
};
return
(
return
(
<
ClassScheduleView
<
ClassScheduleView
currentDate
=
{
currentDate
}
currentDate
=
{
currentDate
}
...
...
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