task status
This commit is contained in:
parent
12af640bae
commit
ec339c48ba
78
lib/models/task_model.dart
Normal file
78
lib/models/task_model.dart
Normal file
@ -0,0 +1,78 @@
|
||||
class TaskModel {
|
||||
final String id;
|
||||
final String taskId;
|
||||
final String task;
|
||||
final String? note;
|
||||
final String taskStatus;
|
||||
final String? taskPriority;
|
||||
final DateTime taskDueDate;
|
||||
final TaskAssignedTo taskAssignedTo;
|
||||
final String? taskAssignedBy;
|
||||
final String? addedFor;
|
||||
final String? addedForId;
|
||||
final String? tradename;
|
||||
final DateTime? createdAt;
|
||||
final DateTime? updatedAt;
|
||||
final int? version;
|
||||
|
||||
TaskModel({
|
||||
required this.id,
|
||||
required this.taskId,
|
||||
required this.task,
|
||||
this.note,
|
||||
required this.taskStatus,
|
||||
this.taskPriority,
|
||||
required this.taskDueDate,
|
||||
required this.taskAssignedTo,
|
||||
this.taskAssignedBy,
|
||||
this.addedFor,
|
||||
this.addedForId,
|
||||
this.tradename,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.version,
|
||||
});
|
||||
|
||||
factory TaskModel.fromJson(Map<String, dynamic> json) {
|
||||
return TaskModel(
|
||||
id: json['_id'],
|
||||
taskId: json['taskId'],
|
||||
task: json['task'],
|
||||
note: json['note'],
|
||||
taskStatus: json['taskStatus'],
|
||||
taskPriority: json['taskPriority'],
|
||||
taskDueDate: DateTime.parse(json['taskDueDate']),
|
||||
taskAssignedTo: TaskAssignedTo.fromJson(json['taskAssignedTo']),
|
||||
taskAssignedBy: json['taskAssignedBy'],
|
||||
addedFor: json['addedFor'],
|
||||
addedForId: json['addedForId'],
|
||||
tradename: json['tradename'],
|
||||
createdAt: DateTime.parse(json['createdAt']),
|
||||
updatedAt: DateTime.parse(json['updatedAt']),
|
||||
version: json['__v'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TaskAssignedTo {
|
||||
final String id;
|
||||
final String name;
|
||||
final String mobileNumber;
|
||||
final String email;
|
||||
|
||||
TaskAssignedTo({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.mobileNumber,
|
||||
required this.email,
|
||||
});
|
||||
|
||||
factory TaskAssignedTo.fromJson(Map<String, dynamic> json) {
|
||||
return TaskAssignedTo(
|
||||
id: json['_id'],
|
||||
name: json['name'],
|
||||
mobileNumber: json['mobileNumber'],
|
||||
email: json['email'],
|
||||
);
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import 'package:cheminova/models/pd_rd_response_model.dart';
|
||||
import 'package:cheminova/models/task_model.dart';
|
||||
import 'package:cheminova/screens/data_submit_successfull.dart';
|
||||
import 'package:cheminova/services/api_client.dart';
|
||||
import 'package:cheminova/services/api_urls.dart';
|
||||
@ -15,6 +16,7 @@ class TaskProvider extends ChangeNotifier {
|
||||
List<PdRdResponseModel> _salesCoordinators = [];
|
||||
List<PdRdResponseModel> _pdList = [];
|
||||
List<PdRdResponseModel> _rdList = [];
|
||||
List<TaskModel> _taskModelList = [];
|
||||
PdRdResponseModel? _selectedDistributor;
|
||||
final TextEditingController _noteController = TextEditingController();
|
||||
final _apiClient = ApiClient();
|
||||
@ -28,6 +30,7 @@ class TaskProvider extends ChangeNotifier {
|
||||
TextEditingController get noteController => _noteController;
|
||||
List<PdRdResponseModel> get pdList => _pdList;
|
||||
List<PdRdResponseModel> get rdList => _rdList;
|
||||
List<TaskModel> get taskModelList => _taskModelList;
|
||||
PdRdResponseModel? get selectedDistributor => _selectedDistributor;
|
||||
|
||||
void setLoading(bool loading) {
|
||||
@ -61,6 +64,7 @@ class TaskProvider extends ChangeNotifier {
|
||||
_selectedPriority = null;
|
||||
_selectedDate = DateFormat('dd/MM/yyyy').format(DateTime.now());
|
||||
_noteController.clear();
|
||||
_taskModelList.clear();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@ -187,4 +191,59 @@ class TaskProvider extends ChangeNotifier {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getNewTasks() async {
|
||||
setLoading(true);
|
||||
clearLists();
|
||||
try {
|
||||
Response response = await _apiClient.get("${ApiUrls.getAllTasks}New");
|
||||
if (response.statusCode == 200) {
|
||||
List<TaskModel> data = (response.data['tasks'] as List)
|
||||
.map((json) => TaskModel.fromJson(json))
|
||||
.toList();
|
||||
_taskModelList = data;
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error occurred: $e");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getPendingTasks() async {
|
||||
setLoading(true);
|
||||
clearLists();
|
||||
try {
|
||||
Response response = await _apiClient.get("${ApiUrls.getAllTasks}Pending");
|
||||
if (response.statusCode == 200) {
|
||||
List<TaskModel> data = (response.data['tasks'] as List)
|
||||
.map((json) => TaskModel.fromJson(json))
|
||||
.toList();
|
||||
_taskModelList = data;
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error occurred: $e");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getCompletedTasks() async {
|
||||
setLoading(true);
|
||||
clearLists();
|
||||
try {
|
||||
Response response =
|
||||
await _apiClient.get("${ApiUrls.getAllTasks}Completed");
|
||||
if (response.statusCode == 200) {
|
||||
List<TaskModel> data = (response.data['tasks'] as List)
|
||||
.map((json) => TaskModel.fromJson(json))
|
||||
.toList();
|
||||
_taskModelList = data;
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error occurred: $e");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,12 @@
|
||||
import 'package:cheminova/models/task_model.dart';
|
||||
import 'package:cheminova/provider/task_provider.dart';
|
||||
import 'package:cheminova/widgets/common_app_bar.dart';
|
||||
import 'package:cheminova/widgets/common_background.dart';
|
||||
import 'package:cheminova/widgets/common_drawer.dart';
|
||||
import 'package:cheminova/widgets/common_text_form_field.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class TaskManagementScreen extends StatefulWidget {
|
||||
const TaskManagementScreen({super.key});
|
||||
@ -13,43 +17,45 @@ class TaskManagementScreen extends StatefulWidget {
|
||||
|
||||
class _TaskManagementScreenState extends State<TaskManagementScreen> {
|
||||
final TextEditingController _searchController = TextEditingController();
|
||||
final List<String> _taskList = [
|
||||
'Task 1',
|
||||
'Task 2',
|
||||
'Task 3',
|
||||
'Task 4',
|
||||
'Task 5',
|
||||
'Task 6',
|
||||
'Task 7',
|
||||
'Task 8',
|
||||
'Task 9',
|
||||
'Task 10',
|
||||
];
|
||||
|
||||
final List<String> _filters = [
|
||||
'All',
|
||||
'Pending',
|
||||
'Completed',
|
||||
];
|
||||
|
||||
List<String> _filteredTaskList = [];
|
||||
List<TaskModel> _filteredTaskList = [];
|
||||
String? _selectedChip; // State to track the selected chip
|
||||
|
||||
void _filterTaskList(String query) {
|
||||
if (query.isEmpty || query == '' || query == ' ') {
|
||||
setState(() {
|
||||
_filteredTaskList = context.read<TaskProvider>().taskModelList;
|
||||
});
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
_filteredTaskList = _taskList
|
||||
.where((task) => task.toLowerCase().contains(query.toLowerCase()))
|
||||
_filteredTaskList = _filteredTaskList
|
||||
.where((task) => task.taskAssignedTo.name
|
||||
.toLowerCase()
|
||||
.contains(query.toLowerCase()))
|
||||
.toList();
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _updateTaskProvider() async {
|
||||
final provider = context.read<TaskProvider>();
|
||||
provider.clear();
|
||||
await provider.getNewTasks();
|
||||
_filteredTaskList.clear();
|
||||
_filteredTaskList = provider.taskModelList;
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_filteredTaskList = _taskList;
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_updateTaskProvider();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final taskProvider = context.watch<TaskProvider>();
|
||||
|
||||
return Scaffold(
|
||||
extendBodyBehindAppBar: true,
|
||||
appBar: CommonAppBar(
|
||||
@ -73,112 +79,110 @@ class _TaskManagementScreenState extends State<TaskManagementScreen> {
|
||||
),
|
||||
drawer: const CommonDrawer(),
|
||||
body: CommonBackground(
|
||||
child: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
child: Container(
|
||||
padding:
|
||||
const EdgeInsets.all(20.0).copyWith(top: 15, bottom: 30),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 30.0)
|
||||
.copyWith(bottom: 50),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.white),
|
||||
color: const Color(0xffB4D1E5).withOpacity(0.5),
|
||||
borderRadius: BorderRadius.circular(26.0),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
CommonTextFormField(
|
||||
controller: _searchController,
|
||||
onChanged: (value) => _filterTaskList(value),
|
||||
title: 'Filter by Sales Coordinator:',
|
||||
child: Stack(
|
||||
children: [
|
||||
SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(20.0)
|
||||
.copyWith(top: 15, bottom: 30),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 30.0)
|
||||
.copyWith(bottom: 50),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.white),
|
||||
color: const Color(0xffB4D1E5).withOpacity(0.5),
|
||||
borderRadius: BorderRadius.circular(26.0),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
_filterChip(
|
||||
title: 'All',
|
||||
icon: const Icon(Icons.all_inclusive),
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
_filterChip(
|
||||
title: 'Pending',
|
||||
icon: const Icon(Icons.pending),
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
_filterChip(
|
||||
title: 'Completed',
|
||||
icon: const Icon(Icons.done),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Text(
|
||||
'Tasks:',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: 'Anek',
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.55,
|
||||
child: ListView.builder(
|
||||
itemCount: _filteredTaskList.length,
|
||||
itemBuilder: (context, index) => _taskView(
|
||||
title: _filteredTaskList[index],
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
CommonTextFormField(
|
||||
controller: _searchController,
|
||||
onChanged: (value) => _filterTaskList(value),
|
||||
title: 'Filter by Sales Coordinator:',
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
_filterChip(
|
||||
title: 'New',
|
||||
icon: const Icon(Icons.new_releases),
|
||||
onSelected: () async {
|
||||
setState(() {
|
||||
_selectedChip = 'New';
|
||||
});
|
||||
await taskProvider.getNewTasks();
|
||||
_filteredTaskList.clear();
|
||||
_filteredTaskList =
|
||||
taskProvider.taskModelList;
|
||||
},
|
||||
isSelected: _selectedChip == 'New',
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
_filterChip(
|
||||
title: 'Pending',
|
||||
icon: const Icon(Icons.pending),
|
||||
onSelected: () async {
|
||||
setState(() {
|
||||
_selectedChip = 'Pending';
|
||||
});
|
||||
await taskProvider.getPendingTasks();
|
||||
_filteredTaskList.clear();
|
||||
_filteredTaskList =
|
||||
taskProvider.taskModelList;
|
||||
},
|
||||
isSelected: _selectedChip == 'Pending',
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
_filterChip(
|
||||
title: 'Completed',
|
||||
icon: const Icon(Icons.done),
|
||||
onSelected: () async {
|
||||
setState(() {
|
||||
_selectedChip = 'Completed';
|
||||
});
|
||||
await taskProvider.getCompletedTasks();
|
||||
_filteredTaskList.clear();
|
||||
_filteredTaskList =
|
||||
taskProvider.taskModelList;
|
||||
},
|
||||
isSelected: _selectedChip == 'Completed',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.55,
|
||||
child: _filteredTaskList.isEmpty
|
||||
? const Center(child: Text('No tasks found'))
|
||||
: ListView.builder(
|
||||
itemCount: _filteredTaskList.length,
|
||||
itemBuilder: (context, index) => _taskView(
|
||||
task: _filteredTaskList[index],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// CommonElevatedButton(
|
||||
// backgroundColor: const Color(0xff004791),
|
||||
// borderRadius: 30,
|
||||
// width: double.infinity,
|
||||
// height: kToolbarHeight - 10,
|
||||
// text: 'EDIT',
|
||||
// onPressed: () => Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) => const AssignTasksScreen(),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(height: 20),
|
||||
// CommonElevatedButton(
|
||||
// backgroundColor: const Color(0xff00784C),
|
||||
// borderRadius: 30,
|
||||
// width: double.infinity,
|
||||
// height: kToolbarHeight - 10,
|
||||
// text: 'REASSIGN',
|
||||
// onPressed: () => Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) =>
|
||||
// const SelectSalesCoordinatorScreen(),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(height: 20),
|
||||
// CommonElevatedButton(
|
||||
// backgroundColor: const Color(0xff00784C),
|
||||
// borderRadius: 30,
|
||||
// width: double.infinity,
|
||||
// height: kToolbarHeight - 10,
|
||||
// text: 'MARK AS COMPLETED',
|
||||
// onPressed: () {},
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (taskProvider.isLoading)
|
||||
Container(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
child: const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -188,7 +192,6 @@ class _TaskManagementScreenState extends State<TaskManagementScreen> {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
// margin: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.white),
|
||||
color: const Color(0xffB4D1E5).withOpacity(0.6),
|
||||
@ -198,37 +201,39 @@ class _TaskManagementScreenState extends State<TaskManagementScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _taskView({required String title}) {
|
||||
Widget _taskView({required TaskModel task}) {
|
||||
final formatedDate = DateFormat('dd/MM/yyyy').format(task.taskDueDate);
|
||||
return Column(
|
||||
children: [
|
||||
_customContainer(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Sales Coordinator: 1',
|
||||
style: TextStyle(
|
||||
Text(
|
||||
"Assigned to: ${task.taskAssignedTo.name}",
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Anek',
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
title,
|
||||
"Task: ${task.task}",
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Anek',
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
const Text(
|
||||
'Status: Pending',
|
||||
style: TextStyle(
|
||||
Text(
|
||||
'Status: ${task.taskStatus}',
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Anek',
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
const Text(
|
||||
'Deadline: 12/12/2024',
|
||||
style: TextStyle(
|
||||
Text(
|
||||
'Deadline:$formatedDate',
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Anek',
|
||||
),
|
||||
),
|
||||
@ -240,14 +245,23 @@ class _TaskManagementScreenState extends State<TaskManagementScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _filterChip({required String title, required Widget icon}) {
|
||||
return Chip(
|
||||
avatar: icon,
|
||||
label: Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Anek',
|
||||
Widget _filterChip({
|
||||
required String title,
|
||||
required Widget icon,
|
||||
required VoidCallback onSelected,
|
||||
required bool isSelected,
|
||||
}) {
|
||||
return GestureDetector(
|
||||
onTap: onSelected,
|
||||
child: Chip(
|
||||
avatar: icon,
|
||||
label: Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Anek',
|
||||
),
|
||||
),
|
||||
backgroundColor: isSelected ? Colors.blue : Colors.grey[200],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -18,4 +18,5 @@ class ApiUrls {
|
||||
static const String getSalesCoordinators = 'salescoordinator/getAll-TM';
|
||||
static const String assignTask = 'task/assign-task';
|
||||
static const String getProductsManual = 'productmanual/getall';
|
||||
static const String getAllTasks = 'task/alltasks/';
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user