Commit 19c4050a by tungnq

TODO: Tối ưu bổ sung thêm modal cho tuần khi nhấn tìm kiếm và chỉnh sửa giao diện của drawerView

parent e10510ea
<svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="24" height="24" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.5 13.1667H36.5M9.27778 1.5V5.38889M28.7222 1.5V5.38889M7.33333 19H11.2222M17.0556 19H20.9444M26.7778 19H30.6667M7.33333 24.8333H11.2222M17.0556 24.8333H20.9444M26.7778 24.8333H30.6667M7.33333 30.6667H11.2222M17.0556 30.6667H20.9444M26.7778 30.6667H30.6667M7.72222 36.5H30.2778C32.4557 36.5 33.5448 36.5 34.3767 36.0761C35.1084 35.7034 35.7034 35.1084 36.0761 34.3767C36.5 33.5448 36.5 32.4557 36.5 30.2778V11.6111C36.5 9.43312 36.5 8.34413 36.0761 7.51226C35.7034 6.78051 35.1084 6.18559 34.3767 5.81276C33.5448 5.38889 32.4557 5.38889 30.2778 5.38889H7.72222C5.54425 5.38889 4.45524 5.38889 3.62337 5.81276C2.89162 6.18559 2.2967 6.78051 1.92387 7.51226C1.5 8.34413 1.5 9.43312 1.5 11.6111V30.2778C1.5 32.4557 1.5 33.5448 1.92387 34.3767C2.2967 35.1084 2.89162 35.7034 3.62337 36.0761C4.45524 36.5 5.54423 36.5 7.72222 36.5Z" stroke="none" stroke-width="2" stroke-linecap="round"/> <path d="M1.5 13.1667H36.5M9.27778 1.5V5.38889M28.7222 1.5V5.38889M7.33333 19H11.2222M17.0556 19H20.9444M26.7778 19H30.6667M7.33333 24.8333H11.2222M17.0556 24.8333H20.9444M26.7778 24.8333H30.6667M7.33333 30.6667H11.2222M17.0556 30.6667H20.9444M26.7778 30.6667H30.6667M7.72222 36.5H30.2778C32.4557 36.5 33.5448 36.5 34.3767 36.0761C35.1084 35.7034 35.7034 35.1084 36.0761 34.3767C36.5 33.5448 36.5 32.4557 36.5 30.2778V11.6111C36.5 9.43312 36.5 8.34413 36.0761 7.51226C35.7034 6.78051 35.1084 6.18559 34.3767 5.81276C33.5448 5.38889 32.4557 5.38889 30.2778 5.38889H7.72222C5.54425 5.38889 4.45524 5.38889 3.62337 5.81276C2.89162 6.18559 2.2967 6.78051 1.92387 7.51226C1.5 8.34413 1.5 9.43312 1.5 11.6111V30.2778C1.5 32.4557 1.5 33.5448 1.92387 34.3767C2.2967 35.1084 2.89162 35.7034 3.62337 36.0761C4.45524 36.5 5.54423 36.5 7.72222 36.5Z" stroke="black" stroke-width="2" stroke-linecap="round"/>
</svg> </svg>
import React, { useRef, useEffect } from 'react'; import React, {useRef, useEffect} from 'react';
import { import {
Dimensions, Dimensions,
Platform, Platform,
...@@ -738,4 +738,4 @@ export const monthNames = [ ...@@ -738,4 +738,4 @@ export const monthNames = [
'Tháng 10', 'Tháng 10',
'Tháng 11', 'Tháng 11',
'Tháng 12', 'Tháng 12',
] ];
\ No newline at end of file
import React, { useState, useMemo, useCallback } from "react"; import React, {useState, useMemo, useCallback} from 'react';
import { import {
DeviceEventEmitter, DeviceEventEmitter,
View, View,
...@@ -6,59 +6,59 @@ import { ...@@ -6,59 +6,59 @@ import {
Image, Image,
TouchableOpacity, TouchableOpacity,
StyleSheet, StyleSheet,
} from "react-native"; } from 'react-native';
import { import {
DrawerContentScrollView, DrawerContentScrollView,
useDrawerProgress, useDrawerProgress,
} from "@react-navigation/drawer"; } from '@react-navigation/drawer';
import R from "../../assets/R"; import R from '../../assets/R';
import Checkbox from "../../components/CheckBox"; import * as ScreenName from '../ScreenNames';
import * as ScreenName from "../ScreenNames"; import CheckBox from '../../components/CheckBox';
const IcDate = R.images.icDateDrawer; const IcDate = R.images.icDate;
const Ic3Date = R.images.ic3Date; const Ic3Date = R.images.ic3Date;
const IcWeek = R.images.icWeek; const IcWeek = R.images.icWeek;
const IcMonth = R.images.icMonth; const IcMonth = R.images.icMonth;
const CustomDrawerContent = (props) => { const CustomDrawerContent = props => {
const progress = useDrawerProgress(); const progress = useDrawerProgress();
const { navigation, state } = props; const {navigation, state} = props;
const checkboxConfigs = useMemo( const checkboxConfigs = useMemo(
() => [ () => [
{ key: "departmentCalendar", label: "Lịch phòng ban" }, {key: 'departmentCalendar', label: 'Lịch phòng ban'},
{ key: "personalCalendar", label: "Lịch cá nhân" }, {key: 'personalCalendar', label: 'Lịch cá nhân'},
{ key: "teachingCalendar", label: "Lịch giảng dạy" }, {key: 'teachingCalendar', label: 'Lịch giảng dạy'},
{ key: "examCalendar", label: "Lịch coi thi" }, {key: 'examCalendar', label: 'Lịch coi thi'},
{ key: "examRoomCalendar", label: "Lịch sử dụng phòng thi" }, {key: 'examRoomCalendar', label: 'Lịch sử dụng phòng thi'},
], ],
[] [],
); );
const filterConfigs = useMemo( const filterConfigs = useMemo(
() => [ () => [
{ {
label: "Theo ngày", label: 'Theo ngày',
screenName: ScreenName.FILTERDATE, screenName: ScreenName.FILTERDATE,
icon: <IcDate stroke={'black'}/> icon: <IcDate stroke={'black'} />,
}, },
{ {
label: "3 ngày", label: '3 ngày',
screenName: ScreenName.FILTER3DATE, screenName: ScreenName.FILTER3DATE,
icon: <Ic3Date /> icon: <Ic3Date />,
}, },
{ {
label: "Tuần", label: 'Tuần',
screenName: ScreenName.FILTERWEEK, screenName: ScreenName.FILTERWEEK,
icon: <IcWeek /> icon: <IcWeek />,
}, },
{ {
label: "Tháng", label: 'Tháng',
screenName: ScreenName.CLASSSCHEDULE, screenName: ScreenName.FILTERMONTH,
icon: <IcMonth /> icon: <IcMonth />,
}, },
], ],
[] [],
); );
const [checkboxStates, setCheckboxStates] = useState({ const [checkboxStates, setCheckboxStates] = useState({
...@@ -72,73 +72,73 @@ const CustomDrawerContent = (props) => { ...@@ -72,73 +72,73 @@ const CustomDrawerContent = (props) => {
const currentRouteName = state.routes[state.index]?.name; const currentRouteName = state.routes[state.index]?.name;
const handleCheckboxChange = useCallback((key, newValue) => { const handleCheckboxChange = useCallback((key, newValue) => {
setCheckboxStates((prev) => ({ setCheckboxStates(prev => ({
...prev, ...prev,
[key]: newValue, [key]: newValue,
})); }));
DeviceEventEmitter.emit("onCheckboxChange", { key, value: newValue }); DeviceEventEmitter.emit('onCheckboxChange', {key, value: newValue});
}, []); }, []);
const handleScreenNavigation = useCallback((screenName) => { const handleScreenNavigation = useCallback(
navigation.navigate(screenName); screenName => {
navigation.closeDrawer(); navigation.navigate(screenName);
}, [navigation]); navigation.closeDrawer();
},
[navigation],
);
const renderCheckbox = useCallback( const renderCheckbox = useCallback(
(config) => ( config => (
<Checkbox <CheckBox
key={config.key} key={config.key}
value={checkboxStates[config.key]} value={checkboxStates[config.key]}
onValueChange={(newValue) => handleCheckboxChange(config.key, newValue)} onValueChange={newValue => handleCheckboxChange(config.key, newValue)}
label={config.label} label={config.label}
labelSpacing={30} labelSpacing={30}
size={25} size={20}
labelSize={R.fontsize.fontsSize16} labelSize={R.fontsize.fontsSize12}
checkedColor={R.colors.black} checkedColor={R.colors.black}
marginBottom={20} marginBottom={20}
labelFontFamily={R.fonts.InterRegular} labelFontFamily={R.fonts.InterRegular}
labelWeight={400} labelWeight={400}
/> />
), ),
[checkboxStates, handleCheckboxChange] [checkboxStates, handleCheckboxChange],
); );
const renderFilterItem = useCallback( const renderFilterItem = useCallback(
(item) => { item => {
const isSelected = currentRouteName === item.screenName; const isSelected = currentRouteName === item.screenName;
return ( return (
<TouchableOpacity <TouchableOpacity
key={item.screenName} key={item.screenName}
style={[ style={[styles.filterItem, isSelected && styles.filterItemSelected]}
styles.filterItem,
isSelected && styles.filterItemSelected,
]}
onPress={() => handleScreenNavigation(item.screenName)} onPress={() => handleScreenNavigation(item.screenName)}
activeOpacity={0.7} activeOpacity={0.7}>
>
{item.icon} {item.icon}
<Text style={[
styles.filterLabel, <Text
isSelected && styles.filterLabelSelected style={[
]}> styles.filterLabel,
isSelected && styles.filterLabelSelected,
]}>
{item.label} {item.label}
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
); );
}, },
[currentRouteName, handleScreenNavigation] [currentRouteName, handleScreenNavigation],
); );
return ( return (
<DrawerContentScrollView <DrawerContentScrollView
{...props} {...props}
contentContainerStyle={styles.scrollContainer} contentContainerStyle={styles.scrollContainer}>
>
<View style={styles.logoContainer}> <View style={styles.logoContainer}>
<Image <Image
source={R.images.igLogo} source={R.images.igLogo}
style={styles.logo} style={styles.logo}
resizeMode="contain" resizeMode="contain"
/> />
...@@ -147,9 +147,9 @@ const CustomDrawerContent = (props) => { ...@@ -147,9 +147,9 @@ const CustomDrawerContent = (props) => {
<View style={styles.filterSection}> <View style={styles.filterSection}>
{filterConfigs.map(renderFilterItem)} {filterConfigs.map(renderFilterItem)}
</View> </View>
<View style={styles.divider} /> <View style={styles.divider} />
<View style={styles.checkboxSection}> <View style={styles.checkboxSection}>
<Text style={styles.sectionTitle}>Loi lch</Text> <Text style={styles.sectionTitle}>Loi lch</Text>
{checkboxConfigs.map(renderCheckbox)} {checkboxConfigs.map(renderCheckbox)}
...@@ -164,38 +164,43 @@ const styles = StyleSheet.create({ ...@@ -164,38 +164,43 @@ const styles = StyleSheet.create({
paddingBottom: 20, paddingBottom: 20,
}, },
logoContainer: { logoContainer: {
alignItems: "center", alignItems: 'center',
marginVertical: 20, marginVertical: 20,
}, },
logo: { logo: {
width: 49, width: 149,
height: 24, height: 24,
}, },
filterSection: { filterSection: {
paddingHorizontal: 0, paddingHorizontal: 0,
}, },
filterItem: { filterItem: {
flexDirection: "row", flexDirection: 'row',
alignItems: "center", alignItems: 'center',
paddingVertical: 10, paddingVertical: 10,
paddingHorizontal: 15, paddingHorizontal: 15,
marginVertical: 4, marginVertical: 4,
}, },
filterIcon: {
width: 20,
height: 20,
},
filterItemSelected: { filterItemSelected: {
backgroundColor: R.colors.blue100, backgroundColor: R.colors.main,
borderRadius: 50, borderRadius: 50,
marginHorizontal: 15, marginHorizontal: 15,
}, },
filterLabel: { filterLabel: {
marginLeft: 30, marginLeft: 30,
fontSize: R.fontsize.fontsSize16, fontSize: R.fontsize.fontsSize12,
color: R.colors.black, color: R.colors.black,
flex: 1, flex: 1,
fontFamily: R.fonts.InterMedium, fontFamily: R.fonts.InterMedium,
fontWeight: '400', fontWeight: '600',
}, },
filterLabelSelected: { filterLabelSelected: {
color: R.colors.blue, color: R.colors.white,
fontWeight: '500',
fontFamily: R.fonts.InterSemiBold, fontFamily: R.fonts.InterSemiBold,
}, },
divider: { divider: {
...@@ -209,7 +214,7 @@ const styles = StyleSheet.create({ ...@@ -209,7 +214,7 @@ const styles = StyleSheet.create({
marginTop: 24, marginTop: 24,
}, },
sectionTitle: { sectionTitle: {
fontWeight: "400", fontWeight: '600',
fontFamily: R.fonts.InterMedium, fontFamily: R.fonts.InterMedium,
marginBottom: 10, marginBottom: 10,
fontSize: R.fontsize.fontsSize16, fontSize: R.fontsize.fontsSize16,
...@@ -217,4 +222,4 @@ const styles = StyleSheet.create({ ...@@ -217,4 +222,4 @@ const styles = StyleSheet.create({
}, },
}); });
export default CustomDrawerContent; export default CustomDrawerContent;
\ No newline at end of file
...@@ -22,4 +22,6 @@ export const CLASSSCHEDULE = 'CLASSSCHEDULE'; ...@@ -22,4 +22,6 @@ export const CLASSSCHEDULE = 'CLASSSCHEDULE';
export const FILTERDATE = 'FILTERDATE'; export const FILTERDATE = 'FILTERDATE';
export const FILTERWEEK = 'FILTERWEEK'; export const FILTERWEEK = 'FILTERWEEK';
export const FILTER3DATE = 'FILTER3DATE'; export const FILTER3DATE = 'FILTER3DATE';
export const DETAILCLASSSCHEDULE = 'DETAILCLASSSCHEDULE'; export const FILTERMONTH = 'FILTERMONTH';
\ No newline at end of file export const DETAILCLASSSCHEDULE = 'DETAILCLASSSCHEDULE';
export const DETAILSCHEDULE = 'DETAILSCHEDULE';
\ No newline at end of file
import React from 'react'; import React, {useState, useRef, useEffect} from 'react';
import {Text, View, StyleSheet} from 'react-native'; import {Dimensions, PanResponder} from 'react-native';
import {useNavigation, useFocusEffect} from '@react-navigation/native';
import {DeviceEventEmitter} from 'react-native';
import FilterWeekView from './view'; import FilterWeekView from './view';
const FilterWeek = (props) => { // ==================== HẰNG SỐ ====================
const {width: screenWidth, height: screenHeight} = Dimensions.get('window');
const HOUR_HEIGHT = 80;
const DAY_COLUMN_WIDTH = (screenWidth - 70) / 7;
const FilterWeek = ({navigation}) => {
const navigationHook = useNavigation();
// ==================== QUẢN LÝ STATE ====================
// B1: State ngày tháng và lịch
const [currentDate, setCurrentDate] = useState(new Date());
const [selectedDate, setSelectedDate] = useState(new Date());
// B2: State month picker
const [showMonthPicker, setShowMonthPicker] = useState(false);
// B3: Tham chiếu scroll
const scrollViewRef = useRef(null);
// ==================== EFFECTS ====================
// Reset về ngày hiện tại khi chuyển màn hình
useFocusEffect(
React.useCallback(() => {
const today = new Date();
setCurrentDate(today);
setSelectedDate(today);
DeviceEventEmitter.emit('onDateChange', today);
// Cập nhật header drawer với tháng hiện tại
DeviceEventEmitter.emit('updateHeaderMonth', today.getMonth());
}, [])
);
useEffect(() => {
DeviceEventEmitter.emit('onDateChange', selectedDate);
}, [selectedDate]);
// ==================== HÀM TIỆN ÍCH ====================
// T1: Định dạng ngày thành chuỗi
const formatDateToString = date => {
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
return `${year}-${month}-${day}`;
};
// T2: Kiểm tra ngày hôm nay
const isToday = someDate => {
const today = new Date();
return (
someDate.getDate() === today.getDate() &&
someDate.getMonth() === today.getMonth() &&
someDate.getFullYear() === today.getFullYear()
);
};
// T3: Lấy tên ngày trong tuần
const getDayName = date => {
const days = ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'];
return days[date.getDay()];
};
// T4: Lấy tên tháng
const getMonthName = monthIndex => {
const months = [
'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 months[monthIndex];
};
// T5: Lấy các ngày trong tuần
const getWeekDates = date => {
const startOfWeek = new Date(date);
startOfWeek.setDate(date.getDate() - date.getDay());
const weekDates = [];
for (let i = 0; i < 7; i++) {
const weekDate = new Date(startOfWeek);
weekDate.setDate(startOfWeek.getDate() + i);
weekDates.push(weekDate);
}
return weekDates;
};
// T6: Tính toán vị trí sự kiện
const calculateEventPosition = (startTime, endTime) => {
const [startHour, startMinute] = startTime.split(':').map(Number);
const [endHour, endMinute] = endTime.split(':').map(Number);
const startTotalMinutes = startHour * 60 + startMinute;
const endTotalMinutes = endHour * 60 + endMinute;
const durationMinutes = endTotalMinutes - startTotalMinutes;
const topPosition = (startTotalMinutes / 60) * HOUR_HEIGHT;
const height = (durationMinutes / 60) * HOUR_HEIGHT;
return {topPosition, height};
};
// ==================== QUẢN LÝ DỮ LIỆU ====================
// D1: Tạo dữ liệu sự kiện mẫu
const createMockEvents = () => {
return [
{
id: '1',
title: 'Lịch vào trực lớp TTCĐT 445.T1',
subtitle: 'CS Địa lý 4D',
time: '07:00',
endTime: '09:00',
date: '2025-09-26',
type: 'class',
},
{
id: '2',
title: 'Meeting team development',
subtitle: 'Phòng họp A1',
time: '10:00',
endTime: '11:30',
date: '2025-09-26',
type: 'meeting',
},
{
id: '3',
title: 'Training React Native',
subtitle: 'Online Zoom',
time: '14:00',
endTime: '16:00',
date: '2025-09-26',
type: 'training',
},
];
};
// D2: Xử lý dữ liệu sự kiện
const mockEvents = createMockEvents();
// D3: Hàm truy vấn sự kiện
const getEventsForDate = date => {
const dateStr = formatDateToString(date);
return mockEvents.filter(event => event.date === dateStr);
};
// ==================== HỆ THỐNG ANIMATION ====================
// A1: Thiết lập PanResponder
const panResponder = PanResponder.create({
onMoveShouldSetPanResponder: (evt, gestureState) => {
return Math.abs(gestureState.dx) > 30 && Math.abs(gestureState.dy) < 100;
},
onPanResponderMove: (evt, gestureState) => {},
onPanResponderRelease: (evt, gestureState) => {
if (gestureState.dx > 50) {
swipeToPrevWeek();
} else if (gestureState.dx < -50) {
swipeToNextWeek();
}
},
});
// ==================== XỬ LÝ SỰ KIỆN ====================
// X1: Xử lý chọn tháng
const handleMonthSelect = monthIndex => {
const newDate = new Date(currentDate);
newDate.setMonth(monthIndex);
setCurrentDate(newDate);
setSelectedDate(newDate);
setShowMonthPicker(false);
DeviceEventEmitter.emit('onDateChange', newDate);
// Cập nhật header drawer với tháng mới
DeviceEventEmitter.emit('updateHeaderMonth', monthIndex);
};
// X2: Xử lý chuyển tuần
const swipeToNextWeek = () => {
const nextWeek = new Date(currentDate);
nextWeek.setDate(currentDate.getDate() + 7);
setCurrentDate(nextWeek);
setSelectedDate(nextWeek);
DeviceEventEmitter.emit('onDateChange', nextWeek);
// Cập nhật header drawer nếu tháng thay đổi
DeviceEventEmitter.emit('updateHeaderMonth', nextWeek.getMonth());
};
const swipeToPrevWeek = () => {
const prevWeek = new Date(currentDate);
prevWeek.setDate(currentDate.getDate() - 7);
setCurrentDate(prevWeek);
setSelectedDate(prevWeek);
DeviceEventEmitter.emit('onDateChange', prevWeek);
// Cập nhật header drawer nếu tháng thay đổi
DeviceEventEmitter.emit('updateHeaderMonth', prevWeek.getMonth());
};
// X3: Xử lý toggle month picker
const toggleMonthPicker = () => {
setShowMonthPicker(!showMonthPicker);
};
return ( return (
<FilterWeekView /> <FilterWeekView
navigation={navigation}
currentDate={currentDate}
selectedDate={selectedDate}
showMonthPicker={showMonthPicker}
scrollViewRef={scrollViewRef}
panResponder={panResponder}
isToday={isToday}
getDayName={getDayName}
getMonthName={getMonthName}
getWeekDates={getWeekDates}
getEventsForDate={getEventsForDate}
calculateEventPosition={calculateEventPosition}
handleMonthSelect={handleMonthSelect}
toggleMonthPicker={toggleMonthPicker}
HOUR_HEIGHT={HOUR_HEIGHT}
DAY_COLUMN_WIDTH={DAY_COLUMN_WIDTH}
/>
); );
}; };
......
import {StyleSheet, Dimensions} from 'react-native';
import R from '../../../assets/R';
const {width} = Dimensions.get('window');
const DAY_COLUMN_WIDTH = (width - 70) / 7;
const styles = StyleSheet.create({
// ==================== CONTAINER CHÍNH ====================
// Tương ứng với View chính trong FilterWeekView (dòng 166)
container: {
flex: 1,
backgroundColor: R.colors.white,
},
// ==================== MONTH PICKER ====================
// Tương ứng với renderMonthPicker() (dòng 19-49)
monthPickerContainer: {
backgroundColor: R.colors.white,
borderBottomWidth: 1,
borderBottomColor: R.colors.gray,
paddingVertical: 10,
},
monthPickerContent: {
paddingHorizontal: 15,
},
monthItem: {
paddingHorizontal: 20,
paddingVertical: 8,
marginRight: 10,
borderRadius: 20,
backgroundColor: R.colors.gray220,
},
monthItemSelected: {
backgroundColor: R.colors.main,
},
monthItemText: {
fontSize: R.fontsize.fontSizeContent,
fontFamily: R.fonts.InterRegular,
color: R.colors.black,
},
monthItemTextSelected: {
color: R.colors.white,
fontFamily: R.fonts.fontMedium,
},
// ==================== WEEK HEADER ====================
// Tương ứng với renderWeekHeader() (dòng 51-87)
weekHeaderContainer: {
flexDirection: 'row',
backgroundColor: R.colors.gray220,
borderBottomWidth: 1,
borderBottomColor: R.colors.gray220,
},
timeColumnHeader: {
width: 70,
},
dayHeaderCell: {
width: DAY_COLUMN_WIDTH,
alignItems: 'center',
justifyContent: 'center',
borderRightWidth: 1,
borderRightColor: R.colors.gray220,
},
dayHeaderText: {
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterMedium,
fontWeight: '600',
color: R.colors.black,
},
dayHeaderNumber: {
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterMedium,
color: R.colors.black,
fontWeight: '600',
},
dayHeaderNumberContainerToday: {
borderRadius: 15,
justifyContent: 'center',
alignItems: 'center',
},
dayHeaderNumberToday: {
color: R.colors.white,
fontFamily: R.fonts.InterMedium,
fontSize: R.fontsize.fontsSize12,
fontWeight: '600',
backgroundColor: R.colors.main,
borderRadius: 30,
paddingHorizontal: 6,
paddingVertical: 4,
marginBottom: 2,
},
dayHeaderTextToday: {
},
// ==================== TIME SLOTS CONTAINER ====================
// Tương ứng với renderTimeSlots() (dòng 89-163)
timeSlotsContainer: {
flex: 1,
backgroundColor: R.colors.white,
},
scrollContent: {
paddingBottom: 50,
},
timelineContainer: {
flexDirection: 'row',
position: 'relative',
},
// ==================== TIME LABELS COLUMN ====================
// Tương ứng với timeLabelsColumn (dòng 100-109)
timeLabelsColumn: {
width: 70,
borderRightWidth: 1,
borderRightColor: R.colors.gray220,
},
timeSlot: {
height: 80,
alignItems: 'center',
justifyContent: 'center',
borderBottomWidth: 1,
borderBottomColor: R.colors.gray220,
},
timeText: {
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterRegular,
fontWeight: '400',
color: R.colors.black,
},
// ==================== WEEK GRID CONTAINER ====================
// Tương ứng với weekGridContainer (dòng 111-158)
weekGridContainer: {
flex: 1,
flexDirection: 'row',
},
dayColumn: {
width: DAY_COLUMN_WIDTH,
position: 'relative',
borderRightWidth: 1,
borderRightColor: R.colors.gray220,
},
gridCell: {
height: 80,
borderBottomWidth: 1,
borderBottomColor: R.colors.gray220,
width: '100%',
},
// ==================== EVENT CARDS ====================
// Tương ứng với event rendering (dòng 118-155)
eventCard: {
borderRadius: 10,
paddingHorizontal: 4,
paddingVertical: 2,
justifyContent: 'center',
},
eventTitle: {
fontSize: R.fontsize.fontsSize14,
fontFamily: R.fonts.InterMedium,
color: R.colors.white,
fontWeight: '600',
marginBottom: 1,
},
eventSubtitle: {
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterRegular,
color: R.colors.white,
fontWeight: '400',
},
eventTime: {
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterRegular,
color: R.colors.white,
fontWeight: '400',
},
});
export default styles;
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