Commit 9ce41d07 by tungnq

TODO: Đã bổ sung thêm logic để lọc công việc theo role và status

parent fb8e80c7
......@@ -33,3 +33,35 @@ export const ADD_PRODUCT = "ADD_PRODUCT";
export const REMOVE_PRODUCT = "REMOVE_PRODUCT";
export const CLEAR_CART = "CLEAR_CART";
//ACTION CÔNG VIỆC VAI TRÒ
export const ROLE = {
ALL : 'ALL',
ASSIGNEE : 'ASSIGNEE', //Giao cho tôi (Giảng viên nhận công việc)
SUPERVISOR : 'SUPERVISOR' //Đang giám sát (Giảng viên giám sát)
}
//ACTION TRẠNG THÁI THEO VAI TRÒ
export const STATUS_BY_ROLE ={
[ROLE.ASSIGNEE]: [
'Đang thực hiện',
'Cần chỉnh sửa',
'Chờ duyệt',
'Đợi báo cáo',
'Đã hoàn thành'
],
[ROLE.SUPERVISOR]:[
'Đang thực hiện',
'Đợi chỉnh sửa',
'Chờ duyệt',
'Đợi báo cáo',
'Đã hoàn thành'
]
}
//ACTION TIẾN ĐỘ CÔNG VIỆC
export const WORK_PROGRESS = {
ALL_WORK_PROGRESS: 'ALL_WORK_PROGRESS',
SUCCESS_WORK_PROGRESS: 'SUCCESS_WORK_PROGRESS',
CONTINUE_WORK_PROGRESS: 'CONTINUE_WORK_PROGRESS',
}
\ No newline at end of file
import React, {useState} from 'react';
import React, {useState, useMemo} from 'react';
import {useNavigation} from '@react-navigation/native';
import ListWorkView from './view';
import * as ScreenName from '../../routers/ScreenNames';
import {WORK_PROGRESS, ROLE} from '../../actions/actionTypes';
import R from '../../assets/R';
/**
* Container component quản lý logic nghiệp vụ cho màn hình danh sách công việc
* Chứa tất cả state và business logic, truyền xuống view component thông qua props
*/
const ListWork = props => {
const {searchQuery, setSearchQuery} = props;
const navigation = useNavigation();
// ==================== STATE MANAGEMENT ====================
// Trạng thái hiển thị modal thêm công việc
const [searchQuery, setSearchQuery] = useState('');
const [modalVisible, setModalVisible] = useState(false);
const [currentTabKey, setCurrentTabKey] = useState(ROLE.ALL);
const [currentDropDownKey, setCurrentDropDownKey] = useState(
WORK_PROGRESS.ALL_WORK_PROGRESS,
);
// Danh sách công việc mẫu với các trạng thái khác nhau
const [dataList, setDataList] = useState([
{
id: 1,
title: 'Tạo thời khóa biểu cho sinh viến khai giảng và học kỳ 2 năm 2025',
status: 'Đang thực hiện',
title: 'Tạo thời khóa biểu cho sinh viên khai giảng và học kỳ 2 năm 2025',
status: 'Đang thực hiện', // hợp lệ cho cả 2 role
deadline: '2025-09-04',
assignedToMe: true,
supervisedByMe: false,
supervisor: [
{id: 1, name: 'Trần Văn Hùng'},
{id: 2, name: 'Nguyễn Văn A'},
],
document: 'BM255, Nguyễn Minh Đức',
workProgress: 'Đang thực hiện',
},
{
id: 2,
title: 'Tạo thời khóa biểu cho sinh viến khai giảng và học kỳ 2 năm 2025',
status: 'Cần chỉnh sửa',
title: 'Tạo thời khóa biểu cho sinh viên khai giảng và học kỳ 2 năm 2025',
status: 'Cần chỉnh sửa', // chỉ hợp lệ với role Giao cho tôi
deadline: '2025-09-04',
assignedToMe: true,
supervisedByMe: false,
supervisor: [
{id: 1, name: 'Trần Văn Hùng'},
{id: 2, name: 'Nguyễn Văn A'},
],
document: 'BM255, Nguyễn Minh Đức',
workProgress: 'Đang hoàn thành',
},
{
id: 3,
title: 'Tạo thời khóa biểu cho sinh viến khai giảng và học kỳ 2 năm 2025',
status: 'Chờ duyệt',
title: 'Tạo thời khóa biểu cho sinh viên khai giảng và học kỳ 2 năm 2025',
status: 'Hoàn thành', // hợp lệ cho cả 2 role
deadline: '2025-09-04',
assignedToMe: true,
supervisedByMe: false,
supervisor: [
{id: 1, name: 'Trần Văn Hùng'},
{id: 2, name: 'Nguyễn Văn A'},
],
document: 'BM255, Nguyễn Minh Đức',
workProgress: 'Đang hoàn thành',
},
{
id: 4,
title: 'Tạo thời khóa biểu cho sinh viên khai giảng và học kỳ 2 năm 2025',
status: 'Đợi báo cáo',
status: 'Đợi báo cáo', // chỉ hợp lệ với role Đang giám sát
deadline: '2025-09-04',
assignedToMe: false,
supervisedByMe: true,
supervisor: [
{id: 1, name: 'Trần Văn Hùng'},
{id: 2, name: 'Nguyễn Văn A'},
],
document: 'BM255, Nguyễn Minh Đức',
workProgress: 'Đang hoàn thành',
},
{
id: 5,
title: 'Tạo thời khóa biểu cho sinh viến khai giảng và học kỳ 2 năm 2025',
status: 'Đã hoàn thành',
title: 'Tạo thời khóa biểu cho sinh viên khai giảng và học kỳ 2 năm 2025',
status: 'Hoàn thành',
deadline: '2025-09-04',
assignedToMe: false,
supervisedByMe: true,
supervisor: [
{id: 1, name: 'Trần Văn Hùng'},
{id: 2, name: 'Nguyễn Văn A'},
],
document:
'Văn bản thông báo lịch nộp thời khóa biểu của học kỳ 2 năm 2025',
workProgress: 'Đang thực hiện',
},
]);
......@@ -99,9 +111,43 @@ const ListWork = props => {
// Xử lý thay đổi bộ lọc tab
const handleFilterChange = item => {
console.log('Bộ lọc đã thay đổi:', item);
// TODO: Thêm logic lọc danh sách theo tab được chọn
setCurrentTabKey(item?.key || ROLE.ALL);
console.log('Tab changed to:', item?.key);
};
// Hiển thị dữ liệu sau khi chọn
const filterList = useMemo(() => {
let base = dataList;
console.log('Dữ liệu danh sách đầu vào', base);
// Lọc theo tab role
if (currentTabKey === ROLE.ASSIGNEE) {
base = base.filter(x => x.assignedToMe);
} else if (currentTabKey === ROLE.SUPERVISOR) {
base = base.filter(x => x.supervisedByMe);
}
// ROLE.ALL không cần filter
// Lọc theo search query
if (searchQuery && searchQuery.trim()) {
const q = searchQuery.trim().toLowerCase();
base = base.filter(
x =>
x.title.toLowerCase().includes(q) ||
x.status.toLowerCase().includes(q),
);
}
// Lọc theo dropdown progress (chỉ khi không phải ALL)
if (currentDropDownKey === WORK_PROGRESS.SUCCESS_WORK_PROGRESS) {
base = base.filter(x => x.status === 'Đã hoàn thành');
} else if (currentDropDownKey === WORK_PROGRESS.CONTINUE_WORK_PROGRESS) {
base = base.filter(x => x.status !== 'Đã hoàn thành');
}
// WORK_PROGRESS.ALL_WORK_PROGRESS không cần filter
console.log('Dữ liệu sau khi lọc:', base);
return base;
}, [dataList, currentTabKey, searchQuery, currentDropDownKey]);
// ==================== NAVIGATION HANDLERS ====================
......@@ -151,8 +197,10 @@ const ListWork = props => {
case 'Chờ duyệt':
return '#007AFF'; // Xanh dương
case 'Cần chỉnh sửa':
return '#FF9500'; // Cam
case 'Đã hoàn thành':
return '#FF9500'; // Cam (assignee)
case 'Đợi chỉnh sửa':
return '#FF9500'; // Cam (supervisor)
case 'Hoàn thành':
return '#34C759'; // Xanh lá
case 'Đợi báo cáo':
return '#007AFF'; // Xanh dương
......@@ -163,66 +211,84 @@ const ListWork = props => {
// Lấy danh sách button theo trạng thái công việc
const getButtonsForStatus = status => {
// Ẩn button cho các trạng thái: hoàn thành, cần chỉnh sửa, đợi báo cáo
if (['Đã hoàn thành', 'Cần chỉnh sửa', 'Đợi báo cáo'].includes(status)) {
return [];
// Đang giám sát
if (currentTabKey === ROLE.SUPERVISOR) {
switch (status) {
case 'Đang thực hiện':
return [
{title: 'Yêu cầu báo cáo', backgroundColor: R.colors.orange, action: 'requestReport'},
{title: 'Chi tiết', backgroundColor: R.colors.blue, action: 'detail'},
];
case 'Đợi chỉnh sửa':
return [{title: 'Chi tiết', backgroundColor: R.colors.blue, action: 'detail'}];
case 'Chờ duyệt':
return [
{title: 'Cần chỉnh sửa', backgroundColor: R.colors.orange, action: 'needsEdit'},
{title: 'Phê duyệt', backgroundColor: R.colors.blue, action: 'approve'},
{title: 'Chi tiết', backgroundColor: R.colors.blue, action: 'detail'},
];
case 'Đợi báo cáo':
return [{title: 'Chi tiết', backgroundColor: R.colors.blue, action: 'detail'}];
case 'Đã hoàn thành':
return [{title: 'Chi tiết', backgroundColor: R.colors.blue, action: 'detail'}];
default:
return [];
}
}
// Trường hợp đặc biệt cho "Chờ duyệt" - hiển thị 2 button
if (status === 'Chờ duyệt') {
return [
{
title: 'Cần chỉnh sửa',
backgroundColor: '#FF9500',
action: 'needsEdit',
},
{
title: 'Phê duyệt',
backgroundColor: '#007AFF',
action: 'approve',
},
];
// Giao cho tôi
if (currentTabKey === ROLE.ASSIGNEE) {
switch (status) {
case 'Đang thực hiện':
case 'Cần chỉnh sửa':
case 'Đợi báo cáo':
return [
{title: 'Báo cáo', backgroundColor: R.colors.orange, action: 'report'},
{title: 'Chi tiết', backgroundColor: R.colors.blue, action: 'detail'},
];
case 'Chờ duyệt':
return [
{title: 'Sửa báo cáo', backgroundColor: R.colors.orange, action: 'editReport'},
{title: 'Chi tiết', backgroundColor: R.colors.blue, action: 'detail'},
];
case 'Hoàn thành':
return [{title: 'Chi tiết', backgroundColor: R.colors.blue, action: 'detail'}];
default:
return [];
}
}
// Button mặc định cho các trạng thái khác
const buttonTitle =
status === 'Đang thực hiện' ? 'Yêu cầu báo cáo' : 'Báo cáo';
return [
{
title: buttonTitle,
backgroundColor: '#FF9500',
action: 'report',
},
];
// Tất cả - hiển thị tất cả buttons có thể
return [{title: 'Chi tiết', backgroundColor: R.colors.blue, action: 'detail'}];
};
const [tabView, setTabView] = useState([
{key: 'all', label: 'Tất cả'},
{key: 'public', label: 'Giao cho tôi'},
{key: 'private', label: 'Đang giám sát'},
{key: ROLE.ALL, label: 'Tất cả'},
{key: ROLE.ASSIGNEE, label: 'Giao cho tôi'},
{key: ROLE.SUPERVISOR, label: 'Đang giám sát'},
]);
// ==================== RENDER ====================
return (
<ListWorkView
// Props dữ liệu
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
dataList={dataList}
modalVisible={modalVisible}
// Props xử lý sự kiện
onFilterChange={handleFilterChange}
onAddWork={handleAddWork}
onSaveWork={handleSaveWork}
onCloseModal={handleCloseModal}
onViewDetail={handleViewDetail}
onReportAction={handleReportAction}
onApprovalAction={handleApprovalAction}
tabView={tabView}
// Props utility functions
getStatusColor={getStatusColor}
getButtonsForStatus={getButtonsForStatus}
// Dữ liệu
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
dataList={filterList}
modalVisible={modalVisible}
tabView={tabView}
// Sự kiện
onFilterChange={handleFilterChange}
onAddWork={handleAddWork}
onSaveWork={handleSaveWork}
onCloseModal={handleCloseModal}
onViewDetail={handleViewDetail}
onReportAction={handleReportAction}
onApprovalAction={handleApprovalAction}
// Utils
getStatusColor={getStatusColor}
getButtonsForStatus={getButtonsForStatus}
/>
);
};
......
......@@ -3,10 +3,8 @@ import {
Modal,
View,
Text,
TextInput,
TouchableOpacity,
ScrollView,
StyleSheet,
Image,
FlatList,
} from 'react-native';
......
......@@ -37,6 +37,26 @@ const styles = StyleSheet.create({
justifyContent: 'center',
borderColor: R.colors.grayBorderInputTextHeader,
},
container_tab_view:{
marginVertical:5
},
item_tab_view:{
backgroundColor: R.colors.gray,
marginHorizontal: 5,
borderRadius: 10,
width: 107,
justifyContent: 'center',
alignItems: 'center',
},
active_tab_view:{
backgroundColor: R.colors.blue,
},
text_tab_view:{
color: R.colors.white,
fontWeight: '400',
fontFamily: R.fonts.fontRegular,
fontSize: R.fontsize.fontSizeContent,
},
text: {
fontSize: R.sizes.sm,
color: R.colors.black,
......
......@@ -23,6 +23,7 @@ const ListWorkView = props => {
setSearchQuery,
dataList,
modalVisible,
tabView,
onFilterChange,
onAddWork,
onSaveWork,
......@@ -31,37 +32,20 @@ const ListWorkView = props => {
onReportAction,
onApprovalAction,
getStatusColor,
getButtonsForStatus,
tabView,
getButtonsForStatus
} = props;
const renderTabView = () => {
return (
<TabViewComponent
data={tabView}
tabStyle={{
backgroundColor: R.colors.gray,
marginHorizontal: 5,
borderRadius: 10,
width: 107,
justifyContent: 'center',
alignItems: 'center',
}}
style={{
marginVertical: 5,
}}
tabStyle={styles.item_tab_view}
style={styles.container_tab_view}
mode="filter"
defaultActiveKey="all"
scrollable={true}
activeTabStyle={{
backgroundColor: R.colors.blue,
}}
textStyle={{
color: R.colors.white,
fontWeight: '400',
fontFamily: R.fonts.fontRegular,
fontSize: R.fontsize.fontSizeContent,
}}
activeTabStyle={styles.active_tab_view}
textStyle={styles.text_tab_view}
showActiveIndicator={false}
onFilterChange={onFilterChange}
/>
......@@ -69,6 +53,7 @@ const ListWorkView = props => {
};
const renderActionButtons = item => {
const buttons = getButtonsForStatus(item.status);
return buttons.map((button, index) => (
......
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