- Added TaskListModel for managing daily tasks with JSON parsing. - Introduced WorkStatusResponseModel and WorkStatus for handling work status data. - Created MenuResponse and MenuItem models for dynamic menu management. - Updated routes to reflect correct naming conventions for task planning screens. - Enhanced DashboardScreen to include dynamic menu functionality and improved task statistics display. - Developed DailyProgressReportScreen for displaying daily progress reports with filtering options. - Implemented DailyTaskPlanningScreen for planning daily tasks with detailed views and actions. - Refactored left navigation bar to align with updated task planning routes.
211 lines
7.2 KiB
Dart
211 lines
7.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:marco/model/dailyTaskPlanning/comment_task_bottom_sheet.dart';
|
|
import 'package:marco/model/dailyTaskPlanning/report_task_bottom_sheet.dart';
|
|
import 'package:marco/model/dailyTaskPlanning/report_action_bottom_sheet.dart';
|
|
|
|
class TaskActionButtons {
|
|
static Widget reportButton({
|
|
required BuildContext context,
|
|
required dynamic task,
|
|
required int completed,
|
|
required VoidCallback refreshCallback,
|
|
}) {
|
|
return OutlinedButton.icon(
|
|
icon: const Icon(Icons.report, size: 18, color: Colors.blueAccent),
|
|
label: const Text('Report', style: TextStyle(color: Colors.blueAccent)),
|
|
style: OutlinedButton.styleFrom(
|
|
side: const BorderSide(color: Colors.blueAccent),
|
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
|
textStyle: const TextStyle(fontSize: 14),
|
|
),
|
|
onPressed: () {
|
|
final activityName =
|
|
task.workItem?.activityMaster?.activityName ?? 'N/A';
|
|
final assigned = '${(task.plannedTask - completed)}';
|
|
final assignedBy =
|
|
"${task.assignedBy.firstName} ${task.assignedBy.lastName ?? ''}";
|
|
final assignedOn = DateFormat('dd-MM-yyyy').format(task.assignmentDate);
|
|
final taskId = task.id;
|
|
final location = [
|
|
task.workItem?.workArea?.floor?.building?.name,
|
|
task.workItem?.workArea?.floor?.floorName,
|
|
task.workItem?.workArea?.areaName,
|
|
].where((e) => e != null && e.isNotEmpty).join(' > ');
|
|
|
|
final teamMembers = task.teamMembers.map((e) => e.firstName).toList();
|
|
final pendingWork = (task.workItem?.plannedWork ?? 0) -
|
|
(task.workItem?.completedWork ?? 0);
|
|
|
|
final taskData = {
|
|
'activity': activityName,
|
|
'assigned': assigned,
|
|
'taskId': taskId,
|
|
'assignedBy': assignedBy,
|
|
'completed': completed,
|
|
'assignedOn': assignedOn,
|
|
'location': location,
|
|
'teamSize': task.teamMembers.length,
|
|
'teamMembers': teamMembers,
|
|
'pendingWork': pendingWork,
|
|
};
|
|
|
|
showModalBottomSheet(
|
|
context: context,
|
|
isScrollControlled: true,
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
|
),
|
|
builder: (ctx) => Padding(
|
|
padding: MediaQuery.of(ctx).viewInsets,
|
|
child: ReportTaskBottomSheet(
|
|
taskData: taskData,
|
|
onReportSuccess: refreshCallback,
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
static Widget commentButton({
|
|
required BuildContext context,
|
|
required dynamic task,
|
|
required VoidCallback refreshCallback,
|
|
required String parentTaskID,
|
|
required String activityId,
|
|
required String workAreaId,
|
|
}) {
|
|
return OutlinedButton.icon(
|
|
icon: const Icon(Icons.comment, size: 18, color: Colors.blueAccent),
|
|
label: const Text('Comment', style: TextStyle(color: Colors.blueAccent)),
|
|
style: OutlinedButton.styleFrom(
|
|
side: const BorderSide(color: Colors.blueAccent),
|
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
|
textStyle: const TextStyle(fontSize: 14),
|
|
),
|
|
onPressed: () {
|
|
final taskData =
|
|
_prepareTaskData(task: task, completed: task.completedTask.toInt());
|
|
|
|
showModalBottomSheet(
|
|
context: context,
|
|
isScrollControlled: true,
|
|
backgroundColor: Colors.transparent,
|
|
builder: (_) => CommentTaskBottomSheet(
|
|
taskData: taskData,
|
|
taskDataId: parentTaskID,
|
|
workAreaId: workAreaId,
|
|
activityId: activityId,
|
|
onCommentSuccess: () {
|
|
refreshCallback();
|
|
Navigator.of(context).pop();
|
|
},
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
static Widget reportActionButton({
|
|
required BuildContext context,
|
|
required dynamic task,
|
|
required int completed,
|
|
required VoidCallback refreshCallback,
|
|
required String parentTaskID,
|
|
required String activityId,
|
|
required String workAreaId,
|
|
}) {
|
|
return OutlinedButton.icon(
|
|
icon: const Icon(Icons.report, size: 18, color: Colors.amber),
|
|
label: const Text('Take Report Action',
|
|
style: TextStyle(color: Colors.amber)),
|
|
style: OutlinedButton.styleFrom(
|
|
side: const BorderSide(color: Colors.amber),
|
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
|
textStyle: const TextStyle(fontSize: 14),
|
|
),
|
|
onPressed: () {
|
|
final taskData = _prepareTaskData(task: task, completed: completed);
|
|
|
|
showModalBottomSheet(
|
|
context: context,
|
|
isScrollControlled: true,
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
|
),
|
|
builder: (ctx) => Padding(
|
|
padding: MediaQuery.of(ctx).viewInsets,
|
|
child: ReportActionBottomSheet(
|
|
taskData: taskData,
|
|
taskDataId: parentTaskID,
|
|
workAreaId: workAreaId,
|
|
activityId: activityId,
|
|
onReportSuccess: refreshCallback,
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
static Map<String, dynamic> _prepareTaskData({
|
|
required dynamic task,
|
|
required int completed,
|
|
}) {
|
|
final activityName = task.workItem?.activityMaster?.activityName ?? 'N/A';
|
|
final assigned = '${(task.plannedTask - completed)}';
|
|
final assignedBy =
|
|
"${task.assignedBy.firstName} ${task.assignedBy.lastName ?? ''}";
|
|
final assignedOn = DateFormat('yyyy-MM-dd').format(task.assignmentDate);
|
|
final taskId = task.id;
|
|
|
|
final location = [
|
|
task.workItem?.workArea?.floor?.building?.name,
|
|
task.workItem?.workArea?.floor?.floorName,
|
|
task.workItem?.workArea?.areaName,
|
|
].where((e) => e != null && e.isNotEmpty).join(' > ');
|
|
|
|
final teamMembers = task.teamMembers
|
|
.map((e) => '${e.firstName} ${e.lastName ?? ''}')
|
|
.toList();
|
|
|
|
final pendingWork =
|
|
(task.workItem?.plannedWork ?? 0) - (task.workItem?.completedWork ?? 0);
|
|
|
|
final taskComments = task.comments.map((comment) {
|
|
final isoDate = comment.timestamp.toIso8601String();
|
|
final commenterName = comment.commentedBy.firstName.isNotEmpty
|
|
? "${comment.commentedBy.firstName} ${comment.commentedBy.lastName ?? ''}"
|
|
.trim()
|
|
: "Unknown";
|
|
|
|
return {
|
|
'text': comment.comment,
|
|
'date': isoDate,
|
|
'commentedBy': commenterName,
|
|
'preSignedUrls': comment.preSignedUrls,
|
|
};
|
|
}).toList();
|
|
|
|
final taskLevelPreSignedUrls = task.reportedPreSignedUrls;
|
|
|
|
return {
|
|
'activity': activityName,
|
|
'assigned': assigned,
|
|
'taskId': taskId,
|
|
'assignedBy': assignedBy,
|
|
'completed': completed,
|
|
'plannedWork': task.plannedTask.toString(),
|
|
'completedWork': completed.toString(),
|
|
'assignedOn': assignedOn,
|
|
'location': location,
|
|
'teamSize': task.teamMembers.length,
|
|
'teamMembers': teamMembers,
|
|
'pendingWork': pendingWork,
|
|
'taskComments': taskComments,
|
|
'reportedPreSignedUrls': taskLevelPreSignedUrls,
|
|
};
|
|
}
|
|
}
|