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';
const ListWork = props => {
const navigation = useNavigation();
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 [currentDropDownKey, setCurrentDropDownKey] = useState(
WORK_PROGRESS.ALL_WORK_PROGRESS,
......@@ -257,19 +258,35 @@ const ListWork = props => {
// Mở modal thêm công việc mới
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
const handleCloseModal = () => {
setModalVisible(false);
// Đóng modal "Đang giám sát"
const handleCloseMonitoringModal = () => {
setModalMonitoringVisible(false);
};
// Xử lý lưu công việc mới
const handleSaveWork = workData => {
console.log('Đang lưu công việc:', workData);
// TODO: Thêm logic lưu công việc vào database
setModalVisible(false);
// Xử lý lưu công việc "Giao cho tôi"
const handleSaveDeliverToMeWork = 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 giao cho tôi vào database
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 ====================
......@@ -469,6 +486,11 @@ const ListWork = props => {
{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 ====================
return (
......@@ -477,13 +499,18 @@ const ListWork = props => {
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
dataList={filterList}
modalVisible={modalVisible}
modalDeliverToMeVisible={modalDeliverToMeVisible}
modalMonitoringVisible={modalMonitoringVisible}
tabView={tabView}
currentTabKey={currentTabKey}
shouldShowFAB={shouldShowFAB()}
// Sự kiện
onFilterChange={handleFilterChange}
onAddWork={handleAddWork}
onSaveWork={handleSaveWork}
onCloseModal={handleCloseModal}
onSaveDeliverToMeWork={handleSaveDeliverToMeWork}
onSaveMonitoringWork={handleSaveMonitoringWork}
onCloseDeliverToMeModal={handleCloseDeliverToMeModal}
onCloseMonitoringModal={handleCloseMonitoringModal}
onViewDetailDeliverToMe={handleViewDetailDeliverToMe}
onReportAction={handleReportAction}
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';
import R from '../../assets/R';
import TabViewComponent from '../../components/TabView';
import AddWorkModal from './modal_add_deliver_to_me/index';
import AddMonitoringModal from './modal_add_monitoring/index';
import Button from '../../components/Button';
import {ROLE} from '../../actions/actionTypes';
const ListWorkView = props => {
const {
searchQuery,
setSearchQuery,
dataList,
modalVisible,
modalDeliverToMeVisible,
modalMonitoringVisible,
tabView,
currentTabKey,
shouldShowFAB,
onFilterChange,
onAddWork,
onSaveWork,
onCloseModal,
onSaveDeliverToMeWork,
onSaveMonitoringWork,
onCloseDeliverToMeModal,
onCloseMonitoringModal,
onViewDetailDeliverToMe,
onReportAction,
onApprovalAction,
......@@ -179,19 +186,28 @@ const ListWorkView = props => {
/>
</View>
</View>
<FAB>
<SubButton
onPress={onAddWork}
label="Tạo công việc"
images={R.images.icMenuEdit}
backgroundColor={R.colors.blue}
/>
</FAB>
{shouldShowFAB && (
<FAB>
<SubButton
onPress={onAddWork}
label={currentTabKey === ROLE.ASSIGNEE ? "Tạo công việc" : "Tạo giám sát"}
images={R.images.icMenuEdit}
backgroundColor={R.colors.blue}
/>
</FAB>
)}
<AddWorkModal
visible={modalVisible}
onClose={onCloseModal}
onSave={onSaveWork}
visible={modalDeliverToMeVisible}
onClose={onCloseDeliverToMeModal}
onSave={onSaveDeliverToMeWork}
/>
<AddMonitoringModal
visible={modalMonitoringVisible}
onClose={onCloseMonitoringModal}
onSave={onSaveMonitoringWork}
/>
</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