feat: Update reportTask method to return success status and improve loading state handling in ReportTaskBottomSheet

This commit is contained in:
Vaibhav Surve 2025-06-12 23:27:50 +05:30
parent 59e6634023
commit 602d8a8dc9
2 changed files with 74 additions and 77 deletions

View File

@ -92,7 +92,7 @@ class ReportTaskController extends MyController {
super.onClose(); super.onClose();
} }
Future<void> reportTask({ Future<bool> reportTask({
required String projectId, required String projectId,
required String comment, required String comment,
required int completedTask, required int completedTask,
@ -110,7 +110,7 @@ class ReportTaskController extends MyController {
message: "Completed work is required.", message: "Completed work is required.",
type: SnackbarType.error, type: SnackbarType.error,
); );
return; return false;
} }
final completedWorkInt = int.tryParse(completedWork); final completedWorkInt = int.tryParse(completedWork);
@ -120,7 +120,7 @@ class ReportTaskController extends MyController {
message: "Completed work must be a positive integer.", message: "Completed work must be a positive integer.",
type: SnackbarType.error, type: SnackbarType.error,
); );
return; return false;
} }
final commentField = commentController.text.trim(); final commentField = commentController.text.trim();
@ -130,34 +130,34 @@ class ReportTaskController extends MyController {
message: "Comment is required.", message: "Comment is required.",
type: SnackbarType.error, type: SnackbarType.error,
); );
return; return false;
} }
try { try {
reportStatus.value = ApiStatus.loading;
isLoading.value = true; isLoading.value = true;
List<Map<String, dynamic>>? imageData; List<Map<String, dynamic>>? imageData;
if (images != null && images.isNotEmpty) { if (images != null && images.isNotEmpty) {
if (images != null && images.isNotEmpty) { final imageFutures = images.map((file) async {
final imageFutures = images.map((file) async { final compressedBytes = await compressImageToUnder100KB(file);
final compressedBytes = await compressImageToUnder100KB(file); if (compressedBytes == null) return null;
if (compressedBytes == null) return null;
final base64Image = base64Encode(compressedBytes); final base64Image = base64Encode(compressedBytes);
final fileName = file.path.split('/').last; final fileName = file.path.split('/').last;
final contentType = _getContentTypeFromFileName(fileName); final contentType = _getContentTypeFromFileName(fileName);
return { return {
"fileName": fileName, "fileName": fileName,
"base64Data": base64Image, "base64Data": base64Image,
"contentType": contentType, "contentType": contentType,
"fileSize": compressedBytes.lengthInBytes, "fileSize": compressedBytes.lengthInBytes,
"description": "Image uploaded for task report", "description": "Image uploaded for task report",
}; };
}).toList(); }).toList();
final results = await Future.wait(imageFutures); final results = await Future.wait(imageFutures);
imageData = results.whereType<Map<String, dynamic>>().toList(); imageData = results.whereType<Map<String, dynamic>>().toList();
}
} }
final success = await ApiService.reportTask( final success = await ApiService.reportTask(
@ -169,28 +169,37 @@ class ReportTaskController extends MyController {
); );
if (success) { if (success) {
reportStatus.value = ApiStatus.success;
showAppSnackbar( showAppSnackbar(
title: "Success", title: "Success",
message: "Task reported successfully!", message: "Task reported successfully!",
type: SnackbarType.success, type: SnackbarType.success,
); );
await taskController.fetchTaskData(projectId); await taskController.fetchTaskData(projectId);
return true;
} else { } else {
reportStatus.value = ApiStatus.failure;
showAppSnackbar( showAppSnackbar(
title: "Error", title: "Error",
message: "Failed to report task.", message: "Failed to report task.",
type: SnackbarType.error, type: SnackbarType.error,
); );
return false;
} }
} catch (e) { } catch (e) {
logger.e("Error reporting task: $e"); logger.e("Error reporting task: $e");
reportStatus.value = ApiStatus.failure;
showAppSnackbar( showAppSnackbar(
title: "Error", title: "Error",
message: "An error occurred while reporting the task.", message: "An error occurred while reporting the task.",
type: SnackbarType.error, type: SnackbarType.error,
); );
return false;
} finally { } finally {
isLoading.value = false; isLoading.value = false;
Future.delayed(const Duration(milliseconds: 500), () {
reportStatus.value = ApiStatus.idle;
});
} }
} }

View File

@ -356,61 +356,49 @@ class _ReportTaskBottomSheetState extends State<ReportTaskBottomSheet>
child: MyText.bodySmall('Cancel'), child: MyText.bodySmall('Cancel'),
), ),
MySpacing.width(12), MySpacing.width(12),
Obx(() { Obx(() {
return MyButton( final isLoading = controller.reportStatus.value == ApiStatus.loading;
onPressed: controller.reportStatus.value ==
ApiStatus.loading return MyButton(
? null onPressed: isLoading
: () async { ? null
if (controller.basicValidator : () async {
.validateForm()) { if (controller.basicValidator.validateForm()) {
await controller.reportTask( final success = await controller.reportTask(
projectId: controller.basicValidator projectId: controller.basicValidator.getController('task_id')?.text ?? '',
.getController('task_id') comment: controller.basicValidator.getController('comment')?.text ?? '',
?.text ?? completedTask: int.tryParse(
'', controller.basicValidator.getController('completed_work')?.text ?? '') ??
comment: controller.basicValidator 0,
.getController('comment') checklist: [],
?.text ?? reportedDate: DateTime.now(),
'', images: controller.selectedImages,
completedTask: int.tryParse( );
controller.basicValidator if (success && widget.onReportSuccess != null) {
.getController( widget.onReportSuccess!();
'completed_work') }
?.text ?? }
'') ?? },
0, elevation: 0,
checklist: [], padding: MySpacing.xy(20, 16),
reportedDate: DateTime.now(), backgroundColor: Colors.blueAccent,
images: controller.selectedImages, borderRadiusAll: AppStyle.buttonRadius.medium,
); child: isLoading
if (widget.onReportSuccess != null) { ? const SizedBox(
widget.onReportSuccess!(); height: 16,
} width: 16,
} child: CircularProgressIndicator(
}, strokeWidth: 2,
elevation: 0, valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
padding: MySpacing.xy(20, 16), ),
backgroundColor: Colors.blueAccent, )
borderRadiusAll: AppStyle.buttonRadius.medium, : MyText.bodySmall(
child: controller.reportStatus.value == 'Report',
ApiStatus.loading color: contentTheme.onPrimary,
? SizedBox( ),
height: 16, );
width: 16, }),
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor:
AlwaysStoppedAnimation<Color>(
contentTheme.onPrimary),
),
)
: MyText.bodySmall(
'Report',
color: contentTheme.onPrimary,
),
);
}),
], ],
), ),
], ],