Commit 6625758a by tungnq

TODO: Thêm modal giám sát và cập nhật chức năng quản lý công việc

parent 5906f75c
...@@ -8,7 +8,8 @@ import R from '../../assets/R'; ...@@ -8,7 +8,8 @@ import R from '../../assets/R';
const ListWork = props => { const ListWork = props => {
const navigation = useNavigation(); const navigation = useNavigation();
const [searchQuery, setSearchQuery] = useState(''); const [searchQuery, setSearchQuery] = useState('');
const [modalVisible, setModalVisible] = useState(false); const [modalDeliverToMeVisible, setModalDeliverToMeVisible] = useState(false);
const [modalMonitoringVisible, setModalMonitoringVisible] = useState(false);
const [currentTabKey, setCurrentTabKey] = useState(ROLE.ALL); const [currentTabKey, setCurrentTabKey] = useState(ROLE.ALL);
const [currentDropDownKey, setCurrentDropDownKey] = useState( const [currentDropDownKey, setCurrentDropDownKey] = useState(
WORK_PROGRESS.ALL_WORK_PROGRESS, WORK_PROGRESS.ALL_WORK_PROGRESS,
...@@ -257,19 +258,35 @@ const ListWork = props => { ...@@ -257,19 +258,35 @@ const ListWork = props => {
// Mở modal thêm công việc mới // Mở modal thêm công việc mới
const handleAddWork = () => { const handleAddWork = () => {
setModalVisible(true); if (currentTabKey === ROLE.ASSIGNEE) {
setModalDeliverToMeVisible(true);
} else if (currentTabKey === ROLE.SUPERVISOR) {
setModalMonitoringVisible(true);
}
};
// Đóng modal "Giao cho tôi"
const handleCloseDeliverToMeModal = () => {
setModalDeliverToMeVisible(false);
}; };
// Đóng modal thêm công việc // Đóng modal "Đang giám sát"
const handleCloseModal = () => { const handleCloseMonitoringModal = () => {
setModalVisible(false); setModalMonitoringVisible(false);
}; };
// Xử lý lưu công việc mới // Xử lý lưu công việc "Giao cho tôi"
const handleSaveWork = workData => { const handleSaveDeliverToMeWork = workData => {
console.log('Đang lưu công việc:', workData); console.log('Đang lưu công việc giao cho tôi:', workData);
// TODO: Thêm logic lưu công việc vào database // TODO: Thêm logic lưu công việc giao cho tôi vào database
setModalVisible(false); setModalDeliverToMeVisible(false);
};
// Xử lý lưu công việc "Đang giám sát"
const handleSaveMonitoringWork = workData => {
console.log('Đang lưu công việc giám sát:', workData);
// TODO: Thêm logic lưu công việc giám sát vào database
setModalMonitoringVisible(false);
}; };
// ==================== FILTER & SEARCH HANDLERS ==================== // ==================== FILTER & SEARCH HANDLERS ====================
...@@ -469,6 +486,11 @@ const ListWork = props => { ...@@ -469,6 +486,11 @@ const ListWork = props => {
{key: ROLE.SUPERVISOR, label: 'Đang giám sát'}, {key: ROLE.SUPERVISOR, label: 'Đang giám sát'},
]); ]);
// Kiểm tra có hiển thị FAB hay không
const shouldShowFAB = () => {
return currentTabKey !== ROLE.ALL;
};
// ==================== RENDER ==================== // ==================== RENDER ====================
return ( return (
...@@ -477,13 +499,18 @@ const ListWork = props => { ...@@ -477,13 +499,18 @@ const ListWork = props => {
searchQuery={searchQuery} searchQuery={searchQuery}
setSearchQuery={setSearchQuery} setSearchQuery={setSearchQuery}
dataList={filterList} dataList={filterList}
modalVisible={modalVisible} modalDeliverToMeVisible={modalDeliverToMeVisible}
modalMonitoringVisible={modalMonitoringVisible}
tabView={tabView} tabView={tabView}
currentTabKey={currentTabKey}
shouldShowFAB={shouldShowFAB()}
// Sự kiện // Sự kiện
onFilterChange={handleFilterChange} onFilterChange={handleFilterChange}
onAddWork={handleAddWork} onAddWork={handleAddWork}
onSaveWork={handleSaveWork} onSaveDeliverToMeWork={handleSaveDeliverToMeWork}
onCloseModal={handleCloseModal} onSaveMonitoringWork={handleSaveMonitoringWork}
onCloseDeliverToMeModal={handleCloseDeliverToMeModal}
onCloseMonitoringModal={handleCloseMonitoringModal}
onViewDetailDeliverToMe={handleViewDetailDeliverToMe} onViewDetailDeliverToMe={handleViewDetailDeliverToMe}
onReportAction={handleReportAction} onReportAction={handleReportAction}
onApprovalAction={handleApprovalAction} onApprovalAction={handleApprovalAction}
......
import AddMonitoringModal from './view';
export default AddMonitoringModal;
import {StyleSheet} from 'react-native';
import R from '../../../assets/R';
const styles = StyleSheet.create({
overlay: {
flex: 1,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
justifyContent: 'center',
alignItems: 'center',
},
modalContainer: {
backgroundColor: 'white',
borderRadius: 12,
padding: 20,
width: '90%',
maxWidth: 400,
maxHeight: '80%',
},
title: {
fontSize: R.fontsize.fontsSizeTitle,
fontWeight: '600',
color: R.colors.blue,
textAlign: 'center',
marginBottom: 20,
},
containerDropdown: {
marginBottom: 15,
},
label: {
fontSize: R.fontsize.fontSizeContent,
fontWeight: '600',
fontFamily: R.fonts.fontMedium,
color: R.colors.black,
marginBottom: 5,
},
required: {
color: R.colors.red,
},
flatList: {
maxHeight: 150,
marginBottom: 10,
},
selectedFlatList: {
maxHeight: 100,
marginBottom: 15,
},
flatListRow: {
justifyContent: 'space-between',
paddingHorizontal: 5,
},
chip: {
backgroundColor: R.colors.grayLight,
borderRadius: 20,
paddingHorizontal: 15,
paddingVertical: 8,
margin: 5,
borderWidth: 1,
borderColor: R.colors.gray,
flex: 0.48,
alignItems: 'center',
},
chipSelected: {
backgroundColor: R.colors.blue1,
borderColor: R.colors.blue,
},
selectedChip: {
backgroundColor: R.colors.blue1,
borderRadius: 20,
paddingHorizontal: 10,
paddingVertical: 8,
margin: 5,
borderWidth: 1,
borderColor: R.colors.blue,
flex: 0.48,
flexDirection: 'row',
alignItems: 'center',
},
textChip: {
fontSize: R.fontsize.fontSizeContent,
color: R.colors.black,
textAlign: 'center',
flex: 1,
},
textChipSelected: {
color: R.colors.blue,
fontWeight: '600',
},
containerIcon: {
marginRight: 5,
},
imageIcon: {
width: 15,
height: 15,
},
attachmentContainer: {
borderWidth: 1,
borderColor: R.colors.blue,
borderRadius: 10,
padding: 20,
alignItems: 'center',
marginBottom: 20,
},
uploadIcon: {
width: 23,
height: 28,
tintColor: R.colors.blue,
marginBottom: 5,
},
attachmentText: {
fontSize: R.fontsize.fontSizeContent,
color: R.colors.blue,
fontWeight: '500',
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'flex-end',
marginTop: 10,
},
});
export default styles;
import React, {useState} from 'react';
import {
Modal,
View,
Text,
TouchableOpacity,
ScrollView,
Image,
FlatList,
} from 'react-native';
import R from '../../../assets/R';
import styles from './style';
import TextField from '../../../components/Input/TextField';
import TextMulti from '../../../components/Input/TextMulti';
import Dropdown from '../../../components/DropdownAlert/Dropdown';
import Button from '../../../components/Button';
const AddMonitoringModal = ({visible, onClose, onSave}) => {
const [formData, setFormData] = useState({
title: '',
content: '',
category: null,
responsible: null,
deadline: null,
assignee: null,
implementer: null,
attachments: [],
});
const [dataList, setDataList] = useState([
{id: 1, name: 'Nguyễn Minh Đức'},
{id: 2, name: 'Trần Văn Hùng'},
{id: 3, name: 'Lê Thị Mai'},
{id: 4, name: 'Phạm Quốc Khánh'},
{id: 5, name: 'Hoàng Anh Tuấn'},
{id: 6, name: 'Vũ Thị Hằng'},
{id: 7, name: 'Ngô Văn Nam'},
{id: 8, name: 'Đinh Thị Lan'},
{id: 9, name: 'Bùi Văn Phúc'},
{id: 10, name: 'Lý Thị Hoa'},
{id: 11, name: 'Phan Minh Hoàng'},
{id: 12, name: 'Tạ Thị Hương'},
{id: 13, name: 'Đoàn Văn Dũng'},
{id: 14, name: 'Nguyễn Thị Vân'},
{id: 15, name: 'Trương Văn Long'},
{id: 16, name: 'Mai Thị Ngọc'},
{id: 17, name: 'Huỳnh Quốc Việt'},
{id: 18, name: 'Lâm Thị Thu'},
{id: 19, name: 'Nguyễn Hữu Tài'},
{id: 20, name: 'Phạm Thị Kim'},
]);
const [selectedItems, setSelectedItems] = useState([]);
const updateFormData = (field, value) => {
setFormData(prev => ({...prev, [field]: value}));
};
const handleSave = () => {
if (formData.title.trim() && formData.content.trim()) {
const workData = {
...formData,
selectedImplementers: selectedItems,
type: 'monitoring', // Đánh dấu đây là công việc giám sát
};
onSave(workData);
resetForm();
} else {
alert('Vui lòng điền đầy đủ thông tin bắt buộc');
}
};
const resetForm = () => {
setFormData({
title: '',
content: '',
category: null,
responsible: null,
deadline: null,
assignee: null,
implementer: null,
attachments: [],
});
setSelectedItems([]);
};
const handleClose = () => {
resetForm();
onClose();
};
const handleSelectItem = item => {
const isSelected = selectedItems.some(selected => selected.id === item.id);
if (isSelected) {
setSelectedItems(prev => prev.filter(selected => selected.id !== item.id));
} else {
setSelectedItems(prev => [...prev, item]);
}
};
const handleRemoveItem = itemId => {
setSelectedItems(prev => prev.filter(item => item.id !== itemId));
};
const renderItem = ({item}) => {
const isSelected = selectedItems.some(selected => selected.id === item.id);
return (
<TouchableOpacity
style={[styles.chip, isSelected && styles.chipSelected]}
onPress={() => handleSelectItem(item)}>
<Text style={[styles.textChip, isSelected && styles.textChipSelected]}>
{item.name}
</Text>
</TouchableOpacity>
);
};
const renderSelectedItem = ({item}) => {
return (
<View style={styles.selectedChip}>
<TouchableOpacity
style={styles.containerIcon}
onPress={() => handleRemoveItem(item.id)}>
<Image
resizeMode="cover"
source={R.images.icCancel}
style={styles.imageIcon}
tintColor={R.colors.blue}
/>
</TouchableOpacity>
<Text style={styles.textChip}>{item.name}</Text>
</View>
);
};
return (
<Modal
visible={visible}
transparent={true}
animationType="slide"
onRequestClose={handleClose}>
<View style={styles.overlay}>
<View style={styles.modalContainer}>
<ScrollView showsVerticalScrollIndicator={false}>
<Text style={styles.title}>To công vic giám sát</Text>
<TextField
title="Tiêu đề công việc"
placeholder="Nhập tiêu đề công việc"
required={true}
value={formData.title}
onChangeText={value => updateFormData('title', value)}
containerMarginBottom={15}
/>
<View style={styles.containerDropdown}>
<Text style={styles.label}>
Loi công vic <Text style={styles.required}>*</Text>
</Text>
<Dropdown
height={35}
placeholder="Chọn loại công việc"
onSelect={item => updateFormData('category', item)}
/>
</View>
<View style={styles.containerDropdown}>
<Text style={styles.label}>
Người chu trách nhim <Text style={styles.required}>*</Text>
</Text>
<Dropdown
height={35}
placeholder="Chọn người chịu trách nhiệm"
onSelect={item => updateFormData('responsible', item)}
/>
</View>
<View style={styles.containerDropdown}>
<Text style={styles.label}>
Thi hn hoàn thành <Text style={styles.required}>*</Text>
</Text>
<Dropdown
height={35}
placeholder="Chọn thời hạn"
onSelect={item => updateFormData('deadline', item)}
/>
</View>
<TextMulti
title="Nội dung công việc"
placeholder="Nhập nội dung chi tiết công việc cần giám sát"
required={true}
value={formData.content}
onChangeText={value => updateFormData('content', value)}
containerMarginBottom={15}
/>
<View style={styles.containerDropdown}>
<Text style={styles.label}>
Người thc hin <Text style={styles.required}>*</Text>
</Text>
<Dropdown
height={35}
placeholder="Chọn người thực hiện"
onSelect={item => updateFormData('implementer', item)}
/>
</View>
<Text style={styles.label}>Danh sách người thc hin:</Text>
<FlatList
data={dataList}
renderItem={renderItem}
keyExtractor={item => item.id.toString()}
numColumns={2}
style={styles.flatList}
showsVerticalScrollIndicator={false}
columnWrapperStyle={styles.flatListRow}
nestedScrollEnabled={true}
scrollEnabled={false}
/>
<Text style={styles.label}>Đã chn:</Text>
<FlatList
data={selectedItems}
renderItem={renderSelectedItem}
keyExtractor={item => item.id.toString()}
numColumns={2}
style={styles.selectedFlatList}
showsVerticalScrollIndicator={false}
columnWrapperStyle={styles.flatListRow}
nestedScrollEnabled={true}
scrollEnabled={false}
/>
<Text style={styles.label}>Tài liu đính kèm</Text>
<TouchableOpacity style={styles.attachmentContainer}>
<Image source={R.images.icDocument} style={styles.uploadIcon} />
<Text style={styles.attachmentText}>Thêm tài liu</Text>
</TouchableOpacity>
<View style={styles.buttonContainer}>
<Button
title="Hủy"
onPress={handleClose}
backgroundColor={R.colors.orange}
width={100}
height={35}
borderRadius={100}
marginRight={10}
fontSize={R.fontsize.fontSizeContent}
textColor={R.colors.white}
/>
<Button
title="Tạo công việc"
onPress={handleSave}
backgroundColor={R.colors.blue}
width={120}
height={35}
borderRadius={100}
fontSize={R.fontsize.fontSizeContent}
textColor={R.colors.white}
/>
</View>
</ScrollView>
</View>
</View>
</Modal>
);
};
export default AddMonitoringModal;
...@@ -15,19 +15,26 @@ import Dropdown from '../../components/DropdownAlert/Dropdown'; ...@@ -15,19 +15,26 @@ import Dropdown from '../../components/DropdownAlert/Dropdown';
import R from '../../assets/R'; import R from '../../assets/R';
import TabViewComponent from '../../components/TabView'; import TabViewComponent from '../../components/TabView';
import AddWorkModal from './modal_add_deliver_to_me/index'; import AddWorkModal from './modal_add_deliver_to_me/index';
import AddMonitoringModal from './modal_add_monitoring/index';
import Button from '../../components/Button'; import Button from '../../components/Button';
import {ROLE} from '../../actions/actionTypes';
const ListWorkView = props => { const ListWorkView = props => {
const { const {
searchQuery, searchQuery,
setSearchQuery, setSearchQuery,
dataList, dataList,
modalVisible, modalDeliverToMeVisible,
modalMonitoringVisible,
tabView, tabView,
currentTabKey,
shouldShowFAB,
onFilterChange, onFilterChange,
onAddWork, onAddWork,
onSaveWork, onSaveDeliverToMeWork,
onCloseModal, onSaveMonitoringWork,
onCloseDeliverToMeModal,
onCloseMonitoringModal,
onViewDetailDeliverToMe, onViewDetailDeliverToMe,
onReportAction, onReportAction,
onApprovalAction, onApprovalAction,
...@@ -179,19 +186,28 @@ const ListWorkView = props => { ...@@ -179,19 +186,28 @@ const ListWorkView = props => {
/> />
</View> </View>
</View> </View>
{shouldShowFAB && (
<FAB> <FAB>
<SubButton <SubButton
onPress={onAddWork} onPress={onAddWork}
label="Tạo công việc" label={currentTabKey === ROLE.ASSIGNEE ? "Tạo công việc" : "Tạo giám sát"}
images={R.images.icMenuEdit} images={R.images.icMenuEdit}
backgroundColor={R.colors.blue} backgroundColor={R.colors.blue}
/> />
</FAB> </FAB>
)}
<AddWorkModal <AddWorkModal
visible={modalVisible} visible={modalDeliverToMeVisible}
onClose={onCloseModal} onClose={onCloseDeliverToMeModal}
onSave={onSaveWork} onSave={onSaveDeliverToMeWork}
/>
<AddMonitoringModal
visible={modalMonitoringVisible}
onClose={onCloseMonitoringModal}
onSave={onSaveMonitoringWork}
/> />
</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