Commit 94256c6f by tungnq

TODO: Đã hoàn thiện giao diện drawer màn lịch học

parent 9390e047
...@@ -18,6 +18,7 @@ import RegisterAbsence from '../screens/list_rest_report/add'; ...@@ -18,6 +18,7 @@ import RegisterAbsence from '../screens/list_rest_report/add';
import CompensateView from '../screens/compensate'; import CompensateView from '../screens/compensate';
import DetailCompensateView from '../screens/compensate/list'; import DetailCompensateView from '../screens/compensate/list';
import CompensateRegisterView from '../screens/compensate/register'; import CompensateRegisterView from '../screens/compensate/register';
import DrawerNavigationView from '../routers/drawer_schedule';
const Stack = createStackNavigator(); const Stack = createStackNavigator();
function MyStack(props) { function MyStack(props) {
...@@ -44,6 +45,7 @@ function MyStack(props) { ...@@ -44,6 +45,7 @@ function MyStack(props) {
<Stack.Screen name={ScreenName.LISTMAKEUPCLASSES} component={CompensateView}/> <Stack.Screen name={ScreenName.LISTMAKEUPCLASSES} component={CompensateView}/>
<Stack.Screen name={ScreenName.MAKEUPSCHEDULELISTBYCOURSE} component={DetailCompensateView}/> <Stack.Screen name={ScreenName.MAKEUPSCHEDULELISTBYCOURSE} component={DetailCompensateView}/>
<Stack.Screen name={ScreenName.REGISTERMAKEUP} component={CompensateRegisterView}/> <Stack.Screen name={ScreenName.REGISTERMAKEUP} component={CompensateRegisterView}/>
<Stack.Screen name={ScreenName.FILTERMONTH} component={DrawerNavigationView}/>
</Stack.Navigator> </Stack.Navigator>
); );
} }
......
...@@ -62,7 +62,7 @@ const TabNavigator = props => { ...@@ -62,7 +62,7 @@ const TabNavigator = props => {
name="NotificationScreen" name="NotificationScreen"
component={Notification} component={Notification}
options={{ options={{
tabBarLabel: 'Notification', tabBarLabel: 'Thông báo',
tabBarIcon: ({color, size}) => ( tabBarIcon: ({color, size}) => (
<Image <Image
source={R.images.icNotification} source={R.images.icNotification}
...@@ -76,7 +76,7 @@ const TabNavigator = props => { ...@@ -76,7 +76,7 @@ const TabNavigator = props => {
name="ProfileScreen" name="ProfileScreen"
component={Profile} component={Profile}
options={{ options={{
tabBarLabel: 'Profile', tabBarLabel: 'Hồ sơ',
tabBarIcon: ({color, size}) => ( tabBarIcon: ({color, size}) => (
<Image <Image
source={R.images.icProfile} source={R.images.icProfile}
......
import React, { useEffect, useState } from "react";
import {
DeviceEventEmitter,
Image,
StyleSheet,
Text,
TouchableOpacity,
View,
} from "react-native";
import { createDrawerNavigator } from "@react-navigation/drawer";
import { connect } from "react-redux";
import ClassSchedule from "../../screens/class_schedule";
import FilterDateView from '../../screens/class_schedule/filterday';
import * as ScreenName from "../ScreenNames";
import CustomDrawerContent from "./itemDrawer";
import R from "../../assets/R";
import FilterWeekView from "../../screens/class_schedule/filterWeek";
import Filter3Date from "../../screens/class_schedule/filter3day";
const Drawer = createDrawerNavigator();
const ArrowLeft = R.images.icBack;
const IconMenu = R.images.icMenu;
const IconSearch = R.images.icSearch;
const DrawerNavigatorView = (props) => {
const [reload, setReload] = useState(false);
const [currentDate, setCurrentDate] = useState(new Date());
const HeaderBackButton = ({ onPress, canGoBack }) => (
<TouchableOpacity
style={styles.headerBackButton}
onPress={onPress}
activeOpacity={0.7}
>
<Image source={ArrowLeft} width={20} height={20} />
</TouchableOpacity>
);
useEffect(() => {
const setLanguageListener = DeviceEventEmitter.addListener(
"setLanguage",
(value) => {
setReload((prev) => !prev);
}
);
const dateChangeListener = DeviceEventEmitter.addListener(
"onDateChange",
(date) => {
setCurrentDate(new Date(date));
}
);
return () => {
setLanguageListener.remove();
dateChangeListener.remove();
};
}, []);
const MenuButton = ({ onPress }) => (
<TouchableOpacity style={styles.menuButton} onPress={onPress}>
<Image source={IconMenu} width={24} height={24} />
</TouchableOpacity>
);
const HeaderTitle = ({ navigation, route }) => {
const getHeaderTitle = () => {
if (route.name === ScreenName.FILTERDATE) {
return `Tháng ${currentDate.getMonth() + 1}`;
}
if (route.name === ScreenName.FILTER3DATE) {
return `Tháng ${currentDate.getMonth() + 1}`;
}
if (route.name === ScreenName.FILTERWEEK) {
return `Tháng ${currentDate.getMonth() + 1}`;
}
return '';
};
return (
<TouchableOpacity style={styles.headerTitleButton}>
<Text style={styles.headerTitleText}>
{getHeaderTitle()}
</Text>
</TouchableOpacity>
);
};
return (
<Drawer.Navigator
drawerContent={(drawerProps) => <CustomDrawerContent {...drawerProps} />}
initialRouteName={ScreenName.FILTERMONTH}
screenOptions={({ navigation, route }) => ({
headerLeft: () => (
<View style={styles.headerLeftContainer}>
<HeaderBackButton
onPress={() => {
if (navigation.canGoBack()) {
navigation.pop();
} else {
navigation.toggleDrawer();
}
}}
canGoBack={navigation.canGoBack()}
/>
<MenuButton
onPress={() => {
navigation.toggleDrawer();
}}
/>
</View>
),
headerTitle: () => (
<HeaderTitle navigation={navigation} route={route} />
),
headerRight: () => (
<View style={styles.headerRightContainer}>
<TouchableOpacity style={styles.searchButton}>
<Image source={IconSearch} width={20} height={20} />
</TouchableOpacity>
<View style={styles.avatarButton} />
</View>
),
headerStyle: {
backgroundColor: R.colors.blue,
},
})}
>
<Drawer.Screen
name={ScreenName.FILTERMONTH}
component={ClassSchedule}
options={{
drawerLabel: () => null,
drawerIcon: () => null,
drawerItemStyle: { height: 0 },
}}
/>
<Drawer.Screen
name={ScreenName.FILTER3DATE}
component={Filter3Date}
options={{
drawerLabel: () => null,
drawerIcon: () => null,
drawerItemStyle: { height: 0 },
}}
/>
<Drawer.Screen
name={ScreenName.FILTERDATE}
component={FilterDateView}
options={{
drawerItemStyle: { height: 0 },
}}
/>
<Drawer.Screen
name={ScreenName.FILTERWEEK}
component={FilterWeekView}
options={{
drawerItemStyle: { height: 0 },
}}
/>
</Drawer.Navigator>
);
};
const mapStateToProps = (state) => ({
user: state.userReducer,
});
const styles = StyleSheet.create({
headerBackButton: {
padding: 10,
marginLeft: 10,
borderRadius: 8,
},
menuButton: {
padding: 10,
marginLeft: 5,
},
headerLeftContainer: {
flexDirection: "row",
alignItems: "center",
},
headerRightContainer: {
flexDirection: "row",
alignItems: "center",
marginRight: 15,
},
searchButton: {
padding: 10,
marginRight: 10,
},
avatarButton: {
width: 30,
height: 30,
borderRadius: 30,
backgroundColor: R.colors.white,
},
headerTitleButton: {
alignItems: 'center',
justifyContent: 'center',
},
headerTitleText: {
fontSize: R.sizes.lg,
color: R.colors.white,
fontFamily: R.fonts.fontMedium,
},
});
export default connect(mapStateToProps, {})(DrawerNavigatorView);
\ No newline at end of file
/**
* ENTRY_POINT: Drawer Navigation Module
* FUNCTIONALITY: Export chính cho drawer navigation system
* FEATURE: Tách biệt logic và giao diện, dễ maintain
*/
// COMPONENT: Import component chính
import DrawerNavigator from './drawerView';
// COMPONENT: Export các component con nếu cần sử dụng riêng
export { default as CustomDrawerContent } from './itemDrawer';
// EXPORT: Export mặc định là DrawerNavigator
export default DrawerNavigator;
/**
* USAGE EXAMPLE:
*
* // Sử dụng drawer navigator chính
* import DrawerNavigator from './drawer';
*
* // Hoặc sử dụng riêng CustomDrawerContent
* import { CustomDrawerContent } from './drawer';
*/
\ No newline at end of file
import React, { useState, useMemo, useCallback } from "react";
import {
DeviceEventEmitter,
View,
Text,
Image,
TouchableOpacity,
StyleSheet,
} from "react-native";
import {
DrawerContentScrollView,
useDrawerProgress,
} from "@react-navigation/drawer";
import R from "../../assets/R";
import * as ScreenName from "../ScreenNames";
import CheckBox from "../../components/CheckBox";
const IcDate = R.images.icDate;
const Ic3Date = R.images.ic3Date;
const IcWeek = R.images.icWeek;
const IcMonth = R.images.icMonth;
const CustomDrawerContent = (props) => {
const progress = useDrawerProgress();
const { navigation, state } = props;
const checkboxConfigs = useMemo(
() => [
{ key: "departmentCalendar", label: "Lịch phòng ban" },
{ key: "personalCalendar", label: "Lịch cá nhân" },
{ key: "teachingCalendar", label: "Lịch giảng dạy" },
{ key: "examCalendar", label: "Lịch coi thi" },
{ key: "examRoomCalendar", label: "Lịch sử dụng phòng thi" },
],
[]
);
const filterConfigs = useMemo(
() => [
{
label: "Theo ngày",
screenName: ScreenName.FILTERDATE,
iconSource: IcDate
},
{
label: "3 ngày",
screenName: ScreenName.FILTER3DATE,
iconSource: Ic3Date
},
{
label: "Tuần",
screenName: ScreenName.FILTERWEEK,
iconSource: IcWeek
},
{
label: "Tháng",
screenName: ScreenName.FILTERMONTH,
iconSource: IcMonth
},
],
[]
);
const [checkboxStates, setCheckboxStates] = useState({
departmentCalendar: false,
personalCalendar: false,
teachingCalendar: false,
examCalendar: false,
examRoomCalendar: false,
});
const currentRouteName = state.routes[state.index]?.name;
const handleCheckboxChange = useCallback((key, newValue) => {
setCheckboxStates((prev) => ({
...prev,
[key]: newValue,
}));
DeviceEventEmitter.emit("onCheckboxChange", { key, value: newValue });
}, []);
const handleScreenNavigation = useCallback((screenName) => {
navigation.navigate(screenName);
navigation.closeDrawer();
}, [navigation]);
const renderCheckbox = useCallback(
(config) => (
<CheckBox
key={config.key}
value={checkboxStates[config.key]}
onValueChange={(newValue) => handleCheckboxChange(config.key, newValue)}
label={config.label}
labelSpacing={30}
size={25}
labelSize={R.sizes.lg}
checkedColor={R.colors.black}
marginBottom={20}
labelFontFamily={R.fonts.fontRegular}
labelWeight={400}
/>
),
[checkboxStates, handleCheckboxChange]
);
const renderFilterItem = useCallback(
(item) => {
const isSelected = currentRouteName === item.screenName;
return (
<TouchableOpacity
key={item.screenName}
style={[
styles.filterItem,
isSelected && styles.filterItemSelected,
]}
onPress={() => handleScreenNavigation(item.screenName)}
activeOpacity={0.7}
>
<Image
source={item.iconSource}
style={styles.filterIcon}
resizeMode="contain"
/>
<Text style={[
styles.filterLabel,
isSelected && styles.filterLabelSelected
]}>
{item.label}
</Text>
</TouchableOpacity>
);
},
[currentRouteName, handleScreenNavigation]
);
return (
<DrawerContentScrollView
{...props}
contentContainerStyle={styles.scrollContainer}
>
<View style={styles.logoContainer}>
<Image
source={R.images.igLogo}
style={styles.logo}
resizeMode="contain"
/>
</View>
<View style={styles.filterSection}>
{filterConfigs.map(renderFilterItem)}
</View>
<View style={styles.divider} />
<View style={styles.checkboxSection}>
<Text style={styles.sectionTitle}>Loi lch</Text>
{checkboxConfigs.map(renderCheckbox)}
</View>
</DrawerContentScrollView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
paddingBottom: 20,
},
logoContainer: {
alignItems: "center",
marginVertical: 20,
},
logo: {
width: 49,
height: 24,
},
filterSection: {
paddingHorizontal: 0,
},
filterItem: {
flexDirection: "row",
alignItems: "center",
paddingVertical: 10,
paddingHorizontal: 15,
marginVertical: 4,
},
filterIcon: {
width: 20,
height: 20,
},
filterItemSelected: {
backgroundColor: R.colors.blue,
borderRadius: 50,
marginHorizontal: 15,
},
filterLabel: {
marginLeft: 30,
fontSize: R.sizes.lg,
color: R.colors.black,
flex: 1,
fontFamily: R.fonts.fontMedium,
fontWeight: '400',
},
filterLabelSelected: {
color: R.colors.blue,
fontFamily: R.fonts.fontSemiBold,
},
divider: {
height: 1,
backgroundColor: R.colors.black,
marginHorizontal: 15,
marginTop: 21,
},
checkboxSection: {
paddingHorizontal: 15,
marginTop: 24,
},
sectionTitle: {
fontWeight: "400",
fontFamily: R.fonts.fontMedium,
marginBottom: 10,
fontSize: R.sizes.lg,
color: R.colors.black,
},
});
export default CustomDrawerContent;
\ No newline at end of file
import React from 'react';
import {Text, View, StyleSheet} from 'react-native';
import DetailClassScheduleView from './view';
const DetailClassSchedule = (props) => {
return (
<DetailClassScheduleView />
);
};
export default DetailClassSchedule;
import { StyleSheet, Text, View } from 'react-native'
const styles = StyleSheet.create({
})
export default styles
\ No newline at end of file
import React from 'react';
import {Text, View, TouchableOpacity, StyleSheet} from 'react-native';
const DetailClassScheduleView = (props) => {
const { } = props;
return (
<View
style={{
}}>
<TouchableOpacity>
<Text>DetailClassSchedule</Text>
</TouchableOpacity>
</View>
);
};
export default DetailClassScheduleView;
import React from 'react';
import {Text, View, StyleSheet} from 'react-native';
import Filter3DayView from './view';
const Filter3Day = (props) => {
return (
<Filter3DayView />
);
};
export default Filter3Day;
import { StyleSheet, Text, View } from 'react-native'
import React from 'react'
const styles = StyleSheet.create({
})
export default styles
\ No newline at end of file
import { StyleSheet, Text, View } from 'react-native'
import React from 'react'
const Filter3DayView = () => {
return (
<View>
<Text>Filter3DayView</Text>
</View>
)
}
export default Filter3DayView
import { StyleSheet, Text, View } from 'react-native'
import React from 'react'
const Filter3DayView = () => {
return (
<View>
<Text>Filter3DayView</Text>
</View>
)
}
export default Filter3DayView
import React from 'react';
import {Text, View, StyleSheet} from 'react-native';
import FilterWeekView from './view';
const FilterWeek = (props) => {
return (
<FilterWeekView />
);
};
export default FilterWeek;
import { StyleSheet } from 'react-native'
import R from '../../../assets/R';
const styles = StyleSheet.create({
container:{
flex:1,
backgroundColor:R.colors.white
},
body:{
flex:1,
backgroundColor:R.colors.white
}
})
export default styles
import React from 'react';
import {Text, View, TouchableOpacity, StyleSheet} from 'react-native';
const FilterWeekView = (props) => {
const { } = props;
return (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<TouchableOpacity>
<Text>FilterWeek</Text>
</TouchableOpacity>
</View>
);
};
export default FilterWeekView;
\ No newline at end of file
import React from 'react';
import {Text, View, StyleSheet} from 'react-native';
import FilterDayView from './view';
const FilterDay = (props) => {
return (
<FilterDayView />
);
};
export default FilterDay;
import { StyleSheet, Text, View } from 'react-native'
const styles = StyleSheet.create({})
export default styles
\ No newline at end of file
import React from 'react';
import {Text, View, TouchableOpacity, StyleSheet} from 'react-native';
const FilterDayView = (props) => {
const { } = props;
return (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<TouchableOpacity>
<Text>FilterDay</Text>
</TouchableOpacity>
</View>
);
};
export default FilterDayView;
const styles = StyleSheet.create({})
\ No newline at end of file
import React from 'react';
import {Text, View, StyleSheet} from 'react-native';
import ClassScheduleView from './view';
const ClassSchedule = (props) => {
const monthNames = [
'Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6',
'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12',
];
return (
<ClassScheduleView monthNames={monthNames}/>
);
};
export default ClassSchedule;
import { StyleSheet } from 'react-native'
import R from '../../assets/R';
const styles = StyleSheet.create({
container:{
flex:1,
backgroundColor:R.colors.white
},
body:{
flex:1,
backgroundColor:R.colors.white
}
})
export default styles
\ No newline at end of file
import React from 'react';
import {Text, View, TouchableOpacity, StyleSheet} from 'react-native';
import styles from './style';
const ClassScheduleView = (props) => {
const { } = props;
const renderHeader =()=>{
return(
<View>
</View>
)
}
return (
<View
style={styles.container}>
<View style={styles.body}>
</View>
</View>
);
};
export default ClassScheduleView;
...@@ -35,6 +35,9 @@ container:{ ...@@ -35,6 +35,9 @@ container:{
btnRegister:{ btnRegister:{
alignItems:'flex-end', alignItems:'flex-end',
}, },
btnRegister2:{
marginVertical:15
},
//Header bảng lịch //Header bảng lịch
tableContainer:{ tableContainer:{
......
...@@ -213,6 +213,19 @@ const CompensateRegisterView = props => { ...@@ -213,6 +213,19 @@ const CompensateRegisterView = props => {
<ScrollView <ScrollView
showsHorizontalScrollIndicator={false} showsHorizontalScrollIndicator={false}
horizontal>{renderSchedule()}</ScrollView> horizontal>{renderSchedule()}</ScrollView>
<View style={styles.btnRegister2}>
<Button
title={'Đăng kí dạy bù'}
backgroundColor={R.colors.blue}
textColor={R.colors.white}
onPress={()=>{}}
fontSize={R.sizes.sm}
fontFamily={R.fonts.fontMedium}
height={35}
containerStyle={{paddingHorizontal: 15, borderRadius: 10}}
/>
</View>
</View> </View>
</ScrollView> </ScrollView>
</View> </View>
......
...@@ -18,7 +18,7 @@ const Home = props => { ...@@ -18,7 +18,7 @@ const Home = props => {
id: 1, id: 1,
title: 'Lịch dạy, coi thi', title: 'Lịch dạy, coi thi',
icon: R.images.icLichDay, icon: R.images.icLichDay,
screenName: SCREENNAME.DRAWERNAVIGATION, screenName: SCREENNAME.FILTERMONTH,
action: 'NAVIGATE', action: 'NAVIGATE',
}, },
{ {
......
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