Commit 5cfc51c6 by tungnq

TODO: Bổ sung tính năng vuốt màn hình cho màn tháng

parent 7d9699f8
import React, {useState, useMemo, useRef} from 'react'; import React, {useState, useMemo, useRef} from 'react';
import {Animated, PanResponder, Dimensions} from 'react-native'; import {Animated, PanResponder, Dimensions, DeviceEventEmitter} from 'react-native';
import ClassScheduleView from './view'; import ClassScheduleView from './view';
// ==================== HẰNG SỐ ==================== // ==================== HẰNG SỐ ====================
...@@ -288,6 +288,10 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => { ...@@ -288,6 +288,10 @@ const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
} }
setCurrentDate(newDate); setCurrentDate(newDate);
setSelectedDate(null); setSelectedDate(null);
// Phát sự kiện để cập nhật header title
DeviceEventEmitter.emit('onDateChange', newDate.toISOString());
if (showBottomSheet) { if (showBottomSheet) {
hideBottomSheetModal(); hideBottomSheetModal();
} }
......
...@@ -7,11 +7,14 @@ const CELL_HEIGHT = (screenHeight - 140) / 6; ...@@ -7,11 +7,14 @@ const CELL_HEIGHT = (screenHeight - 140) / 6;
const BOTTOM_SHEET_HEIGHT = screenHeight * 0.6; const BOTTOM_SHEET_HEIGHT = screenHeight * 0.6;
const styles = StyleSheet.create({ const styles = StyleSheet.create({
// Container chính của màn hình
container: { container: {
flex: 1, flex: 1,
backgroundColor: R.colors.white, backgroundColor: R.colors.white,
alignItems: 'center', alignItems: 'center',
}, },
// Header tháng/năm với nút điều hướng
header: { header: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
...@@ -24,6 +27,7 @@ const styles = StyleSheet.create({ ...@@ -24,6 +27,7 @@ const styles = StyleSheet.create({
color: R.colors.black, color: R.colors.black,
fontWeight: '600', fontWeight: '600',
}, },
// Nút điều hướng tháng trước/sau
navButton: { navButton: {
width: 30, width: 30,
height: 30, height: 30,
...@@ -37,6 +41,8 @@ const styles = StyleSheet.create({ ...@@ -37,6 +41,8 @@ const styles = StyleSheet.create({
fontSize: R.fontsize.fontsSizeTitle, fontSize: R.fontsize.fontsSizeTitle,
fontFamily: R.fonts.fontMedium, fontFamily: R.fonts.fontMedium,
}, },
// Tiêu đề các ngày trong tuần
weekDaysContainer: { weekDaysContainer: {
flexDirection: 'row', flexDirection: 'row',
paddingBottom: 5, paddingBottom: 5,
...@@ -52,10 +58,14 @@ const styles = StyleSheet.create({ ...@@ -52,10 +58,14 @@ const styles = StyleSheet.create({
fontWeight: '600', fontWeight: '600',
color: R.colors.black, color: R.colors.black,
}, },
// Lưới lịch
calendarGrid: {}, calendarGrid: {},
weekRow: { weekRow: {
flexDirection: 'row', flexDirection: 'row',
}, },
// Ô ngày trong lịch
dayCell: { dayCell: {
width: CELL_WIDTH, width: CELL_WIDTH,
minHeight: CELL_HEIGHT, minHeight: CELL_HEIGHT,
...@@ -64,11 +74,12 @@ const styles = StyleSheet.create({ ...@@ -64,11 +74,12 @@ const styles = StyleSheet.create({
padding: 4, padding: 4,
alignItems: 'center', alignItems: 'center',
}, },
// Ô ngày được chọn
selectedDayCell: { selectedDayCell: {
borderColor: R.colors.blue, borderColor: R.colors.blue,
borderWidth: 1, borderWidth: 1,
}, },
// Text số ngày
dayText: { dayText: {
fontSize: R.fontsize.fontSizeLabel, fontSize: R.fontsize.fontSizeLabel,
fontWeight: '400', fontWeight: '400',
...@@ -76,15 +87,18 @@ const styles = StyleSheet.create({ ...@@ -76,15 +87,18 @@ const styles = StyleSheet.create({
color: R.colors.black, color: R.colors.black,
marginBottom: 2, marginBottom: 2,
}, },
// Text ngày không thuộc tháng hiện tại
dayTextInactive: { dayTextInactive: {
color: R.colors.black, color: R.colors.black,
opacity: 1, opacity: 1,
}, },
// Text ngày được chọn
selectedDayText: { selectedDayText: {
color: R.colors.black, color: R.colors.black,
fontWeight: 'bold', fontWeight: 'bold',
fontFamily: R.fonts.fontSemiBold, fontFamily: R.fonts.fontSemiBold,
}, },
// Text ngày hôm nay
todayText: { todayText: {
color: R.colors.white, color: R.colors.white,
fontWeight: 'bold', fontWeight: 'bold',
...@@ -95,10 +109,12 @@ const styles = StyleSheet.create({ ...@@ -95,10 +109,12 @@ const styles = StyleSheet.create({
paddingVertical: 2, paddingVertical: 2,
}, },
// Sự kiện trong ô ngày
eventsContainer: { eventsContainer: {
width: '100%', width: '100%',
flex: 1, flex: 1,
}, },
// Thanh sự kiện nhỏ trong ô ngày
eventBar: { eventBar: {
paddingVertical: 2, paddingVertical: 2,
paddingHorizontal: 5, paddingHorizontal: 5,
...@@ -112,6 +128,7 @@ const styles = StyleSheet.create({ ...@@ -112,6 +128,7 @@ const styles = StyleSheet.create({
fontWeight: '400', fontWeight: '400',
fontFamily: R.fonts.fontRegular, fontFamily: R.fonts.fontRegular,
}, },
// Text hiển thị số sự kiện còn lại
moreEventsText: { moreEventsText: {
fontSize: R.fontsize.fontSizeLabel, fontSize: R.fontsize.fontSizeLabel,
color: R.colors.gray, color: R.colors.gray,
...@@ -119,11 +136,8 @@ const styles = StyleSheet.create({ ...@@ -119,11 +136,8 @@ const styles = StyleSheet.create({
fontFamily: R.fonts.fontRegular, fontFamily: R.fonts.fontRegular,
textAlign: 'center', textAlign: 'center',
}, },
containerBottomSheet: {
flex: 1,
marginBottom: 10,
},
// Modal bottom sheet
modalBackdrop: { modalBackdrop: {
flex: 1, flex: 1,
backgroundColor: R.colors.grayBorderInputTextHeader, backgroundColor: R.colors.grayBorderInputTextHeader,
...@@ -135,9 +149,12 @@ const styles = StyleSheet.create({ ...@@ -135,9 +149,12 @@ const styles = StyleSheet.create({
borderTopLeftRadius: 20, borderTopLeftRadius: 20,
borderTopRightRadius: 20, borderTopRightRadius: 20,
}, },
// Nội dung bottom sheet
bottomSheetContent: { bottomSheetContent: {
height: BOTTOM_SHEET_HEIGHT, height: BOTTOM_SHEET_HEIGHT,
}, },
// Thanh kéo
dragHandle: { dragHandle: {
width: 40, width: 40,
height: 4, height: 4,
...@@ -147,6 +164,7 @@ const styles = StyleSheet.create({ ...@@ -147,6 +164,7 @@ const styles = StyleSheet.create({
marginTop: 10, marginTop: 10,
marginBottom: 15, marginBottom: 15,
}, },
// Header của bottom sheet
bottomSheetHeader: { bottomSheetHeader: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
...@@ -160,6 +178,7 @@ const styles = StyleSheet.create({ ...@@ -160,6 +178,7 @@ const styles = StyleSheet.create({
fontWeight: '600', fontWeight: '600',
flex: 1, flex: 1,
}, },
// Nút đóng bottom sheet
closeButton: { closeButton: {
width: 30, width: 30,
height: 30, height: 30,
...@@ -174,9 +193,18 @@ const styles = StyleSheet.create({ ...@@ -174,9 +193,18 @@ const styles = StyleSheet.create({
fontFamily: R.fonts.fontRegular, fontFamily: R.fonts.fontRegular,
fontWeight: '400', fontWeight: '400',
}, },
// Danh sách sự kiện trong bottom sheet
// ScrollView chứa danh sách sự kiện
eventsScrollView: { eventsScrollView: {
paddingTop: 10, paddingTop: 10,
}, },
// Container cho từng sự kiện
containerBottomSheet: {
flex: 1,
marginBottom: 10,
},
// Trạng thái không có sự kiện
noEventsContainer: { noEventsContainer: {
flex: 1, flex: 1,
alignItems: 'center', alignItems: 'center',
...@@ -189,6 +217,8 @@ const styles = StyleSheet.create({ ...@@ -189,6 +217,8 @@ const styles = StyleSheet.create({
color: R.colors.gray, color: R.colors.gray,
fontWeight: '400', fontWeight: '400',
}, },
// Card sự kiện chi tiết
eventCard: { eventCard: {
flexDirection: 'row', flexDirection: 'row',
backgroundColor: R.colors.white, backgroundColor: R.colors.white,
...@@ -207,6 +237,7 @@ const styles = StyleSheet.create({ ...@@ -207,6 +237,7 @@ const styles = StyleSheet.create({
shadowRadius: 1, shadowRadius: 1,
elevation: 2, elevation: 2,
}, },
// Container thời gian sự kiện
eventTimeContainer: { eventTimeContainer: {
minWidth: 80, minWidth: 80,
alignItems: 'flex-start', alignItems: 'flex-start',
...@@ -219,6 +250,7 @@ const styles = StyleSheet.create({ ...@@ -219,6 +250,7 @@ const styles = StyleSheet.create({
color: R.colors.blue, color: R.colors.blue,
fontWeight: '600', fontWeight: '600',
}, },
// Container nội dung sự kiện
eventContent: { eventContent: {
flex: 1, flex: 1,
}, },
......
...@@ -6,7 +6,8 @@ import { ...@@ -6,7 +6,8 @@ import {
ScrollView, ScrollView,
Modal, Modal,
Animated, Animated,
LogBox LogBox,
PanResponder
} from 'react-native'; } from 'react-native';
import R from '../../assets/R'; import R from '../../assets/R';
import {styles} from './style'; import {styles} from './style';
...@@ -36,6 +37,28 @@ const ClassScheduleView = ({ ...@@ -36,6 +37,28 @@ const ClassScheduleView = ({
getSelectedEvents, getSelectedEvents,
}) => { }) => {
const navigation = useNavigation(); const navigation = useNavigation();
// Tạo PanResponder cho swipe gesture điều hướng tháng
const swipePanResponder = PanResponder.create({
onMoveShouldSetPanResponder: (evt, gestureState) => {
// Chỉ kích hoạt khi vuốt ngang với khoảng cách đủ lớn
return Math.abs(gestureState.dx) > Math.abs(gestureState.dy) && Math.abs(gestureState.dx) > 20;
},
onPanResponderMove: (evt, gestureState) => {
// Có thể thêm animation preview ở đây nếu cần
},
onPanResponderRelease: (evt, gestureState) => {
const swipeThreshold = 50; // Ngưỡng tối thiểu để kích hoạt swipe
if (gestureState.dx > swipeThreshold) {
// Vuốt phải -> tháng trước
navigateMonth('prev');
} else if (gestureState.dx < -swipeThreshold) {
// Vuốt trái -> tháng sau
navigateMonth('next');
}
},
});
const renderHeader = () => { const renderHeader = () => {
const monthNames = [ const monthNames = [
'Tháng 1', 'Tháng 1',
...@@ -214,6 +237,8 @@ const ClassScheduleView = ({ ...@@ -214,6 +237,8 @@ const ClassScheduleView = ({
); );
}; };
// ===== RENDER BOTTOM SHEET - Modal bottom sheet =====
// Sử dụng styles: modalBackdrop, bottomSheet
const renderBottomSheet = () => { const renderBottomSheet = () => {
return ( return (
<Modal <Modal
...@@ -242,10 +267,12 @@ const ClassScheduleView = ({ ...@@ -242,10 +267,12 @@ const ClassScheduleView = ({
); );
}; };
// ===== MAIN RENDER - Render chính của component =====
// Sử dụng styles: container
return ( return (
<View style={styles.container}> <View style={styles.container}>
<ScrollView showsVerticalScrollIndicator={false}> <ScrollView showsVerticalScrollIndicator={false}>
<View style={styles.body}> <View style={styles.body} {...swipePanResponder.panHandlers}>
{renderHeader()} {renderHeader()}
{renderWeekDays()} {renderWeekDays()}
{renderCalendarGrid()} {renderCalendarGrid()}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment