Commit 1f57d4df by tungnq

TODO: Tái cấu trúc component Dropdown để chấp nhận margin động và cải thiện…

TODO: Tái cấu trúc component Dropdown để chấp nhận margin động và cải thiện DetailListWorkMonitoring với xử lý báo cáo và nâng cấp các thành phần giao diện người dùng.
parent 63488e16
...@@ -15,7 +15,7 @@ const Dropdown = ({ ...@@ -15,7 +15,7 @@ const Dropdown = ({
onSelect, onSelect,
height, height,
backgroundColor, backgroundColor,
containerMarginBottom = 5,
// mới thêm // mới thêm
editable = true, editable = true,
disabledBackgroundColor = R.colors.blue1, disabledBackgroundColor = R.colors.blue1,
...@@ -49,7 +49,7 @@ const Dropdown = ({ ...@@ -49,7 +49,7 @@ const Dropdown = ({
const resolvedBorderColor = editable ? R.colors?.grayBorderInputTextHeader || '#ccc' : '#ddd'; const resolvedBorderColor = editable ? R.colors?.grayBorderInputTextHeader || '#ccc' : '#ddd';
return ( return (
<View style={styles.container}> <View style={[styles.container , {marginBottom:containerMarginBottom}]}>
{/* Header */} {/* Header */}
<TouchableOpacity <TouchableOpacity
activeOpacity={editable ? 0.7 : 1} activeOpacity={editable ? 0.7 : 1}
......
...@@ -344,7 +344,6 @@ const ListWork = props => { ...@@ -344,7 +344,6 @@ const ListWork = props => {
// Hiển thị dữ liệu sau khi chọn // Hiển thị dữ liệu sau khi chọn
const filterList = useMemo(() => { const filterList = useMemo(() => {
let base = dataList; let base = dataList;
console.log('Dữ liệu danh sách đầu vào', base);
// Lọc theo tab role // Lọc theo tab role
if (currentTabKey === ROLE.ASSIGNEE) { if (currentTabKey === ROLE.ASSIGNEE) {
......
import React, {useState} from 'react'; import React, {useState} from 'react';
import DetailListWorkMonitoringView from './view'; import DetailListWorkMonitoringView from './view';
const DetailListWorkMonitoring = (props) => { const DetailListWorkMonitoring = props => {
const {route} = props; const {route} = props;
const workItem = route?.params?.workItem || {}; const workItem = route?.params?.workItem || {};
const [showRequestReport, setShowRequyestReport] = useState(false);
const [data, setData] = useState({ const [data, setData] = useState({
id: workItem.id || 1, id: workItem.id || 1,
...@@ -31,8 +32,19 @@ const DetailListWorkMonitoring = (props) => { ...@@ -31,8 +32,19 @@ const DetailListWorkMonitoring = (props) => {
}, },
], ],
document: workItem.document || 'Văn bản công việc giám sát', document: workItem.document || 'Văn bản công việc giám sát',
content: workItem.content || 'Nội dung công việc đang được giám sát và theo dõi tiến độ thực hiện', content:
workItem.content ||
'Nội dung công việc đang được giám sát và theo dõi tiến độ thực hiện',
}); });
const handleReportPress = () => {
if (data.status === 'Đang thực hiện') {
setShowRequyestReport(true);
}else{
setShowRequyestReport(false);
}
};
const [dataList, setDataList] = useState([ const [dataList, setDataList] = useState([
{id: 1, name: 'Nguyễn Minh Đức'}, {id: 1, name: 'Nguyễn Minh Đức'},
...@@ -48,7 +60,8 @@ const DetailListWorkMonitoring = (props) => { ...@@ -48,7 +60,8 @@ const DetailListWorkMonitoring = (props) => {
title: 'Báo cáo tiến độ lần 1', title: 'Báo cáo tiến độ lần 1',
time: '14:30', time: '14:30',
date: '2025-09-10', date: '2025-09-10',
content: 'Báo cáo tiến độ thực hiện công việc được giao. Hiện tại đã hoàn thành 60% công việc theo kế hoạch.', content:
'Báo cáo tiến độ thực hiện công việc được giao. Hiện tại đã hoàn thành 60% công việc theo kế hoạch.',
fileTitle: 'Báo cáo tiến độ - BC001', fileTitle: 'Báo cáo tiến độ - BC001',
responder: [ responder: [
{ {
...@@ -57,7 +70,8 @@ const DetailListWorkMonitoring = (props) => { ...@@ -57,7 +70,8 @@ const DetailListWorkMonitoring = (props) => {
code: '12345', code: '12345',
time: '14:30', time: '14:30',
date: '2025-09-10', date: '2025-09-10',
content: 'Đã hoàn thành phần phân tích yêu cầu và đang triển khai thiết kế hệ thống.', content:
'Đã hoàn thành phần phân tích yêu cầu và đang triển khai thiết kế hệ thống.',
}, },
], ],
}, },
...@@ -66,7 +80,8 @@ const DetailListWorkMonitoring = (props) => { ...@@ -66,7 +80,8 @@ const DetailListWorkMonitoring = (props) => {
title: 'Báo cáo tiến độ lần 2', title: 'Báo cáo tiến độ lần 2',
time: '16:00', time: '16:00',
date: '2025-09-12', date: '2025-09-12',
content: 'Cập nhật tiến độ thực hiện. Đã hoàn thành 80% công việc, dự kiến hoàn thành đúng hạn.', content:
'Cập nhật tiến độ thực hiện. Đã hoàn thành 80% công việc, dự kiến hoàn thành đúng hạn.',
fileTitle: 'Báo cáo tiến độ - BC002', fileTitle: 'Báo cáo tiến độ - BC002',
responder: [ responder: [
{ {
...@@ -75,7 +90,8 @@ const DetailListWorkMonitoring = (props) => { ...@@ -75,7 +90,8 @@ const DetailListWorkMonitoring = (props) => {
code: '12345', code: '12345',
time: '16:00', time: '16:00',
date: '2025-09-12', date: '2025-09-12',
content: 'Đã hoàn thành phần thiết kế và đang trong giai đoạn kiểm thử hệ thống.', content:
'Đã hoàn thành phần thiết kế và đang trong giai đoạn kiểm thử hệ thống.',
}, },
], ],
}, },
...@@ -86,6 +102,8 @@ const DetailListWorkMonitoring = (props) => { ...@@ -86,6 +102,8 @@ const DetailListWorkMonitoring = (props) => {
data={data} data={data}
dataList={dataList} dataList={dataList}
dataReport={dataReport} dataReport={dataReport}
onHandleReportPress={handleReportPress}
setShowRequyestReport={setShowRequyestReport}
/> />
); );
}; };
......
import { StyleSheet } from 'react-native'; import {StyleSheet} from 'react-native';
import R from '../../../assets/R'; import R from '../../../assets/R';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
...@@ -38,6 +38,62 @@ const styles = StyleSheet.create({ ...@@ -38,6 +38,62 @@ const styles = StyleSheet.create({
paddingHorizontal: 10, paddingHorizontal: 10,
borderRadius: 5, borderRadius: 5,
}, },
textChip: {
fontSize: R.fontsize.fontSizeContent,
fontWeight: '400',
fontFamily: R.fonts.fontRegular,
color: R.colors.blueTextChip,
},
containerContent: {
borderWidth: 1,
borderRadius: 10,
padding: 10,
marginVertical: 3,
borderColor: R.colors.grayBorderInputTextHeader,
},
flatListSelect: {
flexDirection: 'row',
flexWrap: 'wrap',
},
chip: {
flexDirection: 'row',
alignItems: 'center',
paddingLeft: 10,
paddingRight: 10,
height: 25,
borderRadius: 10,
marginBottom: 10,
marginRight: 5,
backgroundColor: R.colors.blue2,
alignSelf: 'flex-start',
},
imageIcon: {
width: 15,
height: 15,
},
containerIcon: {
marginRight: 2,
},
attachmentContainer: {
borderWidth: 1,
borderColor: R.colors.blue,
borderRadius: 10,
padding: 20,
alignItems: 'center',
marginTop:3,
marginBottom: 50,
},
uploadIcon: {
width: 23,
height: 28,
tintColor: R.colors.blue,
marginBottom: 5,
},
attachmentText: {
fontSize: R.fontsize.fontSizeContent,
color: R.colors.blue,
fontWeight: '500',
},
sizedBox: { sizedBox: {
height: 10, height: 10,
}, },
......
...@@ -14,12 +14,12 @@ import SubButton from '../../../components/FAB/sub_button'; ...@@ -14,12 +14,12 @@ import SubButton from '../../../components/FAB/sub_button';
import R from '../../../assets/R'; import R from '../../../assets/R';
import Header from '../../../components/Header/Header'; import Header from '../../../components/Header/Header';
import Dropdown from '../../../components/DropdownAlert/Dropdown'; import Dropdown from '../../../components/DropdownAlert/Dropdown';
import Button from '../../../components/Button';
const DetailListWorkMonitoringView = props => { const DetailListWorkMonitoringView = props => {
LogBox.ignoreLogs(['VirtualizedLists should never be nested']); LogBox.ignoreLogs(['VirtualizedLists should never be nested']);
const {data, dataList, dataReport} = props; const {data, dataList, dataReport, onHandleReportPress, setShowRequestReport} = props;
const [showApprovalModal, setShowApprovalModal] = useState(false);
const [showRequestEditModal, setShowRequestEditModal] = useState(false);
const getColor = status => { const getColor = status => {
switch (status) { switch (status) {
...@@ -37,136 +37,205 @@ const DetailListWorkMonitoringView = props => { ...@@ -37,136 +37,205 @@ const DetailListWorkMonitoringView = props => {
return R.colors.gray; return R.colors.gray;
} }
}; };
const shouldShowFAB = () => {
return data.status === 'Đang thực hiện';
};
const renderReportItem = ({item}) => { const renderItem_1 = ({item, onPress}) => {
return ( return (
<View style={styles.containerCard}> <View style={styles.chip}>
<View style={{flexDirection: 'row', marginBottom: 3}}> <TouchableOpacity
<Text style={[styles.text, {color: R.colors.blue}]}> style={styles.containerIcon}
{item.title} -{' '} onPress={() => handleItemPress(item)}>
</Text> <Image
<Text style={[styles.text, {color: R.colors.blue}]}> resizeMode="cover"
{item.time}{' '} source={R.images.icCancel}
</Text> style={styles.imageIcon}
<Text style={[styles.text, {color: R.colors.blue}]}> tintColor={R.colors.blue}
{item.date} />
</Text> </TouchableOpacity>
</View> <Text style={styles.textChip}> {`${item.id}, ${item.name}`}</Text>
<Text style={styles.text}>{item.content}</Text>
<View style={styles.sizedBox} />
<View style={styles.containerText}>
<Text style={styles.text}>Tp đính kèm: </Text>
<Text style={[styles.text, {color: R.colors.blue}]}>
{item.fileTitle}
</Text>
</View> </View>
<View style={styles.sizedBox} /> );
<FlatList };
data={item.responder}
renderItem={renderResponderItem} const renderButton = () => {
keyExtractor={item => item.id.toString()} return (
<View style={styles.btnRegister2}>
<Button
title={'Cập nhật thông tin công việc'}
backgroundColor={R.colors.blue}
textColor={R.colors.white}
onPress={() => handleReportPress()}
fontSize={R.sizes.sm}
fontFamily={R.fonts.fontMedium}
height={35}
containerStyle={{paddingHorizontal: 15, borderRadius: 10}}
/> />
</View> </View>
); );
}; };
const renderResponderItem = ({item}) => { const renderBody = item => {
return ( return (
<View style={styles.containerCard}> <View style={styles.body}>
<View style={{flexDirection: 'row', marginBottom: 3}}> <Text
<Text style={[styles.text, {color: R.colors.blue}]}> style={[
{item.name} - {item.code} -{' '} styles.text,
{fontSize: R.fontsize.fontSizeSubTitle, marginBottom: 3},
]}>
{data.title}
</Text> </Text>
<Text style={[styles.text, {color: R.colors.blue}]}>
{item.time}{' '} <Text style={[styles.text, {marginBottom: 3, textAlign: 'right'}]}>
Trng thái:{' '}
<Text style={{color: getColor(data.status)}}>{data.status}</Text>
</Text>
<Text style={[styles.text, {marginBottom: 3}]}>
Công vic thuc văn bn:{' '}
<Text style={[styles.sub_text, {color: R.colors.blue}]}>
{data.document}
</Text> </Text>
<Text style={[styles.text, {color: R.colors.blue}]}> </Text>
{item.date} <Text style={[styles.text, {marginBottom: 3}]}>Ni dung công vic</Text>
<View style={styles.containerContent}>
<Text style={[styles.text, {color: R.colors.gray}]}>
{data.content}
</Text> </Text>
</View> </View>
<Text style={styles.text}>{item.content}</Text> <Text style={styles.text}>
Ngày đến hn <Text style={{color: R.colors.red}}>*</Text>
</Text>
<View style={styles.containerContent}>
<Text style={styles.text}>{data.deadline}</Text>
</View> </View>
);
};
const renderImplementerItem = ({item}) => { <View style={styles.containerDropDown}>
return ( <Text
<View style={styles.containerText}> style={[
<Text style={styles.text}>{item.name}</Text> styles.text,
{
marginBottom: 3,
},
]}>
Người theo dõi
</Text>
<Dropdown
height={35}
items={item}
placeholder="Công việc theo văn bản"
/>
</View> </View>
); <Text style={[styles.text, {marginBottom: 3}]}>
}; Danh sách người theo dõi đã chn
</Text>
<FlatList
data={dataList}
renderItem={({item}) => renderItem_1({item, onPress: () => {}})}
keyExtractor={(item, index) =>
item.id?.toString() || index.toString()
}
numColumns={2}
style={{maxHeight: 150}}
showsVerticalScrollIndicator={true}
columnWrapperStyle={styles.flatListSelect}
nestedScrollEnabled={true}
scrollEnabled={true}
/>
return ( <View style={styles.containerDropDown}>
<View style={styles.container}> <Text
<Header title={'Chi tiết công việc giám sát'} />
<ScrollView style={styles.body}>
<View style={styles.containerCard}>
<View
style={[ style={[
styles.containerText, styles.text,
{backgroundColor: getColor(data.status)}, {
marginBottom: 3,
},
]}> ]}>
<Text style={[styles.text, {color: R.colors.white}]}> Người thc hin công vic
{data.status}
</Text> </Text>
<Dropdown height={35} items={item} />
</View> </View>
<View style={styles.sizedBox} /> <Text style={[styles.text, {marginBottom: 3}]}>
<Text style={styles.text}>{data.title}</Text> Danh sách người thc hin công vic đã chn
<View style={styles.sizedBox} />
<View style={styles.containerText}>
<Text style={styles.text}>Ngày đến hn: </Text>
<Text style={[styles.text, {color: R.colors.blue}]}>
{data.deadline}
</Text> </Text>
</View>
<View style={styles.sizedBox} />
<View style={styles.containerText}>
<Text style={styles.text}>Người thc hin: </Text>
</View>
<FlatList <FlatList
data={data.implementer} data={dataList}
renderItem={renderImplementerItem} renderItem={({item}) => renderItem_1({item, onPress: () => {}})}
keyExtractor={item => item.id.toString()} keyExtractor={(item, index) =>
item.id?.toString() || index.toString()
}
numColumns={2}
style={{maxHeight: 150}}
showsVerticalScrollIndicator={true}
columnWrapperStyle={styles.flatListSelect}
nestedScrollEnabled={true}
scrollEnabled={true}
/> />
<View style={styles.sizedBox} />
<View style={styles.containerText}> <View style={styles.containerDropDown}>
<Text style={styles.text}>Thuc văn bn: </Text> <Text
<Text style={[styles.text, {color: R.colors.blue}]}> style={[
{data.document} styles.text,
{
marginBottom: 3,
},
]}>
Th
</Text> </Text>
<Dropdown height={35} items={item} />
</View> </View>
<View style={styles.sizedBox} /> <Text style={[styles.text, {marginBottom: 3}]}>
<Text style={styles.text}>{data.content}</Text> Danh sách th đã chn
</View> </Text>
<View style={styles.containerCard}>
<Text style={styles.text}>Lch s báo cáo</Text>
<View style={styles.sizedBox} />
<FlatList <FlatList
data={dataReport} data={dataList}
renderItem={renderReportItem} renderItem={({item}) => renderItem_1({item, onPress: () => {}})}
keyExtractor={item => item.id.toString()} keyExtractor={(item, index) =>
item.id?.toString() || index.toString()
}
numColumns={2}
style={{maxHeight: 150}}
showsVerticalScrollIndicator={true}
columnWrapperStyle={styles.flatListSelect}
nestedScrollEnabled={true}
scrollEnabled={true}
/> />
<Text style={[styles.text, {marginBottom: 3}]}>Tài liu đính kèm</Text>
<TouchableOpacity style={styles.containerFile}>
<Text style={[styles.text, {fontSize: R.sizes.xs}]}>
Quyết định thông báo đào to - QD347583
</Text>
<Image source={R.images.icDownload} style={styles.image} />
</TouchableOpacity>
<TouchableOpacity style={styles.attachmentContainer}>
<Image source={R.images.icDocument} style={styles.uploadIcon} />
<Text style={styles.attachmentText}>Thêm tài liu</Text>
</TouchableOpacity>
{renderButton()}
</View> </View>
);
};
return (
<View style={styles.container}>
<Header title={'Chi tiết công việc giám sát'} />
<ScrollView showsVerticalScrollIndicator={false}>
{renderBody()}
</ScrollView> </ScrollView>
<FAB {shouldShowFAB() && (
style={styles.fab} <FAB>
onPress={() => console.log('FAB pressed for monitoring actions')}>
<SubButton
onPress={() => setShowApprovalModal(true)}
title={'Phê duyệt'}
/>
<SubButton <SubButton
onPress={() => setShowRequestEditModal(true)} onPress={onHandleReportPress}
title={'Yêu cầu chỉnh sửa'} label={'Yêu cầu báo cáo'}
/> images={R.images.icEdit}
<SubButton backgroundColor={R.colors.orange}
onPress={() => console.log('Request report')}
title={'Yêu cầu báo cáo'}
/> />
</FAB> </FAB>
)}
</View> </View>
); );
}; };
......
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