Commit 8afeceec by tungnq

TODO: Đã hoàn thiện giao diện danh sách sinh viên chưa có chức năng tìm kiếm

parent 891b8366
......@@ -7,7 +7,7 @@ import TabNavigator from './TabNavigation';
import * as ScreenName from './ScreenNames';
import NotificationAdd from '../screens/notification/add';
import ClassActivity from '../screens/academic_advisor';
import ListStudentClass from '../screens/academic_advisor/list_student';
const Stack = createStackNavigator();
function MyStack(props) {
......@@ -23,6 +23,7 @@ function MyStack(props) {
<Stack.Screen name={ScreenName.DETAILNOTIFICATION} component={NotificationDetail} />
<Stack.Screen name={ScreenName.ADDNOTIFICATION} component={NotificationAdd} />
<Stack.Screen name={ScreenName.LISTACADEMICADVISOR} component={ClassActivity} />
<Stack.Screen name={ScreenName.LISTSTUDENTCLASS} component={ListStudentClass} />
</Stack.Navigator>
);
}
......
import React from 'react';
import React, {useMemo, useState} from 'react';
import {Text, View, StyleSheet} from 'react-native';
import ListStudentView from './view';
const ListStudent = (props) => {
const [searchText, setSearchText] = useState('');
const handleSearchChange = (text) => {
setSearchText(text);
};
const filter = useMemo(()=>{
if(!searchText.trim()) return dataListStudent;
return dataListStudent.filter(item => item.name.toLowerCase().includes(searchText.toLowerCase()));
},[dataListStudent, searchText]);
const [dataListStudent, setDataListStudent]= useState([
{
id:'1',
name:'Nguyễn Minh Đức',
status:'Đang học',
gender:'Nam',
code_student:'259128',
date_student:'23/10/2004',
tele_phone:'0987654321',
},
{
id:'2',
name:'Bùi Thanh Ngọc',
status:'Cảnh cáo',
gender:'Nữ',
code_student:'259128',
date_student:'23/10/2004',
tele_phone:'0987654321',
},
{
id:'3',
name:'Trần Văn Hùng',
status:'Thôi học',
gender:'Nam',
code_student:'259128',
date_student:'23/10/2004',
tele_phone:'0987654321',
},
])
const getStatusColor = (status)=>{
const statusColor ={
'Đang học': '#4CAF50',
'Cảnh cáo': '#FFC107',
'Thôi học': '#F44336',
}
return statusColor[status] || '#9E9E9E';
}
const statusStats = useMemo(()=>{
const stats = dataListStudent.reduce((acc, student)=>{
acc[student.status] =(acc[student.status] || 0 ) + 1;
return acc;
},{});
return Object.entries(stats).map(([status, count]) =>({
status,
count,
color: getStatusColor(status),
}));
},[dataListStudent]);
return (
<ListStudentView />
<ListStudentView
searchText={searchText}
onSearchChange={handleSearchChange}
filter={dataListStudent}
statusStats={statusStats}
/>
);
};
......
import {StyleSheet, Text, View} from 'react-native';
import R from '../../../assets/R';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: R.colors.white,
},
//Search
containerSearchBox: {
borderColor: R.colors.grayBorderInputTextHeader,
borderWidth: 1,
borderRadius: 100,
marginHorizontal: 15,
marginVertical: 15,
backgroundColor: R.colors.white,
flexDirection: 'row',
maxHeight: 41,
},
boxIconSearch: {
maxWidth: 35,
maxHeight: 35,
alignItems: 'center',
justifyContent: 'center',
marginHorizontal: Platform.OS === 'ios' ? 5 : 10,
},
inputSearch: {
fontSize: R.sizes.sm,
fontFamily: R.fonts.fontMedium,
fontWeight: '500',
flex: 1,
},
//Filter
statusContainer: {
marginBottom: 15,
marginHorizontal: 15,
flexDirection: "row",
justifyContent: "space-around"
},
statusCard: {
flexDirection: 'row',
alignItems: 'center',
},
statusDot: {
width: 10,
height: 10,
borderRadius: 5,
marginRight: 5,
},
statusText: {
fontSize: R.sizes.sm,
fontFamily: R.fonts.fontMedium,
fontWeight: '600',
color: R.colors.black,
marginRight: 5,
},
statusCount: {
fontSize: R.sizes.sm,
fontFamily: R.fonts.fontRegular,
fontWeight: '400',
color: R.colors.black,
},
body: {},
listContainer: {
paddingBottom: 20,
},
studentCard: {
backgroundColor: R.colors.white,
borderRadius: 15,
marginBottom: 15,
marginHorizontal: 15,
padding: 15,
shadowColor: R.colors.black,
shadowOffset: {width: 0.5, height: 2},
shadowOpacity: Platform.OS === 'ios' ? 0.25 : 1,
shadowRadius: 2,
elevation: Platform.OS === 'ios' ? 1 : 2,
},
studentCardContent: {
flexDirection: 'row',
},
leftSection: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
},
rightSection: {
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
},
genderIcon: {
width: 15,
height: 15,
marginHorizontal: 5,
},
studentInfo: {
flex: 1,
flexDirection: 'row',
},
studentName: {
fontSize: R.sizes.sm,
fontFamily: R.fonts.fontMedium,
fontWeight: '600',
color: R.colors.black,
},
statusIndicator: {
width: 15,
height: 15,
borderRadius: 15,
marginLeft: 17,
},
sizedBox: {
height: 5,
},
});
export default styles;
import React from 'react';
import {Text, View, TouchableOpacity, StyleSheet} from 'react-native';
import {
Text,
View,
TouchableOpacity,
StyleSheet,
SafeAreaView,
TextInput,
Image,
Platform,
ScrollView,
FlatList,
} from 'react-native';
import Header from '../../../components/Header/Header';
import styles from './style';
import R from '../../../assets/R';
const ListStudentView = props => {
const {searchText, onSearchChange, filter, statusStats} = props;
console.log(props);
//Search
const renderSearchBox = () => {
return (
<View style={styles.containerSearchBox}>
<View style={styles.boxIconSearch}>
<Image
source={R.images.icSearchHeader}
maxWidth={Platform.OS === 'ios' ? 16 : 20}
maxHeight={Platform.OS === 'ios' ? 16 : 20}
resizeMode="contain"
tintColor={R.colors.gray}
/>
</View>
<TextInput
placeholder="Tìm kiếm"
value={searchText}
onChangeText={onSearchChange}
placeholderTextColor={R.colors.gray}
color={R.colors.black}
style={styles.inputSearch}
/>
</View>
);
};
//List status
const renderListStatus = () => {
return (
<View
style={styles.statusContainer}
>
{statusStats.map((stat, index) => (
<View
key={index}
style={[styles.statusCard, {borderLeftColor: stat.color}]}>
<View style={[styles.statusDot, {backgroundColor: stat.color}]} />
<Text style={[styles.statusText, {color: stat.color}]}>
{stat.status}
</Text>
<Text style={[styles.statusCount, {color: stat.color}]}>
({stat.count})
</Text>
</View>
))}
</View>
);
};
const ListStudentView = (props) => {
const { } = props;
return (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<TouchableOpacity>
<Text>ListStudent</Text>
//List student
const renderStudentItem = ({item}) => {
const isLeftIcon = item.gender === 'Nam';
const genderIcon =
item.gender === 'Nam' ? R.images.icMale : R.images.icFemale;
const statusColor = getStatusColor(item.status);
return (
<TouchableOpacity style={styles.studentCard}>
<View style={styles.studentCardContent}>
<View style={styles.studentInfo}>
{/*Tên sinh viên*/}
<View style={styles.leftSection}>
<Text style={styles.studentName}>{item.name}</Text>
{isLeftIcon && (
<Image source={genderIcon} style={styles.genderIcon} resizeMode="contain"/>
)}
{!isLeftIcon && (
<Image source={genderIcon} style={styles.genderIcon} resizeMode="contain"/>
)}
</View>
<View style={styles.rightSection}>
{/*Mã sinh viên*/}
<Text style={styles.studentName}>MSV: {item.code_student}</Text>
{/*Trạng thái*/}
<View
style={[
styles.statusIndicator,
{backgroundColor: statusColor},
]}>
<Text style={styles.statusIndicatorText}></Text>
</View>
</View>
</View>
</View>
<View style={styles.sizedBox}></View>
<View style={styles.studentCardContent}>
<View style={styles.studentInfo}>
{/*Tên sinh viên*/}
<View style={styles.leftSection}>
<Text style={[styles.studentName,{fontFamily:R.fonts.fontRegular,fontWeight:'400'}]}>Ngày sinh: {item.date_student}</Text>
</View>
<View style={styles.rightSection}>
{/*Mã sinh viên*/}
<Text style={[styles.studentName,{fontFamily:R.fonts.fontRegular,fontWeight:'400'}]}>SĐT: {item.tele_phone}</Text>
</View>
</View>
</View>
</TouchableOpacity>
</View>
);
};
const getStatusColor = status => {
const statusColors = {
'Đang học': '#4CAF50',
'Cảnh cáo': '#FF9800',
'Thôi học': '#F44336',
};
return statusColors[status] || '#9E9E9E';
};
return (
<SafeAreaView style={styles.container}>
<Header title={'Danh sách sinh viên lớp ATTT2024.1'} isBack />
<View style={styles.body}>
{renderSearchBox()}
{renderListStatus()}
<View>
<FlatList
data={filter || []}
renderItem={renderStudentItem}
vertical
keyExtractor={(item, index) => `${index}`}
showsVerticalScrollIndicator={false}
/>
</View>
</View>
</SafeAreaView>
);
};
export default ListStudentView;
const styles = StyleSheet.create({})
\ No newline at end of file
......@@ -4,8 +4,11 @@ import styles from './style';
import Header from '../../components/Header/Header';
import Button from '../../components/Button';
import R from '../../assets/R';
import*as SCREENNAME from '../../routers/ScreenNames';
import { useNavigation } from '@react-navigation/native';
const ClassActivityView = (props) => {
const {dataList,setDataList} = props;
const navigate = useNavigation();
const renderItem =({
item,
}) => {
......@@ -23,7 +26,7 @@ const ClassActivityView = (props) => {
<View style={styles.containerButton}>
<Button
title='Chi tiết'
onPress={()=>{}}
onPress={()=>{navigate.navigate(SCREENNAME.LISTSTUDENTCLASS)}}
backgroundColor={R.colors.blue}
textColor={R.colors.white}
height={30}
......
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