diff --git a/README.md b/README.md index 850d67e..071a587 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# marco +# On Field Work A new Flutter project. diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 6499e02..4a7cbdf 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -8,7 +8,7 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Marco + On Field Work CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -13,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - marco + on field work CFBundlePackageType APPL CFBundleShortVersionString diff --git a/lib/app_constant.dart b/lib/app_constant.dart index 8d5f2b5..55c95b9 100644 --- a/lib/app_constant.dart +++ b/lib/app_constant.dart @@ -8,5 +8,5 @@ class AppConstant { static int iOSAppVersion = 1; static String version = "1.0.0"; - static String get appName => 'Marco'; + static String get appName => 'On Field Work'; } diff --git a/lib/controller/attendance/attendance_screen_controller.dart b/lib/controller/attendance/attendance_screen_controller.dart index cab2ffd..5aebd4d 100644 --- a/lib/controller/attendance/attendance_screen_controller.dart +++ b/lib/controller/attendance/attendance_screen_controller.dart @@ -5,19 +5,19 @@ import 'package:image_picker/image_picker.dart'; import 'package:geolocator/geolocator.dart'; import 'package:intl/intl.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/widgets/my_image_compressor.dart'; -import 'package:marco/helpers/widgets/time_stamp_image_helper.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/widgets/my_image_compressor.dart'; +import 'package:on_field_work/helpers/widgets/time_stamp_image_helper.dart'; -import 'package:marco/model/attendance/attendance_model.dart'; -import 'package:marco/model/project_model.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/model/attendance/attendance_log_model.dart'; -import 'package:marco/model/regularization_log_model.dart'; -import 'package:marco/model/attendance/attendance_log_view_model.dart'; -import 'package:marco/model/attendance/organization_per_project_list_model.dart'; -import 'package:marco/controller/project_controller.dart'; +import 'package:on_field_work/model/attendance/attendance_model.dart'; +import 'package:on_field_work/model/project_model.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/model/attendance/attendance_log_model.dart'; +import 'package:on_field_work/model/regularization_log_model.dart'; +import 'package:on_field_work/model/attendance/attendance_log_view_model.dart'; +import 'package:on_field_work/model/attendance/organization_per_project_list_model.dart'; +import 'package:on_field_work/controller/project_controller.dart'; class AttendanceController extends GetxController { // ------------------ Data Models ------------------ diff --git a/lib/controller/auth/forgot_password_controller.dart b/lib/controller/auth/forgot_password_controller.dart index 8d544d7..35683b4 100644 --- a/lib/controller/auth/forgot_password_controller.dart +++ b/lib/controller/auth/forgot_password_controller.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/my_controller.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/helpers/widgets/my_form_validator.dart'; -import 'package:marco/helpers/widgets/my_validators.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/controller/my_controller.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/helpers/widgets/my_form_validator.dart'; +import 'package:on_field_work/helpers/widgets/my_validators.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; class ForgotPasswordController extends MyController { final MyFormValidator basicValidator = MyFormValidator(); diff --git a/lib/controller/auth/login_controller.dart b/lib/controller/auth/login_controller.dart index 40cbd25..408ab5a 100644 --- a/lib/controller/auth/login_controller.dart +++ b/lib/controller/auth/login_controller.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/my_controller.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/helpers/widgets/my_form_validator.dart'; -import 'package:marco/helpers/widgets/my_validators.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/services/app_logger.dart'; +import 'package:on_field_work/controller/my_controller.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/helpers/widgets/my_form_validator.dart'; +import 'package:on_field_work/helpers/widgets/my_validators.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; class LoginController extends MyController { final MyFormValidator basicValidator = MyFormValidator(); diff --git a/lib/controller/auth/mpin_controller.dart b/lib/controller/auth/mpin_controller.dart index a03b1f2..d72db80 100644 --- a/lib/controller/auth/mpin_controller.dart +++ b/lib/controller/auth/mpin_controller.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/widgets/my_form_validator.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/firebase/firebase_messaging_service.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/controller/project_controller.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/widgets/my_form_validator.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/firebase/firebase_messaging_service.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/controller/project_controller.dart'; class MPINController extends GetxController { final MyFormValidator basicValidator = MyFormValidator(); diff --git a/lib/controller/auth/otp_controller.dart b/lib/controller/auth/otp_controller.dart index 53cfeb5..e677816 100644 --- a/lib/controller/auth/otp_controller.dart +++ b/lib/controller/auth/otp_controller.dart @@ -1,10 +1,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; class OTPController extends GetxController { final formKey = GlobalKey(); diff --git a/lib/controller/auth/register_account_controller.dart b/lib/controller/auth/register_account_controller.dart index 8236b90..b0db3c3 100644 --- a/lib/controller/auth/register_account_controller.dart +++ b/lib/controller/auth/register_account_controller.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/my_controller.dart'; -import 'package:marco/helpers/widgets/my_form_validator.dart'; -import 'package:marco/helpers/widgets/my_validators.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; +import 'package:on_field_work/controller/my_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_form_validator.dart'; +import 'package:on_field_work/helpers/widgets/my_validators.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; class RegisterAccountController extends MyController { MyFormValidator basicValidator = MyFormValidator(); diff --git a/lib/controller/auth/reset_password_controller.dart b/lib/controller/auth/reset_password_controller.dart index 842ca40..c411b5d 100644 --- a/lib/controller/auth/reset_password_controller.dart +++ b/lib/controller/auth/reset_password_controller.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/my_controller.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/helpers/widgets/my_form_validator.dart'; -import 'package:marco/helpers/widgets/my_validators.dart'; -import 'package:marco/helpers/services/app_logger.dart'; +import 'package:on_field_work/controller/my_controller.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/helpers/widgets/my_form_validator.dart'; +import 'package:on_field_work/helpers/widgets/my_validators.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; class ResetPasswordController extends MyController { MyFormValidator basicValidator = MyFormValidator(); diff --git a/lib/controller/dashboard/dashboard_controller.dart b/lib/controller/dashboard/dashboard_controller.dart index 50e801a..e6ed81b 100644 --- a/lib/controller/dashboard/dashboard_controller.dart +++ b/lib/controller/dashboard/dashboard_controller.dart @@ -1,12 +1,12 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/model/dashboard/project_progress_model.dart'; -import 'package:marco/model/dashboard/pending_expenses_model.dart'; -import 'package:marco/model/dashboard/expense_type_report_model.dart'; -import 'package:marco/model/dashboard/monthly_expence_model.dart'; -import 'package:marco/model/expense/expense_type_model.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/model/dashboard/project_progress_model.dart'; +import 'package:on_field_work/model/dashboard/pending_expenses_model.dart'; +import 'package:on_field_work/model/dashboard/expense_type_report_model.dart'; +import 'package:on_field_work/model/dashboard/monthly_expence_model.dart'; +import 'package:on_field_work/model/expense/expense_type_model.dart'; class DashboardController extends GetxController { // ========================= @@ -58,7 +58,7 @@ class DashboardController extends GetxController { final Rx pendingExpensesData = Rx(null); // ========================= -// Expense Type Report +// Expense Category Report // ========================= final RxBool isExpenseTypeReportLoading = false.obs; final Rx expenseTypeReportData = @@ -355,15 +355,15 @@ class DashboardController extends GetxController { if (response != null && response.success) { expenseTypeReportData.value = response.data; - logSafe('Expense Type Report fetched successfully.', + logSafe('Expense Category Report fetched successfully.', level: LogLevel.info); } else { expenseTypeReportData.value = null; - logSafe('Failed to fetch Expense Type Report.', level: LogLevel.error); + logSafe('Failed to fetch Expense Category Report.', level: LogLevel.error); } } catch (e, st) { expenseTypeReportData.value = null; - logSafe('Error fetching Expense Type Report', + logSafe('Error fetching Expense Category Report', level: LogLevel.error, error: e, stackTrace: st); } finally { isExpenseTypeReportLoading.value = false; diff --git a/lib/controller/directory/add_comment_controller.dart b/lib/controller/directory/add_comment_controller.dart index fcc3357..69f1aaf 100644 --- a/lib/controller/directory/add_comment_controller.dart +++ b/lib/controller/directory/add_comment_controller.dart @@ -1,9 +1,9 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/controller/directory/directory_controller.dart'; -import 'package:marco/controller/directory/notes_controller.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/controller/directory/directory_controller.dart'; +import 'package:on_field_work/controller/directory/notes_controller.dart'; class AddCommentController extends GetxController { final String contactId; diff --git a/lib/controller/directory/add_contact_controller.dart b/lib/controller/directory/add_contact_controller.dart index 0c549c3..96989a7 100644 --- a/lib/controller/directory/add_contact_controller.dart +++ b/lib/controller/directory/add_contact_controller.dart @@ -1,7 +1,7 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; class AddContactController extends GetxController { final RxList categories = [].obs; diff --git a/lib/controller/directory/create_bucket_controller.dart b/lib/controller/directory/create_bucket_controller.dart index 80338d5..325b589 100644 --- a/lib/controller/directory/create_bucket_controller.dart +++ b/lib/controller/directory/create_bucket_controller.dart @@ -1,7 +1,7 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; class BucketController extends GetxController { RxBool isCreating = false.obs; diff --git a/lib/controller/directory/directory_controller.dart b/lib/controller/directory/directory_controller.dart index bef19f1..5bfba60 100644 --- a/lib/controller/directory/directory_controller.dart +++ b/lib/controller/directory/directory_controller.dart @@ -1,10 +1,10 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/model/directory/contact_model.dart'; -import 'package:marco/model/directory/contact_bucket_list_model.dart'; -import 'package:marco/model/directory/directory_comment_model.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/model/directory/contact_model.dart'; +import 'package:on_field_work/model/directory/contact_bucket_list_model.dart'; +import 'package:on_field_work/model/directory/directory_comment_model.dart'; class DirectoryController extends GetxController { // -------------------- CONTACTS -------------------- diff --git a/lib/controller/directory/manage_bucket_controller.dart b/lib/controller/directory/manage_bucket_controller.dart index 72ad336..66e0995 100644 --- a/lib/controller/directory/manage_bucket_controller.dart +++ b/lib/controller/directory/manage_bucket_controller.dart @@ -1,9 +1,9 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/controller/directory/directory_controller.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/controller/directory/directory_controller.dart'; class ManageBucketController extends GetxController { RxList allEmployees = [].obs; diff --git a/lib/controller/directory/notes_controller.dart b/lib/controller/directory/notes_controller.dart index 1868414..2185633 100644 --- a/lib/controller/directory/notes_controller.dart +++ b/lib/controller/directory/notes_controller.dart @@ -1,8 +1,8 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/model/directory/note_list_response_model.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/model/directory/note_list_response_model.dart'; class NotesController extends GetxController { RxList notesList = [].obs; diff --git a/lib/controller/document/document_details_controller.dart b/lib/controller/document/document_details_controller.dart index c160a0d..c2edc2e 100644 --- a/lib/controller/document/document_details_controller.dart +++ b/lib/controller/document/document_details_controller.dart @@ -1,7 +1,7 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/document/document_details_model.dart'; -import 'package:marco/model/document/document_version_model.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/model/document/document_details_model.dart'; +import 'package:on_field_work/model/document/document_version_model.dart'; class DocumentDetailsController extends GetxController { /// Observables diff --git a/lib/controller/document/document_upload_controller.dart b/lib/controller/document/document_upload_controller.dart index c7e33c7..56fe638 100644 --- a/lib/controller/document/document_upload_controller.dart +++ b/lib/controller/document/document_upload_controller.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/document/master_document_type_model.dart'; -import 'package:marco/model/document/master_document_tags.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/model/document/master_document_type_model.dart'; +import 'package:on_field_work/model/document/master_document_tags.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; class DocumentUploadController extends GetxController { // Observables diff --git a/lib/controller/document/user_document_controller.dart b/lib/controller/document/user_document_controller.dart index 5667003..a424dce 100644 --- a/lib/controller/document/user_document_controller.dart +++ b/lib/controller/document/user_document_controller.dart @@ -1,8 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/document/document_filter_model.dart'; -import 'package:marco/model/document/documents_list_model.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/model/document/document_filter_model.dart'; +import 'package:on_field_work/model/document/documents_list_model.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; class DocumentController extends GetxController { // ==================== Observables ==================== @@ -38,7 +39,6 @@ class DocumentController extends GetxController { final endDate = Rxn(); // ==================== Lifecycle ==================== - @override void onClose() { // Don't dispose searchController here - it's managed by the page @@ -87,13 +87,23 @@ class DocumentController extends GetxController { entityId: entityId, reset: true, ); + + // Show success snackbar + showAppSnackbar( + title: 'Success', + message: isActive ? 'Document deactivated' : 'Document activated', + type: SnackbarType.success, + ); + return true; } else { errorMessage.value = 'Failed to update document state'; + _showError('Failed to update document state'); return false; } } catch (e) { errorMessage.value = 'Error updating document: $e'; + _showError('Error updating document: $e'); debugPrint('❌ Error toggling document state: $e'); return false; } finally { @@ -110,17 +120,13 @@ class DocumentController extends GetxController { bool reset = false, }) async { try { - // Reset pagination if needed if (reset) { pageNumber.value = 1; documents.clear(); hasMore.value = true; } - // Don't fetch if no more data if (!hasMore.value && !reset) return; - - // Prevent duplicate requests if (isLoading.value) return; isLoading.value = true; @@ -147,12 +153,24 @@ class DocumentController extends GetxController { errorMessage.value = response?.message ?? 'Failed to fetch documents'; if (documents.isEmpty) { _showError('Failed to load documents'); + } else { + showAppSnackbar( + title: 'Warning', + message: 'No more documents to load', + type: SnackbarType.warning, + ); } } } catch (e) { errorMessage.value = 'Error fetching documents: $e'; if (documents.isEmpty) { _showError('Error loading documents'); + } else { + showAppSnackbar( + title: 'Error', + message: 'Error fetching additional documents', + type: SnackbarType.error, + ); } debugPrint('❌ Error fetching documents: $e'); } finally { @@ -185,17 +203,12 @@ class DocumentController extends GetxController { isVerified.value != null; } - /// Show error message + /// Show error message via snackbar void _showError(String message) { - Get.snackbar( - 'Error', - message, - snackPosition: SnackPosition.BOTTOM, - backgroundColor: Colors.red.shade100, - colorText: Colors.red.shade900, - margin: const EdgeInsets.all(16), - borderRadius: 8, - duration: const Duration(seconds: 3), + showAppSnackbar( + title: 'Error', + message: message, + type: SnackbarType.error, ); } diff --git a/lib/controller/dynamicMenu/dynamic_menu_controller.dart b/lib/controller/dynamicMenu/dynamic_menu_controller.dart index f55cb1e..f5f259c 100644 --- a/lib/controller/dynamicMenu/dynamic_menu_controller.dart +++ b/lib/controller/dynamicMenu/dynamic_menu_controller.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'package:get/get.dart'; -import 'package:marco/model/dynamicMenu/dynamic_menu_model.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; +import 'package:on_field_work/model/dynamicMenu/dynamic_menu_model.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; class DynamicMenuController extends GetxController { // UI reactive states diff --git a/lib/controller/employee/add_employee_controller.dart b/lib/controller/employee/add_employee_controller.dart index 44aa286..fbbab27 100644 --- a/lib/controller/employee/add_employee_controller.dart +++ b/lib/controller/employee/add_employee_controller.dart @@ -1,11 +1,11 @@ import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/my_controller.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/widgets/my_form_validator.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/controller/my_controller.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/widgets/my_form_validator.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; import 'package:permission_handler/permission_handler.dart'; diff --git a/lib/controller/employee/assign_projects_controller.dart b/lib/controller/employee/assign_projects_controller.dart index 37581ae..7962b8c 100644 --- a/lib/controller/employee/assign_projects_controller.dart +++ b/lib/controller/employee/assign_projects_controller.dart @@ -1,10 +1,10 @@ import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/model/global_project_model.dart'; -import 'package:marco/model/employees/assigned_projects_model.dart'; -import 'package:marco/controller/project_controller.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/model/global_project_model.dart'; +import 'package:on_field_work/model/employees/assigned_projects_model.dart'; +import 'package:on_field_work/controller/project_controller.dart'; class AssignProjectController extends GetxController { final String employeeId; diff --git a/lib/controller/employee/employees_screen_controller.dart b/lib/controller/employee/employees_screen_controller.dart index a8d9f1a..d8a4c9e 100644 --- a/lib/controller/employee/employees_screen_controller.dart +++ b/lib/controller/employee/employees_screen_controller.dart @@ -1,8 +1,8 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/model/employees/employee_details_model.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/model/employees/employee_details_model.dart'; class EmployeesScreenController extends GetxController { /// ✅ Data lists diff --git a/lib/controller/error_pages/coming_soon_controller.dart b/lib/controller/error_pages/coming_soon_controller.dart index 50c820a..429b37e 100644 --- a/lib/controller/error_pages/coming_soon_controller.dart +++ b/lib/controller/error_pages/coming_soon_controller.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:get/get.dart'; -import 'package:marco/controller/my_controller.dart'; +import 'package:on_field_work/controller/my_controller.dart'; class ComingSoonController extends MyController { Timer? countdownTimer; diff --git a/lib/controller/error_pages/error_404_controller.dart b/lib/controller/error_pages/error_404_controller.dart index 7894d01..90323dc 100644 --- a/lib/controller/error_pages/error_404_controller.dart +++ b/lib/controller/error_pages/error_404_controller.dart @@ -1,5 +1,5 @@ import 'package:get/get.dart'; -import 'package:marco/controller/my_controller.dart'; +import 'package:on_field_work/controller/my_controller.dart'; class Error404Controller extends MyController { void goToDashboardScreen() { diff --git a/lib/controller/error_pages/error_500_controller.dart b/lib/controller/error_pages/error_500_controller.dart index c080b64..13f7827 100644 --- a/lib/controller/error_pages/error_500_controller.dart +++ b/lib/controller/error_pages/error_500_controller.dart @@ -1,5 +1,5 @@ import 'package:get/get.dart'; -import 'package:marco/controller/my_controller.dart'; +import 'package:on_field_work/controller/my_controller.dart'; class Error500Controller extends MyController { void goToDashboardScreen() { diff --git a/lib/controller/expense/add_expense_controller.dart b/lib/controller/expense/add_expense_controller.dart index 11ce63d..32e53fd 100644 --- a/lib/controller/expense/add_expense_controller.dart +++ b/lib/controller/expense/add_expense_controller.dart @@ -10,14 +10,14 @@ import 'package:intl/intl.dart'; import 'package:mime/mime.dart'; import 'package:image_picker/image_picker.dart'; -import 'package:marco/controller/expense/expense_screen_controller.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/model/expense/expense_type_model.dart'; -import 'package:marco/model/expense/payment_types_model.dart'; -import 'package:marco/helpers/widgets/time_stamp_image_helper.dart'; +import 'package:on_field_work/controller/expense/expense_screen_controller.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/model/expense/expense_type_model.dart'; +import 'package:on_field_work/model/expense/payment_types_model.dart'; +import 'package:on_field_work/helpers/widgets/time_stamp_image_helper.dart'; class AddExpenseController extends GetxController { // --- Text Controllers --- @@ -196,7 +196,7 @@ class AddExpenseController extends GetxController { 'Location: ${locationController.text}', 'Transaction Date: ${transactionDateController.text}', 'No. of Persons: ${noOfPersonsController.text}', - 'Expense Type: ${selectedExpenseType.value?.name}', + 'Expense Category: ${selectedExpenseType.value?.name}', 'Payment Mode: ${selectedPaymentMode.value?.name}', 'Paid By: ${selectedPaidBy.value?.name}', 'Attachments: ${attachments.length}', @@ -445,7 +445,7 @@ class AddExpenseController extends GetxController { return null; } if (expenseType == null) { - _errorSnackbar("Expense type not selected"); + _errorSnackbar("Expense Category not selected"); return null; } if (paymentMode == null) { @@ -517,7 +517,7 @@ class AddExpenseController extends GetxController { final missing = []; if (selectedProject.value.isEmpty) missing.add("Project"); - if (selectedExpenseType.value == null) missing.add("Expense Type"); + if (selectedExpenseType.value == null) missing.add("Expense Category"); if (selectedPaymentMode.value == null) missing.add("Payment Mode"); if (selectedPaidBy.value == null) missing.add("Paid By"); if (amountController.text.trim().isEmpty) missing.add("Amount"); diff --git a/lib/controller/expense/expense_detail_controller.dart b/lib/controller/expense/expense_detail_controller.dart index afc925a..9ba8376 100644 --- a/lib/controller/expense/expense_detail_controller.dart +++ b/lib/controller/expense/expense_detail_controller.dart @@ -1,8 +1,8 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/model/expense/expense_detail_model.dart'; -import 'package:marco/model/employees/employee_model.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/model/expense/expense_detail_model.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; import 'package:flutter/material.dart'; class ExpenseDetailController extends GetxController { diff --git a/lib/controller/expense/expense_screen_controller.dart b/lib/controller/expense/expense_screen_controller.dart index 11714a3..9cab200 100644 --- a/lib/controller/expense/expense_screen_controller.dart +++ b/lib/controller/expense/expense_screen_controller.dart @@ -1,13 +1,13 @@ import 'dart:convert'; import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/model/expense/expense_list_model.dart'; -import 'package:marco/model/expense/payment_types_model.dart'; -import 'package:marco/model/expense/expense_type_model.dart'; -import 'package:marco/model/expense/expense_status_model.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/model/expense/expense_list_model.dart'; +import 'package:on_field_work/model/expense/payment_types_model.dart'; +import 'package:on_field_work/model/expense/expense_type_model.dart'; +import 'package:on_field_work/model/expense/expense_status_model.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; import 'package:flutter/material.dart'; class ExpenseController extends GetxController { @@ -213,7 +213,7 @@ class ExpenseController extends GetxController { selectedCreatedByEmployees.clear(); } - /// Fetch master data: expense types, payment modes, and expense status + /// Fetch master data: Expense Categorys, payment modes, and expense status Future fetchMasterData() async { try { final expenseTypesData = await ApiService.getMasterExpenseTypes(); diff --git a/lib/controller/extra_pages/faqs_controller.dart b/lib/controller/extra_pages/faqs_controller.dart index 4ac1905..a704d75 100644 --- a/lib/controller/extra_pages/faqs_controller.dart +++ b/lib/controller/extra_pages/faqs_controller.dart @@ -1,5 +1,5 @@ -import 'package:marco/controller/my_controller.dart'; -import 'package:marco/helpers/widgets/my_text_utils.dart'; +import 'package:on_field_work/controller/my_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text_utils.dart'; class FaqsController extends MyController { final List dataExpansionPanel = [true, false, false, false, false, false]; diff --git a/lib/controller/extra_pages/pricing_controller.dart b/lib/controller/extra_pages/pricing_controller.dart index 6db7583..0ab3745 100644 --- a/lib/controller/extra_pages/pricing_controller.dart +++ b/lib/controller/extra_pages/pricing_controller.dart @@ -1,4 +1,4 @@ -import 'package:marco/controller/my_controller.dart'; +import 'package:on_field_work/controller/my_controller.dart'; class PricingController extends MyController { bool isMonth = false; diff --git a/lib/controller/finance/add_payment_request_controller.dart b/lib/controller/finance/add_payment_request_controller.dart index 1ff0a4e..e7688b9 100644 --- a/lib/controller/finance/add_payment_request_controller.dart +++ b/lib/controller/finance/add_payment_request_controller.dart @@ -8,12 +8,12 @@ import 'package:image_picker/image_picker.dart'; import 'package:mime/mime.dart'; import 'package:intl/intl.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/widgets/time_stamp_image_helper.dart'; -import 'package:marco/model/finance/expense_category_model.dart'; -import 'package:marco/model/finance/currency_list_model.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/widgets/time_stamp_image_helper.dart'; +import 'package:on_field_work/model/finance/expense_category_model.dart'; +import 'package:on_field_work/model/finance/currency_list_model.dart'; class AddPaymentRequestController extends GetxController { // Loading States diff --git a/lib/controller/finance/advance_payment_controller.dart b/lib/controller/finance/advance_payment_controller.dart index 84eb917..9fc63f9 100644 --- a/lib/controller/finance/advance_payment_controller.dart +++ b/lib/controller/finance/advance_payment_controller.dart @@ -1,9 +1,9 @@ import 'dart:async'; import 'package:get/get.dart'; -import 'package:marco/model/finance/advance_payment_model.dart'; -import 'package:marco/model/finance/get_employee_model.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/api_service.dart'; +import 'package:on_field_work/model/finance/advance_payment_model.dart'; +import 'package:on_field_work/model/finance/get_employee_model.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; class AdvancePaymentController extends GetxController { /// Advance payments list diff --git a/lib/controller/finance/payment_request_controller.dart b/lib/controller/finance/payment_request_controller.dart index 63bd234..14b9e56 100644 --- a/lib/controller/finance/payment_request_controller.dart +++ b/lib/controller/finance/payment_request_controller.dart @@ -1,8 +1,8 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/finance/payment_request_list_model.dart'; -import 'package:marco/model/finance/payment_request_filter.dart'; -import 'package:marco/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/model/finance/payment_request_list_model.dart'; +import 'package:on_field_work/model/finance/payment_request_filter.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; class PaymentRequestController extends GetxController { // ---------------- Observables ---------------- @@ -32,13 +32,14 @@ class PaymentRequestController extends GetxController { Future fetchPaymentRequestFilterOptions() async { try { final response = await ApiService.getExpensePaymentRequestFilterApi(); - if (response != null) { - projects.assignAll(response.data.projects); - payees.assignAll(response.data.payees); - categories.assignAll(response.data.expenseCategory); - currencies.assignAll(response.data.currency); - statuses.assignAll(response.data.status); - createdBy.assignAll(response.data.createdBy); + + if (response != null && response.data != null) { + projects.assignAll(response.data!.projects ?? []); + payees.assignAll(response.data!.payees ?? []); + categories.assignAll(response.data!.expenseCategory ?? []); + currencies.assignAll(response.data!.currency ?? []); + statuses.assignAll(response.data!.status ?? []); + createdBy.assignAll(response.data!.createdBy ?? []); } else { logSafe("Payment request filter API returned null", level: LogLevel.warning); @@ -63,7 +64,7 @@ class PaymentRequestController extends GetxController { isLoading.value = false; } -// ---------------- Load More ---------------- + // ---------------- Load More ---------------- Future loadMorePaymentRequests() async { if (isLoading.value || !_hasMoreData) return; @@ -74,7 +75,7 @@ class PaymentRequestController extends GetxController { isLoading.value = false; } -// ---------------- Internal API Call ---------------- + // ---------------- Internal API Call ---------------- Future _fetchPaymentRequestsFromApi() async { try { final response = await ApiService.getExpensePaymentRequestListApi( @@ -84,17 +85,17 @@ class PaymentRequestController extends GetxController { searchString: searchString.value, ); - if (response != null && response.data.data.isNotEmpty) { + final data = response?.data; + final reqList = data?.data ?? []; + + if (response != null && data != null && reqList.isNotEmpty) { if (_pageNumber == 1) { - // First page, replace the list - paymentRequests.assignAll(response.data.data); + paymentRequests.assignAll(reqList); } else { - // Append next page items at the end - paymentRequests.addAll(response.data.data); + paymentRequests.addAll(reqList); } - // If returned data is less than page size, no more data - if (response.data.data.length < _pageSize) { + if (reqList.length < _pageSize) { _hasMoreData = false; } } else { diff --git a/lib/controller/finance/payment_request_detail_controller.dart b/lib/controller/finance/payment_request_detail_controller.dart index b0d17fb..d790eb4 100644 --- a/lib/controller/finance/payment_request_detail_controller.dart +++ b/lib/controller/finance/payment_request_detail_controller.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/model/finance/payment_request_details_model.dart'; -import 'package:marco/model/expense/payment_types_model.dart'; -import 'package:marco/helpers/widgets/time_stamp_image_helper.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/model/finance/payment_request_details_model.dart'; +import 'package:on_field_work/model/expense/payment_types_model.dart'; +import 'package:on_field_work/helpers/widgets/time_stamp_image_helper.dart'; import 'package:image_picker/image_picker.dart'; import 'dart:convert'; import 'dart:io'; @@ -13,6 +13,7 @@ import 'package:file_picker/file_picker.dart'; import 'package:geocoding/geocoding.dart'; import 'package:geolocator/geolocator.dart'; import 'package:mime/mime.dart'; +import 'package:on_field_work/controller/finance/payment_request_controller.dart'; class PaymentRequestDetailController extends GetxController { final Rx paymentRequest = Rx(null); @@ -26,6 +27,8 @@ class PaymentRequestDetailController extends GetxController { final RxList employeeSearchResults = [].obs; final TextEditingController employeeSearchController = TextEditingController(); + PaymentRequestController get paymentRequestController => + Get.find(); final RxBool isSearchingEmployees = false.obs; // Attachments @@ -297,6 +300,7 @@ class PaymentRequestDetailController extends GetxController { message: 'Payment submitted successfully', type: SnackbarType.success); await fetchPaymentRequestDetail(); + paymentRequestController.fetchPaymentRequests(); } else { showAppSnackbar( title: 'Error', diff --git a/lib/controller/layout/auth_layout_2_controller.dart b/lib/controller/layout/auth_layout_2_controller.dart index bcf35eb..3d096d4 100644 --- a/lib/controller/layout/auth_layout_2_controller.dart +++ b/lib/controller/layout/auth_layout_2_controller.dart @@ -1,3 +1,3 @@ -import 'package:marco/controller/my_controller.dart'; +import 'package:on_field_work/controller/my_controller.dart'; class AuthLayout2Controller extends MyController {} diff --git a/lib/controller/layout/auth_layout_controller.dart b/lib/controller/layout/auth_layout_controller.dart index e873fb4..555cbf9 100644 --- a/lib/controller/layout/auth_layout_controller.dart +++ b/lib/controller/layout/auth_layout_controller.dart @@ -1,7 +1,7 @@ import 'dart:async'; -import 'package:marco/controller/my_controller.dart'; -import 'package:marco/helpers/widgets/my_text_utils.dart'; +import 'package:on_field_work/controller/my_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text_utils.dart'; import 'package:flutter/material.dart'; class AuthLayoutController extends MyController { diff --git a/lib/controller/layout/layout_controller.dart b/lib/controller/layout/layout_controller.dart index 1ee06ea..a3cca3a 100644 --- a/lib/controller/layout/layout_controller.dart +++ b/lib/controller/layout/layout_controller.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/theme/theme_customizer.dart'; -import 'package:marco/model/project_model.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/theme/theme_customizer.dart'; +import 'package:on_field_work/model/project_model.dart'; class LayoutController extends GetxController { // Theme Customization @@ -55,7 +55,7 @@ class LayoutController extends GetxController { isLoadingProjects.value = true; try { - final response = await ApiService.getProjects(); + final response = await ApiService.getGlobalProjects(); if (response != null && response.isNotEmpty) { final fetchedProjects = response.map((json) => ProjectModel.fromJson(json)).toList(); diff --git a/lib/controller/my_controller.dart b/lib/controller/my_controller.dart index b831e8c..190c84f 100644 --- a/lib/controller/my_controller.dart +++ b/lib/controller/my_controller.dart @@ -1,5 +1,5 @@ import 'package:get/get_state_manager/get_state_manager.dart'; -import 'package:marco/helpers/theme/theme_customizer.dart'; +import 'package:on_field_work/helpers/theme/theme_customizer.dart'; abstract class MyController extends GetxController { @override diff --git a/lib/controller/permission_controller.dart b/lib/controller/permission_controller.dart index 30253d7..8e17ecc 100644 --- a/lib/controller/permission_controller.dart +++ b/lib/controller/permission_controller.dart @@ -2,11 +2,11 @@ import 'dart:async'; import 'dart:convert'; import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/permission_service.dart'; -import 'package:marco/model/user_permission.dart'; -import 'package:marco/model/employees/employee_info.dart'; -import 'package:marco/model/projects_model.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/permission_service.dart'; +import 'package:on_field_work/model/user_permission.dart'; +import 'package:on_field_work/model/employees/employee_info.dart'; +import 'package:on_field_work/model/projects_model.dart'; class PermissionController extends GetxController { var permissions = [].obs; diff --git a/lib/controller/project_controller.dart b/lib/controller/project_controller.dart index a31cfcd..0ffafa9 100644 --- a/lib/controller/project_controller.dart +++ b/lib/controller/project_controller.dart @@ -1,8 +1,8 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/global_project_model.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/model/global_project_model.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; class ProjectController extends GetxController { RxList projects = [].obs; diff --git a/lib/controller/service_project/add_service_project_job_controller.dart b/lib/controller/service_project/add_service_project_job_controller.dart index e53fcd6..3d07097 100644 --- a/lib/controller/service_project/add_service_project_job_controller.dart +++ b/lib/controller/service_project/add_service_project_job_controller.dart @@ -1,56 +1,58 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/controller/service_project/service_project_details_screen_controller.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/controller/service_project/service_project_details_screen_controller.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/model/service_project/service_project_branches_model.dart'; class AddServiceProjectJobController extends GetxController { -// Form Controllers + // FORM CONTROLLERS final titleCtrl = TextEditingController(); final descCtrl = TextEditingController(); final tagCtrl = TextEditingController(); - final FocusNode searchFocusNode = FocusNode(); - final RxBool showEmployeePicker = true.obs; + final searchFocusNode = FocusNode(); -// Observables + // OBSERVABLES final startDate = Rx(DateTime.now()); final dueDate = Rx(DateTime.now().add(const Duration(days: 1))); + final enteredTags = [].obs; - - final employees = [].obs; final selectedAssignees = [].obs; - final isSearchingEmployees = false.obs; -// Loading states + // Branches + final branches = [].obs; + final selectedBranch = Rxn(); + final isBranchLoading = false.obs; + + // Loading final isLoading = false.obs; - final isAllEmployeeLoading = false.obs; - final allEmployees = [].obs; - final employeeSearchResults = [].obs; - - @override - void onInit() { - super.onInit(); - } @override void onClose() { titleCtrl.dispose(); descCtrl.dispose(); tagCtrl.dispose(); + searchFocusNode.dispose(); super.onClose(); } - /// Toggle employee selection - void toggleAssignee(EmployeeModel employee) { - if (selectedAssignees.contains(employee)) { - selectedAssignees.remove(employee); - } else { - selectedAssignees.add(employee); + // FETCH BRANCHES + Future fetchBranches(String projectId) async { + isBranchLoading.value = true; + + final response = await ApiService.getServiceProjectBranchesFull( + projectId: projectId, + ); + + if (response != null && response.success) { + branches.assignAll(response.data?.data ?? []); } + + isBranchLoading.value = false; } - /// Create Service Project Job API call + // CREATE JOB Future createJob(String projectId) async { if (titleCtrl.text.trim().isEmpty || descCtrl.text.trim().isEmpty) { showAppSnackbar( @@ -63,18 +65,22 @@ class AddServiceProjectJobController extends GetxController { final assigneeIds = selectedAssignees.map((e) => e.id).toList(); + isLoading.value = true; + final success = await ApiService.createServiceProjectJobApi( title: titleCtrl.text.trim(), description: descCtrl.text.trim(), projectId: projectId, + branchId: selectedBranch.value?.id, assignees: assigneeIds.map((id) => {"id": id}).toList(), startDate: startDate.value!, dueDate: dueDate.value!, tags: enteredTags.map((tag) => {"name": tag}).toList(), ); + isLoading.value = false; + if (success) { - // 🔥 Auto-refresh job list in ServiceProjectDetailsController if (Get.isRegistered()) { Get.find().refreshJobsAfterAdd(); } diff --git a/lib/controller/service_project/service_project_allocation_controller.dart b/lib/controller/service_project/service_project_allocation_controller.dart index a59b399..dd85f35 100644 --- a/lib/controller/service_project/service_project_allocation_controller.dart +++ b/lib/controller/service_project/service_project_allocation_controller.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/model/service_project/job_allocation_model.dart'; -import 'package:marco/helpers/services/api_service.dart'; +import 'package:on_field_work/model/service_project/job_allocation_model.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; class ServiceProjectAllocationController extends GetxController { final projectId = ''.obs; diff --git a/lib/controller/service_project/service_project_details_screen_controller.dart b/lib/controller/service_project/service_project_details_screen_controller.dart index 41f0954..46f43aa 100644 --- a/lib/controller/service_project/service_project_details_screen_controller.dart +++ b/lib/controller/service_project/service_project_details_screen_controller.dart @@ -1,11 +1,11 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/service_project/service_projects_details_model.dart'; -import 'package:marco/model/service_project/job_list_model.dart'; -import 'package:marco/model/service_project/service_project_job_detail_model.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/model/service_project/service_projects_details_model.dart'; +import 'package:on_field_work/model/service_project/job_list_model.dart'; +import 'package:on_field_work/model/service_project/service_project_job_detail_model.dart'; import 'package:geolocator/geolocator.dart'; -import 'package:marco/model/service_project/job_attendance_logs_model.dart'; -import 'package:marco/model/service_project/job_allocation_model.dart'; +import 'package:on_field_work/model/service_project/job_attendance_logs_model.dart'; +import 'package:on_field_work/model/service_project/job_allocation_model.dart'; import 'dart:convert'; import 'dart:io'; @@ -17,6 +17,7 @@ class ServiceProjectDetailsController extends GetxController { var projectDetail = Rxn(); var jobList = [].obs; var jobDetail = Rxn(); + var showArchivedJobs = false.obs; // true = archived, false = active // Loading states var isLoading = false.obs; @@ -39,21 +40,47 @@ class ServiceProjectDetailsController extends GetxController { var teamList = [].obs; var isTeamLoading = false.obs; var teamErrorMessage = ''.obs; + var filteredJobList = [].obs; // -------------------- Lifecycle -------------------- @override void onInit() { super.onInit(); - fetchProjectJobs(); // always load jobs even without projectId + fetchProjectJobs(); + filteredJobList.value = jobList; } // -------------------- Project -------------------- void setProjectId(String id) { + if (projectId.value == id) return; projectId.value = id; - fetchProjectDetail(); + + // Reset pagination and list pageNumber = 1; hasMoreJobs.value = true; - fetchProjectJobs(); // no initialLoad + jobList.clear(); + filteredJobList.clear(); + + // Fetch project detail + fetchProjectDetail(); + + // Always fetch jobs for this project + fetchProjectJobs(refresh: true); + } + + void updateJobSearch(String searchText) { + if (searchText.isEmpty) { + filteredJobList.value = jobList; + } else { + filteredJobList.value = jobList.where((job) { + final lowerSearch = searchText.toLowerCase(); + return job.title.toLowerCase().contains(lowerSearch) || + (job.description.toLowerCase().contains(lowerSearch)) || + (job.tags?.any( + (tag) => tag.name.toLowerCase().contains(lowerSearch)) ?? + false); + }).toList(); + } } Future fetchProjectTeams() async { @@ -135,33 +162,39 @@ class ServiceProjectDetailsController extends GetxController { } // -------------------- Job List (modified to always load) -------------------- - Future fetchProjectJobs() async { - if (!hasMoreJobs.value) return; + Future fetchProjectJobs({bool refresh = false}) async { + if (projectId.value.isEmpty) return; + + if (refresh) pageNumber = 1; + if (!hasMoreJobs.value && !refresh) return; isJobLoading.value = true; jobErrorMessage.value = ''; try { final result = await ApiService.getServiceProjectJobListApi( - projectId: projectId.value, // allows empty projectId + projectId: projectId.value, pageNumber: pageNumber, pageSize: pageSize, isActive: true, + isArchive: showArchivedJobs.value, ); if (result != null && result.data != null) { final newJobs = result.data?.data ?? []; - if (pageNumber == 1) { + if (refresh || pageNumber == 1) { jobList.value = newJobs; } else { jobList.addAll(newJobs); } + filteredJobList.value = jobList; + hasMoreJobs.value = newJobs.length == pageSize; if (hasMoreJobs.value) pageNumber++; } else { - jobErrorMessage.value = result?.message ?? "Failed to fetch job list"; + jobErrorMessage.value = result?.message ?? "Failed to fetch jobs"; } } catch (e) { jobErrorMessage.value = "Error fetching jobs: $e"; diff --git a/lib/controller/service_project/service_project_screen_controller.dart b/lib/controller/service_project/service_project_screen_controller.dart index 401b68b..22d4a5c 100644 --- a/lib/controller/service_project/service_project_screen_controller.dart +++ b/lib/controller/service_project/service_project_screen_controller.dart @@ -1,6 +1,6 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/service_project/service_projects_list_model.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/model/service_project/service_projects_list_model.dart'; class ServiceProjectController extends GetxController { final projects = [].obs; diff --git a/lib/controller/task_planning/add_task_controller.dart b/lib/controller/task_planning/add_task_controller.dart index b3df752..6a7ef5e 100644 --- a/lib/controller/task_planning/add_task_controller.dart +++ b/lib/controller/task_planning/add_task_controller.dart @@ -1,9 +1,9 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/widgets/my_form_validator.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/model/dailyTaskPlanning/master_work_category_model.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/widgets/my_form_validator.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/master_work_category_model.dart'; class AddTaskController extends GetxController { RxMap uploadingStates = {}.obs; diff --git a/lib/controller/task_planning/daily_task_controller.dart b/lib/controller/task_planning/daily_task_controller.dart index 7fddd48..7f25e49 100644 --- a/lib/controller/task_planning/daily_task_controller.dart +++ b/lib/controller/task_planning/daily_task_controller.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/project_model.dart'; -import 'package:marco/model/dailyTaskPlanning/daily_task_model.dart'; -import 'package:marco/model/dailyTaskPlanning/daily_progress_report_filter_response_model.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/model/project_model.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/daily_task_model.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/daily_progress_report_filter_response_model.dart'; class DailyTaskController extends GetxController { List projects = []; diff --git a/lib/controller/task_planning/daily_task_planning_controller.dart b/lib/controller/task_planning/daily_task_planning_controller.dart index a0d24df..8ebd877 100644 --- a/lib/controller/task_planning/daily_task_planning_controller.dart +++ b/lib/controller/task_planning/daily_task_planning_controller.dart @@ -1,11 +1,11 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/widgets/my_form_validator.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/model/project_model.dart'; -import 'package:marco/model/dailyTaskPlanning/daily_task_planning_model.dart'; -import 'package:marco/model/employees/employee_model.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/widgets/my_form_validator.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/model/project_model.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/daily_task_planning_model.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; class DailyTaskPlanningController extends GetxController { List projects = []; diff --git a/lib/controller/task_planning/report_task_action_controller.dart b/lib/controller/task_planning/report_task_action_controller.dart index 491e618..91633f2 100644 --- a/lib/controller/task_planning/report_task_action_controller.dart +++ b/lib/controller/task_planning/report_task_action_controller.dart @@ -4,16 +4,16 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:image_picker/image_picker.dart'; -import 'package:marco/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; -import 'package:marco/controller/my_controller.dart'; -import 'package:marco/controller/task_Planning/daily_task_Planning_controller.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/widgets/my_form_validator.dart'; -import 'package:marco/helpers/widgets/my_image_compressor.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/model/dailyTaskPlanning/work_status_model.dart'; -import 'package:marco/helpers/widgets/time_stamp_image_helper.dart'; +import 'package:on_field_work/controller/my_controller.dart'; +import 'package:on_field_work/controller/task_Planning/daily_task_Planning_controller.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/widgets/my_form_validator.dart'; +import 'package:on_field_work/helpers/widgets/my_image_compressor.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/work_status_model.dart'; +import 'package:on_field_work/helpers/widgets/time_stamp_image_helper.dart'; enum ApiStatus { idle, loading, success, failure } diff --git a/lib/controller/task_planning/report_task_controller.dart b/lib/controller/task_planning/report_task_controller.dart index 8aec032..34d0711 100644 --- a/lib/controller/task_planning/report_task_controller.dart +++ b/lib/controller/task_planning/report_task_controller.dart @@ -1,17 +1,17 @@ import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; -import 'package:marco/controller/my_controller.dart'; -import 'package:marco/helpers/widgets/my_form_validator.dart'; -import 'package:marco/helpers/services/api_service.dart'; +import 'package:on_field_work/controller/my_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_form_validator.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/controller/task_Planning/daily_task_Planning_controller.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/controller/task_Planning/daily_task_Planning_controller.dart'; import 'package:image_picker/image_picker.dart'; import 'dart:io'; import 'dart:convert'; -import 'package:marco/helpers/widgets/my_image_compressor.dart'; -import 'package:marco/helpers/widgets/time_stamp_image_helper.dart'; +import 'package:on_field_work/helpers/widgets/my_image_compressor.dart'; +import 'package:on_field_work/helpers/widgets/time_stamp_image_helper.dart'; enum ApiStatus { idle, loading, success, failure } diff --git a/lib/controller/tenant/all_organization_controller.dart b/lib/controller/tenant/all_organization_controller.dart index 75ce2fd..80ea99a 100644 --- a/lib/controller/tenant/all_organization_controller.dart +++ b/lib/controller/tenant/all_organization_controller.dart @@ -1,7 +1,7 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/all_organization_model.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/model/all_organization_model.dart'; class AllOrganizationController extends GetxController { RxList organizations = [].obs; diff --git a/lib/controller/tenant/organization_selection_controller.dart b/lib/controller/tenant/organization_selection_controller.dart index ee6db6e..4b84375 100644 --- a/lib/controller/tenant/organization_selection_controller.dart +++ b/lib/controller/tenant/organization_selection_controller.dart @@ -1,7 +1,7 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/attendance/organization_per_project_list_model.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/model/attendance/organization_per_project_list_model.dart'; class OrganizationController extends GetxController { /// List of organizations assigned to the selected project diff --git a/lib/controller/tenant/service_controller.dart b/lib/controller/tenant/service_controller.dart index f832157..eed1d8f 100644 --- a/lib/controller/tenant/service_controller.dart +++ b/lib/controller/tenant/service_controller.dart @@ -1,7 +1,7 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/model/tenant/tenant_services_model.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/model/tenant/tenant_services_model.dart'; class ServiceController extends GetxController { List services = []; diff --git a/lib/controller/tenant/tenant_selection_controller.dart b/lib/controller/tenant/tenant_selection_controller.dart index 7952e91..c5074be 100644 --- a/lib/controller/tenant/tenant_selection_controller.dart +++ b/lib/controller/tenant/tenant_selection_controller.dart @@ -1,10 +1,10 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/tenant_service.dart'; -import 'package:marco/model/tenant/tenant_list_model.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/controller/permission_controller.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/tenant_service.dart'; +import 'package:on_field_work/model/tenant/tenant_list_model.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; class TenantSelectionController extends GetxController { final TenantService _tenantService = TenantService(); diff --git a/lib/controller/tenant/tenant_switch_controller.dart b/lib/controller/tenant/tenant_switch_controller.dart index 5d73dc7..1ecaa8a 100644 --- a/lib/controller/tenant/tenant_switch_controller.dart +++ b/lib/controller/tenant/tenant_switch_controller.dart @@ -1,10 +1,10 @@ import 'package:get/get.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/tenant_service.dart'; -import 'package:marco/model/tenant/tenant_list_model.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/controller/permission_controller.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/tenant_service.dart'; +import 'package:on_field_work/model/tenant/tenant_list_model.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; class TenantSwitchController extends GetxController { final TenantService _tenantService = TenantService(); diff --git a/lib/controller/ui/buttons_controller.dart b/lib/controller/ui/buttons_controller.dart index 9141c6a..71c61ec 100644 --- a/lib/controller/ui/buttons_controller.dart +++ b/lib/controller/ui/buttons_controller.dart @@ -1,4 +1,4 @@ -import 'package:marco/controller/my_controller.dart'; +import 'package:on_field_work/controller/my_controller.dart'; class ButtonsController extends MyController { List selected = List.filled(3, false); diff --git a/lib/controller/ui/carousels_controller.dart b/lib/controller/ui/carousels_controller.dart index 6f64dc4..b5d6955 100644 --- a/lib/controller/ui/carousels_controller.dart +++ b/lib/controller/ui/carousels_controller.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:carousel_slider/carousel_controller.dart'; -import 'package:marco/controller/my_controller.dart'; +import 'package:on_field_work/controller/my_controller.dart'; import 'package:flutter/material.dart'; class CarouselsController extends MyController { diff --git a/lib/controller/ui/dialogs_controller.dart b/lib/controller/ui/dialogs_controller.dart index 670848f..00fba9d 100644 --- a/lib/controller/ui/dialogs_controller.dart +++ b/lib/controller/ui/dialogs_controller.dart @@ -1,5 +1,5 @@ -import 'package:marco/controller/my_controller.dart'; -import 'package:marco/helpers/widgets/my_text_utils.dart'; +import 'package:on_field_work/controller/my_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text_utils.dart'; class DialogsController extends MyController { List dummyTexts = diff --git a/lib/controller/ui/loaders_controller.dart b/lib/controller/ui/loaders_controller.dart index 55fc120..933d214 100644 --- a/lib/controller/ui/loaders_controller.dart +++ b/lib/controller/ui/loaders_controller.dart @@ -1,3 +1,3 @@ -import 'package:marco/controller/my_controller.dart'; +import 'package:on_field_work/controller/my_controller.dart'; class LoadersController extends MyController {} diff --git a/lib/controller/ui/modal_controller.dart b/lib/controller/ui/modal_controller.dart index e1f5660..9fcd3d3 100644 --- a/lib/controller/ui/modal_controller.dart +++ b/lib/controller/ui/modal_controller.dart @@ -1,5 +1,5 @@ -import 'package:marco/controller/my_controller.dart'; -import 'package:marco/helpers/widgets/my_text_utils.dart'; +import 'package:on_field_work/controller/my_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text_utils.dart'; import 'package:flutter/animation.dart'; import 'package:flutter/material.dart'; diff --git a/lib/controller/ui/notification_controller.dart b/lib/controller/ui/notification_controller.dart index 5a02ff2..d78a484 100644 --- a/lib/controller/ui/notification_controller.dart +++ b/lib/controller/ui/notification_controller.dart @@ -1,10 +1,10 @@ import 'dart:async'; -import 'package:marco/controller/my_controller.dart'; -import 'package:marco/helpers/extensions/string.dart'; -import 'package:marco/helpers/theme/admin_theme.dart'; -import 'package:marco/helpers/widgets/my_button.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/controller/my_controller.dart'; +import 'package:on_field_work/helpers/extensions/string.dart'; +import 'package:on_field_work/helpers/theme/admin_theme.dart'; +import 'package:on_field_work/helpers/widgets/my_button.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; diff --git a/lib/controller/ui/tabs_controller.dart b/lib/controller/ui/tabs_controller.dart index 77789ca..57641bc 100644 --- a/lib/controller/ui/tabs_controller.dart +++ b/lib/controller/ui/tabs_controller.dart @@ -1,5 +1,5 @@ -import 'package:marco/controller/my_controller.dart'; -import 'package:marco/helpers/widgets/my_text_utils.dart'; +import 'package:on_field_work/controller/my_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text_utils.dart'; import 'package:flutter/material.dart'; class TabsController extends MyController { diff --git a/lib/controller/ui/toast_message_controller.dart b/lib/controller/ui/toast_message_controller.dart index 61c4656..232036f 100644 --- a/lib/controller/ui/toast_message_controller.dart +++ b/lib/controller/ui/toast_message_controller.dart @@ -1,4 +1,4 @@ -import 'package:marco/controller/my_controller.dart'; +import 'package:on_field_work/controller/my_controller.dart'; import 'package:flutter/material.dart'; class ToastMessageController extends MyController { diff --git a/lib/helpers/extensions/app_localization_delegate.dart b/lib/helpers/extensions/app_localization_delegate.dart index 4668e1e..a9c87f7 100644 --- a/lib/helpers/extensions/app_localization_delegate.dart +++ b/lib/helpers/extensions/app_localization_delegate.dart @@ -1,5 +1,5 @@ -import 'package:marco/helpers/services/localizations/language.dart'; -import 'package:marco/helpers/theme/app_notifier.dart'; +import 'package:on_field_work/helpers/services/localizations/language.dart'; +import 'package:on_field_work/helpers/theme/app_notifier.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; diff --git a/lib/helpers/extensions/string.dart b/lib/helpers/extensions/string.dart index 0e818c3..da4627c 100644 --- a/lib/helpers/extensions/string.dart +++ b/lib/helpers/extensions/string.dart @@ -1,5 +1,5 @@ import 'dart:ui'; -import 'package:marco/helpers/services/localizations/translator.dart'; +import 'package:on_field_work/helpers/services/localizations/translator.dart'; extension StringUtil on String { Color get toColor { diff --git a/lib/helpers/services/api_endpoints.dart b/lib/helpers/services/api_endpoints.dart index 8b5b277..743c8e1 100644 --- a/lib/helpers/services/api_endpoints.dart +++ b/lib/helpers/services/api_endpoints.dart @@ -3,6 +3,8 @@ class ApiEndpoints { // static const String baseUrl = "https://api.marcoaiot.com/api"; // static const String baseUrl = "https://devapi.marcoaiot.com/api"; // static const String baseUrl = "https://mapi.marcoaiot.com/api"; + // static const String baseUrl = "https://api.onfieldwork.com/api"; + static const String getMasterCurrencies = "/Master/currencies/list"; static const String getMasterExpensesCategories = @@ -145,8 +147,9 @@ class ApiEndpoints { static const String editServiceProjectJob = "/serviceproject/job/edit"; static const String createServiceProjectJob = "/serviceproject/job/create"; static const String serviceProjectUpateJobAttendance = "/serviceproject/job/attendance"; - static const String serviceProjectUpateJobAttendanceLog = "/job/attendance/log"; + static const String serviceProjectUpateJobAttendanceLog = "/serviceproject/job/attendance/log"; static const String getServiceProjectUpateJobAllocationList = "/serviceproject/get/allocation/list"; static const String manageServiceProjectUpateJobAllocation = "/serviceproject/manage/allocation"; static const String getTeamRoles = "/master/team-roles/list"; + static const String getServiceProjectBranches = "/serviceproject/branch/list"; } diff --git a/lib/helpers/services/api_service.dart b/lib/helpers/services/api_service.dart index f3d7ce2..2c22e46 100644 --- a/lib/helpers/services/api_service.dart +++ b/lib/helpers/services/api_service.dart @@ -4,41 +4,42 @@ import 'package:http/http.dart' as http; import 'package:image_picker/image_picker.dart'; import 'package:intl/intl.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/helpers/services/api_endpoints.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/helpers/services/api_endpoints.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; import 'package:jwt_decoder/jwt_decoder.dart'; -import 'package:marco/model/dashboard/project_progress_model.dart'; -import 'package:marco/model/dashboard/dashboard_tasks_model.dart'; -import 'package:marco/model/dashboard/dashboard_teams_model.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/model/document/document_filter_model.dart'; -import 'package:marco/model/document/documents_list_model.dart'; -import 'package:marco/model/document/master_document_tags.dart'; -import 'package:marco/model/document/master_document_type_model.dart'; -import 'package:marco/model/document/document_details_model.dart'; -import 'package:marco/model/document/document_version_model.dart'; -import 'package:marco/model/attendance/organization_per_project_list_model.dart'; -import 'package:marco/model/tenant/tenant_services_model.dart'; -import 'package:marco/model/dailyTaskPlanning/daily_task_model.dart'; -import 'package:marco/model/dailyTaskPlanning/daily_progress_report_filter_response_model.dart'; -import 'package:marco/model/all_organization_model.dart'; -import 'package:marco/model/dashboard/pending_expenses_model.dart'; -import 'package:marco/model/dashboard/expense_type_report_model.dart'; -import 'package:marco/model/dashboard/monthly_expence_model.dart'; -import 'package:marco/model/finance/expense_category_model.dart'; -import 'package:marco/model/finance/currency_list_model.dart'; -import 'package:marco/model/finance/payment_payee_request_model.dart'; -import 'package:marco/model/finance/payment_request_list_model.dart'; -import 'package:marco/model/finance/payment_request_filter.dart'; -import 'package:marco/model/finance/payment_request_details_model.dart'; -import 'package:marco/model/finance/advance_payment_model.dart'; -import 'package:marco/model/service_project/service_projects_list_model.dart'; -import 'package:marco/model/service_project/service_projects_details_model.dart'; -import 'package:marco/model/service_project/job_list_model.dart'; -import 'package:marco/model/service_project/service_project_job_detail_model.dart'; -import 'package:marco/model/service_project/job_attendance_logs_model.dart'; -import 'package:marco/model/service_project/job_allocation_model.dart'; +import 'package:on_field_work/model/dashboard/project_progress_model.dart'; +import 'package:on_field_work/model/dashboard/dashboard_tasks_model.dart'; +import 'package:on_field_work/model/dashboard/dashboard_teams_model.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/model/document/document_filter_model.dart'; +import 'package:on_field_work/model/document/documents_list_model.dart'; +import 'package:on_field_work/model/document/master_document_tags.dart'; +import 'package:on_field_work/model/document/master_document_type_model.dart'; +import 'package:on_field_work/model/document/document_details_model.dart'; +import 'package:on_field_work/model/document/document_version_model.dart'; +import 'package:on_field_work/model/attendance/organization_per_project_list_model.dart'; +import 'package:on_field_work/model/tenant/tenant_services_model.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/daily_task_model.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/daily_progress_report_filter_response_model.dart'; +import 'package:on_field_work/model/all_organization_model.dart'; +import 'package:on_field_work/model/dashboard/pending_expenses_model.dart'; +import 'package:on_field_work/model/dashboard/expense_type_report_model.dart'; +import 'package:on_field_work/model/dashboard/monthly_expence_model.dart'; +import 'package:on_field_work/model/finance/expense_category_model.dart'; +import 'package:on_field_work/model/finance/currency_list_model.dart'; +import 'package:on_field_work/model/finance/payment_payee_request_model.dart'; +import 'package:on_field_work/model/finance/payment_request_list_model.dart'; +import 'package:on_field_work/model/finance/payment_request_filter.dart'; +import 'package:on_field_work/model/finance/payment_request_details_model.dart'; +import 'package:on_field_work/model/finance/advance_payment_model.dart'; +import 'package:on_field_work/model/service_project/service_projects_list_model.dart'; +import 'package:on_field_work/model/service_project/service_projects_details_model.dart'; +import 'package:on_field_work/model/service_project/job_list_model.dart'; +import 'package:on_field_work/model/service_project/service_project_job_detail_model.dart'; +import 'package:on_field_work/model/service_project/job_attendance_logs_model.dart'; +import 'package:on_field_work/model/service_project/job_allocation_model.dart'; +import 'package:on_field_work/model/service_project/service_project_branches_model.dart'; class ApiService { static const bool enableLogs = true; @@ -310,6 +311,51 @@ class ApiService { } } + /// Fetch Service Project Branches with full response + static Future getServiceProjectBranchesFull({ + required String projectId, + int pageNumber = 1, + int pageSize = 20, + String searchString = '', + bool isActive = true, + }) async { + final queryParams = { + 'pageNumber': pageNumber.toString(), + 'pageSize': pageSize.toString(), + 'searchString': searchString, + 'isActive': isActive.toString(), + }; + + final endpoint = "${ApiEndpoints.getServiceProjectBranches}/$projectId"; + + try { + final response = await _getRequest( + endpoint, + queryParams: queryParams, + ); + + if (response == null) { + _log("getServiceProjectBranchesFull: No response received."); + return null; + } + + final parsedJson = _parseResponseForAllData( + response, + label: "ServiceProjectBranchesFull", + ); + + if (parsedJson == null) return null; + + return ServiceProjectBranchesResponse.fromJson(parsedJson); + } catch (e, stack) { + _log( + "Exception in getServiceProjectBranchesFull: $e\n$stack", + level: LogLevel.error, + ); + return null; + } + } + // Service Project Module APIs static Future?> getTeamRoles() async { try { @@ -558,6 +604,7 @@ class ApiService { required DateTime startDate, required DateTime dueDate, required List> tags, + required String? branchId, }) async { const endpoint = ApiEndpoints.createServiceProjectJob; logSafe("Creating Service Project Job for projectId: $projectId"); @@ -570,6 +617,7 @@ class ApiService { "startDate": startDate.toIso8601String(), "dueDate": dueDate.toIso8601String(), "tags": tags, + "projectBranchId": branchId, }; try { @@ -604,15 +652,18 @@ class ApiService { } } - /// Get Service Project Job List + /// Get Service Project Job List (Active or Archived) static Future getServiceProjectJobListApi({ required String projectId, int pageNumber = 1, int pageSize = 20, bool isActive = true, + bool isArchive = false, // new parameter to fetch archived jobs }) async { const endpoint = ApiEndpoints.getServiceProjectJobList; - logSafe("Fetching Job List for Service Project: $projectId"); + logSafe( + "Fetching Job List for Service Project: $projectId | isActive: $isActive | isArchive: $isArchive", + ); try { final queryParams = { @@ -620,27 +671,35 @@ class ApiService { 'pageNumber': pageNumber.toString(), 'pageSize': pageSize.toString(), 'isActive': isActive.toString(), + if (isArchive) + 'isArchive': 'true', }; final response = await _getRequest(endpoint, queryParams: queryParams); if (response == null) { - logSafe("Service Project Job List request failed: null response", - level: LogLevel.error); + logSafe( + "Service Project Job List request failed: null response", + level: LogLevel.error, + ); return null; } final jsonResponse = _parseResponseForAllData( response, - label: "Service Project Job List", + label: isArchive + ? "Archived Service Project Job List" + : "Active Service Project Job List", ); if (jsonResponse != null) { return JobResponse.fromJson(jsonResponse); } } catch (e, stack) { - logSafe("Exception during getServiceProjectJobListApi: $e", - level: LogLevel.error); + logSafe( + "Exception during getServiceProjectJobListApi: $e", + level: LogLevel.error, + ); logSafe("StackTrace: $stack", level: LogLevel.debug); } @@ -1281,14 +1340,14 @@ class ApiService { return null; } - /// Get Expense Type Report + /// Get Expense Category Report static Future getExpenseTypeReportApi({ required String projectId, required DateTime startDate, required DateTime endDate, }) async { const endpoint = ApiEndpoints.getExpenseTypeReport; - logSafe("Fetching Expense Type Report for projectId: $projectId"); + logSafe("Fetching Expense Category Report for projectId: $projectId"); try { final response = await _getRequest( @@ -1301,13 +1360,13 @@ class ApiService { ); if (response == null) { - logSafe("Expense Type Report request failed: null response", + logSafe("Expense Category Report request failed: null response", level: LogLevel.error); return null; } final jsonResponse = - _parseResponseForAllData(response, label: "Expense Type Report"); + _parseResponseForAllData(response, label: "Expense Category Report"); if (jsonResponse != null) { return ExpenseTypeReportResponse.fromJson(jsonResponse); @@ -2380,11 +2439,11 @@ class ApiService { : null); } - /// Fetch Master Expense Types + /// Fetch Master Expense Categorys static Future?> getMasterExpenseTypes() async { const endpoint = ApiEndpoints.getMasterExpenseCategory; return _getRequest(endpoint).then((res) => res != null - ? _parseResponse(res, label: 'Master Expense Types') + ? _parseResponse(res, label: 'Master Expense Categorys') : null); } diff --git a/lib/helpers/services/app_initializer.dart b/lib/helpers/services/app_initializer.dart index acd9b88..1196355 100644 --- a/lib/helpers/services/app_initializer.dart +++ b/lib/helpers/services/app_initializer.dart @@ -1,13 +1,13 @@ import 'package:flutter/services.dart'; import 'package:url_strategy/url_strategy.dart'; import 'package:firebase_core/firebase_core.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/helpers/services/firebase/firebase_messaging_service.dart'; -import 'package:marco/helpers/services/device_info_service.dart'; -import 'package:marco/helpers/theme/theme_customizer.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/helpers/services/firebase/firebase_messaging_service.dart'; +import 'package:on_field_work/helpers/services/device_info_service.dart'; +import 'package:on_field_work/helpers/theme/theme_customizer.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; Future initializeApp() async { try { diff --git a/lib/helpers/services/app_logger.dart b/lib/helpers/services/app_logger.dart index 1e631ea..d67a41d 100644 --- a/lib/helpers/services/app_logger.dart +++ b/lib/helpers/services/app_logger.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'package:logger/logger.dart'; import 'package:intl/intl.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:marco/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; /// Global logger instance Logger? _appLogger; diff --git a/lib/helpers/services/auth_service.dart b/lib/helpers/services/auth_service.dart index 8bbe2da..7582157 100644 --- a/lib/helpers/services/auth_service.dart +++ b/lib/helpers/services/auth_service.dart @@ -1,8 +1,8 @@ import 'dart:convert'; import 'package:http/http.dart' as http; -import 'package:marco/helpers/services/api_endpoints.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/api_endpoints.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; class AuthService { static const String _baseUrl = ApiEndpoints.baseUrl; diff --git a/lib/helpers/services/firebase/firebase_messaging_service.dart b/lib/helpers/services/firebase/firebase_messaging_service.dart index 1ac8c60..b908454 100644 --- a/lib/helpers/services/firebase/firebase_messaging_service.dart +++ b/lib/helpers/services/firebase/firebase_messaging_service.dart @@ -1,10 +1,10 @@ import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:logger/logger.dart'; -import 'package:marco/helpers/services/local_notification_service.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/helpers/services/notification_action_handler.dart'; +import 'package:on_field_work/helpers/services/local_notification_service.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/helpers/services/notification_action_handler.dart'; /// Firebase Notification Service class FirebaseNotificationService { diff --git a/lib/helpers/services/localizations/language.dart b/lib/helpers/services/localizations/language.dart index 58a96a8..fe054dc 100644 --- a/lib/helpers/services/localizations/language.dart +++ b/lib/helpers/services/localizations/language.dart @@ -1,5 +1,5 @@ -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/theme/theme_customizer.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/theme/theme_customizer.dart'; import 'package:flutter/material.dart'; class Language { diff --git a/lib/helpers/services/localizations/translator.dart b/lib/helpers/services/localizations/translator.dart index aef7dc0..1d96ef1 100644 --- a/lib/helpers/services/localizations/translator.dart +++ b/lib/helpers/services/localizations/translator.dart @@ -1,7 +1,7 @@ import 'dart:convert'; import 'dart:developer'; -import 'package:marco/helpers/services/localizations/language.dart'; +import 'package:on_field_work/helpers/services/localizations/language.dart'; import 'package:flutter/services.dart'; import 'package:get/get_utils/src/extensions/string_extensions.dart'; import 'package:shared_preferences/shared_preferences.dart'; diff --git a/lib/helpers/services/notification_action_handler.dart b/lib/helpers/services/notification_action_handler.dart index e799668..cbb57f0 100644 --- a/lib/helpers/services/notification_action_handler.dart +++ b/lib/helpers/services/notification_action_handler.dart @@ -1,17 +1,17 @@ import 'package:get/get.dart'; import 'package:logger/logger.dart'; -import 'package:marco/controller/attendance/attendance_screen_controller.dart'; -import 'package:marco/controller/task_planning/daily_task_controller.dart'; -import 'package:marco/controller/task_Planning/daily_task_Planning_controller.dart'; -import 'package:marco/controller/expense/expense_screen_controller.dart'; -import 'package:marco/controller/expense/expense_detail_controller.dart'; -import 'package:marco/controller/directory/directory_controller.dart'; -import 'package:marco/controller/directory/notes_controller.dart'; -import 'package:marco/controller/document/user_document_controller.dart'; -import 'package:marco/controller/document/document_details_controller.dart'; -import 'package:marco/controller/dashboard/dashboard_controller.dart'; -import 'package:marco/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/controller/attendance/attendance_screen_controller.dart'; +import 'package:on_field_work/controller/task_planning/daily_task_controller.dart'; +import 'package:on_field_work/controller/task_Planning/daily_task_Planning_controller.dart'; +import 'package:on_field_work/controller/expense/expense_screen_controller.dart'; +import 'package:on_field_work/controller/expense/expense_detail_controller.dart'; +import 'package:on_field_work/controller/directory/directory_controller.dart'; +import 'package:on_field_work/controller/directory/notes_controller.dart'; +import 'package:on_field_work/controller/document/user_document_controller.dart'; +import 'package:on_field_work/controller/document/document_details_controller.dart'; +import 'package:on_field_work/controller/dashboard/dashboard_controller.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; /// Handles incoming FCM notification actions and updates UI/controllers. class NotificationActionHandler { @@ -414,12 +414,17 @@ class NotificationActionHandler { required String notFoundMessage, required String successMessage, }) { + if (!Get.isRegistered()) { + _logger.w(notFoundMessage); + return; + } + try { final controller = Get.find(); onFound(controller); _logger.i(successMessage); } catch (e) { - _logger.w(notFoundMessage); + _logger.w('⚠️ Error updating controller: $e'); } } } diff --git a/lib/helpers/services/permission_service.dart b/lib/helpers/services/permission_service.dart index c3ee52e..0093e05 100644 --- a/lib/helpers/services/permission_service.dart +++ b/lib/helpers/services/permission_service.dart @@ -2,13 +2,13 @@ import 'dart:convert'; import 'package:get/get.dart'; import 'package:http/http.dart' as http; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/model/user_permission.dart'; -import 'package:marco/model/employees/employee_info.dart'; -import 'package:marco/model/projects_model.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/helpers/services/api_endpoints.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/model/user_permission.dart'; +import 'package:on_field_work/model/employees/employee_info.dart'; +import 'package:on_field_work/model/projects_model.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/helpers/services/api_endpoints.dart'; class PermissionService { // In-memory cache keyed by user token diff --git a/lib/helpers/services/storage/local_storage.dart b/lib/helpers/services/storage/local_storage.dart index b47dda4..d71d514 100644 --- a/lib/helpers/services/storage/local_storage.dart +++ b/lib/helpers/services/storage/local_storage.dart @@ -2,13 +2,13 @@ import 'dart:convert'; import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/helpers/services/localizations/language.dart'; -import 'package:marco/helpers/theme/theme_customizer.dart'; -import 'package:marco/model/employees/employee_info.dart'; -import 'package:marco/model/user_permission.dart'; -import 'package:marco/model/dynamicMenu/dynamic_menu_model.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/helpers/services/localizations/language.dart'; +import 'package:on_field_work/helpers/theme/theme_customizer.dart'; +import 'package:on_field_work/model/employees/employee_info.dart'; +import 'package:on_field_work/model/user_permission.dart'; +import 'package:on_field_work/model/dynamicMenu/dynamic_menu_model.dart'; class LocalStorage { static const String _loggedInUserKey = "user"; diff --git a/lib/helpers/services/tenant_service.dart b/lib/helpers/services/tenant_service.dart index 3d9be30..5a574c7 100644 --- a/lib/helpers/services/tenant_service.dart +++ b/lib/helpers/services/tenant_service.dart @@ -1,13 +1,13 @@ import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:get/get.dart'; -import 'package:marco/controller/project_controller.dart'; +import 'package:on_field_work/controller/project_controller.dart'; -import 'package:marco/helpers/services/api_endpoints.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/model/tenant/tenant_list_model.dart'; +import 'package:on_field_work/helpers/services/api_endpoints.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/model/tenant/tenant_list_model.dart'; /// Abstract interface for tenant service functionality abstract class ITenantService { @@ -63,29 +63,39 @@ class TenantService implements ITenantService { {bool hasRetried = false}) async { try { final headers = await _authorizedHeaders(); - logSafe("➡️ GET $_baseUrl/auth/get/user/tenants\nHeaders: $headers", - level: LogLevel.info); - final response = await http - .get(Uri.parse("$_baseUrl/auth/get/user/tenants"), headers: headers); - final data = jsonDecode(response.body); + final response = await http.get( + Uri.parse("$_baseUrl/auth/get/user/tenants"), + headers: headers, + ); - logSafe( - "⬅️ Response: ${jsonEncode(data)} [Status: ${response.statusCode}]", - level: LogLevel.info); - - if (response.statusCode == 200 && data['success'] == true) { - logSafe("✅ Tenants fetched successfully."); - return List>.from(data['data']); + // ✅ Handle empty response BEFORE decoding + if (response.body.isEmpty || response.body.trim().isEmpty) { + logSafe("❌ Empty tenant response — auto logout"); + await LocalStorage.logout(); + return null; } + Map data; + try { + data = jsonDecode(response.body); + } catch (e) { + logSafe("❌ Invalid JSON in tenant response — auto logout"); + await LocalStorage.logout(); + return null; + } + + // SUCCESS CASE + if (response.statusCode == 200 && data['success'] == true) { + final list = data['data']; + if (list is! List) return null; + return List>.from(list); + } + + // TOKEN EXPIRED if (response.statusCode == 401 && !hasRetried) { - logSafe("⚠️ Unauthorized while fetching tenants. Refreshing token...", - level: LogLevel.warning); final refreshed = await AuthService.refreshToken(); if (refreshed) return getTenants(hasRetried: true); - logSafe("❌ Token refresh failed while fetching tenants.", - level: LogLevel.error); return null; } @@ -130,7 +140,7 @@ class TenantService implements ITenantService { } // 🔹 Register FCM token after tenant selection - final fcmToken = LocalStorage.getFcmToken(); + final fcmToken = LocalStorage.getFcmToken(); if (fcmToken?.isNotEmpty ?? false) { final success = await AuthService.registerDeviceToken(fcmToken!); logSafe( diff --git a/lib/helpers/theme/admin_theme.dart b/lib/helpers/theme/admin_theme.dart index 55d5680..4354a12 100644 --- a/lib/helpers/theme/admin_theme.dart +++ b/lib/helpers/theme/admin_theme.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:marco/helpers/theme/theme_customizer.dart'; +import 'package:on_field_work/helpers/theme/theme_customizer.dart'; enum LeftBarThemeType { light, dark } enum ContentThemeType { light, dark } diff --git a/lib/helpers/theme/app_notifier.dart b/lib/helpers/theme/app_notifier.dart index de68471..e2306df 100644 --- a/lib/helpers/theme/app_notifier.dart +++ b/lib/helpers/theme/app_notifier.dart @@ -1,8 +1,8 @@ -import 'package:marco/helpers/services/localizations/language.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/theme/theme_customizer.dart'; -import 'package:marco/helpers/widgets/my.dart'; +import 'package:on_field_work/helpers/services/localizations/language.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/theme/theme_customizer.dart'; +import 'package:on_field_work/helpers/widgets/my.dart'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; diff --git a/lib/helpers/theme/app_theme.dart b/lib/helpers/theme/app_theme.dart index 1d3e8bb..f994415 100644 --- a/lib/helpers/theme/app_theme.dart +++ b/lib/helpers/theme/app_theme.dart @@ -6,13 +6,13 @@ * */ import 'dart:io'; import 'dart:math'; -import 'package:marco/helpers/theme/admin_theme.dart'; -import 'package:marco/helpers/theme/theme_customizer.dart'; -import 'package:marco/helpers/widgets/my.dart'; -import 'package:marco/helpers/widgets/my_breadcrumb_item.dart'; -import 'package:marco/helpers/widgets/my_constant.dart'; -import 'package:marco/helpers/widgets/my_screen_media.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/helpers/theme/admin_theme.dart'; +import 'package:on_field_work/helpers/theme/theme_customizer.dart'; +import 'package:on_field_work/helpers/widgets/my.dart'; +import 'package:on_field_work/helpers/widgets/my_breadcrumb_item.dart'; +import 'package:on_field_work/helpers/widgets/my_constant.dart'; +import 'package:on_field_work/helpers/widgets/my_screen_media.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -230,7 +230,7 @@ class AppStyle { containerRadius: AppStyle.containerRadius.medium, cardRadius: AppStyle.cardRadius.medium, buttonRadius: AppStyle.buttonRadius.medium, - defaultBreadCrumbItem: MyBreadcrumbItem(name: 'Marco', route: '/client/dashboard'), + defaultBreadCrumbItem: MyBreadcrumbItem(name: 'On Field Work', route: '/client/dashboard'), )); bool isMobile = true; try { diff --git a/lib/helpers/theme/theme_customizer.dart b/lib/helpers/theme/theme_customizer.dart index 7c2eeaf..e785d33 100644 --- a/lib/helpers/theme/theme_customizer.dart +++ b/lib/helpers/theme/theme_customizer.dart @@ -1,12 +1,12 @@ import 'dart:convert'; import 'package:flutter/material.dart'; -import 'package:marco/helpers/services/json_decoder.dart'; -import 'package:marco/helpers/services/localizations/language.dart'; -import 'package:marco/helpers/services/localizations/translator.dart'; -import 'package:marco/helpers/services/navigation_services.dart'; -import 'package:marco/helpers/theme/admin_theme.dart'; -import 'package:marco/helpers/theme/app_notifier.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/services/json_decoder.dart'; +import 'package:on_field_work/helpers/services/localizations/language.dart'; +import 'package:on_field_work/helpers/services/localizations/translator.dart'; +import 'package:on_field_work/helpers/services/navigation_services.dart'; +import 'package:on_field_work/helpers/theme/admin_theme.dart'; +import 'package:on_field_work/helpers/theme/app_notifier.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; diff --git a/lib/helpers/theme/theme_editor_widget.dart b/lib/helpers/theme/theme_editor_widget.dart index 05b2561..0a49c45 100644 --- a/lib/helpers/theme/theme_editor_widget.dart +++ b/lib/helpers/theme/theme_editor_widget.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/wave_background.dart'; -import 'package:marco/helpers/theme/admin_theme.dart'; -import 'package:marco/helpers/theme/theme_customizer.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/wave_background.dart'; +import 'package:on_field_work/helpers/theme/admin_theme.dart'; +import 'package:on_field_work/helpers/theme/theme_customizer.dart'; class ThemeOption { final String label; diff --git a/lib/helpers/utils/base_bottom_sheet.dart b/lib/helpers/utils/base_bottom_sheet.dart index c2094e1..db496ce 100644 --- a/lib/helpers/utils/base_bottom_sheet.dart +++ b/lib/helpers/utils/base_bottom_sheet.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; class BaseBottomSheet extends StatefulWidget { final String title; diff --git a/lib/helpers/utils/contact_picker_helper.dart b/lib/helpers/utils/contact_picker_helper.dart index 73c2840..b7ef560 100644 --- a/lib/helpers/utils/contact_picker_helper.dart +++ b/lib/helpers/utils/contact_picker_helper.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; import 'package:permission_handler/permission_handler.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; class ContactPickerHelper { static Future pickIndianPhoneNumber(BuildContext context) async { diff --git a/lib/helpers/utils/launcher_utils.dart b/lib/helpers/utils/launcher_utils.dart index 5733bd6..3c7d560 100644 --- a/lib/helpers/utils/launcher_utils.dart +++ b/lib/helpers/utils/launcher_utils.dart @@ -1,7 +1,7 @@ import 'package:flutter/services.dart'; import 'package:url_launcher/url_launcher.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; class LauncherUtils { /// Launches the phone dialer with the provided phone number diff --git a/lib/helpers/utils/mixins/ui_mixin.dart b/lib/helpers/utils/mixins/ui_mixin.dart index 5467112..74cbcb1 100644 --- a/lib/helpers/utils/mixins/ui_mixin.dart +++ b/lib/helpers/utils/mixins/ui_mixin.dart @@ -1,7 +1,7 @@ -import 'package:marco/helpers/theme/admin_theme.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/widgets/my_dashed_divider.dart'; -import 'package:marco/helpers/widgets/my_navigation_mixin.dart'; +import 'package:on_field_work/helpers/theme/admin_theme.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/widgets/my_dashed_divider.dart'; +import 'package:on_field_work/helpers/widgets/my_navigation_mixin.dart'; import 'package:flutter/material.dart'; mixin UIMixin { diff --git a/lib/helpers/utils/permission_constants.dart b/lib/helpers/utils/permission_constants.dart index a5e9036..b5e3b2c 100644 --- a/lib/helpers/utils/permission_constants.dart +++ b/lib/helpers/utils/permission_constants.dart @@ -161,6 +161,30 @@ class MenuItems { /// Documents menu static const String documents = "92d2cc39-9e6a-46b2-ae50-84fbf83c95d3"; - /// Service Projects + /// Service Projects static const String serviceProjects = "7faddfe7-994b-4712-91c2-32ba44129d9b"; } + +/// Contains all job status IDs used across the application. +class JobStatus { + /// Level 1 - New + static const String newStatus = "32d76a02-8f44-4aa0-9b66-c3716c45a918"; + + /// Level 2 - Assigned + static const String assigned = "cfa1886d-055f-4ded-84c6-42a2a8a14a66"; + + /// Level 3 - In Progress + static const String inProgress = "5a6873a5-fed7-4745-a52f-8f61bf3bd72d"; + + /// Level 4 - Work Done + static const String workDone = "aab71020-2fb8-44d9-9430-c9a7e9bf33b0"; + + /// Level 5 - Review Done + static const String reviewDone = "ed10ab57-dbaa-4ca5-8ecd-56745dcbdbd7"; + + /// Level 6 - Closed + static const String closed = "3ddeefb5-ae3c-4e10-a922-35e0a452bb69"; + + /// Level 7 - On Hold + static const String onHold = "75a0c8b8-9c6a-41af-80bf-b35bab722eb2"; +} diff --git a/lib/helpers/utils/utils.dart b/lib/helpers/utils/utils.dart index 8a72760..b132652 100644 --- a/lib/helpers/utils/utils.dart +++ b/lib/helpers/utils/utils.dart @@ -1,5 +1,5 @@ import 'package:intl/intl.dart'; -import 'package:marco/helpers/extensions/date_time_extension.dart'; +import 'package:on_field_work/helpers/extensions/date_time_extension.dart'; class Utils { static getDateStringFromDateTime(DateTime dateTime, diff --git a/lib/helpers/widgets/avatar.dart b/lib/helpers/widgets/avatar.dart index c206631..a816649 100644 --- a/lib/helpers/widgets/avatar.dart +++ b/lib/helpers/widgets/avatar.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; class Avatar extends StatelessWidget { final String firstName; diff --git a/lib/helpers/widgets/custom_app_bar.dart b/lib/helpers/widgets/custom_app_bar.dart index 0b39ad0..6d3159f 100644 --- a/lib/helpers/widgets/custom_app_bar.dart +++ b/lib/helpers/widgets/custom_app_bar.dart @@ -1,16 +1,18 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; class CustomAppBar extends StatelessWidget implements PreferredSizeWidget { final String title; + final String? projectName; final VoidCallback? onBackPressed; const CustomAppBar({ super.key, required this.title, + this.projectName, this.onBackPressed, }); @@ -51,21 +53,26 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget { MySpacing.height(2), - // PROJECT NAME ROW (copied exactly) + // PROJECT NAME ROW GetBuilder( builder: (projectController) { - final projectName = + // NEW LOGIC — simple and safe + final displayProjectName = + projectName ?? projectController.selectedProject?.name ?? - 'Select Project'; + 'Select Project'; return Row( children: [ - const Icon(Icons.work_outline, - size: 14, color: Colors.grey), + const Icon( + Icons.work_outline, + size: 14, + color: Colors.grey, + ), MySpacing.width(4), Expanded( child: MyText.bodySmall( - projectName, + displayProjectName, fontWeight: 600, overflow: TextOverflow.ellipsis, color: Colors.grey[700], diff --git a/lib/helpers/widgets/dashbaord/attendance_overview_chart.dart b/lib/helpers/widgets/dashbaord/attendance_overview_chart.dart index e0f1fad..52c78f0 100644 --- a/lib/helpers/widgets/dashbaord/attendance_overview_chart.dart +++ b/lib/helpers/widgets/dashbaord/attendance_overview_chart.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; -import 'package:marco/controller/dashboard/dashboard_controller.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/controller/dashboard/dashboard_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; class AttendanceDashboardChart extends StatelessWidget { AttendanceDashboardChart({Key? key}) : super(key: key); diff --git a/lib/helpers/widgets/dashbaord/dashboard_overview_widgets.dart b/lib/helpers/widgets/dashbaord/dashboard_overview_widgets.dart index 3ced75a..f6ae671 100644 --- a/lib/helpers/widgets/dashbaord/dashboard_overview_widgets.dart +++ b/lib/helpers/widgets/dashbaord/dashboard_overview_widgets.dart @@ -4,10 +4,10 @@ import 'package:intl/intl.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; // Assuming these exist in the project -import 'package:marco/controller/dashboard/dashboard_controller.dart'; -import 'package:marco/helpers/widgets/my_card.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/controller/dashboard/dashboard_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_card.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; class DashboardOverviewWidgets { static final DashboardController dashboardController = diff --git a/lib/helpers/widgets/dashbaord/expense_breakdown_chart.dart b/lib/helpers/widgets/dashbaord/expense_breakdown_chart.dart index 9dc6efc..bf60c1c 100644 --- a/lib/helpers/widgets/dashbaord/expense_breakdown_chart.dart +++ b/lib/helpers/widgets/dashbaord/expense_breakdown_chart.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; -import 'package:marco/controller/dashboard/dashboard_controller.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/model/dashboard/expense_type_report_model.dart'; -import 'package:marco/helpers/utils/utils.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/controller/dashboard/dashboard_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/model/dashboard/expense_type_report_model.dart'; +import 'package:on_field_work/helpers/utils/utils.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; class ExpenseTypeReportChart extends StatelessWidget { ExpenseTypeReportChart({Key? key}) : super(key: key); diff --git a/lib/helpers/widgets/dashbaord/expense_by_status_widget.dart b/lib/helpers/widgets/dashbaord/expense_by_status_widget.dart index 9d10826..cf80f6f 100644 --- a/lib/helpers/widgets/dashbaord/expense_by_status_widget.dart +++ b/lib/helpers/widgets/dashbaord/expense_by_status_widget.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/dashboard/dashboard_controller.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/utils/utils.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; -import 'package:marco/controller/expense/expense_screen_controller.dart'; -import 'package:marco/view/expense/expense_screen.dart'; +import 'package:on_field_work/controller/dashboard/dashboard_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/utils/utils.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/controller/expense/expense_screen_controller.dart'; +import 'package:on_field_work/view/expense/expense_screen.dart'; import 'package:collection/collection.dart'; class ExpenseByStatusWidget extends StatelessWidget { diff --git a/lib/helpers/widgets/dashbaord/monthly_expense_dashboard_chart.dart b/lib/helpers/widgets/dashbaord/monthly_expense_dashboard_chart.dart index d3e27cf..e438d00 100644 --- a/lib/helpers/widgets/dashbaord/monthly_expense_dashboard_chart.dart +++ b/lib/helpers/widgets/dashbaord/monthly_expense_dashboard_chart.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; -import 'package:marco/controller/dashboard/dashboard_controller.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/utils/utils.dart'; +import 'package:on_field_work/controller/dashboard/dashboard_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/utils/utils.dart'; import 'package:intl/intl.dart'; // ========================= @@ -203,7 +203,7 @@ class _ChartHeader extends StatelessWidget { final selectedType = controller.selectedExpenseType.value; return PopupMenuButton( - tooltip: 'Filter by Expense Type', + tooltip: 'Filter by Expense Category', onSelected: (String value) { if (value == 'all') { controller.updateSelectedExpenseType(null); diff --git a/lib/helpers/widgets/dashbaord/project_progress_chart.dart b/lib/helpers/widgets/dashbaord/project_progress_chart.dart index ed2acb5..fc01eea 100644 --- a/lib/helpers/widgets/dashbaord/project_progress_chart.dart +++ b/lib/helpers/widgets/dashbaord/project_progress_chart.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; -import 'package:marco/model/dashboard/project_progress_model.dart'; -import 'package:marco/controller/dashboard/dashboard_controller.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/utils/utils.dart'; +import 'package:on_field_work/model/dashboard/project_progress_model.dart'; +import 'package:on_field_work/controller/dashboard/dashboard_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/utils/utils.dart'; class ProjectProgressChart extends StatelessWidget { final List data; diff --git a/lib/helpers/widgets/date_range_picker.dart b/lib/helpers/widgets/date_range_picker.dart index 83982bc..907f765 100644 --- a/lib/helpers/widgets/date_range_picker.dart +++ b/lib/helpers/widgets/date_range_picker.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/utils/utils.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/utils/utils.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; typedef OnDateRangeSelected = void Function(DateTime? start, DateTime? end); diff --git a/lib/helpers/widgets/expense/expense_detail_helpers.dart b/lib/helpers/widgets/expense/expense_detail_helpers.dart index 1a5f450..dcb43ac 100644 --- a/lib/helpers/widgets/expense/expense_detail_helpers.dart +++ b/lib/helpers/widgets/expense/expense_detail_helpers.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; /// Returns a formatted color for the expense status. Color getExpenseStatusColor(String? status, {String? colorCode}) { diff --git a/lib/helpers/widgets/expense/expense_form_widgets.dart b/lib/helpers/widgets/expense/expense_form_widgets.dart index d383ac9..0d2c4a1 100644 --- a/lib/helpers/widgets/expense/expense_form_widgets.dart +++ b/lib/helpers/widgets/expense/expense_form_widgets.dart @@ -4,8 +4,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:url_launcher/url_launcher_string.dart'; -import 'package:marco/helpers/widgets/image_viewer_dialog.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/widgets/image_viewer_dialog.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; /// 🔹 Common Colors & Styles final _hintStyle = TextStyle(fontSize: 14, color: Colors.grey[600]); diff --git a/lib/helpers/widgets/expense/expense_main_components.dart b/lib/helpers/widgets/expense/expense_main_components.dart index ae04ff6..dccfff1 100644 --- a/lib/helpers/widgets/expense/expense_main_components.dart +++ b/lib/helpers/widgets/expense/expense_main_components.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/controller/expense/expense_screen_controller.dart'; -import 'package:marco/helpers/utils/date_time_utils.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/model/expense/expense_list_model.dart'; -import 'package:marco/view/expense/expense_detail_screen.dart'; -import 'package:marco/helpers/widgets/my_confirmation_dialog.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/controller/expense/expense_screen_controller.dart'; +import 'package:on_field_work/helpers/utils/date_time_utils.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/model/expense/expense_list_model.dart'; +import 'package:on_field_work/view/expense/expense_detail_screen.dart'; +import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; class ExpenseAppBar extends StatelessWidget implements PreferredSizeWidget { final ProjectController projectController; @@ -303,13 +303,9 @@ class ExpenseList extends StatelessWidget { child: InkWell( borderRadius: BorderRadius.circular(8), onTap: () async { - final result = await Get.to( + await Get.to( () => ExpenseDetailScreen(expenseId: expense.id), - arguments: {'expense': expense}, ); - if (result == true && onViewDetail != null) { - await onViewDetail!(); - } }, child: Padding( padding: const EdgeInsets.symmetric(vertical: 8), diff --git a/lib/helpers/widgets/my.dart b/lib/helpers/widgets/my.dart index a1dd282..c62500f 100644 --- a/lib/helpers/widgets/my.dart +++ b/lib/helpers/widgets/my.dart @@ -1,7 +1,7 @@ -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/widgets/my_constant.dart'; -import 'package:marco/helpers/widgets/my_screen_media.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/widgets/my_constant.dart'; +import 'package:on_field_work/helpers/widgets/my_screen_media.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; import 'package:flutter/material.dart'; class My { diff --git a/lib/helpers/widgets/my_base_exception.dart b/lib/helpers/widgets/my_base_exception.dart index de1118d..944ec23 100644 --- a/lib/helpers/widgets/my_base_exception.dart +++ b/lib/helpers/widgets/my_base_exception.dart @@ -1,6 +1,6 @@ import 'dart:developer'; -import 'package:marco/helpers/widgets/my_exception.dart'; +import 'package:on_field_work/helpers/widgets/my_exception.dart'; class BaseException extends MyException { StackTrace? stackTrace; diff --git a/lib/helpers/widgets/my_bottom_navigation_bar.dart b/lib/helpers/widgets/my_bottom_navigation_bar.dart index 332a7a0..2b9b7ec 100644 --- a/lib/helpers/widgets/my_bottom_navigation_bar.dart +++ b/lib/helpers/widgets/my_bottom_navigation_bar.dart @@ -1,10 +1,10 @@ // ignore_for_file: unrelated_type_equality_checks -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/widgets/my_bottom_navigation_bar_item.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/widgets/my_bottom_navigation_bar_item.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; import 'package:flutter/material.dart'; enum MyBottomNavigationBarType { diff --git a/lib/helpers/widgets/my_breadcrumb.dart b/lib/helpers/widgets/my_breadcrumb.dart index 06b8e2a..46ad674 100644 --- a/lib/helpers/widgets/my_breadcrumb.dart +++ b/lib/helpers/widgets/my_breadcrumb.dart @@ -1,11 +1,11 @@ import 'package:flutter_lucide/flutter_lucide.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/widgets/my_breadcrumb_item.dart'; -import 'package:marco/helpers/widgets/my_constant.dart'; -import 'package:marco/helpers/widgets/my_responsive.dart'; -import 'package:marco/helpers/widgets/my_router.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/widgets/my_breadcrumb_item.dart'; +import 'package:on_field_work/helpers/widgets/my_constant.dart'; +import 'package:on_field_work/helpers/widgets/my_responsive.dart'; +import 'package:on_field_work/helpers/widgets/my_router.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; import 'package:flutter/material.dart'; class MyBreadcrumb extends StatelessWidget { diff --git a/lib/helpers/widgets/my_button.dart b/lib/helpers/widgets/my_button.dart index 42e3ebf..7750c97 100644 --- a/lib/helpers/widgets/my_button.dart +++ b/lib/helpers/widgets/my_button.dart @@ -1,4 +1,4 @@ -import 'package:marco/helpers/widgets/my_constant.dart'; +import 'package:on_field_work/helpers/widgets/my_constant.dart'; import 'package:flutter/material.dart'; enum MyButtonType { elevated, outlined, text } diff --git a/lib/helpers/widgets/my_card.dart b/lib/helpers/widgets/my_card.dart index e5afe95..b37f7a8 100644 --- a/lib/helpers/widgets/my_card.dart +++ b/lib/helpers/widgets/my_card.dart @@ -1,7 +1,7 @@ -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/utils/my_shadow.dart'; -import 'package:marco/helpers/widgets/my_constant.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/utils/my_shadow.dart'; +import 'package:on_field_work/helpers/widgets/my_constant.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; import 'package:flutter/material.dart'; class MyCard extends StatelessWidget { diff --git a/lib/helpers/widgets/my_confirmation_dialog.dart b/lib/helpers/widgets/my_confirmation_dialog.dart index 28dfa60..338a2fd 100644 --- a/lib/helpers/widgets/my_confirmation_dialog.dart +++ b/lib/helpers/widgets/my_confirmation_dialog.dart @@ -1,18 +1,42 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; class ConfirmDialog extends StatelessWidget { final String title; final String message; + + /// Text for confirm button (default: "Delete") final String confirmText; + + /// Text for cancel button (default: "Cancel") final String cancelText; + + /// Icon shown in the dialog header (default: Icons.delete) final IconData icon; + + /// Icon for confirm button (default: Icons.delete_forever) + final IconData confirmIcon; + + /// Icon for cancel button (default: Icons.close) + final IconData cancelIcon; + + /// Background color for confirm button (default: Colors.redAccent) final Color confirmColor; + + /// Callback fired when confirm is pressed and awaited. final Future Function() onConfirm; + + /// External RxBool to observe the loading state, if null internal is used final RxBool? isProcessing; + /// Custom error message shown in snackbar if confirmation fails + final String errorMessage; + + /// Text shown in confirm button while loading + final String loadingText; + const ConfirmDialog({ super.key, required this.title, @@ -21,28 +45,44 @@ class ConfirmDialog extends StatelessWidget { this.confirmText = "Delete", this.cancelText = "Cancel", this.icon = Icons.delete, + this.confirmIcon = Icons.delete_forever, + this.cancelIcon = Icons.close, this.confirmColor = Colors.redAccent, this.isProcessing, + this.errorMessage = "Failed to complete action. Try again.", + this.loadingText = "Submitting…", }); @override Widget build(BuildContext context) { - // Use provided RxBool, or create one internally final RxBool loading = isProcessing ?? false.obs; + final theme = Theme.of(context); return Dialog( + backgroundColor: theme.colorScheme.surface, + insetPadding: const EdgeInsets.symmetric(horizontal: 24, vertical: 24), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 28), - child: _ContentView( - title: title, - message: message, - icon: icon, - confirmColor: confirmColor, - confirmText: confirmText, - cancelText: cancelText, - loading: loading, - onConfirm: onConfirm, + child: ConstrainedBox( + constraints: const BoxConstraints( + minWidth: 280, + maxWidth: 480, + ), + child: Padding( + padding: const EdgeInsets.fromLTRB(24, 20, 24, 16), + child: _ContentView( + title: title, + message: message, + icon: icon, + confirmColor: confirmColor, + confirmText: confirmText, + cancelText: cancelText, + confirmIcon: confirmIcon, + cancelIcon: cancelIcon, + loading: loading, + onConfirm: onConfirm, + errorMessage: errorMessage, + loadingText: loadingText, + ), ), ), ); @@ -50,11 +90,12 @@ class ConfirmDialog extends StatelessWidget { } class _ContentView extends StatelessWidget { - final String title, message, confirmText, cancelText; - final IconData icon; + final String title, message, confirmText, cancelText, loadingText; + final IconData icon, confirmIcon, cancelIcon; final Color confirmColor; final RxBool loading; final Future Function() onConfirm; + final String errorMessage; const _ContentView({ required this.title, @@ -63,71 +104,113 @@ class _ContentView extends StatelessWidget { required this.confirmColor, required this.confirmText, required this.cancelText, + required this.confirmIcon, + required this.cancelIcon, required this.loading, required this.onConfirm, + required this.errorMessage, + required this.loadingText, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); + final colorScheme = theme.colorScheme; return Column( mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Icon(icon, size: 48, color: confirmColor), - const SizedBox(height: 16), - MyText.titleLarge( - title, - fontWeight: 600, - color: theme.colorScheme.onBackground, - ), - const SizedBox(height: 12), - MyText.bodySmall( - message, - textAlign: TextAlign.center, - color: theme.colorScheme.onSurface.withValues(alpha: 0.7), - ), - const SizedBox(height: 24), Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: Obx(() => _DialogButton( - text: cancelText, - icon: Icons.close, - color: Colors.grey, - isLoading: false, - onPressed: loading.value - ? null // disable while loading - : () => Navigator.pop(context, false), - )), + Container( + decoration: BoxDecoration( + color: confirmColor.withOpacity(0.12), + shape: BoxShape.circle, + ), + padding: const EdgeInsets.all(10), + child: Icon( + icon, + size: 22, + color: confirmColor, + ), ), const SizedBox(width: 12), Expanded( - child: Obx(() => _DialogButton( - text: confirmText, - icon: Icons.delete_forever, - color: confirmColor, - isLoading: loading.value, - onPressed: () async { - try { - loading.value = true; - await onConfirm(); // 🔥 call API - Navigator.pop(context, true); // close on success - } catch (e) { - // Show error, dialog stays open - showAppSnackbar( - title: "Error", - message: "Failed to delete. Try again.", - type: SnackbarType.error, - ); - } finally { - loading.value = false; - } - }, - )), + child: MyText.titleLarge( + title, + fontWeight: 700, + color: colorScheme.onSurface, + ), ), ], ), + const SizedBox(height: 12), + MyText.bodyMedium( + message, + textAlign: TextAlign.left, + color: colorScheme.onSurface.withValues(alpha: 0.75), + ), + const SizedBox(height: 20), + Divider( + height: 1, + color: colorScheme.outlineVariant.withValues(alpha: 0.6), + ), + const SizedBox(height: 12), + Align( + alignment: Alignment.center, + child: SizedBox( + width: double.infinity, // allow full available width + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Obx( + () => _DialogButton( + text: cancelText, + icon: cancelIcon, + color: Colors.transparent, + textColor: colorScheme.onSurface, + isFilled: false, + isLoading: false, + onPressed: loading.value ? null : () => Navigator.pop(context, false), + ), + ), + ), + const SizedBox(width: 20), + Expanded( + child: Obx( + () => _DialogButton( + text: loading.value ? loadingText : confirmText, + icon: confirmIcon, + color: confirmColor, + textColor: Colors.white, + isFilled: true, + isLoading: loading.value, + onPressed: () async { + try { + loading.value = true; + await onConfirm(); + Navigator.pop(context, true); + } catch (e) { + showAppSnackbar( + title: "Error", + message: errorMessage, + type: SnackbarType.error, + ); + } finally { + loading.value = false; + } + }, + ), + ), + ), + ], + ), + ), +), + ], ); } @@ -137,6 +220,8 @@ class _DialogButton extends StatelessWidget { final String text; final IconData icon; final Color color; + final Color textColor; + final bool isFilled; final VoidCallback? onPressed; final bool isLoading; @@ -144,36 +229,73 @@ class _DialogButton extends StatelessWidget { required this.text, required this.icon, required this.color, + required this.textColor, + required this.isFilled, required this.onPressed, this.isLoading = false, }); @override Widget build(BuildContext context) { - return ElevatedButton.icon( - onPressed: isLoading ? null : onPressed, - icon: isLoading - ? SizedBox( - width: 18, - height: 18, - child: CircularProgressIndicator( - strokeWidth: 2, - color: Colors.white, - ), - ) - : Icon(icon, color: Colors.white), - label: MyText.bodyMedium( - isLoading ? "Submitting.." : text, - color: Colors.white, - fontWeight: 600, - ), - style: ElevatedButton.styleFrom( - backgroundColor: color, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - ), - padding: const EdgeInsets.symmetric(vertical: 12), - ), + final theme = Theme.of(context); + + final ButtonStyle style = isFilled + ? ElevatedButton.styleFrom( + backgroundColor: color, + foregroundColor: textColor, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(999), + ), + padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 10), + ) + : OutlinedButton.styleFrom( + foregroundColor: textColor, + side: BorderSide( + color: theme.colorScheme.outline.withValues(alpha: 0.7), + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(999), + ), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), + ); + + final Widget iconWidget = isLoading + ? SizedBox( + width: 18, + height: 18, + child: CircularProgressIndicator( + strokeWidth: 2, + color: isFilled ? Colors.white : theme.colorScheme.primary, + ), + ) + : Icon(icon, size: 18); + + final Widget labelWidget = MyText.bodyMedium( + text, + color: isFilled ? Colors.white : textColor, + fontWeight: 600, ); + + final child = Row( + mainAxisSize: MainAxisSize.min, + children: [ + iconWidget, + const SizedBox(width: 8), + Flexible(child: labelWidget), + ], + ); + + return isFilled + ? ElevatedButton( + onPressed: isLoading ? null : onPressed, + style: style, + child: child, + ) + : OutlinedButton( + onPressed: isLoading ? null : onPressed, + style: style, + child: child, + ); } } diff --git a/lib/helpers/widgets/my_constant.dart b/lib/helpers/widgets/my_constant.dart index d43f4e6..df808b5 100644 --- a/lib/helpers/widgets/my_constant.dart +++ b/lib/helpers/widgets/my_constant.dart @@ -1,4 +1,4 @@ -import 'package:marco/helpers/widgets/my_breadcrumb_item.dart'; +import 'package:on_field_work/helpers/widgets/my_breadcrumb_item.dart'; class MyConstantData { final double containerRadius; diff --git a/lib/helpers/widgets/my_container.dart b/lib/helpers/widgets/my_container.dart index 8241aab..e934e72 100644 --- a/lib/helpers/widgets/my_container.dart +++ b/lib/helpers/widgets/my_container.dart @@ -1,6 +1,6 @@ -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/widgets/my_constant.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/widgets/my_constant.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; import 'package:flutter/material.dart'; class MyContainer extends StatelessWidget { diff --git a/lib/helpers/widgets/my_custom_skeleton.dart b/lib/helpers/widgets/my_custom_skeleton.dart index 5bb5309..8b2db2e 100644 --- a/lib/helpers/widgets/my_custom_skeleton.dart +++ b/lib/helpers/widgets/my_custom_skeleton.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:marco/helpers/widgets/my_card.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/utils/my_shadow.dart'; +import 'package:on_field_work/helpers/widgets/my_card.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/utils/my_shadow.dart'; class SkeletonLoaders { static Widget buildLoadingSkeleton() { diff --git a/lib/helpers/widgets/my_flex.dart b/lib/helpers/widgets/my_flex.dart index 157ef6d..abc8b64 100644 --- a/lib/helpers/widgets/my_flex.dart +++ b/lib/helpers/widgets/my_flex.dart @@ -1,10 +1,10 @@ -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/widgets/my_flex_item.dart'; -import 'package:marco/helpers/widgets/my_list_extension.dart'; -import 'package:marco/helpers/widgets/my_responsive.dart'; -import 'package:marco/helpers/widgets/my_screen_media.dart'; -import 'package:marco/helpers/widgets/my_screen_media_type.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/widgets/my_flex_item.dart'; +import 'package:on_field_work/helpers/widgets/my_list_extension.dart'; +import 'package:on_field_work/helpers/widgets/my_responsive.dart'; +import 'package:on_field_work/helpers/widgets/my_screen_media.dart'; +import 'package:on_field_work/helpers/widgets/my_screen_media_type.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; import 'package:flutter/material.dart'; class MyFlex extends StatelessWidget { diff --git a/lib/helpers/widgets/my_flex_item.dart b/lib/helpers/widgets/my_flex_item.dart index 2d4ab46..7801c85 100644 --- a/lib/helpers/widgets/my_flex_item.dart +++ b/lib/helpers/widgets/my_flex_item.dart @@ -1,6 +1,6 @@ -import 'package:marco/helpers/widgets/my_display_type.dart'; -import 'package:marco/helpers/widgets/my_screen_media.dart'; -import 'package:marco/helpers/widgets/my_screen_media_type.dart'; +import 'package:on_field_work/helpers/widgets/my_display_type.dart'; +import 'package:on_field_work/helpers/widgets/my_screen_media.dart'; +import 'package:on_field_work/helpers/widgets/my_screen_media_type.dart'; import 'package:flutter/material.dart'; class MyFlexItem extends StatelessWidget { diff --git a/lib/helpers/widgets/my_form_validator.dart b/lib/helpers/widgets/my_form_validator.dart index ed1f630..e5c48bf 100644 --- a/lib/helpers/widgets/my_form_validator.dart +++ b/lib/helpers/widgets/my_form_validator.dart @@ -1,4 +1,4 @@ -import 'package:marco/helpers/widgets/my_field_validator.dart'; +import 'package:on_field_work/helpers/widgets/my_field_validator.dart'; import 'package:flutter/material.dart'; import 'package:get/get_utils/get_utils.dart'; diff --git a/lib/helpers/widgets/my_image_compressor.dart b/lib/helpers/widgets/my_image_compressor.dart index ce8bb2b..d1d2d61 100644 --- a/lib/helpers/widgets/my_image_compressor.dart +++ b/lib/helpers/widgets/my_image_compressor.dart @@ -3,7 +3,7 @@ import 'dart:typed_data'; import 'package:flutter_image_compress/flutter_image_compress.dart'; import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart' as path; -import 'package:marco/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; diff --git a/lib/helpers/widgets/my_loading_component.dart b/lib/helpers/widgets/my_loading_component.dart index b716abb..1d02fda 100644 --- a/lib/helpers/widgets/my_loading_component.dart +++ b/lib/helpers/widgets/my_loading_component.dart @@ -1,10 +1,10 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart'; -import 'package:marco/images.dart'; -import 'package:marco/helpers/widgets/my_card.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/utils/my_shadow.dart'; +import 'package:on_field_work/images.dart'; +import 'package:on_field_work/helpers/widgets/my_card.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/utils/my_shadow.dart'; class LoadingComponent extends StatelessWidget { final bool isLoading; final Widget child; diff --git a/lib/helpers/widgets/my_on_boarding.dart b/lib/helpers/widgets/my_on_boarding.dart index c274324..95a06a4 100644 --- a/lib/helpers/widgets/my_on_boarding.dart +++ b/lib/helpers/widgets/my_on_boarding.dart @@ -1,9 +1,9 @@ import 'dart:async'; -import 'package:marco/helpers/widgets/my_page_dragger.dart'; -import 'package:marco/helpers/widgets/my_page_indicator.dart'; -import 'package:marco/helpers/widgets/my_page_reveal.dart'; -import 'package:marco/helpers/widgets/my_pages.dart'; +import 'package:on_field_work/helpers/widgets/my_page_dragger.dart'; +import 'package:on_field_work/helpers/widgets/my_page_indicator.dart'; +import 'package:on_field_work/helpers/widgets/my_page_reveal.dart'; +import 'package:on_field_work/helpers/widgets/my_pages.dart'; import 'package:flutter/material.dart'; class MyOnBoarding extends StatefulWidget { diff --git a/lib/helpers/widgets/my_page_dragger.dart b/lib/helpers/widgets/my_page_dragger.dart index 2969e83..83f4807 100644 --- a/lib/helpers/widgets/my_page_dragger.dart +++ b/lib/helpers/widgets/my_page_dragger.dart @@ -3,7 +3,7 @@ import 'dart:async'; import 'dart:ui'; -import 'package:marco/helpers/widgets/my_page_indicator.dart'; +import 'package:on_field_work/helpers/widgets/my_page_indicator.dart'; import 'package:flutter/material.dart'; class MyPageDragger extends StatefulWidget { diff --git a/lib/helpers/widgets/my_page_indicator.dart b/lib/helpers/widgets/my_page_indicator.dart index 0d7d803..0019513 100644 --- a/lib/helpers/widgets/my_page_indicator.dart +++ b/lib/helpers/widgets/my_page_indicator.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -import 'package:marco/helpers/widgets/my_pages.dart'; +import 'package:on_field_work/helpers/widgets/my_pages.dart'; import 'package:flutter/material.dart'; class MyPagerIndicator extends StatelessWidget { diff --git a/lib/helpers/widgets/my_responsive.dart b/lib/helpers/widgets/my_responsive.dart index e9b869b..9aba068 100644 --- a/lib/helpers/widgets/my_responsive.dart +++ b/lib/helpers/widgets/my_responsive.dart @@ -1,5 +1,5 @@ -import 'package:marco/helpers/widgets/my_screen_media.dart'; -import 'package:marco/helpers/widgets/my_screen_media_type.dart'; +import 'package:on_field_work/helpers/widgets/my_screen_media.dart'; +import 'package:on_field_work/helpers/widgets/my_screen_media_type.dart'; import 'package:flutter/material.dart'; class MyResponsive extends StatelessWidget { diff --git a/lib/helpers/widgets/my_route.dart b/lib/helpers/widgets/my_route.dart index 6a7fef3..4c9b835 100644 --- a/lib/helpers/widgets/my_route.dart +++ b/lib/helpers/widgets/my_route.dart @@ -1,4 +1,4 @@ -import 'package:marco/helpers/widgets/my_middleware.dart'; +import 'package:on_field_work/helpers/widgets/my_middleware.dart'; import 'package:flutter/material.dart'; class MyRoute { diff --git a/lib/helpers/widgets/my_route_exception.dart b/lib/helpers/widgets/my_route_exception.dart index 8ec9b10..fe917df 100644 --- a/lib/helpers/widgets/my_route_exception.dart +++ b/lib/helpers/widgets/my_route_exception.dart @@ -1,4 +1,4 @@ -import 'package:marco/helpers/widgets/my_base_exception.dart'; +import 'package:on_field_work/helpers/widgets/my_base_exception.dart'; class RouteException extends BaseException { final String message; diff --git a/lib/helpers/widgets/my_router.dart b/lib/helpers/widgets/my_router.dart index 8d46ccb..91fb4f7 100644 --- a/lib/helpers/widgets/my_router.dart +++ b/lib/helpers/widgets/my_router.dart @@ -1,7 +1,7 @@ -import 'package:marco/helpers/widgets/my_middleware.dart'; -import 'package:marco/helpers/widgets/my_route.dart'; -import 'package:marco/helpers/widgets/my_route_exception.dart'; -import 'package:marco/helpers/widgets/my_routes.dart'; +import 'package:on_field_work/helpers/widgets/my_middleware.dart'; +import 'package:on_field_work/helpers/widgets/my_route.dart'; +import 'package:on_field_work/helpers/widgets/my_route_exception.dart'; +import 'package:on_field_work/helpers/widgets/my_routes.dart'; import 'package:flutter/material.dart'; diff --git a/lib/helpers/widgets/my_routes.dart b/lib/helpers/widgets/my_routes.dart index 4d2ec41..654e952 100644 --- a/lib/helpers/widgets/my_routes.dart +++ b/lib/helpers/widgets/my_routes.dart @@ -3,7 +3,7 @@ -import 'package:marco/helpers/widgets/my_route.dart'; +import 'package:on_field_work/helpers/widgets/my_route.dart'; class MyRoutes { static List _routes = []; diff --git a/lib/helpers/widgets/my_screen_media.dart b/lib/helpers/widgets/my_screen_media.dart index a350a75..96e882d 100644 --- a/lib/helpers/widgets/my_screen_media.dart +++ b/lib/helpers/widgets/my_screen_media.dart @@ -1,7 +1,7 @@ -import 'package:marco/helpers/widgets/my_display_type.dart'; -import 'package:marco/helpers/widgets/my_screen_media_type.dart'; +import 'package:on_field_work/helpers/widgets/my_display_type.dart'; +import 'package:on_field_work/helpers/widgets/my_screen_media_type.dart'; class MyScreenMedia { static int flexColumns = 12; diff --git a/lib/helpers/widgets/my_team_model_sheet.dart b/lib/helpers/widgets/my_team_model_sheet.dart index f879073..968a558 100644 --- a/lib/helpers/widgets/my_team_model_sheet.dart +++ b/lib/helpers/widgets/my_team_model_sheet.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; class TeamBottomSheet { static void show({ diff --git a/lib/helpers/widgets/my_text.dart b/lib/helpers/widgets/my_text.dart index fb9960b..47bb06f 100644 --- a/lib/helpers/widgets/my_text.dart +++ b/lib/helpers/widgets/my_text.dart @@ -1,7 +1,7 @@ // ignore_for_file: annotate_overrides, overridden_fields import 'package:flutter/material.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; class MyText extends StatelessWidget { final Key? key; diff --git a/lib/helpers/widgets/my_text_style.dart b/lib/helpers/widgets/my_text_style.dart index 19fdb6f..cec0c05 100644 --- a/lib/helpers/widgets/my_text_style.dart +++ b/lib/helpers/widgets/my_text_style.dart @@ -1,6 +1,6 @@ // ignore_for_file: prefer_generic_function_type_aliases -import 'package:marco/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; diff --git a/lib/helpers/widgets/my_validators.dart b/lib/helpers/widgets/my_validators.dart index 0e3df03..936d185 100644 --- a/lib/helpers/widgets/my_validators.dart +++ b/lib/helpers/widgets/my_validators.dart @@ -1,5 +1,5 @@ -import 'package:marco/helpers/utils/my_string_utils.dart'; -import 'package:marco/helpers/widgets/my_field_validator.dart'; +import 'package:on_field_work/helpers/utils/my_string_utils.dart'; +import 'package:on_field_work/helpers/widgets/my_field_validator.dart'; class MyEmailValidator extends MyFieldValidatorRule { @override diff --git a/lib/helpers/widgets/responsive.dart b/lib/helpers/widgets/responsive.dart index 2c0c5ed..7570871 100644 --- a/lib/helpers/widgets/responsive.dart +++ b/lib/helpers/widgets/responsive.dart @@ -1,4 +1,4 @@ -import 'package:marco/helpers/widgets/my_screen_media.dart'; +import 'package:on_field_work/helpers/widgets/my_screen_media.dart'; export 'my_display_type.dart'; export 'my_screen_media.dart'; diff --git a/lib/helpers/widgets/team_members_bottom_sheet.dart b/lib/helpers/widgets/team_members_bottom_sheet.dart index 949f870..7d44099 100644 --- a/lib/helpers/widgets/team_members_bottom_sheet.dart +++ b/lib/helpers/widgets/team_members_bottom_sheet.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/model/directory/contact_bucket_list_model.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/model/directory/contact_bucket_list_model.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; class TeamMembersBottomSheet { static void show( diff --git a/lib/helpers/widgets/tenant/all_organization_selector.dart b/lib/helpers/widgets/tenant/all_organization_selector.dart index 8a1fc67..10efce3 100644 --- a/lib/helpers/widgets/tenant/all_organization_selector.dart +++ b/lib/helpers/widgets/tenant/all_organization_selector.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/tenant/all_organization_controller.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/model/all_organization_model.dart'; +import 'package:on_field_work/controller/tenant/all_organization_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/model/all_organization_model.dart'; class AllOrganizationListView extends StatelessWidget { final AllOrganizationController controller; diff --git a/lib/helpers/widgets/tenant/organization_selector.dart b/lib/helpers/widgets/tenant/organization_selector.dart index e902b24..0ca2476 100644 --- a/lib/helpers/widgets/tenant/organization_selector.dart +++ b/lib/helpers/widgets/tenant/organization_selector.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/tenant/organization_selection_controller.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/model/attendance/organization_per_project_list_model.dart'; +import 'package:on_field_work/controller/tenant/organization_selection_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/model/attendance/organization_per_project_list_model.dart'; class OrganizationSelector extends StatelessWidget { final OrganizationController controller; diff --git a/lib/helpers/widgets/tenant/service_selector.dart b/lib/helpers/widgets/tenant/service_selector.dart index d9c65a9..a0b876e 100644 --- a/lib/helpers/widgets/tenant/service_selector.dart +++ b/lib/helpers/widgets/tenant/service_selector.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/model/tenant/tenant_services_model.dart'; -import 'package:marco/controller/tenant/service_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/model/tenant/tenant_services_model.dart'; +import 'package:on_field_work/controller/tenant/service_controller.dart'; class ServiceSelector extends StatelessWidget { final ServiceController controller; diff --git a/lib/helpers/widgets/time_stamp_image_helper.dart b/lib/helpers/widgets/time_stamp_image_helper.dart index 954a205..74ffb48 100644 --- a/lib/helpers/widgets/time_stamp_image_helper.dart +++ b/lib/helpers/widgets/time_stamp_image_helper.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; -import 'package:marco/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; class TimestampImageHelper { /// Adds a timestamp to an image file and returns a new File diff --git a/lib/main.dart b/lib/main.dart index 77307e9..9ca62c0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,12 +2,12 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; -import 'package:marco/helpers/services/app_initializer.dart'; -import 'package:marco/view/my_app.dart'; -import 'package:marco/helpers/theme/app_notifier.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/view/layouts/offline_screen.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/services/app_initializer.dart'; +import 'package:on_field_work/view/my_app.dart'; +import 'package:on_field_work/helpers/theme/app_notifier.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/view/layouts/offline_screen.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); diff --git a/lib/model/attendance/attendence_action_button.dart b/lib/model/attendance/attendence_action_button.dart index 9b1d35c..fefc312 100644 --- a/lib/model/attendance/attendence_action_button.dart +++ b/lib/model/attendance/attendence_action_button.dart @@ -2,11 +2,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/controller/attendance/attendance_screen_controller.dart'; -import 'package:marco/helpers/utils/attendance_actions.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/controller/attendance/attendance_screen_controller.dart'; +import 'package:on_field_work/helpers/utils/attendance_actions.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; class AttendanceActionButton extends StatefulWidget { final dynamic employee; diff --git a/lib/model/attendance/attendence_filter_sheet.dart b/lib/model/attendance/attendence_filter_sheet.dart index abeaaa7..38e1fc8 100644 --- a/lib/model/attendance/attendence_filter_sheet.dart +++ b/lib/model/attendance/attendence_filter_sheet.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/controller/attendance/attendance_screen_controller.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/utils/permission_constants.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/controller/attendance/attendance_screen_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/utils/date_time_utils.dart'; -import 'package:marco/helpers/widgets/date_range_picker.dart'; +import 'package:on_field_work/helpers/utils/date_time_utils.dart'; +import 'package:on_field_work/helpers/widgets/date_range_picker.dart'; class AttendanceFilterBottomSheet extends StatefulWidget { final AttendanceController controller; diff --git a/lib/model/attendance/log_details_view.dart b/lib/model/attendance/log_details_view.dart index 598703f..1172445 100644 --- a/lib/model/attendance/log_details_view.dart +++ b/lib/model/attendance/log_details_view.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:cached_network_image/cached_network_image.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/utils/date_time_utils.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/utils/date_time_utils.dart'; class AttendanceLogViewButton extends StatefulWidget { final dynamic employee; diff --git a/lib/model/attendance/regualrize_action_button.dart b/lib/model/attendance/regualrize_action_button.dart index 450d4f8..8f8ce77 100644 --- a/lib/model/attendance/regualrize_action_button.dart +++ b/lib/model/attendance/regualrize_action_button.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:marco/helpers/utils/attendance_actions.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/controller/project_controller.dart'; +import 'package:on_field_work/helpers/utils/attendance_actions.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/controller/project_controller.dart'; import 'package:get/get.dart'; enum ButtonActions { approve, reject } diff --git a/lib/model/dailyTaskPlanning/assign_task_bottom_sheet .dart b/lib/model/dailyTaskPlanning/assign_task_bottom_sheet .dart index 4db2228..99dae49 100644 --- a/lib/model/dailyTaskPlanning/assign_task_bottom_sheet .dart +++ b/lib/model/dailyTaskPlanning/assign_task_bottom_sheet .dart @@ -1,17 +1,17 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/task_Planning/daily_task_Planning_controller.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/controller/tenant/organization_selection_controller.dart'; -import 'package:marco/controller/tenant/service_controller.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/tenant/organization_selector.dart'; -import 'package:marco/helpers/widgets/tenant/service_selector.dart'; -import 'package:marco/model/attendance/organization_per_project_list_model.dart'; -import 'package:marco/model/tenant/tenant_services_model.dart'; +import 'package:on_field_work/controller/task_Planning/daily_task_Planning_controller.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/controller/tenant/organization_selection_controller.dart'; +import 'package:on_field_work/controller/tenant/service_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/tenant/organization_selector.dart'; +import 'package:on_field_work/helpers/widgets/tenant/service_selector.dart'; +import 'package:on_field_work/model/attendance/organization_per_project_list_model.dart'; +import 'package:on_field_work/model/tenant/tenant_services_model.dart'; class AssignTaskBottomSheet extends StatefulWidget { final String workLocation; diff --git a/lib/model/dailyTaskPlanning/comment_task_bottom_sheet.dart b/lib/model/dailyTaskPlanning/comment_task_bottom_sheet.dart index 24d37d6..df2cde1 100644 --- a/lib/model/dailyTaskPlanning/comment_task_bottom_sheet.dart +++ b/lib/model/dailyTaskPlanning/comment_task_bottom_sheet.dart @@ -4,17 +4,17 @@ import 'package:intl/intl.dart'; import 'dart:io'; import 'dart:math' as math; // --- Assumed Imports (ensure these paths are correct in your project) --- -import 'package:marco/controller/task_planning/report_task_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_button.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/helpers/widgets/my_team_model_sheet.dart'; -import 'package:marco/helpers/widgets/image_viewer_dialog.dart'; -import 'package:marco/model/dailyTaskPlanning/create_task_botom_sheet.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/controller/task_planning/report_task_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_button.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/widgets/my_team_model_sheet.dart'; +import 'package:on_field_work/helpers/widgets/image_viewer_dialog.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/create_task_botom_sheet.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; // --- Form Field Keys (Unchanged) --- class _FormFieldKeys { diff --git a/lib/model/dailyTaskPlanning/create_task_botom_sheet.dart b/lib/model/dailyTaskPlanning/create_task_botom_sheet.dart index 1d5fe62..b187c28 100644 --- a/lib/model/dailyTaskPlanning/create_task_botom_sheet.dart +++ b/lib/model/dailyTaskPlanning/create_task_botom_sheet.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/task_planning/add_task_controller.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/controller/task_planning/add_task_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; void showCreateTaskBottomSheet({ required String workArea, diff --git a/lib/model/dailyTaskPlanning/daily_progress_report_filter.dart b/lib/model/dailyTaskPlanning/daily_progress_report_filter.dart index a289858..f968da8 100644 --- a/lib/model/dailyTaskPlanning/daily_progress_report_filter.dart +++ b/lib/model/dailyTaskPlanning/daily_progress_report_filter.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/task_planning/daily_task_controller.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/date_range_picker.dart'; +import 'package:on_field_work/controller/task_planning/daily_task_controller.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/date_range_picker.dart'; class DailyTaskFilterBottomSheet extends StatelessWidget { final DailyTaskController controller; diff --git a/lib/model/dailyTaskPlanning/daily_task_planning_filter.dart b/lib/model/dailyTaskPlanning/daily_task_planning_filter.dart index aa9a521..6018c24 100644 --- a/lib/model/dailyTaskPlanning/daily_task_planning_filter.dart +++ b/lib/model/dailyTaskPlanning/daily_task_planning_filter.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/controller/task_Planning/daily_task_Planning_controller.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/controller/task_Planning/daily_task_Planning_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; class DailyTaskPlanningFilter extends StatelessWidget { final DailyTaskPlanningController controller; diff --git a/lib/model/dailyTaskPlanning/report_action_bottom_sheet.dart b/lib/model/dailyTaskPlanning/report_action_bottom_sheet.dart index 0a75eb2..e080e63 100644 --- a/lib/model/dailyTaskPlanning/report_action_bottom_sheet.dart +++ b/lib/model/dailyTaskPlanning/report_action_bottom_sheet.dart @@ -1,16 +1,16 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/task_planning/report_task_action_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/helpers/widgets/my_team_model_sheet.dart'; -import 'package:marco/helpers/widgets/image_viewer_dialog.dart'; -import 'package:marco/model/dailyTaskPlanning/create_task_botom_sheet.dart'; -import 'package:marco/model/dailyTaskPlanning/report_action_widgets.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/controller/task_planning/report_task_action_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/widgets/my_team_model_sheet.dart'; +import 'package:on_field_work/helpers/widgets/image_viewer_dialog.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/create_task_botom_sheet.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/report_action_widgets.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; class ReportActionBottomSheet extends StatefulWidget { final Map taskData; diff --git a/lib/model/dailyTaskPlanning/report_action_widgets.dart b/lib/model/dailyTaskPlanning/report_action_widgets.dart index 8d5cc2f..783c225 100644 --- a/lib/model/dailyTaskPlanning/report_action_widgets.dart +++ b/lib/model/dailyTaskPlanning/report_action_widgets.dart @@ -1,10 +1,10 @@ import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:marco/helpers/widgets/my_button.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/image_viewer_dialog.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/widgets/my_button.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/image_viewer_dialog.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; import 'package:get/get.dart'; /// Show labeled row with optional icon diff --git a/lib/model/dailyTaskPlanning/report_task_bottom_sheet.dart b/lib/model/dailyTaskPlanning/report_task_bottom_sheet.dart index 62841e6..5f5d814 100644 --- a/lib/model/dailyTaskPlanning/report_task_bottom_sheet.dart +++ b/lib/model/dailyTaskPlanning/report_task_bottom_sheet.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/task_planning/report_task_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_button.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/controller/task_planning/report_task_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_button.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; class ReportTaskBottomSheet extends StatefulWidget { final Map taskData; diff --git a/lib/model/dailyTaskPlanning/task_action_buttons.dart b/lib/model/dailyTaskPlanning/task_action_buttons.dart index e15d627..f6f4af0 100644 --- a/lib/model/dailyTaskPlanning/task_action_buttons.dart +++ b/lib/model/dailyTaskPlanning/task_action_buttons.dart @@ -1,8 +1,8 @@ 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'; +import 'package:on_field_work/model/dailyTaskPlanning/comment_task_bottom_sheet.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/report_task_bottom_sheet.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/report_action_bottom_sheet.dart'; class TaskActionButtons { static Widget reportButton({ diff --git a/lib/model/dailyTaskPlanning/task_list_model.dart b/lib/model/dailyTaskPlanning/task_list_model.dart index 98e32ee..5804974 100644 --- a/lib/model/dailyTaskPlanning/task_list_model.dart +++ b/lib/model/dailyTaskPlanning/task_list_model.dart @@ -1,7 +1,7 @@ import 'dart:convert'; -import 'package:marco/helpers/services/json_decoder.dart'; -import 'package:marco/model/identifier_model.dart'; +import 'package:on_field_work/helpers/services/json_decoder.dart'; +import 'package:on_field_work/model/identifier_model.dart'; import 'package:flutter/services.dart'; class TaskListModel extends IdentifierModel { diff --git a/lib/model/directory/add_comment_bottom_sheet.dart b/lib/model/directory/add_comment_bottom_sheet.dart index 25b5540..ac736da 100644 --- a/lib/model/directory/add_comment_bottom_sheet.dart +++ b/lib/model/directory/add_comment_bottom_sheet.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/directory/add_comment_controller.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/controller/directory/add_comment_controller.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; class AddCommentBottomSheet extends StatefulWidget { final String contactId; diff --git a/lib/model/directory/add_contact_bottom_sheet.dart b/lib/model/directory/add_contact_bottom_sheet.dart index f0f456d..05ededf 100644 --- a/lib/model/directory/add_contact_bottom_sheet.dart +++ b/lib/model/directory/add_contact_bottom_sheet.dart @@ -2,13 +2,13 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:collection/collection.dart'; -import 'package:marco/controller/directory/add_contact_controller.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/model/directory/contact_model.dart'; -import 'package:marco/helpers/utils/contact_picker_helper.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/controller/directory/add_contact_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/model/directory/contact_model.dart'; +import 'package:on_field_work/helpers/utils/contact_picker_helper.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; class AddContactBottomSheet extends StatefulWidget { final ContactModel? existingContact; diff --git a/lib/model/directory/create_bucket_bottom_sheet.dart b/lib/model/directory/create_bucket_bottom_sheet.dart index 212035d..64c3750 100644 --- a/lib/model/directory/create_bucket_bottom_sheet.dart +++ b/lib/model/directory/create_bucket_bottom_sheet.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/directory/create_bucket_controller.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/controller/directory/create_bucket_controller.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; class CreateBucketBottomSheet extends StatefulWidget { const CreateBucketBottomSheet({super.key}); diff --git a/lib/model/directory/directory_filter_bottom_sheet.dart b/lib/model/directory/directory_filter_bottom_sheet.dart index 4443f61..e851591 100644 --- a/lib/model/directory/directory_filter_bottom_sheet.dart +++ b/lib/model/directory/directory_filter_bottom_sheet.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/directory/directory_controller.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/controller/directory/directory_controller.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; class DirectoryFilterBottomSheet extends StatefulWidget { const DirectoryFilterBottomSheet({super.key}); diff --git a/lib/model/directory/edit_bucket_bottom_sheet.dart b/lib/model/directory/edit_bucket_bottom_sheet.dart index 7347b63..f4dedfb 100644 --- a/lib/model/directory/edit_bucket_bottom_sheet.dart +++ b/lib/model/directory/edit_bucket_bottom_sheet.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:collection/collection.dart'; -import 'package:marco/controller/directory/manage_bucket_controller.dart'; -import 'package:marco/controller/directory/directory_controller.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/model/directory/contact_bucket_list_model.dart'; +import 'package:on_field_work/controller/directory/manage_bucket_controller.dart'; +import 'package:on_field_work/controller/directory/directory_controller.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/model/directory/contact_bucket_list_model.dart'; class EditBucketBottomSheet { static void show( diff --git a/lib/model/document/document_edit_bottom_sheet.dart b/lib/model/document/document_edit_bottom_sheet.dart index fa375dd..27fc11e 100644 --- a/lib/model/document/document_edit_bottom_sheet.dart +++ b/lib/model/document/document_edit_bottom_sheet.dart @@ -3,14 +3,14 @@ import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/document/document_upload_controller.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/image_viewer_dialog.dart'; -import 'package:marco/model/document/master_document_type_model.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/controller/document/document_upload_controller.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/image_viewer_dialog.dart'; +import 'package:on_field_work/model/document/master_document_type_model.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; import 'package:url_launcher/url_launcher.dart'; class DocumentEditBottomSheet extends StatefulWidget { diff --git a/lib/model/document/document_upload_bottom_sheet.dart b/lib/model/document/document_upload_bottom_sheet.dart index 24313b2..17c0c16 100644 --- a/lib/model/document/document_upload_bottom_sheet.dart +++ b/lib/model/document/document_upload_bottom_sheet.dart @@ -3,13 +3,13 @@ import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/document/document_upload_controller.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/helpers/widgets/image_viewer_dialog.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/controller/document/document_upload_controller.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/helpers/widgets/image_viewer_dialog.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; class DocumentUploadBottomSheet extends StatefulWidget { final Function(Map) onSubmit; diff --git a/lib/model/document/user_document_filter_bottom_sheet.dart b/lib/model/document/user_document_filter_bottom_sheet.dart index c50fb1c..3ce1c5b 100644 --- a/lib/model/document/user_document_filter_bottom_sheet.dart +++ b/lib/model/document/user_document_filter_bottom_sheet.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/document/user_document_controller.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/model/document/document_filter_model.dart'; +import 'package:on_field_work/controller/document/user_document_controller.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/model/document/document_filter_model.dart'; import 'dart:convert'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/date_range_picker.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/date_range_picker.dart'; class UserDocumentFilterBottomSheet extends StatefulWidget { final String entityId; diff --git a/lib/model/employees/add_employee_bottom_sheet.dart b/lib/model/employees/add_employee_bottom_sheet.dart index 59dba23..9eba27c 100644 --- a/lib/model/employees/add_employee_bottom_sheet.dart +++ b/lib/model/employees/add_employee_bottom_sheet.dart @@ -3,15 +3,15 @@ import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; -import 'package:marco/controller/employee/add_employee_controller.dart'; -import 'package:marco/controller/employee/employees_screen_controller.dart'; -import 'package:marco/controller/tenant/all_organization_controller.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/controller/employee/add_employee_controller.dart'; +import 'package:on_field_work/controller/employee/employees_screen_controller.dart'; +import 'package:on_field_work/controller/tenant/all_organization_controller.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; class AddEmployeeBottomSheet extends StatefulWidget { final Map? employeeData; diff --git a/lib/model/employees/employee_detail_bottom_sheet.dart b/lib/model/employees/employee_detail_bottom_sheet.dart index 5509992..522987a 100644 --- a/lib/model/employees/employee_detail_bottom_sheet.dart +++ b/lib/model/employees/employee_detail_bottom_sheet.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; import 'package:intl/intl.dart'; -import 'package:marco/controller/employee/employees_screen_controller.dart'; -import 'package:marco/view/employees/assign_employee_bottom_sheet.dart'; +import 'package:on_field_work/controller/employee/employees_screen_controller.dart'; +import 'package:on_field_work/view/employees/assign_employee_bottom_sheet.dart'; class EmployeeDetailBottomSheet extends StatefulWidget { final String employeeId; diff --git a/lib/model/employees/multiple_select_bottomsheet.dart b/lib/model/employees/multiple_select_bottomsheet.dart index 336bb1a..829dc4f 100644 --- a/lib/model/employees/multiple_select_bottomsheet.dart +++ b/lib/model/employees/multiple_select_bottomsheet.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; class EmployeeSelectionBottomSheet extends StatefulWidget { final List initiallySelected; diff --git a/lib/model/expense/add_expense_bottom_sheet.dart b/lib/model/expense/add_expense_bottom_sheet.dart index 317bf9b..1f6711a 100644 --- a/lib/model/expense/add_expense_bottom_sheet.dart +++ b/lib/model/expense/add_expense_bottom_sheet.dart @@ -1,17 +1,17 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/expense/add_expense_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/model/expense/expense_type_model.dart'; -import 'package:marco/model/expense/payment_types_model.dart'; -import 'package:marco/model/expense/employee_selector_bottom_sheet.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/utils/validators.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/widgets/my_confirmation_dialog.dart'; -import 'package:marco/helpers/widgets/expense/expense_form_widgets.dart'; +import 'package:on_field_work/controller/expense/add_expense_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/model/expense/expense_type_model.dart'; +import 'package:on_field_work/model/expense/payment_types_model.dart'; +import 'package:on_field_work/model/expense/employee_selector_bottom_sheet.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/utils/validators.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart'; +import 'package:on_field_work/helpers/widgets/expense/expense_form_widgets.dart'; /// Show bottom sheet wrapper Future showAddExpenseBottomSheet({ @@ -112,7 +112,7 @@ class _AddExpenseBottomSheetState extends State<_AddExpenseBottomSheet> return false; } if (controller.selectedExpenseType.value == null) { - _showError("Please select an expense type"); + _showError("Please select an Expense Category"); return false; } if (controller.selectedPaymentMode.value == null) { @@ -178,10 +178,10 @@ class _AddExpenseBottomSheetState extends State<_AddExpenseBottomSheet> _buildDropdownField( icon: Icons.category_outlined, - title: "Expense Type", + title: "Expense Category", requiredField: true, value: controller.selectedExpenseType.value?.name ?? - "Select Expense Type", + "Select Expense Category", onTap: () => _showOptionList( controller.expenseTypes.toList(), (e) => e.name, diff --git a/lib/model/expense/comment_bottom_sheet.dart b/lib/model/expense/comment_bottom_sheet.dart index 447a629..4f579c9 100644 --- a/lib/model/expense/comment_bottom_sheet.dart +++ b/lib/model/expense/comment_bottom_sheet.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; Future showCommentBottomSheet(BuildContext context, String actionText) async { final commentController = TextEditingController(); diff --git a/lib/model/expense/employee_selector_bottom_sheet.dart b/lib/model/expense/employee_selector_bottom_sheet.dart index 7da90c6..760028f 100644 --- a/lib/model/expense/employee_selector_bottom_sheet.dart +++ b/lib/model/expense/employee_selector_bottom_sheet.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/model/employees/employee_model.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; class ReusableEmployeeSelectorBottomSheet extends StatelessWidget { final TextEditingController searchController; diff --git a/lib/model/expense/employee_selector_for_filter_bottom_sheet.dart b/lib/model/expense/employee_selector_for_filter_bottom_sheet.dart index 890d932..2e4fd13 100644 --- a/lib/model/expense/employee_selector_for_filter_bottom_sheet.dart +++ b/lib/model/expense/employee_selector_for_filter_bottom_sheet.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; class EmployeeSelectorBottomSheet extends StatefulWidget { final RxList selectedEmployees; diff --git a/lib/model/expense/expense_detail_model.dart b/lib/model/expense/expense_detail_model.dart index 116205e..5477e49 100644 --- a/lib/model/expense/expense_detail_model.dart +++ b/lib/model/expense/expense_detail_model.dart @@ -2,7 +2,7 @@ class ExpenseDetailModel { final String id; final Project project; - final ExpensesType expensesType; + final ExpensesType expensesType; final PaymentMode paymentMode; final Person paidBy; final Person createdBy; @@ -13,18 +13,25 @@ class ExpenseDetailModel { final String createdAt; final String supplerName; final double amount; + final double? baseAmount; + final double? taxAmount; + final double? tdsPercentage; final ExpenseStatus status; - final List nextStatus; + final List nextStatus; final bool preApproved; final String transactionId; final String description; final String location; + final Currency? currency; final List documents; final List expenseLogs; + final String? gstNumber; - final int noOfPersons; + final int? noOfPersons; final bool isActive; final dynamic expensesReimburse; + final String? expenseUId; + final String? paymentRequestUID; ExpenseDetailModel({ required this.id, @@ -40,51 +47,87 @@ class ExpenseDetailModel { required this.createdAt, required this.supplerName, required this.amount, + this.baseAmount, + this.taxAmount, + this.tdsPercentage, required this.status, required this.nextStatus, required this.preApproved, required this.transactionId, required this.description, required this.location, + this.currency, required this.documents, required this.expenseLogs, this.gstNumber, - required this.noOfPersons, + this.noOfPersons, required this.isActive, this.expensesReimburse, + this.expenseUId, + this.paymentRequestUID, }); factory ExpenseDetailModel.fromJson(Map json) { return ExpenseDetailModel( id: json['id'] ?? '', - project: json['project'] != null ? Project.fromJson(json['project']) : Project.empty(), - expensesType: json['expensesType'] != null - ? ExpensesType.fromJson(json['expensesType']) + project: json['project'] != null + ? Project.fromJson(json['project']) + : Project.empty(), + expensesType: json['expenseCategory'] != null + ? ExpensesType.fromJson(json['expenseCategory']) : ExpensesType.empty(), paymentMode: json['paymentMode'] != null ? PaymentMode.fromJson(json['paymentMode']) : PaymentMode.empty(), - paidBy: json['paidBy'] != null ? Person.fromJson(json['paidBy']) : Person.empty(), - createdBy: json['createdBy'] != null ? Person.fromJson(json['createdBy']) : Person.empty(), - reviewedBy: json['reviewedBy'] != null ? Person.fromJson(json['reviewedBy']) : null, - approvedBy: json['approvedBy'] != null ? Person.fromJson(json['approvedBy']) : null, - processedBy: json['processedBy'] != null ? Person.fromJson(json['processedBy']) : null, + paidBy: json['paidBy'] != null + ? Person.fromJson(json['paidBy']) + : Person.empty(), + createdBy: json['createdBy'] != null + ? Person.fromJson(json['createdBy']) + : Person.empty(), + reviewedBy: json['reviewedBy'] != null + ? Person.fromJson(json['reviewedBy']) + : null, + approvedBy: json['approvedBy'] != null + ? Person.fromJson(json['approvedBy']) + : null, + processedBy: json['processedBy'] != null + ? Person.fromJson(json['processedBy']) + : null, transactionDate: json['transactionDate'] ?? '', createdAt: json['createdAt'] ?? '', supplerName: json['supplerName'] ?? '', amount: (json['amount'] as num?)?.toDouble() ?? 0.0, - status: json['status'] != null ? ExpenseStatus.fromJson(json['status']) : ExpenseStatus.empty(), - nextStatus: (json['nextStatus'] as List?)?.map((e) => ExpenseStatus.fromJson(e)).toList() ?? [], + baseAmount: (json['baseAmount'] as num?)?.toDouble(), + taxAmount: (json['taxAmount'] as num?)?.toDouble(), + tdsPercentage: (json['tdsPercentage'] as num?)?.toDouble(), + status: json['status'] != null + ? ExpenseStatus.fromJson(json['status']) + : ExpenseStatus.empty(), + nextStatus: (json['nextStatus'] as List?) + ?.map((e) => ExpenseStatus.fromJson(e)) + .toList() ?? + [], preApproved: json['preApproved'] ?? false, transactionId: json['transactionId'] ?? '', description: json['description'] ?? '', location: json['location'] ?? '', - documents: (json['documents'] as List?)?.map((e) => ExpenseDocument.fromJson(e)).toList() ?? [], - expenseLogs: (json['expenseLogs'] as List?)?.map((e) => ExpenseLog.fromJson(e)).toList() ?? [], + currency: + json['currency'] != null ? Currency.fromJson(json['currency']) : null, + documents: (json['documents'] as List?) + ?.map((e) => ExpenseDocument.fromJson(e)) + .toList() ?? + [], + expenseLogs: (json['expenseLogs'] as List?) + ?.map((e) => ExpenseLog.fromJson(e)) + .toList() ?? + [], gstNumber: json['gstNumber']?.toString(), - noOfPersons: json['noOfPersons'] ?? 0, + noOfPersons: json['noOfPersons'] != null ? json['noOfPersons'] : null, isActive: json['isActive'] ?? true, expensesReimburse: json['expensesReimburse'], + expenseUId: json['expenseUId']?.toString(), + paymentRequestUID: json['paymentRequestUID']?.toString(), ); } } @@ -94,20 +137,20 @@ class Project { final String id; final String name; final String shortName; - final String projectAddress; - final String contactPerson; - final String startDate; - final String endDate; + final String? projectAddress; + final String? contactPerson; + final String? startDate; + final String? endDate; final String projectStatusId; Project({ required this.id, required this.name, required this.shortName, - required this.projectAddress, - required this.contactPerson, - required this.startDate, - required this.endDate, + this.projectAddress, + this.contactPerson, + this.startDate, + this.endDate, required this.projectStatusId, }); @@ -116,10 +159,10 @@ class Project { id: json['id'] ?? '', name: json['name'] ?? '', shortName: json['shortName'] ?? '', - projectAddress: json['projectAddress'] ?? '', - contactPerson: json['contactPerson'] ?? '', - startDate: json['startDate'] ?? '', - endDate: json['endDate'] ?? '', + projectAddress: json['projectAddress'], + contactPerson: json['contactPerson'], + startDate: json['startDate'], + endDate: json['endDate'], projectStatusId: json['projectStatusId'] ?? '', ); } @@ -128,10 +171,6 @@ class Project { id: '', name: '', shortName: '', - projectAddress: '', - contactPerson: '', - startDate: '', - endDate: '', projectStatusId: '', ); } @@ -141,12 +180,14 @@ class ExpensesType { final String id; final String name; final bool noOfPersonsRequired; + final bool isAttachmentRequried; final String description; ExpensesType({ required this.id, required this.name, required this.noOfPersonsRequired, + required this.isAttachmentRequried, required this.description, }); @@ -155,6 +196,7 @@ class ExpensesType { id: json['id'] ?? '', name: json['name'] ?? '', noOfPersonsRequired: json['noOfPersonsRequired'] ?? false, + isAttachmentRequried: json['isAttachmentRequried'] ?? false, description: json['description'] ?? '', ); } @@ -163,6 +205,7 @@ class ExpensesType { id: '', name: '', noOfPersonsRequired: false, + isAttachmentRequried: false, description: '', ); } @@ -199,6 +242,7 @@ class Person { final String id; final String firstName; final String lastName; + final String? email; final String photo; final String jobRoleId; final String jobRoleName; @@ -207,6 +251,7 @@ class Person { required this.id, required this.firstName, required this.lastName, + this.email, required this.photo, required this.jobRoleId, required this.jobRoleName, @@ -217,7 +262,8 @@ class Person { id: json['id'] ?? '', firstName: json['firstName'] ?? '', lastName: json['lastName'] ?? '', - photo: json['photo'] is String ? json['photo'] : '', + email: json['email'], + photo: json['photo'] ?? '', jobRoleId: json['jobRoleId'] ?? '', jobRoleName: json['jobRoleName'] ?? '', ); @@ -227,6 +273,7 @@ class Person { id: '', firstName: '', lastName: '', + email: null, photo: '', jobRoleId: '', jobRoleName: '', @@ -322,10 +369,39 @@ class ExpenseLog { factory ExpenseLog.fromJson(Map json) { return ExpenseLog( id: json['id'] ?? '', - updatedBy: json['updatedBy'] != null ? Person.fromJson(json['updatedBy']) : Person.empty(), + updatedBy: json['updatedBy'] != null + ? Person.fromJson(json['updatedBy']) + : Person.empty(), action: json['action'] ?? '', updateAt: json['updateAt'] ?? '', comment: json['comment'] ?? '', ); } } + +// ---------------- Currency ---------------- +class Currency { + final String id; + final String currencyCode; + final String currencyName; + final String symbol; + final bool isActive; + + Currency({ + required this.id, + required this.currencyCode, + required this.currencyName, + required this.symbol, + required this.isActive, + }); + + factory Currency.fromJson(Map json) { + return Currency( + id: json['id'] ?? '', + currencyCode: json['currencyCode'] ?? '', + currencyName: json['currencyName'] ?? '', + symbol: json['symbol'] ?? '', + isActive: json['isActive'] ?? true, + ); + } +} diff --git a/lib/model/expense/expense_list_model.dart b/lib/model/expense/expense_list_model.dart index 2058fe3..f241470 100644 --- a/lib/model/expense/expense_list_model.dart +++ b/lib/model/expense/expense_list_model.dart @@ -312,7 +312,7 @@ class Project { }; } -/// --- Expense Type --- +/// --- Expense Category --- class ExpenseType { final String id; final String name; diff --git a/lib/model/expense/reimbursement_bottom_sheet.dart b/lib/model/expense/reimbursement_bottom_sheet.dart index 6ca4d81..75db7b1 100644 --- a/lib/model/expense/reimbursement_bottom_sheet.dart +++ b/lib/model/expense/reimbursement_bottom_sheet.dart @@ -2,13 +2,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; -import 'package:marco/controller/expense/expense_detail_controller.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/model/expense/employee_selector_bottom_sheet.dart'; +import 'package:on_field_work/controller/expense/expense_detail_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/model/expense/employee_selector_bottom_sheet.dart'; class ReimbursementBottomSheet extends StatefulWidget { final String expenseId; diff --git a/lib/model/finance/add_payment_request_bottom_sheet.dart b/lib/model/finance/add_payment_request_bottom_sheet.dart index 0fe6e8d..b27dde4 100644 --- a/lib/model/finance/add_payment_request_bottom_sheet.dart +++ b/lib/model/finance/add_payment_request_bottom_sheet.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; -import 'package:marco/controller/finance/add_payment_request_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/utils/validators.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/widgets/expense/expense_form_widgets.dart'; -import 'package:marco/helpers/widgets/my_confirmation_dialog.dart'; +import 'package:on_field_work/controller/finance/add_payment_request_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/utils/validators.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/widgets/expense/expense_form_widgets.dart'; +import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart'; Future showPaymentRequestBottomSheet({ bool isEdit = false, diff --git a/lib/model/finance/make_expense_bottom_sheet.dart b/lib/model/finance/make_expense_bottom_sheet.dart index 54cc8fe..9ffb114 100644 --- a/lib/model/finance/make_expense_bottom_sheet.dart +++ b/lib/model/finance/make_expense_bottom_sheet.dart @@ -1,12 +1,12 @@ // create_expense_bottom_sheet.dart import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/widgets/expense/expense_form_widgets.dart'; -import 'package:marco/helpers/utils/validators.dart'; -import 'package:marco/controller/finance/payment_request_detail_controller.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/widgets/expense/expense_form_widgets.dart'; +import 'package:on_field_work/helpers/utils/validators.dart'; +import 'package:on_field_work/controller/finance/payment_request_detail_controller.dart'; Future showCreateExpenseBottomSheet({required String statusId}) { return Get.bottomSheet( diff --git a/lib/model/finance/payment_request_filter_bottom_sheet.dart b/lib/model/finance/payment_request_filter_bottom_sheet.dart index 8d680b2..d468da1 100644 --- a/lib/model/finance/payment_request_filter_bottom_sheet.dart +++ b/lib/model/finance/payment_request_filter_bottom_sheet.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/finance/payment_request_controller.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/date_range_picker.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/model/expense/employee_selector_for_filter_bottom_sheet.dart'; +import 'package:on_field_work/controller/finance/payment_request_controller.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/date_range_picker.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/model/expense/employee_selector_for_filter_bottom_sheet.dart'; class PaymentRequestFilterBottomSheet extends StatefulWidget { final PaymentRequestController controller; diff --git a/lib/model/finance/payment_request_list_model.dart b/lib/model/finance/payment_request_list_model.dart index 538ccd4..42c2cc7 100644 --- a/lib/model/finance/payment_request_list_model.dart +++ b/lib/model/finance/payment_request_list_model.dart @@ -13,21 +13,23 @@ class PaymentRequestResponse { required this.data, }); - bool success; - String message; - PaymentRequestData data; + bool? success; + String? message; + PaymentRequestData? data; factory PaymentRequestResponse.fromJson(Map json) => PaymentRequestResponse( success: json["success"], message: json["message"], - data: PaymentRequestData.fromJson(json["data"]), + data: json["data"] != null + ? PaymentRequestData.fromJson(json["data"]) + : null, ); Map toJson() => { "success": success, "message": message, - "data": data.toJson(), + "data": data?.toJson(), }; } @@ -39,25 +41,27 @@ class PaymentRequestData { required this.data, }); - int currentPage; - int totalPages; - int totalEntities; - List data; + int? currentPage; + int? totalPages; + int? totalEntities; + List? data; factory PaymentRequestData.fromJson(Map json) => PaymentRequestData( currentPage: json["currentPage"], totalPages: json["totalPages"], totalEntities: json["totalEntities"], - data: List.from( - json["data"].map((x) => PaymentRequest.fromJson(x))), + data: json["data"] != null + ? List.from( + json["data"].map((x) => PaymentRequest.fromJson(x))) + : [], ); Map toJson() => { "currentPage": currentPage, "totalPages": totalPages, "totalEntities": totalEntities, - "data": List.from(data.map((x) => x.toJson())), + "data": data?.map((x) => x.toJson()).toList(), }; } @@ -82,23 +86,23 @@ class PaymentRequest { required this.isExpenseCreated, }); - String id; - String title; - String description; + String? id; + String? title; + String? description; dynamic recurringPayment; - String paymentRequestUID; - String payee; - Currency currency; - num amount; - DateTime dueDate; - Project project; - ExpenseCategory expenseCategory; - ExpenseStatus expenseStatus; - bool isAdvancePayment; - DateTime createdAt; - CreatedBy createdBy; - bool isActive; - bool isExpenseCreated; + String? paymentRequestUID; + String? payee; + Currency? currency; + num? amount; + DateTime? dueDate; + Project? project; + ExpenseCategory? expenseCategory; + ExpenseStatus? expenseStatus; + bool? isAdvancePayment; + DateTime? createdAt; + CreatedBy? createdBy; + bool? isActive; + bool? isExpenseCreated; factory PaymentRequest.fromJson(Map json) => PaymentRequest( id: json["id"], @@ -107,15 +111,28 @@ class PaymentRequest { recurringPayment: json["recurringPayment"], paymentRequestUID: json["paymentRequestUID"], payee: json["payee"], - currency: Currency.fromJson(json["currency"]), + currency: json["currency"] != null + ? Currency.fromJson(json["currency"]) + : null, amount: json["amount"], - dueDate: DateTime.parse(json["dueDate"]), - project: Project.fromJson(json["project"]), - expenseCategory: ExpenseCategory.fromJson(json["expenseCategory"]), - expenseStatus: ExpenseStatus.fromJson(json["expenseStatus"]), + dueDate: json["dueDate"] != null + ? DateTime.parse(json["dueDate"]) + : null, + project: + json["project"] != null ? Project.fromJson(json["project"]) : null, + expenseCategory: json["expenseCategory"] != null + ? ExpenseCategory.fromJson(json["expenseCategory"]) + : null, + expenseStatus: json["expenseStatus"] != null + ? ExpenseStatus.fromJson(json["expenseStatus"]) + : null, isAdvancePayment: json["isAdvancePayment"], - createdAt: DateTime.parse(json["createdAt"]), - createdBy: CreatedBy.fromJson(json["createdBy"]), + createdAt: json["createdAt"] != null + ? DateTime.parse(json["createdAt"]) + : null, + createdBy: json["createdBy"] != null + ? CreatedBy.fromJson(json["createdBy"]) + : null, isActive: json["isActive"], isExpenseCreated: json["isExpenseCreated"], ); @@ -127,15 +144,15 @@ class PaymentRequest { "recurringPayment": recurringPayment, "paymentRequestUID": paymentRequestUID, "payee": payee, - "currency": currency.toJson(), + "currency": currency?.toJson(), "amount": amount, - "dueDate": dueDate.toIso8601String(), - "project": project.toJson(), - "expenseCategory": expenseCategory.toJson(), - "expenseStatus": expenseStatus.toJson(), + "dueDate": dueDate?.toIso8601String(), + "project": project?.toJson(), + "expenseCategory": expenseCategory?.toJson(), + "expenseStatus": expenseStatus?.toJson(), "isAdvancePayment": isAdvancePayment, - "createdAt": createdAt.toIso8601String(), - "createdBy": createdBy.toJson(), + "createdAt": createdAt?.toIso8601String(), + "createdBy": createdBy?.toJson(), "isActive": isActive, "isExpenseCreated": isExpenseCreated, }; @@ -150,11 +167,11 @@ class Currency { required this.isActive, }); - String id; - String currencyCode; - String currencyName; - String symbol; - bool isActive; + String? id; + String? currencyCode; + String? currencyName; + String? symbol; + bool? isActive; factory Currency.fromJson(Map json) => Currency( id: json["id"], @@ -179,8 +196,8 @@ class Project { required this.name, }); - String id; - String name; + String? id; + String? name; factory Project.fromJson(Map json) => Project( id: json["id"], @@ -202,13 +219,14 @@ class ExpenseCategory { required this.description, }); - String id; - String name; - bool noOfPersonsRequired; - bool isAttachmentRequried; - String description; + String? id; + String? name; + bool? noOfPersonsRequired; + bool? isAttachmentRequried; + String? description; - factory ExpenseCategory.fromJson(Map json) => ExpenseCategory( + factory ExpenseCategory.fromJson(Map json) => + ExpenseCategory( id: json["id"], name: json["name"], noOfPersonsRequired: json["noOfPersonsRequired"], @@ -236,13 +254,13 @@ class ExpenseStatus { required this.isSystem, }); - String id; - String name; - String displayName; - String description; + String? id; + String? name; + String? displayName; + String? description; dynamic permissionIds; - String color; - bool isSystem; + String? color; + bool? isSystem; factory ExpenseStatus.fromJson(Map json) => ExpenseStatus( id: json["id"], @@ -276,13 +294,13 @@ class CreatedBy { required this.jobRoleName, }); - String id; - String firstName; - String lastName; - String email; - String photo; - String jobRoleId; - String jobRoleName; + String? id; + String? firstName; + String? lastName; + String? email; + String? photo; + String? jobRoleId; + String? jobRoleName; factory CreatedBy.fromJson(Map json) => CreatedBy( id: json["id"], diff --git a/lib/model/finance/payment_request_rembursement_bottom_sheet.dart b/lib/model/finance/payment_request_rembursement_bottom_sheet.dart index f8f6983..c89f3b5 100644 --- a/lib/model/finance/payment_request_rembursement_bottom_sheet.dart +++ b/lib/model/finance/payment_request_rembursement_bottom_sheet.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; -import 'package:marco/controller/finance/payment_request_detail_controller.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/model/expense/employee_selector_bottom_sheet.dart'; +import 'package:on_field_work/controller/finance/payment_request_detail_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/model/expense/employee_selector_bottom_sheet.dart'; class UpdatePaymentRequestWithReimbursement extends StatefulWidget { final String expenseId; diff --git a/lib/model/identifier_model.dart b/lib/model/identifier_model.dart index 9545686..f90c7ab 100644 --- a/lib/model/identifier_model.dart +++ b/lib/model/identifier_model.dart @@ -1,5 +1,5 @@ -import 'package:marco/model/model.dart'; +import 'package:on_field_work/model/model.dart'; abstract class IdentifierModel extends Model { final int id; diff --git a/lib/model/my_paginated_table.dart b/lib/model/my_paginated_table.dart index d35ba28..c14bf72 100644 --- a/lib/model/my_paginated_table.dart +++ b/lib/model/my_paginated_table.dart @@ -1,8 +1,8 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; class MyPaginatedTable extends StatefulWidget { final String? title; diff --git a/lib/model/service_project/add_service_project_job_bottom_sheet.dart b/lib/model/service_project/add_service_project_job_bottom_sheet.dart index 081c0b3..3b4d133 100644 --- a/lib/model/service_project/add_service_project_job_bottom_sheet.dart +++ b/lib/model/service_project/add_service_project_job_bottom_sheet.dart @@ -1,14 +1,15 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/date_range_picker.dart'; -import 'package:marco/controller/service_project/add_service_project_job_controller.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/model/employees/multiple_select_bottomsheet.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/date_range_picker.dart'; +import 'package:on_field_work/controller/service_project/add_service_project_job_controller.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/model/employees/multiple_select_bottomsheet.dart'; +import 'package:on_field_work/model/service_project/service_project_branches_model.dart'; class AddServiceProjectJobBottomSheet extends StatefulWidget { final String projectId; @@ -31,6 +32,7 @@ class _AddServiceProjectJobBottomSheetState super.initState(); _selectedEmployees = RxList.from(controller.selectedAssignees); + controller.fetchBranches(widget.projectId); } @override @@ -89,6 +91,54 @@ class _AddServiceProjectJobBottomSheetState ), ], ); + Widget _branchSelector() => Obx(() { + if (controller.isBranchLoading.value) { + return const Center(child: CircularProgressIndicator()); + } + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + MyText.labelMedium("Select Branch (Optional)"), + MySpacing.height(8), + PopupMenuButton( + onSelected: (branch) { + controller.selectedBranch.value = branch; + }, + itemBuilder: (_) => controller.branches + .map( + (b) => PopupMenuItem( + value: b, + child: Text(b.branchName), + ), + ) + .toList(), + child: Container( + padding: + const EdgeInsets.symmetric(horizontal: 14, vertical: 14), + decoration: BoxDecoration( + color: Colors.grey.shade100, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.grey.shade300), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Obx(() => Text( + controller.selectedBranch.value?.branchName ?? + "Select Branch (Optional)", + style: MyTextStyle.bodySmall( + color: Colors.grey.shade700, + ), + )), + const Icon(Icons.arrow_drop_down), + ], + ), + ), + ), + ], + ); + }); Widget _employeeSelector() => Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -203,6 +253,8 @@ class _AddServiceProjectJobBottomSheetState MySpacing.height(16), _employeeSelector(), MySpacing.height(16), + _branchSelector(), + MySpacing.height(16), _labelWithStar("Tags", required: true), MySpacing.height(8), _tagInput(), diff --git a/lib/model/service_project/job_allocation_model.dart b/lib/model/service_project/job_allocation_model.dart index bc29a63..14ffefd 100644 --- a/lib/model/service_project/job_allocation_model.dart +++ b/lib/model/service_project/job_allocation_model.dart @@ -15,16 +15,26 @@ class ServiceProjectAllocationResponse { required this.timestamp, }); - factory ServiceProjectAllocationResponse.fromJson(Map json) { + factory ServiceProjectAllocationResponse.fromJson(Map? json) { + if (json == null) { + return ServiceProjectAllocationResponse( + success: false, + message: "", + data: [], + statusCode: 0, + timestamp: DateTime.now(), + ); + } + return ServiceProjectAllocationResponse( - success: json['success'] as bool, - message: json['message'] as String, - data: (json['data'] as List) + success: json['success'] as bool? ?? false, + message: json['message'] as String? ?? "", + data: (json['data'] as List? ?? []) .map((e) => ServiceProjectAllocation.fromJson(e)) .toList(), errors: json['errors'], - statusCode: json['statusCode'] as int, - timestamp: DateTime.parse(json['timestamp'] as String), + statusCode: json['statusCode'] as int? ?? 0, + timestamp: DateTime.tryParse(json['timestamp'] ?? "") ?? DateTime.now(), ); } @@ -61,17 +71,30 @@ class ServiceProjectAllocation { this.reAssignedBy, }); - factory ServiceProjectAllocation.fromJson(Map json) { + factory ServiceProjectAllocation.fromJson(Map? json) { + if (json == null) { + return ServiceProjectAllocation( + id: "", + project: Project.fromJson(null), + employee: Employee.fromJson(null), + teamRole: TeamRole.fromJson(null), + isActive: false, + assignedAt: DateTime.now(), + assignedBy: Employee.fromJson(null), + ); + } + return ServiceProjectAllocation( - id: json['id'] as String, + id: json['id'] as String? ?? "", project: Project.fromJson(json['project']), employee: Employee.fromJson(json['employee']), teamRole: TeamRole.fromJson(json['teamRole']), - isActive: json['isActive'] as bool, - assignedAt: DateTime.parse(json['assignedAt'] as String), + isActive: json['isActive'] as bool? ?? false, + assignedAt: + DateTime.tryParse(json['assignedAt'] ?? "") ?? DateTime.now(), assignedBy: Employee.fromJson(json['assignedBy']), reAssignedAt: json['reAssignedAt'] != null - ? DateTime.parse(json['reAssignedAt']) + ? DateTime.tryParse(json['reAssignedAt']) ?? DateTime.now() : null, reAssignedBy: json['reAssignedBy'] != null ? Employee.fromJson(json['reAssignedBy']) @@ -111,15 +134,28 @@ class Project { required this.contactEmail, }); - factory Project.fromJson(Map json) { + factory Project.fromJson(Map? json) { + if (json == null) { + return Project( + id: "", + name: "", + shortName: "", + assignedDate: DateTime.now(), + contactName: "", + contactPhone: "", + contactEmail: "", + ); + } + return Project( - id: json['id'] as String, - name: json['name'] as String, - shortName: json['shortName'] as String, - assignedDate: DateTime.parse(json['assignedDate'] as String), - contactName: json['contactName'] as String, - contactPhone: json['contactPhone'] as String, - contactEmail: json['contactEmail'] as String, + id: json['id'] as String? ?? "", + name: json['name'] as String? ?? "", + shortName: json['shortName'] as String? ?? "", + assignedDate: + DateTime.tryParse(json['assignedDate'] ?? "") ?? DateTime.now(), + contactName: json['contactName'] as String? ?? "", + contactPhone: json['contactPhone'] as String? ?? "", + contactEmail: json['contactEmail'] as String? ?? "", ); } @@ -153,15 +189,27 @@ class Employee { required this.jobRoleName, }); - factory Employee.fromJson(Map json) { + factory Employee.fromJson(Map? json) { + if (json == null) { + return Employee( + id: "", + firstName: "", + lastName: "", + email: null, + photo: null, + jobRoleId: "", + jobRoleName: "", + ); + } + return Employee( - id: json['id'] as String, - firstName: json['firstName'] as String, - lastName: json['lastName'] as String, + id: json['id'] as String? ?? "", + firstName: json['firstName'] as String? ?? "", + lastName: json['lastName'] as String? ?? "", email: json['email'] as String?, photo: json['photo'] as String?, - jobRoleId: json['jobRoleId'] as String, - jobRoleName: json['jobRoleName'] as String, + jobRoleId: json['jobRoleId'] as String? ?? "", + jobRoleName: json['jobRoleName'] as String? ?? "", ); } @@ -187,11 +235,19 @@ class TeamRole { required this.description, }); - factory TeamRole.fromJson(Map json) { + factory TeamRole.fromJson(Map? json) { + if (json == null) { + return TeamRole( + id: "", + name: "", + description: "", + ); + } + return TeamRole( - id: json['id'] as String, - name: json['name'] as String, - description: json['description'] as String, + id: json['id'] as String? ?? "", + name: json['name'] as String? ?? "", + description: json['description'] as String? ?? "", ); } diff --git a/lib/model/service_project/service_project_allocation_bottomsheet.dart b/lib/model/service_project/service_project_allocation_bottomsheet.dart index 7ea4614..3a1e0bf 100644 --- a/lib/model/service_project/service_project_allocation_bottomsheet.dart +++ b/lib/model/service_project/service_project_allocation_bottomsheet.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/controller/service_project/service_project_allocation_controller.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/model/employees/multiple_select_bottomsheet.dart'; -import 'package:marco/model/service_project/job_allocation_model.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/controller/service_project/service_project_allocation_controller.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/model/employees/multiple_select_bottomsheet.dart'; +import 'package:on_field_work/model/service_project/job_allocation_model.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; class RoleEmployeeAllocation { final TeamRole role; diff --git a/lib/model/service_project/service_project_branches_model.dart b/lib/model/service_project/service_project_branches_model.dart new file mode 100644 index 0000000..6bdc639 --- /dev/null +++ b/lib/model/service_project/service_project_branches_model.dart @@ -0,0 +1,149 @@ +class ServiceProjectBranchesResponse { + final bool success; + final String message; + final Data? data; + final dynamic errors; + final int statusCode; + final DateTime timestamp; + + ServiceProjectBranchesResponse({ + required this.success, + required this.message, + required this.data, + required this.errors, + required this.statusCode, + required this.timestamp, + }); + + factory ServiceProjectBranchesResponse.fromJson(Map json) { + return ServiceProjectBranchesResponse( + success: json['success'] ?? false, + message: json['message'] ?? '', + data: json['data'] != null ? Data.fromJson(json['data']) : null, + errors: json['errors'], + statusCode: json['statusCode'] ?? 0, + timestamp: DateTime.tryParse(json['timestamp'] ?? '') ?? DateTime.now(), + ); + } +} + +class Data { + final int currentPage; + final int totalPages; + final int totalEntities; + final List data; + + Data({ + required this.currentPage, + required this.totalPages, + required this.totalEntities, + required this.data, + }); + + factory Data.fromJson(Map json) { + return Data( + currentPage: json['currentPage'] ?? 0, + totalPages: json['totalPages'] ?? 0, + totalEntities: json['totalEntities'] ?? 0, + data: json['data'] != null + ? List.from( + json['data'].map((x) => Branch.fromJson(x)), + ) + : [], + ); + } +} + +class Branch { + final String id; + final String branchName; + final Project project; + final String? contactInformation; + final String? address; + final String? branchType; + final DateTime? createdAt; + final CreatedBy? createdBy; + + Branch({ + required this.id, + required this.branchName, + required this.project, + this.contactInformation, + this.address, + this.branchType, + this.createdAt, + this.createdBy, + }); + + factory Branch.fromJson(Map json) { + return Branch( + id: json['id'] ?? '', + branchName: json['branchName'] ?? '', + project: Project.fromJson(json['project'] ?? {}), + contactInformation: json['contactInformation'], + address: json['address'], + branchType: json['branchType'], + createdAt: + json['createdAt'] != null ? DateTime.parse(json['createdAt']) : null, + createdBy: + json['createdBy'] != null ? CreatedBy.fromJson(json['createdBy']) : null, + ); + } +} + +class Project { + final String id; + final String name; + final String shortName; + final DateTime? assignedDate; + + Project({ + required this.id, + required this.name, + required this.shortName, + this.assignedDate, + }); + + factory Project.fromJson(Map json) { + return Project( + id: json['id'] ?? '', + name: json['name'] ?? '', + shortName: json['shortName'] ?? '', + assignedDate: json['assignedDate'] != null + ? DateTime.parse(json['assignedDate']) + : null, + ); + } +} + +class CreatedBy { + final String id; + final String firstName; + final String lastName; + final String email; + final String? photo; + final String jobRoleId; + final String jobRoleName; + + CreatedBy({ + required this.id, + required this.firstName, + required this.lastName, + required this.email, + this.photo, + required this.jobRoleId, + required this.jobRoleName, + }); + + factory CreatedBy.fromJson(Map json) { + return CreatedBy( + id: json['id'] ?? '', + firstName: json['firstName'] ?? '', + lastName: json['lastName'] ?? '', + email: json['email'] ?? '', + photo: json['photo'], + jobRoleId: json['jobRoleId'] ?? '', + jobRoleName: json['jobRoleName'] ?? '', + ); + } +} diff --git a/lib/model/service_project/service_project_job_detail_model.dart b/lib/model/service_project/service_project_job_detail_model.dart index f340416..e7b48fc 100644 --- a/lib/model/service_project/service_project_job_detail_model.dart +++ b/lib/model/service_project/service_project_job_detail_model.dart @@ -1,91 +1,99 @@ class JobDetailsResponse { - final bool success; - final String message; + final bool? success; + final String? message; final JobData? data; final dynamic errors; - final int statusCode; - final String timestamp; + final int? statusCode; + final String? timestamp; JobDetailsResponse({ - required this.success, - required this.message, + this.success, + this.message, this.data, this.errors, - required this.statusCode, - required this.timestamp, + this.statusCode, + this.timestamp, }); - factory JobDetailsResponse.fromJson(Map json) { + factory JobDetailsResponse.fromJson(Map? json) { + if (json == null) return JobDetailsResponse(); + return JobDetailsResponse( - success: json['success'] as bool, - message: json['message'] as String, + success: json['success'] as bool?, + message: json['message'] as String?, data: json['data'] != null ? JobData.fromJson(json['data']) : null, errors: json['errors'], - statusCode: json['statusCode'] as int, - timestamp: json['timestamp'] as String, + statusCode: json['statusCode'] as int?, + timestamp: json['timestamp'] as String?, ); } } class JobData { - final String id; - final String title; - final String description; - final String jobTicketUId; - final Project project; - final List assignees; - final Status status; - final String startDate; - final String dueDate; - final bool isActive; + final String? id; + final String? title; + final String? description; + final String? jobTicketUId; + final Project? project; + final List? assignees; + final Status? status; + final String? startDate; + final String? dueDate; + final bool? isActive; final dynamic taggingAction; final String? attendanceId; final int? nextTaggingAction; - final String createdAt; - final User createdBy; - final List tags; - final List updateLogs; + final String? createdAt; + final User? createdBy; + final List? tags; + final List? updateLogs; + final ProjectBranch? projectBranch; JobData({ - required this.id, - required this.title, - required this.description, - required this.jobTicketUId, - required this.project, - required this.assignees, - required this.status, - required this.startDate, - required this.dueDate, - required this.isActive, + this.id, + this.title, + this.description, + this.jobTicketUId, + this.project, + this.assignees, + this.status, + this.startDate, + this.dueDate, + this.isActive, this.taggingAction, this.attendanceId, this.nextTaggingAction, - required this.createdAt, - required this.createdBy, - required this.tags, - required this.updateLogs, + this.createdAt, + this.createdBy, + this.tags, + this.updateLogs, + this.projectBranch, }); - factory JobData.fromJson(Map json) { + factory JobData.fromJson(Map? json) { + if (json == null) return JobData(); + return JobData( - id: json['id'] as String, - title: json['title'] as String, - description: json['description'] as String, - jobTicketUId: json['jobTicketUId'] as String, - project: Project.fromJson(json['project']), + id: json['id'] as String?, + title: json['title'] as String?, + description: json['description'] as String?, + jobTicketUId: json['jobTicketUId'] as String?, + project: + json['project'] != null ? Project.fromJson(json['project']) : null, assignees: (json['assignees'] as List?) ?.map((e) => Assignee.fromJson(e)) .toList() ?? [], - status: Status.fromJson(json['status']), - startDate: json['startDate'] as String, - dueDate: json['dueDate'] as String, - isActive: json['isActive'] as bool, + status: json['status'] != null ? Status.fromJson(json['status']) : null, + startDate: json['startDate'] as String?, + dueDate: json['dueDate'] as String?, + isActive: json['isActive'] as bool?, taggingAction: json['taggingAction'], attendanceId: json['attendanceId'] as String?, nextTaggingAction: json['nextTaggingAction'] as int?, - createdAt: json['createdAt'] as String, - createdBy: User.fromJson(json['createdBy']), + createdAt: json['createdAt'] as String?, + createdBy: + json['createdBy'] != null ? User.fromJson(json['createdBy']) : null, tags: (json['tags'] as List?) ?.map((e) => Tag.fromJson(e)) .toList() ?? @@ -94,125 +102,156 @@ class JobData { ?.map((e) => UpdateLog.fromJson(e)) .toList() ?? [], + projectBranch: json['projectBranch'] != null + ? ProjectBranch.fromJson(json['projectBranch']) + : null, ); } } class Project { - final String id; - final String name; - final String shortName; - final String assignedDate; - final String contactName; - final String contactPhone; - final String contactEmail; + final String? id; + final String? name; + final String? shortName; + final String? assignedDate; + final String? contactName; + final String? contactPhone; + final String? contactEmail; Project({ - required this.id, - required this.name, - required this.shortName, - required this.assignedDate, - required this.contactName, - required this.contactPhone, - required this.contactEmail, + this.id, + this.name, + this.shortName, + this.assignedDate, + this.contactName, + this.contactPhone, + this.contactEmail, }); - factory Project.fromJson(Map json) { + factory Project.fromJson(Map? json) { + if (json == null) return Project(); + return Project( - id: json['id'] as String, - name: json['name'] as String, - shortName: json['shortName'] as String, - assignedDate: json['assignedDate'] as String, - contactName: json['contactName'] as String, - contactPhone: json['contactPhone'] as String, - contactEmail: json['contactEmail'] as String, + id: json['id'] as String?, + name: json['name'] as String?, + shortName: json['shortName'] as String?, + assignedDate: json['assignedDate'] as String?, + contactName: json['contactName'] as String?, + contactPhone: json['contactPhone'] as String?, + contactEmail: json['contactEmail'] as String?, ); } } class Assignee { - final String id; - final String firstName; - final String lastName; + final String? id; + final String? firstName; + final String? lastName; final String? email; final String? photo; - final String jobRoleId; - final String jobRoleName; + final String? jobRoleId; + final String? jobRoleName; Assignee({ - required this.id, - required this.firstName, - required this.lastName, + this.id, + this.firstName, + this.lastName, this.email, this.photo, - required this.jobRoleId, - required this.jobRoleName, + this.jobRoleId, + this.jobRoleName, }); - factory Assignee.fromJson(Map json) { + factory Assignee.fromJson(Map? json) { + if (json == null) return Assignee(); + return Assignee( - id: json['id'] as String, - firstName: json['firstName'] as String, - lastName: json['lastName'] as String, + id: json['id'] as String?, + firstName: json['firstName'] as String?, + lastName: json['lastName'] as String?, email: json['email'] as String?, photo: json['photo'] as String?, - jobRoleId: json['jobRoleId'] as String, - jobRoleName: json['jobRoleName'] as String, + jobRoleId: json['jobRoleId'] as String?, + jobRoleName: json['jobRoleName'] as String?, + ); + } +} + +class ProjectBranch { + final String? id; + final String? branchName; + final String? branchType; + + ProjectBranch({ + this.id, + this.branchName, + this.branchType, + }); + + factory ProjectBranch.fromJson(Map json) { + return ProjectBranch( + id: json['id'], + branchName: json['branchName'], + branchType: json['branchType'], ); } } class Status { - final String id; - final String name; - final String displayName; - final int level; + final String? id; + final String? name; + final String? displayName; + final int? level; Status({ - required this.id, - required this.name, - required this.displayName, - required this.level, + this.id, + this.name, + this.displayName, + this.level, }); - factory Status.fromJson(Map json) { + factory Status.fromJson(Map? json) { + if (json == null) return Status(); + return Status( - id: json['id'] as String, - name: json['name'] as String, - displayName: json['displayName'] as String, - level: json['level'] as int, + id: json['id'] as String?, + name: json['name'] as String?, + displayName: json['displayName'] as String?, + level: json['level'] as int?, ); } } class User { - final String id; - final String firstName; - final String lastName; + final String? id; + final String? firstName; + final String? lastName; final String? email; final String? photo; - final String jobRoleId; - final String jobRoleName; + final String? jobRoleId; + final String? jobRoleName; User({ - required this.id, - required this.firstName, - required this.lastName, + this.id, + this.firstName, + this.lastName, this.email, this.photo, - required this.jobRoleId, - required this.jobRoleName, + this.jobRoleId, + this.jobRoleName, }); - factory User.fromJson(Map json) { + factory User.fromJson(Map? json) { + if (json == null) return User(); + return User( - id: json['id'] as String, - firstName: json['firstName'] as String, - lastName: json['lastName'] as String, + id: json['id'] as String?, + firstName: json['firstName'] as String?, + lastName: json['lastName'] as String?, email: json['email'] as String?, photo: json['photo'] as String?, - jobRoleId: json['jobRoleId'] as String, - jobRoleName: json['jobRoleName'] as String, + jobRoleId: json['jobRoleId'] as String?, + jobRoleName: json['jobRoleName'] as String?, ); } } @@ -223,7 +262,9 @@ class Tag { Tag({this.id, this.name}); - factory Tag.fromJson(Map json) { + factory Tag.fromJson(Map? json) { + if (json == null) return Tag(); + return Tag( id: json['id'] as String?, name: json['name'] as String?, @@ -232,27 +273,32 @@ class Tag { } class UpdateLog { - final String id; + final String? id; final Status? status; - final Status nextStatus; - final String comment; - final User updatedBy; + final Status? nextStatus; + final String? comment; + final User? updatedBy; UpdateLog({ - required this.id, + this.id, this.status, - required this.nextStatus, - required this.comment, - required this.updatedBy, + this.nextStatus, + this.comment, + this.updatedBy, }); - factory UpdateLog.fromJson(Map json) { + factory UpdateLog.fromJson(Map? json) { + if (json == null) return UpdateLog(); + return UpdateLog( - id: json['id'] as String, + id: json['id'] as String?, status: json['status'] != null ? Status.fromJson(json['status']) : null, - nextStatus: Status.fromJson(json['nextStatus']), - comment: json['comment'] as String, - updatedBy: User.fromJson(json['updatedBy']), + nextStatus: json['nextStatus'] != null + ? Status.fromJson(json['nextStatus']) + : null, + comment: json['comment'] as String?, + updatedBy: + json['updatedBy'] != null ? User.fromJson(json['updatedBy']) : null, ); } } diff --git a/lib/res/assets_res.dart b/lib/res/assets_res.dart index cc0b6c3..5a5d010 100644 --- a/lib/res/assets_res.dart +++ b/lib/res/assets_res.dart @@ -6,7 +6,7 @@ class AssetsRes { AssetsRes._(); - static const String PROJECT_NAME = 'marco'; + static const String PROJECT_NAME = 'on_field_work'; static const String PROJECT_VERSION = '1.0.0+1'; static const String LOADING_LOGO = 'assets/logo/loading_logo.png'; } diff --git a/lib/routes.dart b/lib/routes.dart index bfef6ea..bbd8931 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,30 +1,30 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/helpers/services/tenant_service.dart'; -import 'package:marco/view/auth/forgot_password_screen.dart'; -import 'package:marco/view/auth/login_screen.dart'; -import 'package:marco/view/auth/register_account_screen.dart'; -import 'package:marco/view/auth/reset_password_screen.dart'; -import 'package:marco/view/error_pages/coming_soon_screen.dart'; -import 'package:marco/view/error_pages/error_404_screen.dart'; -import 'package:marco/view/error_pages/error_500_screen.dart'; -import 'package:marco/view/dashboard/dashboard_screen.dart'; -import 'package:marco/view/Attendence/attendance_screen.dart'; -import 'package:marco/view/taskPlanning/daily_task_planning.dart'; -import 'package:marco/view/taskPlanning/daily_progress_report.dart'; -import 'package:marco/view/employees/employees_screen.dart'; -import 'package:marco/view/auth/login_option_screen.dart'; -import 'package:marco/view/auth/mpin_screen.dart'; -import 'package:marco/view/auth/mpin_auth_screen.dart'; -import 'package:marco/view/directory/directory_main_screen.dart'; -import 'package:marco/view/expense/expense_screen.dart'; -import 'package:marco/view/document/user_document_screen.dart'; -import 'package:marco/view/tenant/tenant_selection_screen.dart'; -import 'package:marco/view/finance/finance_screen.dart'; -import 'package:marco/view/finance/advance_payment_screen.dart'; -import 'package:marco/view/finance/payment_request_screen.dart'; -import 'package:marco/view/service_project/service_project_screen.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/helpers/services/tenant_service.dart'; +import 'package:on_field_work/view/auth/forgot_password_screen.dart'; +import 'package:on_field_work/view/auth/login_screen.dart'; +import 'package:on_field_work/view/auth/register_account_screen.dart'; +import 'package:on_field_work/view/auth/reset_password_screen.dart'; +import 'package:on_field_work/view/error_pages/coming_soon_screen.dart'; +import 'package:on_field_work/view/error_pages/error_404_screen.dart'; +import 'package:on_field_work/view/error_pages/error_500_screen.dart'; +import 'package:on_field_work/view/dashboard/dashboard_screen.dart'; +import 'package:on_field_work/view/Attendence/attendance_screen.dart'; +import 'package:on_field_work/view/taskPlanning/daily_task_planning.dart'; +import 'package:on_field_work/view/taskPlanning/daily_progress_report.dart'; +import 'package:on_field_work/view/employees/employees_screen.dart'; +import 'package:on_field_work/view/auth/login_option_screen.dart'; +import 'package:on_field_work/view/auth/mpin_screen.dart'; +import 'package:on_field_work/view/auth/mpin_auth_screen.dart'; +import 'package:on_field_work/view/directory/directory_main_screen.dart'; +import 'package:on_field_work/view/expense/expense_screen.dart'; +import 'package:on_field_work/view/document/user_document_screen.dart'; +import 'package:on_field_work/view/tenant/tenant_selection_screen.dart'; +import 'package:on_field_work/view/finance/finance_screen.dart'; +import 'package:on_field_work/view/finance/advance_payment_screen.dart'; +import 'package:on_field_work/view/finance/payment_request_screen.dart'; +import 'package:on_field_work/view/service_project/service_project_screen.dart'; class AuthMiddleware extends GetMiddleware { @override RouteSettings? redirect(String? route) { diff --git a/lib/view/Attendence/attendance_logs_tab.dart b/lib/view/Attendence/attendance_logs_tab.dart index 9bb3bdc..2b89fc8 100644 --- a/lib/view/Attendence/attendance_logs_tab.dart +++ b/lib/view/Attendence/attendance_logs_tab.dart @@ -1,16 +1,16 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/attendance/attendance_screen_controller.dart'; -import 'package:marco/helpers/utils/date_time_utils.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/helpers/widgets/my_card.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; -import 'package:marco/model/attendance/log_details_view.dart'; -import 'package:marco/model/attendance/attendence_action_button.dart'; -import 'package:marco/helpers/utils/attendance_actions.dart'; +import 'package:on_field_work/controller/attendance/attendance_screen_controller.dart'; +import 'package:on_field_work/helpers/utils/date_time_utils.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/widgets/my_card.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/model/attendance/log_details_view.dart'; +import 'package:on_field_work/model/attendance/attendence_action_button.dart'; +import 'package:on_field_work/helpers/utils/attendance_actions.dart'; class AttendanceLogsTab extends StatefulWidget { final AttendanceController controller; diff --git a/lib/view/Attendence/attendance_screen.dart b/lib/view/Attendence/attendance_screen.dart index 2a5614a..b782fdb 100644 --- a/lib/view/Attendence/attendance_screen.dart +++ b/lib/view/Attendence/attendance_screen.dart @@ -1,19 +1,19 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_flex.dart'; -import 'package:marco/helpers/widgets/my_flex_item.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/controller/attendance/attendance_screen_controller.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/model/attendance/attendence_filter_sheet.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/view/Attendence/regularization_requests_tab.dart'; -import 'package:marco/view/Attendence/attendance_logs_tab.dart'; -import 'package:marco/view/Attendence/todays_attendance_tab.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_flex.dart'; +import 'package:on_field_work/helpers/widgets/my_flex_item.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/controller/attendance/attendance_screen_controller.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/model/attendance/attendence_filter_sheet.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/view/Attendence/regularization_requests_tab.dart'; +import 'package:on_field_work/view/Attendence/attendance_logs_tab.dart'; +import 'package:on_field_work/view/Attendence/todays_attendance_tab.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; class AttendanceScreen extends StatefulWidget { const AttendanceScreen({super.key}); diff --git a/lib/view/Attendence/attendence_log_screen.dart b/lib/view/Attendence/attendence_log_screen.dart index 05266ae..9ee894d 100644 --- a/lib/view/Attendence/attendence_log_screen.dart +++ b/lib/view/Attendence/attendence_log_screen.dart @@ -1,23 +1,23 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/utils/my_shadow.dart'; -import 'package:marco/helpers/widgets/my_breadcrumb.dart'; -import 'package:marco/helpers/widgets/my_breadcrumb_item.dart'; -import 'package:marco/helpers/widgets/my_card.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; -import 'package:marco/helpers/widgets/my_flex.dart'; -import 'package:marco/helpers/widgets/my_flex_item.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/view/layouts/layout.dart'; -import 'package:marco/controller/attendance/attendance_screen_controller.dart'; -import 'package:marco/controller/permission_controller.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/utils/my_shadow.dart'; +import 'package:on_field_work/helpers/widgets/my_breadcrumb.dart'; +import 'package:on_field_work/helpers/widgets/my_breadcrumb_item.dart'; +import 'package:on_field_work/helpers/widgets/my_card.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_flex.dart'; +import 'package:on_field_work/helpers/widgets/my_flex_item.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/view/layouts/layout.dart'; +import 'package:on_field_work/controller/attendance/attendance_screen_controller.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; import 'package:intl/intl.dart'; -import 'package:marco/model/attendance/attendence_action_button.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/model/attendance/log_details_view.dart'; +import 'package:on_field_work/model/attendance/attendence_action_button.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/model/attendance/log_details_view.dart'; class AttendenceLogScreen extends StatefulWidget { const AttendenceLogScreen({super.key}); diff --git a/lib/view/Attendence/regularization_requests_tab.dart b/lib/view/Attendence/regularization_requests_tab.dart index 6db7739..52eea9d 100644 --- a/lib/view/Attendence/regularization_requests_tab.dart +++ b/lib/view/Attendence/regularization_requests_tab.dart @@ -2,15 +2,15 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; -import 'package:marco/controller/attendance/attendance_screen_controller.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/helpers/widgets/my_card.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; -import 'package:marco/model/attendance/log_details_view.dart'; -import 'package:marco/model/attendance/regualrize_action_button.dart'; +import 'package:on_field_work/controller/attendance/attendance_screen_controller.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/widgets/my_card.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/model/attendance/log_details_view.dart'; +import 'package:on_field_work/model/attendance/regualrize_action_button.dart'; class RegularizationRequestsTab extends StatelessWidget { final AttendanceController controller; diff --git a/lib/view/Attendence/todays_attendance_tab.dart b/lib/view/Attendence/todays_attendance_tab.dart index 3ac6d35..ff5d525 100644 --- a/lib/view/Attendence/todays_attendance_tab.dart +++ b/lib/view/Attendence/todays_attendance_tab.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/attendance/attendance_screen_controller.dart'; -import 'package:marco/helpers/utils/date_time_utils.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/helpers/widgets/my_card.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; -import 'package:marco/model/attendance/log_details_view.dart'; -import 'package:marco/model/attendance/attendence_action_button.dart'; +import 'package:on_field_work/controller/attendance/attendance_screen_controller.dart'; +import 'package:on_field_work/helpers/utils/date_time_utils.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/widgets/my_card.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/model/attendance/log_details_view.dart'; +import 'package:on_field_work/model/attendance/attendence_action_button.dart'; class TodaysAttendanceTab extends StatelessWidget { final AttendanceController controller; diff --git a/lib/view/auth/email_login_form.dart b/lib/view/auth/email_login_form.dart index e716c02..b4e36bb 100644 --- a/lib/view/auth/email_login_form.dart +++ b/lib/view/auth/email_login_form.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/auth/login_controller.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_button.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/controller/auth/login_controller.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_button.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; -import 'package:marco/helpers/services/api_endpoints.dart'; +import 'package:on_field_work/helpers/services/api_endpoints.dart'; class EmailLoginForm extends StatefulWidget { EmailLoginForm({super.key}); diff --git a/lib/view/auth/forgot_password_screen.dart b/lib/view/auth/forgot_password_screen.dart index d9e8150..9b85f4a 100644 --- a/lib/view/auth/forgot_password_screen.dart +++ b/lib/view/auth/forgot_password_screen.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/auth/forgot_password_controller.dart'; -import 'package:marco/helpers/services/api_endpoints.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_button.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/images.dart'; -import 'package:marco/helpers/widgets/wave_background.dart'; +import 'package:on_field_work/controller/auth/forgot_password_controller.dart'; +import 'package:on_field_work/helpers/services/api_endpoints.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_button.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/images.dart'; +import 'package:on_field_work/helpers/widgets/wave_background.dart'; class ForgotPasswordScreen extends StatefulWidget { const ForgotPasswordScreen({super.key}); @@ -124,7 +124,7 @@ class _ForgotPasswordScreenState extends State return Column( children: [ MyText( - "Welcome to Marco", + "Welcome to On Field Work", fontSize: 24, fontWeight: 600, color: Colors.black87, diff --git a/lib/view/auth/login_option_screen.dart b/lib/view/auth/login_option_screen.dart index 2f08def..c514a92 100644 --- a/lib/view/auth/login_option_screen.dart +++ b/lib/view/auth/login_option_screen.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/images.dart'; -import 'package:marco/view/auth/email_login_form.dart'; -import 'package:marco/view/auth/otp_login_form.dart'; -import 'package:marco/helpers/services/api_endpoints.dart'; -import 'package:marco/view/auth/request_demo_bottom_sheet.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/wave_background.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/images.dart'; +import 'package:on_field_work/view/auth/email_login_form.dart'; +import 'package:on_field_work/view/auth/otp_login_form.dart'; +import 'package:on_field_work/helpers/services/api_endpoints.dart'; +import 'package:on_field_work/view/auth/request_demo_bottom_sheet.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/wave_background.dart'; enum LoginOption { email, otp } @@ -182,7 +182,7 @@ class _WelcomeScreenState extends State return Column( children: [ MyText( - "Welcome to Marco", + "Welcome to On Field Work", fontSize: 26, fontWeight: 800, color: Colors.black87, diff --git a/lib/view/auth/login_screen.dart b/lib/view/auth/login_screen.dart index 56d0733..9748825 100644 --- a/lib/view/auth/login_screen.dart +++ b/lib/view/auth/login_screen.dart @@ -1,17 +1,17 @@ import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/auth/login_controller.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_button.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/view/layouts/auth_layout.dart'; -import 'package:marco/images.dart'; -import 'package:marco/view/auth/request_demo_bottom_sheet.dart'; -import 'package:marco/helpers/services/api_endpoints.dart'; +import 'package:on_field_work/controller/auth/login_controller.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_button.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/view/layouts/auth_layout.dart'; +import 'package:on_field_work/images.dart'; +import 'package:on_field_work/view/auth/request_demo_bottom_sheet.dart'; +import 'package:on_field_work/helpers/services/api_endpoints.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); diff --git a/lib/view/auth/mpin_auth_screen.dart b/lib/view/auth/mpin_auth_screen.dart index fdef51d..ace339c 100644 --- a/lib/view/auth/mpin_auth_screen.dart +++ b/lib/view/auth/mpin_auth_screen.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/auth/mpin_controller.dart'; -import 'package:marco/helpers/widgets/my_button.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/images.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/services/api_endpoints.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/wave_background.dart'; +import 'package:on_field_work/controller/auth/mpin_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_button.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/images.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/services/api_endpoints.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/wave_background.dart'; class MPINAuthScreen extends StatefulWidget { @@ -92,7 +92,7 @@ class _MPINAuthScreenState extends State children: [ const SizedBox(height: 12), MyText( - "Welcome to Marco", + "Welcome to On Field Work", fontSize: 24, fontWeight: 800, color: Colors.black87, diff --git a/lib/view/auth/mpin_screen.dart b/lib/view/auth/mpin_screen.dart index b453b29..772d195 100644 --- a/lib/view/auth/mpin_screen.dart +++ b/lib/view/auth/mpin_screen.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/auth/mpin_controller.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/widgets/my_button.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/controller/auth/mpin_controller.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/widgets/my_button.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; class MPINScreen extends StatelessWidget { const MPINScreen({super.key}); diff --git a/lib/view/auth/otp_login_form.dart b/lib/view/auth/otp_login_form.dart index e8b75b0..ecd8b32 100644 --- a/lib/view/auth/otp_login_form.dart +++ b/lib/view/auth/otp_login_form.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/widgets/my_button.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/controller/auth/otp_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/widgets/my_button.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/controller/auth/otp_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; class OTPLoginScreen extends StatefulWidget { const OTPLoginScreen({super.key}); diff --git a/lib/view/auth/register_account_screen.dart b/lib/view/auth/register_account_screen.dart index 1262d83..01f9ae8 100644 --- a/lib/view/auth/register_account_screen.dart +++ b/lib/view/auth/register_account_screen.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/auth/register_account_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_button.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/view/layouts/auth_layout.dart'; +import 'package:on_field_work/controller/auth/register_account_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_button.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/view/layouts/auth_layout.dart'; class RegisterAccountScreen extends StatefulWidget { const RegisterAccountScreen({super.key}); diff --git a/lib/view/auth/request_demo_bottom_sheet.dart b/lib/view/auth/request_demo_bottom_sheet.dart index d7f839d..2673d8e 100644 --- a/lib/view/auth/request_demo_bottom_sheet.dart +++ b/lib/view/auth/request_demo_bottom_sheet.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:marco/helpers/widgets/my_form_validator.dart'; -import 'package:marco/helpers/services/auth_service.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_form_validator.dart'; +import 'package:on_field_work/helpers/services/auth_service.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; class OrganizationFormBottomSheet { static void show(BuildContext context) { diff --git a/lib/view/auth/reset_password_screen.dart b/lib/view/auth/reset_password_screen.dart index 53b22be..e1cf2dc 100644 --- a/lib/view/auth/reset_password_screen.dart +++ b/lib/view/auth/reset_password_screen.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/auth/reset_password_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_button.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/view/layouts/auth_layout.dart'; +import 'package:on_field_work/controller/auth/reset_password_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_button.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/view/layouts/auth_layout.dart'; class ResetPasswordScreen extends StatefulWidget { const ResetPasswordScreen({super.key}); diff --git a/lib/view/dashboard/dashboard_screen.dart b/lib/view/dashboard/dashboard_screen.dart index 9cbe20d..59c8e95 100644 --- a/lib/view/dashboard/dashboard_screen.dart +++ b/lib/view/dashboard/dashboard_screen.dart @@ -1,22 +1,22 @@ import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/dashboard/dashboard_controller.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/controller/dynamicMenu/dynamic_menu_controller.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_card.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/dashbaord/attendance_overview_chart.dart'; -import 'package:marco/helpers/widgets/dashbaord/project_progress_chart.dart'; -import 'package:marco/helpers/widgets/dashbaord/expense_breakdown_chart.dart'; -import 'package:marco/helpers/widgets/dashbaord/expense_by_status_widget.dart'; -import 'package:marco/helpers/widgets/dashbaord/monthly_expense_dashboard_chart.dart'; -import 'package:marco/helpers/widgets/dashbaord/dashboard_overview_widgets.dart'; -import 'package:marco/view/layouts/layout.dart'; -import 'package:marco/helpers/utils/permission_constants.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/controller/dashboard/dashboard_controller.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/controller/dynamicMenu/dynamic_menu_controller.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_card.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/dashbaord/attendance_overview_chart.dart'; +import 'package:on_field_work/helpers/widgets/dashbaord/project_progress_chart.dart'; +import 'package:on_field_work/helpers/widgets/dashbaord/expense_breakdown_chart.dart'; +import 'package:on_field_work/helpers/widgets/dashbaord/expense_by_status_widget.dart'; +import 'package:on_field_work/helpers/widgets/dashbaord/monthly_expense_dashboard_chart.dart'; +import 'package:on_field_work/helpers/widgets/dashbaord/dashboard_overview_widgets.dart'; +import 'package:on_field_work/view/layouts/layout.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; class DashboardScreen extends StatefulWidget { const DashboardScreen({super.key}); diff --git a/lib/view/directory/contact_detail_screen.dart b/lib/view/directory/contact_detail_screen.dart index badb0bf..b031fe0 100644 --- a/lib/view/directory/contact_detail_screen.dart +++ b/lib/view/directory/contact_detail_screen.dart @@ -1,18 +1,18 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/controller/directory/directory_controller.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/model/directory/contact_model.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/helpers/utils/launcher_utils.dart'; -import 'package:marco/model/directory/add_comment_bottom_sheet.dart'; -import 'package:marco/model/directory/add_contact_bottom_sheet.dart'; -import 'package:marco/helpers/utils/date_time_utils.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; -import 'package:marco/helpers/widgets/my_confirmation_dialog.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/controller/directory/directory_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/model/directory/contact_model.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/utils/launcher_utils.dart'; +import 'package:on_field_work/model/directory/add_comment_bottom_sheet.dart'; +import 'package:on_field_work/model/directory/add_contact_bottom_sheet.dart'; +import 'package:on_field_work/helpers/utils/date_time_utils.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; class ContactDetailScreen extends StatefulWidget { final ContactModel contact; diff --git a/lib/view/directory/directory_main_screen.dart b/lib/view/directory/directory_main_screen.dart index c5d55a1..473efaf 100644 --- a/lib/view/directory/directory_main_screen.dart +++ b/lib/view/directory/directory_main_screen.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/directory/directory_controller.dart'; -import 'package:marco/controller/directory/notes_controller.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/controller/directory/directory_controller.dart'; +import 'package:on_field_work/controller/directory/notes_controller.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; -import 'package:marco/view/directory/directory_view.dart'; -import 'package:marco/view/directory/notes_view.dart'; +import 'package:on_field_work/view/directory/directory_view.dart'; +import 'package:on_field_work/view/directory/notes_view.dart'; class DirectoryMainScreen extends StatefulWidget { const DirectoryMainScreen({super.key}); diff --git a/lib/view/directory/directory_view.dart b/lib/view/directory/directory_view.dart index caf5433..cf91ca5 100644 --- a/lib/view/directory/directory_view.dart +++ b/lib/view/directory/directory_view.dart @@ -1,23 +1,23 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/controller/directory/directory_controller.dart'; -import 'package:marco/controller/directory/create_bucket_controller.dart'; -import 'package:marco/helpers/utils/launcher_utils.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; -import 'package:marco/model/directory/add_contact_bottom_sheet.dart'; -import 'package:marco/model/directory/directory_filter_bottom_sheet.dart'; -import 'package:marco/model/directory/create_bucket_bottom_sheet.dart'; -import 'package:marco/view/directory/contact_detail_screen.dart'; -import 'package:marco/view/directory/manage_bucket_screen.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/helpers/utils/permission_constants.dart'; -import 'package:marco/helpers/widgets/my_confirmation_dialog.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/controller/directory/directory_controller.dart'; +import 'package:on_field_work/controller/directory/create_bucket_controller.dart'; +import 'package:on_field_work/helpers/utils/launcher_utils.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/model/directory/add_contact_bottom_sheet.dart'; +import 'package:on_field_work/model/directory/directory_filter_bottom_sheet.dart'; +import 'package:on_field_work/model/directory/create_bucket_bottom_sheet.dart'; +import 'package:on_field_work/view/directory/contact_detail_screen.dart'; +import 'package:on_field_work/view/directory/manage_bucket_screen.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart'; class DirectoryView extends StatefulWidget { @override diff --git a/lib/view/directory/edit_bucket_model.dart b/lib/view/directory/edit_bucket_model.dart index b4a331f..71646b3 100644 --- a/lib/view/directory/edit_bucket_model.dart +++ b/lib/view/directory/edit_bucket_model.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; class EditBucketBottomSheet extends StatelessWidget { const EditBucketBottomSheet({super.key}); diff --git a/lib/view/directory/manage_bucket_screen.dart b/lib/view/directory/manage_bucket_screen.dart index d43bde7..9cca6d9 100644 --- a/lib/view/directory/manage_bucket_screen.dart +++ b/lib/view/directory/manage_bucket_screen.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/directory/directory_controller.dart'; -import 'package:marco/controller/directory/manage_bucket_controller.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/utils/permission_constants.dart'; -import 'package:marco/helpers/widgets/team_members_bottom_sheet.dart'; -import 'package:marco/model/directory/edit_bucket_bottom_sheet.dart'; +import 'package:on_field_work/controller/directory/directory_controller.dart'; +import 'package:on_field_work/controller/directory/manage_bucket_controller.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/helpers/widgets/team_members_bottom_sheet.dart'; +import 'package:on_field_work/model/directory/edit_bucket_bottom_sheet.dart'; class ManageBucketsScreen extends StatefulWidget { final PermissionController permissionController; diff --git a/lib/view/directory/notes_view.dart b/lib/view/directory/notes_view.dart index d374fdc..9378819 100644 --- a/lib/view/directory/notes_view.dart +++ b/lib/view/directory/notes_view.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; -import 'package:marco/controller/directory/notes_controller.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/helpers/utils/date_time_utils.dart'; -import 'package:marco/helpers/widgets/my_confirmation_dialog.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/controller/directory/notes_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/utils/date_time_utils.dart'; +import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; class NotesView extends StatefulWidget { const NotesView({super.key}); diff --git a/lib/view/document/document_details_page.dart b/lib/view/document/document_details_page.dart index 1c07d7b..e645cc5 100644 --- a/lib/view/document/document_details_page.dart +++ b/lib/view/document/document_details_page.dart @@ -2,17 +2,17 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:url_launcher/url_launcher.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; -import 'package:marco/model/document/document_details_model.dart'; -import 'package:marco/controller/document/document_details_controller.dart'; -import 'package:marco/helpers/widgets/custom_app_bar.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/model/document/document_edit_bottom_sheet.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/model/document/document_details_model.dart'; +import 'package:on_field_work/controller/document/document_details_controller.dart'; +import 'package:on_field_work/helpers/widgets/custom_app_bar.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/model/document/document_edit_bottom_sheet.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; class DocumentDetailsPage extends StatefulWidget { final String documentId; diff --git a/lib/view/document/user_document_screen.dart b/lib/view/document/user_document_screen.dart index ced6530..8a11f63 100644 --- a/lib/view/document/user_document_screen.dart +++ b/lib/view/document/user_document_screen.dart @@ -3,23 +3,23 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; -import 'package:marco/controller/document/document_details_controller.dart'; -import 'package:marco/controller/document/document_upload_controller.dart'; -import 'package:marco/controller/document/user_document_controller.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/helpers/utils/permission_constants.dart'; -import 'package:marco/helpers/widgets/custom_app_bar.dart'; -import 'package:marco/helpers/widgets/my_confirmation_dialog.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; -import 'package:marco/model/document/document_upload_bottom_sheet.dart'; -import 'package:marco/model/document/documents_list_model.dart'; -import 'package:marco/model/document/user_document_filter_bottom_sheet.dart'; -import 'package:marco/view/document/document_details_page.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/controller/document/document_details_controller.dart'; +import 'package:on_field_work/controller/document/document_upload_controller.dart'; +import 'package:on_field_work/controller/document/user_document_controller.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/helpers/widgets/custom_app_bar.dart'; +import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/model/document/document_upload_bottom_sheet.dart'; +import 'package:on_field_work/model/document/documents_list_model.dart'; +import 'package:on_field_work/model/document/user_document_filter_bottom_sheet.dart'; +import 'package:on_field_work/view/document/document_details_page.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; class UserDocumentsPage extends StatefulWidget { final String? entityId; diff --git a/lib/view/employees/assign_employee_bottom_sheet.dart b/lib/view/employees/assign_employee_bottom_sheet.dart index 61440ea..f6ae76a 100644 --- a/lib/view/employees/assign_employee_bottom_sheet.dart +++ b/lib/view/employees/assign_employee_bottom_sheet.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/controller/employee/assign_projects_controller.dart'; -import 'package:marco/model/global_project_model.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/controller/employee/assign_projects_controller.dart'; +import 'package:on_field_work/model/global_project_model.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; class AssignProjectBottomSheet extends StatefulWidget { final String employeeId; diff --git a/lib/view/employees/employee_detail_screen.dart b/lib/view/employees/employee_detail_screen.dart index 18d35c4..a65d6bc 100644 --- a/lib/view/employees/employee_detail_screen.dart +++ b/lib/view/employees/employee_detail_screen.dart @@ -1,20 +1,20 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; -import 'package:marco/controller/employee/employees_screen_controller.dart'; -import 'package:marco/helpers/widgets/custom_app_bar.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/utils/launcher_utils.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; -import 'package:marco/model/employees/add_employee_bottom_sheet.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; -import 'package:marco/view/employees/manage_reporting_bottom_sheet.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/view/employees/assign_employee_bottom_sheet.dart'; -import 'package:marco/model/employees/employee_details_model.dart'; +import 'package:on_field_work/controller/employee/employees_screen_controller.dart'; +import 'package:on_field_work/helpers/widgets/custom_app_bar.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/utils/launcher_utils.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/model/employees/add_employee_bottom_sheet.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/view/employees/manage_reporting_bottom_sheet.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/view/employees/assign_employee_bottom_sheet.dart'; +import 'package:on_field_work/model/employees/employee_details_model.dart'; class EmployeeDetailPage extends StatefulWidget { final String employeeId; diff --git a/lib/view/employees/employee_profile_screen.dart b/lib/view/employees/employee_profile_screen.dart index 726c452..5dbcfbd 100644 --- a/lib/view/employees/employee_profile_screen.dart +++ b/lib/view/employees/employee_profile_screen.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/view/employees/employee_detail_screen.dart'; -import 'package:marco/view/document/user_document_screen.dart'; -import 'package:marco/helpers/widgets/custom_app_bar.dart'; +import 'package:on_field_work/view/employees/employee_detail_screen.dart'; +import 'package:on_field_work/view/document/user_document_screen.dart'; +import 'package:on_field_work/helpers/widgets/custom_app_bar.dart'; class EmployeeProfilePage extends StatefulWidget { final String employeeId; diff --git a/lib/view/employees/employees_screen.dart b/lib/view/employees/employees_screen.dart index db1f821..da60eca 100644 --- a/lib/view/employees/employees_screen.dart +++ b/lib/view/employees/employees_screen.dart @@ -1,22 +1,22 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/model/employees/add_employee_bottom_sheet.dart'; -import 'package:marco/controller/employee/employees_screen_controller.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/helpers/utils/launcher_utils.dart'; -import 'package:marco/view/employees/assign_employee_bottom_sheet.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/helpers/utils/permission_constants.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; -import 'package:marco/view/employees/employee_profile_screen.dart'; -import 'package:marco/view/employees/manage_reporting_bottom_sheet.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/model/employees/add_employee_bottom_sheet.dart'; +import 'package:on_field_work/controller/employee/employees_screen_controller.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/helpers/utils/launcher_utils.dart'; +import 'package:on_field_work/view/employees/assign_employee_bottom_sheet.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/view/employees/employee_profile_screen.dart'; +import 'package:on_field_work/view/employees/manage_reporting_bottom_sheet.dart'; class EmployeesScreen extends StatefulWidget { const EmployeesScreen({super.key}); diff --git a/lib/view/employees/manage_reporting_bottom_sheet.dart b/lib/view/employees/manage_reporting_bottom_sheet.dart index 9bdf9f7..83b495d 100644 --- a/lib/view/employees/manage_reporting_bottom_sheet.dart +++ b/lib/view/employees/manage_reporting_bottom_sheet.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/controller/employee/employees_screen_controller.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/controller/employee/employees_screen_controller.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; class ManageReportingBottomSheet extends StatefulWidget { final EmployeeModel? initialEmployee; diff --git a/lib/view/error_pages/coming_soon_screen.dart b/lib/view/error_pages/coming_soon_screen.dart index 5e8e455..8fc9ec5 100644 --- a/lib/view/error_pages/coming_soon_screen.dart +++ b/lib/view/error_pages/coming_soon_screen.dart @@ -1,9 +1,9 @@ -import 'package:marco/controller/error_pages/coming_soon_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/images.dart'; +import 'package:on_field_work/controller/error_pages/coming_soon_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/images.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; diff --git a/lib/view/error_pages/error_404_screen.dart b/lib/view/error_pages/error_404_screen.dart index fa7b3c6..9d24f1a 100644 --- a/lib/view/error_pages/error_404_screen.dart +++ b/lib/view/error_pages/error_404_screen.dart @@ -1,9 +1,9 @@ -import 'package:marco/controller/error_pages/error_404_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/images.dart'; +import 'package:on_field_work/controller/error_pages/error_404_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/images.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; diff --git a/lib/view/error_pages/error_500_screen.dart b/lib/view/error_pages/error_500_screen.dart index de7003f..fe42291 100644 --- a/lib/view/error_pages/error_500_screen.dart +++ b/lib/view/error_pages/error_500_screen.dart @@ -1,9 +1,9 @@ -import 'package:marco/controller/error_pages/error_500_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/images.dart'; +import 'package:on_field_work/controller/error_pages/error_500_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/images.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; diff --git a/lib/view/expense/expense_detail_screen.dart b/lib/view/expense/expense_detail_screen.dart index b9109c1..6d0c4be 100644 --- a/lib/view/expense/expense_detail_screen.dart +++ b/lib/view/expense/expense_detail_screen.dart @@ -1,27 +1,27 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/expense/expense_detail_controller.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/helpers/utils/date_time_utils.dart'; -import 'package:marco/helpers/widgets/image_viewer_dialog.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/model/expense/add_expense_bottom_sheet.dart'; -import 'package:marco/model/expense/comment_bottom_sheet.dart'; -import 'package:marco/model/expense/expense_detail_model.dart'; -import 'package:marco/model/expense/reimbursement_bottom_sheet.dart'; -import 'package:marco/controller/expense/add_expense_controller.dart'; -import 'package:marco/helpers/services/app_logger.dart'; +import 'package:on_field_work/controller/expense/expense_detail_controller.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/helpers/utils/date_time_utils.dart'; +import 'package:on_field_work/helpers/widgets/image_viewer_dialog.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/model/expense/add_expense_bottom_sheet.dart'; +import 'package:on_field_work/model/expense/comment_bottom_sheet.dart'; +import 'package:on_field_work/model/expense/expense_detail_model.dart'; +import 'package:on_field_work/model/expense/reimbursement_bottom_sheet.dart'; +import 'package:on_field_work/controller/expense/add_expense_controller.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; import 'package:url_launcher/url_launcher.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; -import 'package:marco/helpers/widgets/expense/expense_detail_helpers.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/model/employees/employee_info.dart'; +import 'package:on_field_work/helpers/widgets/expense/expense_detail_helpers.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/model/employees/employee_info.dart'; import 'package:timeline_tile/timeline_tile.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; class ExpenseDetailScreen extends StatefulWidget { final String expenseId; @@ -33,21 +33,27 @@ class ExpenseDetailScreen extends StatefulWidget { class _ExpenseDetailScreenState extends State with UIMixin { - final controller = Get.put(ExpenseDetailController()); + late final ExpenseDetailController controller; final projectController = Get.find(); final permissionController = Get.put(PermissionController()); EmployeeInfo? employeeInfo; final RxBool canSubmit = false.obs; bool _checkedPermission = false; - @override void initState() { super.initState(); + controller = Get.put(ExpenseDetailController(), tag: widget.expenseId); controller.init(widget.expenseId); _loadEmployeeInfo(); } + @override + void dispose() { + Get.delete(tag: widget.expenseId); + super.dispose(); + } + void _loadEmployeeInfo() async { final info = await LocalStorage.getEmployeeInfo(); employeeInfo = info; @@ -97,49 +103,93 @@ class _ExpenseDetailScreenState extends State final formattedAmount = formatExpenseAmount(expense.amount); return MyRefreshIndicator( - onRefresh: () async { - await controller.fetchExpenseDetails(); - }, - child: SingleChildScrollView( - padding: EdgeInsets.fromLTRB( - 8, 8, 8, 30 + MediaQuery.of(context).padding.bottom), - child: Center( - child: Container( - constraints: const BoxConstraints(maxWidth: 520), - child: Card( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5)), - elevation: 3, - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 14, horizontal: 14), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _InvoiceHeader(expense: expense), - const Divider(height: 30, thickness: 1.2), - InvoiceLogs(logs: expense.expenseLogs), - const Divider(height: 30, thickness: 1.2), - _InvoiceParties(expense: expense), - const Divider(height: 30, thickness: 1.2), - _InvoiceDetailsTable(expense: expense), - const Divider(height: 30, thickness: 1.2), - _InvoiceDocuments(documents: expense.documents), - const Divider(height: 30, thickness: 1.2), - _InvoiceTotals( - expense: expense, - formattedAmount: formattedAmount, - statusColor: statusColor, - ), - const Divider(height: 30, thickness: 1.2), - ], + onRefresh: () async { + await controller.fetchExpenseDetails(); + }, + child: SingleChildScrollView( + padding: EdgeInsets.fromLTRB( + 12, 12, 12, 30 + MediaQuery.of(context).padding.bottom), + child: Center( + child: Container( + constraints: const BoxConstraints(maxWidth: 520), + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5)), + elevation: 3, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 14, horizontal: 14), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // ---------------- Header & Status ---------------- + _InvoiceHeader(expense: expense), + const Divider(height: 30, thickness: 1.2), + + // ---------------- Activity Logs ---------------- + InvoiceLogs(logs: expense.expenseLogs), + const Divider(height: 30, thickness: 1.2), + // ---------------- Amount & Summary ---------------- + Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + MyText.bodyMedium('Amount', + fontWeight: 600), + const SizedBox(height: 4), + MyText.bodyLarge( + formattedAmount, + fontWeight: 700, + color: statusColor, + ), + ], + ), + const Spacer(), + // Optional: Pre-approved badge + if (expense.preApproved) + Container( + padding: const EdgeInsets.symmetric( + horizontal: 10, vertical: 4), + decoration: BoxDecoration( + color: Colors.green.withOpacity(0.15), + borderRadius: BorderRadius.circular(5), + ), + child: MyText.bodySmall( + 'Pre-Approved', + fontWeight: 600, + color: Colors.green, + ), + ), + ], + ), + const Divider(height: 30, thickness: 1.2), + + // ---------------- Parties ---------------- + _InvoicePartiesTable(expense: expense), + const Divider(height: 30, thickness: 1.2), + + // ---------------- Expense Details ---------------- + _InvoiceDetailsTable(expense: expense), + const Divider(height: 30, thickness: 1.2), + + // ---------------- Documents ---------------- + _InvoiceDocuments(documents: expense.documents), + const Divider(height: 30, thickness: 1.2), + + // ---------------- Totals ---------------- + _InvoiceTotals( + expense: expense, + formattedAmount: formattedAmount, + statusColor: statusColor, + ), + ], + ), ), ), ), ), - ), - ), - ); + )); }), ), floatingActionButton: Obx(() { @@ -498,24 +548,43 @@ class _InvoiceHeader extends StatelessWidget { } } -class _InvoiceParties extends StatelessWidget { +class _InvoicePartiesTable extends StatelessWidget { final ExpenseDetailModel expense; - const _InvoiceParties({required this.expense}); + const _InvoicePartiesTable({required this.expense}); + @override Widget build(BuildContext context) { + // List of label-value pairs + final parties = [ + {'label': 'Project', 'value': expense.project.name}, + { + 'label': 'Paid By', + 'value': '${expense.paidBy.firstName} ${expense.paidBy.lastName}' + }, + {'label': 'Supplier', 'value': expense.supplerName}, + { + 'label': 'Created By', + 'value': '${expense.createdBy.firstName} ${expense.createdBy.lastName}' + }, + ]; + return Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ - labelValueBlock('Project', expense.project.name), - MySpacing.height(16), - labelValueBlock('Paid By:', - '${expense.paidBy.firstName} ${expense.paidBy.lastName}'), - MySpacing.height(16), - labelValueBlock('Supplier', expense.supplerName), - MySpacing.height(16), - labelValueBlock('Created By:', - '${expense.createdBy.firstName} ${expense.createdBy.lastName}'), - ], + children: parties.map((item) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 6), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + MyText.bodySmall('${item['label']}:', fontWeight: 600), + const SizedBox(width: 6), + Expanded( + child: MyText.bodySmall(item['value']!, fontWeight: 500), + ), + ], + ), + ); + }).toList(), ); } } @@ -523,6 +592,7 @@ class _InvoiceParties extends StatelessWidget { class _InvoiceDetailsTable extends StatelessWidget { final ExpenseDetailModel expense; const _InvoiceDetailsTable({required this.expense}); + @override Widget build(BuildContext context) { final transactionDate = DateTimeUtils.convertUtcToLocal( @@ -531,36 +601,45 @@ class _InvoiceDetailsTable extends StatelessWidget { final createdAt = DateTimeUtils.convertUtcToLocal( expense.createdAt.toString(), format: 'dd MMM yyyy'); + + // List of all label-value pairs + final details = [ + {'label': 'Expense Category', 'value': expense.expensesType.name}, + {'label': 'Payment Mode', 'value': expense.paymentMode.name}, + {'label': 'Transaction Date', 'value': transactionDate}, + {'label': 'Created At', 'value': createdAt}, + {'label': 'Pre-Approved', 'value': expense.preApproved ? 'Yes' : 'No'}, + { + 'label': 'Description', + 'value': + expense.description.trim().isNotEmpty ? expense.description : '-' + }, + ]; + return Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _detailItem("Expense Type:", expense.expensesType.name), - _detailItem("Payment Mode:", expense.paymentMode.name), - _detailItem("Transaction Date:", transactionDate), - _detailItem("Created At:", createdAt), - _detailItem("Pre-Approved:", expense.preApproved ? 'Yes' : 'No'), - _detailItem("Description:", - expense.description.trim().isNotEmpty ? expense.description : '-', - isDescription: true), - ], + children: details.map((item) { + final isDescription = item['label'] == 'Description'; + return Padding( + padding: const EdgeInsets.symmetric(vertical: 6), + child: Row( + crossAxisAlignment: isDescription + ? CrossAxisAlignment.start + : CrossAxisAlignment.center, + children: [ + MyText.bodySmall('${item['label']}:', fontWeight: 600), + const SizedBox(width: 6), + Expanded( + child: isDescription + ? ExpandableDescription(description: item['value']!) + : MyText.bodySmall(item['value']!, fontWeight: 500), + ), + ], + ), + ); + }).toList(), ); } - - Widget _detailItem(String title, String value, - {bool isDescription = false}) => - Padding( - padding: const EdgeInsets.symmetric(vertical: 10), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - MyText.bodySmall(title, fontWeight: 600), - MySpacing.height(3), - isDescription - ? ExpandableDescription(description: value) - : MyText.bodySmall(value, fontWeight: 500), - ], - ), - ); } class _InvoiceDocuments extends StatelessWidget { diff --git a/lib/view/expense/expense_filter_bottom_sheet.dart b/lib/view/expense/expense_filter_bottom_sheet.dart index 0c6d565..f2da450 100644 --- a/lib/view/expense/expense_filter_bottom_sheet.dart +++ b/lib/view/expense/expense_filter_bottom_sheet.dart @@ -2,15 +2,15 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/expense/expense_screen_controller.dart'; -import 'package:marco/helpers/utils/base_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/model/expense/employee_selector_for_filter_bottom_sheet.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/date_range_picker.dart'; +import 'package:on_field_work/controller/expense/expense_screen_controller.dart'; +import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/model/expense/employee_selector_for_filter_bottom_sheet.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/date_range_picker.dart'; class ExpenseFilterBottomSheet extends StatefulWidget { final ExpenseController expenseController; diff --git a/lib/view/expense/expense_screen.dart b/lib/view/expense/expense_screen.dart index 453ae00..d0f2c9f 100644 --- a/lib/view/expense/expense_screen.dart +++ b/lib/view/expense/expense_screen.dart @@ -1,17 +1,17 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/controller/expense/expense_screen_controller.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; -import 'package:marco/model/expense/expense_list_model.dart'; -import 'package:marco/model/expense/add_expense_bottom_sheet.dart'; -import 'package:marco/view/expense/expense_filter_bottom_sheet.dart'; -import 'package:marco/helpers/widgets/expense/expense_main_components.dart'; -import 'package:marco/helpers/utils/permission_constants.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/controller/expense/expense_screen_controller.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/model/expense/expense_list_model.dart'; +import 'package:on_field_work/model/expense/add_expense_bottom_sheet.dart'; +import 'package:on_field_work/view/expense/expense_filter_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/expense/expense_main_components.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; class ExpenseMainScreen extends StatefulWidget { const ExpenseMainScreen({super.key}); diff --git a/lib/view/finance/advance_payment_screen.dart b/lib/view/finance/advance_payment_screen.dart index 2c1fe40..afa41bb 100644 --- a/lib/view/finance/advance_payment_screen.dart +++ b/lib/view/finance/advance_payment_screen.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/finance/advance_payment_controller.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/controller/finance/advance_payment_controller.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; diff --git a/lib/view/finance/finance_screen.dart b/lib/view/finance/finance_screen.dart index eaa1508..32cba67 100644 --- a/lib/view/finance/finance_screen.dart +++ b/lib/view/finance/finance_screen.dart @@ -1,18 +1,18 @@ import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/controller/dynamicMenu/dynamic_menu_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_card.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/dashbaord/expense_breakdown_chart.dart'; -import 'package:marco/helpers/widgets/dashbaord/expense_by_status_widget.dart'; -import 'package:marco/helpers/widgets/dashbaord/monthly_expense_dashboard_chart.dart'; -import 'package:marco/controller/dashboard/dashboard_controller.dart'; -import 'package:marco/helpers/utils/permission_constants.dart'; -import 'package:marco/model/dynamicMenu/dynamic_menu_model.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/controller/dynamicMenu/dynamic_menu_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_card.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/dashbaord/expense_breakdown_chart.dart'; +import 'package:on_field_work/helpers/widgets/dashbaord/expense_by_status_widget.dart'; +import 'package:on_field_work/helpers/widgets/dashbaord/monthly_expense_dashboard_chart.dart'; +import 'package:on_field_work/controller/dashboard/dashboard_controller.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/model/dynamicMenu/dynamic_menu_model.dart'; class FinanceScreen extends StatefulWidget { const FinanceScreen({super.key}); diff --git a/lib/view/finance/payment_request_detail_screen.dart b/lib/view/finance/payment_request_detail_screen.dart index 3d1e647..a00aefd 100644 --- a/lib/view/finance/payment_request_detail_screen.dart +++ b/lib/view/finance/payment_request_detail_screen.dart @@ -1,26 +1,26 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/finance/payment_request_detail_controller.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/helpers/utils/date_time_utils.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; +import 'package:on_field_work/controller/finance/payment_request_detail_controller.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/helpers/utils/date_time_utils.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; import 'package:timeline_tile/timeline_tile.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/model/finance/payment_request_details_model.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/model/finance/payment_request_details_model.dart'; import 'package:url_launcher/url_launcher.dart'; -import 'package:marco/helpers/widgets/image_viewer_dialog.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/helpers/widgets/image_viewer_dialog.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; import 'package:timeago/timeago.dart' as timeago; -import 'package:marco/model/expense/comment_bottom_sheet.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/model/employees/employee_info.dart'; -import 'package:marco/helpers/widgets/my_snackbar.dart'; -import 'package:marco/model/finance/payment_request_rembursement_bottom_sheet.dart'; -import 'package:marco/model/finance/make_expense_bottom_sheet.dart'; -import 'package:marco/model/finance/add_payment_request_bottom_sheet.dart'; +import 'package:on_field_work/model/expense/comment_bottom_sheet.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/model/employees/employee_info.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/model/finance/payment_request_rembursement_bottom_sheet.dart'; +import 'package:on_field_work/model/finance/make_expense_bottom_sheet.dart'; +import 'package:on_field_work/model/finance/add_payment_request_bottom_sheet.dart'; class PaymentRequestDetailScreen extends StatefulWidget { final String paymentRequestId; @@ -119,8 +119,9 @@ class _PaymentRequestDetailScreenState extends State final request = controller.paymentRequest.value; - if ((controller.errorMessage.value ).isNotEmpty) { - return Center(child: MyText.bodyMedium(controller.errorMessage.value)); + if ((controller.errorMessage.value).isNotEmpty) { + return Center( + child: MyText.bodyMedium(controller.errorMessage.value)); } if (request == null) { @@ -152,7 +153,8 @@ class _PaymentRequestDetailScreenState extends State request: request, colorParser: _parseColor, employeeInfo: employeeInfo, - onEdit: () => _openEditPaymentRequestBottomSheet(request), + onEdit: () => + _openEditPaymentRequestBottomSheet(request), ), const Divider(height: 30, thickness: 1.2), _Logs( @@ -272,8 +274,7 @@ class _PaymentRequestDetailScreenState extends State message: success ? 'Status updated successfully' : 'Failed to update status', - type: - success ? SnackbarType.success : SnackbarType.error, + type: success ? SnackbarType.success : SnackbarType.error, ); if (success) await controller.fetchPaymentRequestDetail(); @@ -323,8 +324,8 @@ class _PaymentRequestDetailScreenState extends State ), MySpacing.height(2), GetBuilder(builder: (_) { - final name = - projectController.selectedProject?.name ?? 'Select Project'; + final name = projectController.selectedProject?.name ?? + 'Select Project'; return Row( children: [ const Icon(Icons.work_outline, @@ -410,10 +411,35 @@ class _HeaderState extends State<_Header> with UIMixin { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - MyText.bodyMedium( - 'ID: ${widget.request.paymentRequestUID ?? '-'}', - fontWeight: 700, - fontSize: 14, + Row( + children: [ + MyText.bodyMedium( + 'ID: ${widget.request.paymentRequestUID ?? '-'}', + fontWeight: 700, + fontSize: 14, + ), + + // 🔥 ADVANCE CHIP — show only if true + if (widget.request.isAdvancePayment == true) ...[ + const SizedBox(width: 8), + Container( + padding: + const EdgeInsets.symmetric(horizontal: 6, vertical: 2), + decoration: BoxDecoration( + color: Colors.orange.shade700, + borderRadius: BorderRadius.circular(4), + ), + child: const Text( + 'ADVANCE', + style: TextStyle( + color: Colors.white, + fontSize: 10, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ], ), if (canEdit) IconButton( @@ -513,17 +539,17 @@ class _Logs extends StatelessWidget { final last = updatedBy?.lastName ?? ''; final initials = '${first.isNotEmpty ? first[0] : ''}${last.isNotEmpty ? last[0] : ''}'; - final name = ((first + ' ' + last).trim().isNotEmpty) - ? '$first $last' - : '-'; + final name = + ((first + ' ' + last).trim().isNotEmpty) ? '$first $last' : '-'; final updatedAt = log.updatedAt; final timeAgo = (updatedAt != null) - ? timeago.format(updatedAt.toUtc().add(const Duration(hours: 5, minutes: 30))) + ? timeago.format(updatedAt + .toUtc() + .add(const Duration(hours: 5, minutes: 30))) : '-'; - final nextStatusColor = - colorParser(log.nextStatus?.color ?? ''); + final nextStatusColor = colorParser(log.nextStatus?.color ?? ''); return TimelineTile( alignment: TimelineAlign.start, @@ -667,14 +693,18 @@ class _DetailsTable extends StatelessWidget { _labelValueRow("Transaction ID:", request.paidTransactionId ?? ''), _labelValueRow("Payee:", request.payee ?? '-'), _labelValueRow("Project:", request.project?.name ?? '-'), - _labelValueRow("Expense Category:", request.expenseCategory?.name ?? '-'), + _labelValueRow( + "Expense Category:", request.expenseCategory?.name ?? '-'), // Amounts - _labelValueRow("Amount:", _formatCurrencyAmount(currencySymbol, request.amount)), + _labelValueRow( + "Amount:", _formatCurrencyAmount(currencySymbol, request.amount)), if (request.baseAmount != null) - _labelValueRow("Base Amount:", _formatCurrencyAmount(currencySymbol, request.baseAmount)), + _labelValueRow("Base Amount:", + _formatCurrencyAmount(currencySymbol, request.baseAmount)), if (request.taxAmount != null) - _labelValueRow("Tax Amount:", _formatCurrencyAmount(currencySymbol, request.taxAmount)), + _labelValueRow("Tax Amount:", + _formatCurrencyAmount(currencySymbol, request.taxAmount)), if (request.expenseCategory?.noOfPersonsRequired == true) _labelValueRow("Additional Persons Required:", "Yes"), if (request.expenseCategory?.isAttachmentRequried == true) @@ -706,27 +736,36 @@ class _DetailsTable extends StatelessWidget { format: 'dd MMM yyyy'), ), if (request.paidBy != null) - _labelValueRow("Paid By:", "${request.paidBy?.firstName ?? ''} ${request.paidBy?.lastName ?? ''}".trim()), + _labelValueRow( + "Paid By:", + "${request.paidBy?.firstName ?? ''} ${request.paidBy?.lastName ?? ''}" + .trim()), // Flags - _labelValueRow( - "Advance Payment:", (request.isAdvancePayment ?? false) ? "Yes" : "No"), - _labelValueRow( - "Expense Created:", (request.isExpenseCreated ?? false) ? "Yes" : "No"), + _labelValueRow("Advance Payment:", + (request.isAdvancePayment ?? false) ? "Yes" : "No"), + _labelValueRow("Expense Created:", + (request.isExpenseCreated ?? false) ? "Yes" : "No"), _labelValueRow("Active:", (request.isActive ?? false) ? "Yes" : "No"), // Recurring Payment Info if (request.recurringPayment != null) ...[ const SizedBox(height: 6), MyText.bodySmall("Recurring Payment Info:", fontWeight: 600), - _labelValueRow("Recurring ID:", request.recurringPayment?.recurringPaymentUID ?? '-'), - _labelValueRow("Amount:", _formatCurrencyAmount(currencySymbol, request.recurringPayment?.amount)), - _labelValueRow("Variable Amount:", (request.recurringPayment?.isVariable ?? false) ? "Yes" : "No"), + _labelValueRow("Recurring ID:", + request.recurringPayment?.recurringPaymentUID ?? '-'), + _labelValueRow( + "Amount:", + _formatCurrencyAmount( + currencySymbol, request.recurringPayment?.amount)), + _labelValueRow("Variable Amount:", + (request.recurringPayment?.isVariable ?? false) ? "Yes" : "No"), ], // Description & Attachments _labelValueRow("Description:", request.description ?? '-'), - _labelValueRow("Attachment:", (request.attachments ?? []).isNotEmpty ? "Yes" : "No"), + _labelValueRow("Attachment:", + (request.attachments ?? []).isNotEmpty ? "Yes" : "No"), ], ); } diff --git a/lib/view/finance/payment_request_screen.dart b/lib/view/finance/payment_request_screen.dart index 417bfd4..e259b97 100644 --- a/lib/view/finance/payment_request_screen.dart +++ b/lib/view/finance/payment_request_screen.dart @@ -1,17 +1,18 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/controller/finance/payment_request_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/model/finance/payment_request_filter_bottom_sheet.dart'; -import 'package:marco/model/finance/add_payment_request_bottom_sheet.dart'; -import 'package:marco/helpers/utils/date_time_utils.dart'; -import 'package:marco/view/finance/payment_request_detail_screen.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/controller/finance/payment_request_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/model/finance/payment_request_filter_bottom_sheet.dart'; +import 'package:on_field_work/model/finance/add_payment_request_bottom_sheet.dart'; +import 'package:on_field_work/helpers/utils/date_time_utils.dart'; +import 'package:on_field_work/view/finance/payment_request_detail_screen.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; class PaymentRequestMainScreen extends StatefulWidget { const PaymentRequestMainScreen({super.key}); @@ -68,19 +69,29 @@ class _PaymentRequestMainScreenState extends State final now = DateTime.now(); final filtered = paymentController.paymentRequests.where((e) { - return query.isEmpty || - e.title.toLowerCase().contains(query) || - e.payee.toLowerCase().contains(query); + final title = e.title?.toLowerCase() ?? ""; + final payee = e.payee?.toLowerCase() ?? ""; + + return query.isEmpty || title.contains(query) || payee.contains(query); }).toList() - ..sort((a, b) => b.dueDate.compareTo(a.dueDate)); + ..sort((a, b) { + final aDate = a.dueDate ?? DateTime(1900); + final bDate = b.dueDate ?? DateTime(1900); + return bDate.compareTo(aDate); + }); + + DateTime startOfMonth = DateTime(now.year, now.month, 1); + DateTime previousMonthEnd = DateTime(now.year, now.month, 0); return isHistory - ? filtered - .where((e) => e.dueDate.isBefore(DateTime(now.year, now.month, 1))) - .toList() - : filtered - .where((e) => e.dueDate.isAfter(DateTime(now.year, now.month, 0))) - .toList(); + ? filtered.where((e) { + final d = e.dueDate; + return d != null && d.isBefore(startOfMonth); + }).toList() + : filtered.where((e) { + final d = e.dueDate; + return d != null && d.isAfter(previousMonthEnd); + }).toList(); } @override @@ -283,10 +294,8 @@ class _PaymentRequestMainScreenState extends State final list = filteredList(isHistory: isHistory); - // Single ScrollController for this list + // ScrollController for infinite scroll final scrollController = ScrollController(); - - // Load more when reaching near bottom scrollController.addListener(() { if (scrollController.position.pixels >= scrollController.position.maxScrollExtent - 100 && @@ -295,7 +304,7 @@ class _PaymentRequestMainScreenState extends State } }); - return RefreshIndicator( + return MyRefreshIndicator( onRefresh: _refreshPaymentRequests, child: list.isEmpty ? ListView( @@ -315,14 +324,13 @@ class _PaymentRequestMainScreenState extends State ], ) : ListView.separated( - controller: scrollController, // attach controller + controller: scrollController, padding: const EdgeInsets.fromLTRB(12, 12, 12, 80), - itemCount: list.length + 1, // extra item for loading + itemCount: list.length + 1, separatorBuilder: (_, __) => Divider(color: Colors.grey.shade300, height: 20), itemBuilder: (context, index) { if (index == list.length) { - // Show loading indicator at bottom return Obx(() => paymentController.isLoading.value ? const Padding( padding: EdgeInsets.symmetric(vertical: 16), @@ -330,7 +338,6 @@ class _PaymentRequestMainScreenState extends State ) : const SizedBox.shrink()); } - final item = list[index]; return _buildPaymentRequestTile(item); }, @@ -348,7 +355,6 @@ class _PaymentRequestMainScreenState extends State child: InkWell( borderRadius: BorderRadius.circular(8), onTap: () { - // Navigate to detail screen, passing the payment request ID Get.to(() => PaymentRequestDetailScreen(paymentRequestId: item.id)); }, child: Padding( @@ -359,6 +365,30 @@ class _PaymentRequestMainScreenState extends State Row( children: [ MyText.bodyMedium(item.expenseCategory.name, fontWeight: 600), + + // ------------------------------- + // ADV CHIP (only if advance) + // ------------------------------- + if (item.isAdvancePayment == true) ...[ + const SizedBox(width: 8), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 6, vertical: 2), + decoration: BoxDecoration( + color: Colors.orange.withOpacity(0.2), + borderRadius: BorderRadius.circular(4), + border: Border.all(color: Colors.orange), + ), + child: const Text( + "ADV", + style: TextStyle( + fontSize: 10, + color: Colors.orange, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ], ), const SizedBox(height: 6), diff --git a/lib/view/layouts/auth_layout.dart b/lib/view/layouts/auth_layout.dart index e21455a..332fd1a 100644 --- a/lib/view/layouts/auth_layout.dart +++ b/lib/view/layouts/auth_layout.dart @@ -1,12 +1,12 @@ -import 'package:marco/controller/layout/auth_layout_controller.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; -import 'package:marco/helpers/widgets/my_flex.dart'; -import 'package:marco/helpers/widgets/my_flex_item.dart'; -import 'package:marco/helpers/widgets/my_responsive.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/controller/layout/auth_layout_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_flex.dart'; +import 'package:on_field_work/helpers/widgets/my_flex_item.dart'; +import 'package:on_field_work/helpers/widgets/my_responsive.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/images.dart'; +import 'package:on_field_work/images.dart'; class AuthLayout extends StatelessWidget { final Widget? child; diff --git a/lib/view/layouts/layout.dart b/lib/view/layouts/layout.dart index 10405c3..2aaf940 100644 --- a/lib/view/layouts/layout.dart +++ b/lib/view/layouts/layout.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/layout/layout_controller.dart'; -import 'package:marco/helpers/widgets/my_responsive.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/model/employees/employee_info.dart'; -import 'package:marco/helpers/services/api_endpoints.dart'; -import 'package:marco/images.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/view/layouts/user_profile_right_bar.dart'; +import 'package:on_field_work/controller/layout/layout_controller.dart'; +import 'package:on_field_work/helpers/widgets/my_responsive.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/model/employees/employee_info.dart'; +import 'package:on_field_work/helpers/services/api_endpoints.dart'; +import 'package:on_field_work/images.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/view/layouts/user_profile_right_bar.dart'; class Layout extends StatefulWidget { final Widget? child; diff --git a/lib/view/layouts/left_bar.dart b/lib/view/layouts/left_bar.dart index 8b332cf..fb55b26 100644 --- a/lib/view/layouts/left_bar.dart +++ b/lib/view/layouts/left_bar.dart @@ -1,19 +1,19 @@ -import 'package:marco/helpers/theme/theme_customizer.dart'; -import 'package:marco/helpers/services/url_service.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/utils/my_shadow.dart'; -import 'package:marco/helpers/widgets/my_card.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/images.dart'; -import 'package:marco/widgets/custom_pop_menu.dart'; +import 'package:on_field_work/helpers/theme/theme_customizer.dart'; +import 'package:on_field_work/helpers/services/url_service.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/utils/my_shadow.dart'; +import 'package:on_field_work/helpers/widgets/my_card.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/images.dart'; +import 'package:on_field_work/widgets/custom_pop_menu.dart'; import 'package:flutter/material.dart'; import 'package:get/route_manager.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/model/employees/employee_info.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/model/employees/employee_info.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; typedef LeftbarMenuFunction = void Function(String key); diff --git a/lib/view/layouts/offline_screen.dart b/lib/view/layouts/offline_screen.dart index 15fc1d8..76cf4eb 100644 --- a/lib/view/layouts/offline_screen.dart +++ b/lib/view/layouts/offline_screen.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/images.dart'; -import 'package:marco/helpers/widgets/wave_background.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/images.dart'; +import 'package:on_field_work/helpers/widgets/wave_background.dart'; class OfflineScreen extends StatefulWidget { diff --git a/lib/view/layouts/right_bar.dart b/lib/view/layouts/right_bar.dart index b1d0160..67778ee 100644 --- a/lib/view/layouts/right_bar.dart +++ b/lib/view/layouts/right_bar.dart @@ -1,8 +1,8 @@ -import 'package:marco/helpers/theme/theme_customizer.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/widgets/custom_switch.dart'; +import 'package:on_field_work/helpers/theme/theme_customizer.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/widgets/custom_switch.dart'; import 'package:flutter/material.dart'; class RightBar extends StatefulWidget { diff --git a/lib/view/layouts/top_bar.dart b/lib/view/layouts/top_bar.dart index f79e7a3..a2fd536 100644 --- a/lib/view/layouts/top_bar.dart +++ b/lib/view/layouts/top_bar.dart @@ -1,20 +1,20 @@ -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/theme/theme_customizer.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/utils/my_shadow.dart'; -import 'package:marco/helpers/widgets/my_button.dart'; -import 'package:marco/helpers/widgets/my_card.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; -import 'package:marco/helpers/widgets/my_dashed_divider.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_text_style.dart'; -import 'package:marco/widgets/custom_pop_menu.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/theme/theme_customizer.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/utils/my_shadow.dart'; +import 'package:on_field_work/helpers/widgets/my_button.dart'; +import 'package:on_field_work/helpers/widgets/my_card.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_dashed_divider.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_text_style.dart'; +import 'package:on_field_work/widgets/custom_pop_menu.dart'; import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/model/employees/employee_info.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/model/employees/employee_info.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; class TopBar extends StatefulWidget { const TopBar({super.key}); diff --git a/lib/view/layouts/user_profile_right_bar.dart b/lib/view/layouts/user_profile_right_bar.dart index 2ef33ba..ddca327 100644 --- a/lib/view/layouts/user_profile_right_bar.dart +++ b/lib/view/layouts/user_profile_right_bar.dart @@ -2,19 +2,19 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/model/employees/employee_info.dart'; -import 'package:marco/controller/auth/mpin_controller.dart'; -import 'package:marco/view/employees/employee_profile_screen.dart'; -import 'package:marco/helpers/services/tenant_service.dart'; -import 'package:marco/view/tenant/tenant_selection_screen.dart'; -import 'package:marco/controller/tenant/tenant_switch_controller.dart'; -import 'package:marco/helpers/theme/theme_editor_widget.dart'; - +import 'package:package_info_plus/package_info_plus.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/model/employees/employee_info.dart'; +import 'package:on_field_work/controller/auth/mpin_controller.dart'; +import 'package:on_field_work/view/employees/employee_profile_screen.dart'; +import 'package:on_field_work/helpers/services/tenant_service.dart'; +import 'package:on_field_work/view/tenant/tenant_selection_screen.dart'; +import 'package:on_field_work/controller/tenant/tenant_switch_controller.dart'; +import 'package:on_field_work/helpers/theme/theme_editor_widget.dart'; class UserProfileBar extends StatefulWidget { final bool isCondensed; @@ -30,6 +30,7 @@ class _UserProfileBarState extends State bool _isLoading = true; bool hasMpin = true; bool _isThemeEditorVisible = false; + String _appVersion = ''; @override void initState() { @@ -40,6 +41,11 @@ class _UserProfileBarState extends State Future _initData() async { employeeInfo = LocalStorage.getEmployeeInfo()!; hasMpin = await LocalStorage.getIsMpin(); + + // Fetch app version + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + _appVersion = '${packageInfo.version}+${packageInfo.buildNumber}'; + setState(() => _isLoading = false); } @@ -79,55 +85,155 @@ class _UserProfileBarState extends State ), ), child: SafeArea( - bottom: true, - child: Stack( - children: [ - Offstage( - offstage: _isThemeEditorVisible, - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - _isLoading - ? const _LoadingSection() - : _userProfileSection(isCondensed), - if (!_isLoading && !isCondensed) _switchTenantRow(), - MySpacing.height(12), - Divider( - indent: 18, - endIndent: 18, - thickness: 0.7, - color: Colors.grey.withOpacity(0.25), - ), - MySpacing.height(12), - _supportAndSettingsMenu(isCondensed), - const Spacer(), - Divider( - indent: 18, - endIndent: 18, - thickness: 0.35, - color: Colors.grey.withOpacity(0.18), - ), - _logoutButton(isCondensed), - ], - ), + bottom: true, + child: Stack( + children: [ + Offstage( + offstage: _isThemeEditorVisible, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _isLoading + ? const _LoadingSection() + : _userProfileSection(isCondensed), + if (!_isLoading && !isCondensed) _switchTenantRow(), + MySpacing.height(12), + Divider( + indent: 18, + endIndent: 18, + thickness: 0.7, + color: Colors.grey.withOpacity(0.25), + ), + MySpacing.height(12), + _supportAndSettingsMenu(isCondensed), + MySpacing.height(12), + + // Subtle version text for expanded mode + if (!isCondensed && _appVersion.isNotEmpty) + _versionText(), + + const Spacer(), + Divider( + indent: 18, + endIndent: 18, + thickness: 0.35, + color: Colors.grey.withOpacity(0.18), + ), + _logoutButton(isCondensed), + ], ), - Offstage( - offstage: !_isThemeEditorVisible, - child: ThemeEditorWidget( - onClose: () { - setState(() => _isThemeEditorVisible = false); - }, - ), + ), + Offstage( + offstage: !_isThemeEditorVisible, + child: ThemeEditorWidget( + onClose: () { + setState(() => _isThemeEditorVisible = false); + }, ), - ], - )), + ), + + // Floating badge for condensed mode + if (isCondensed && _appVersion.isNotEmpty) _versionBadge(), + ], + ), + ), ), ), ), ); } - // ==================== CONTINUE EXISTING CODE ===================== + // =================== Version Widgets =================== + + Widget _versionText() { + return Padding( + padding: const EdgeInsets.only(top: 4, bottom: 12), + child: Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(16), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 6), + decoration: BoxDecoration( + color: Colors.grey.shade100.withOpacity(0.85), + borderRadius: BorderRadius.circular(16), + border: Border.all( + color: Colors.grey.shade200, + width: 0.7, + ), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.12), + blurRadius: 3, + offset: const Offset(0, 1), + ), + ], + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(Icons.info_outline, size: 14, color: Colors.grey[700]), + const SizedBox(width: 4), + Text( + 'Version: $_appVersion', + style: TextStyle( + fontSize: 12, + color: Colors.grey[800], + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ), + ), + ), + ); + } + + Widget _versionBadge() { + return Positioned( + bottom: 10, + right: 14, + child: ClipRRect( + borderRadius: BorderRadius.circular(16), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 5), + decoration: BoxDecoration( + color: Colors.grey.shade100.withOpacity(0.85), + borderRadius: BorderRadius.circular(16), + border: Border.all( + color: Colors.grey.shade300, + width: 1, + ), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.17), + blurRadius: 6, + offset: const Offset(0, 2), + ), + ], + ), + child: Text( + _appVersion, + style: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Colors.black87, + letterSpacing: 0.4, + ), + ), + ), + ), + ), + ); + } + + // =================== Existing methods =================== + Widget _switchTenantRow() { final TenantSwitchController tenantSwitchController = Get.put(TenantSwitchController()); @@ -443,24 +549,20 @@ class _UserProfileBarState extends State child: Column( mainAxisSize: MainAxisSize.min, children: [ - // Top icon Icon(LucideIcons.log_out, size: 56, color: primaryColor), MySpacing.height(18), - // Title MyText.titleLarge( "Logout Confirmation", fontWeight: 700, textAlign: TextAlign.center, ), MySpacing.height(14), - // Subtitle MyText.bodyMedium( "Are you sure you want to logout?\nYou will need to login again to continue.", color: Colors.grey[700], textAlign: TextAlign.center, ), MySpacing.height(30), - // Buttons Row( children: [ Expanded( diff --git a/lib/view/my_app.dart b/lib/view/my_app.dart index 5b4a66a..068843e 100644 --- a/lib/view/my_app.dart +++ b/lib/view/my_app.dart @@ -3,15 +3,15 @@ import 'package:get/get.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:provider/provider.dart'; -import 'package:marco/helpers/services/app_logger.dart'; -import 'package:marco/helpers/extensions/app_localization_delegate.dart'; -import 'package:marco/helpers/services/localizations/language.dart'; -import 'package:marco/helpers/services/navigation_services.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/theme/theme_customizer.dart'; -import 'package:marco/helpers/theme/app_notifier.dart'; -import 'package:marco/routes.dart'; +import 'package:on_field_work/helpers/services/app_logger.dart'; +import 'package:on_field_work/helpers/extensions/app_localization_delegate.dart'; +import 'package:on_field_work/helpers/services/localizations/language.dart'; +import 'package:on_field_work/helpers/services/navigation_services.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/theme/theme_customizer.dart'; +import 'package:on_field_work/helpers/theme/app_notifier.dart'; +import 'package:on_field_work/routes.dart'; class MyApp extends StatelessWidget { const MyApp({super.key}); diff --git a/lib/view/service_project/jobs_tab.dart b/lib/view/service_project/jobs_tab.dart new file mode 100644 index 0000000..096db50 --- /dev/null +++ b/lib/view/service_project/jobs_tab.dart @@ -0,0 +1,375 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:on_field_work/helpers/utils/date_time_utils.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/controller/service_project/service_project_details_screen_controller.dart'; +import 'package:on_field_work/view/service_project/service_project_job_detail_screen.dart'; +import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; + +class JobsTab extends StatefulWidget { + final ScrollController scrollController; + final String projectName; + + const JobsTab({super.key, required this.scrollController, required this.projectName}); + + @override + _JobsTabState createState() => _JobsTabState(); +} + +class _JobsTabState extends State { + final TextEditingController searchController = TextEditingController(); + late ServiceProjectDetailsController controller; + + @override + void initState() { + super.initState(); + controller = Get.find(); + + // Ensure only active jobs are displayed initially + controller.showArchivedJobs.value = false; + controller.fetchProjectJobs(refresh: true); + + searchController.addListener(() { + controller.updateJobSearch(searchController.text); + }); + } + + @override + void dispose() { + searchController.dispose(); + super.dispose(); + } + + Widget _buildSearchBar() { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8), + child: Row( + children: [ + Expanded( + child: SizedBox( + height: 35, + child: TextField( + controller: searchController, + decoration: InputDecoration( + contentPadding: const EdgeInsets.symmetric(horizontal: 12), + prefixIcon: + const Icon(Icons.search, size: 20, color: Colors.grey), + suffixIcon: ValueListenableBuilder( + valueListenable: searchController, + builder: (context, value, _) { + if (value.text.isEmpty) return const SizedBox.shrink(); + return IconButton( + icon: const Icon(Icons.clear, + size: 20, color: Colors.grey), + onPressed: () { + searchController.clear(); + controller.updateJobSearch(''); + }, + ); + }, + ), + hintText: 'Search jobs...', + filled: true, + fillColor: Colors.white, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: BorderSide(color: Colors.grey.shade300), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: BorderSide(color: Colors.grey.shade300), + ), + ), + ), + ), + ), + const SizedBox(width: 10), + Container( + height: 35, + padding: const EdgeInsets.symmetric(horizontal: 5), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.grey.shade300), + borderRadius: BorderRadius.circular(5), + ), + child: Obx(() { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Text( + "Archived", + style: TextStyle(fontSize: 14, color: Colors.black87), + ), + Switch( + value: controller.showArchivedJobs.value, + onChanged: (val) { + controller.showArchivedJobs.value = val; + controller.fetchProjectJobs(refresh: true); + }, + activeColor: Colors.blue, + inactiveThumbColor: Colors.grey, + ), + ], + ); + }), + ), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + _buildSearchBar(), + Expanded( + child: Obx(() { + if (controller.isJobLoading.value && + controller.filteredJobList.isEmpty) { + return const Center(child: CircularProgressIndicator()); + } + + if (controller.jobErrorMessage.value.isNotEmpty && + controller.filteredJobList.isEmpty) { + return Center( + child: MyText.bodyMedium(controller.jobErrorMessage.value)); + } + + if (controller.filteredJobList.isEmpty) { + return Center(child: MyText.bodyMedium("No jobs found")); + } + + return ListView.separated( + controller: widget.scrollController, + padding: const EdgeInsets.fromLTRB(12, 0, 12, 12), + itemCount: controller.filteredJobList.length + 1, + separatorBuilder: (_, __) => const SizedBox(height: 12), + itemBuilder: (context, index) { + if (index == controller.filteredJobList.length) { + return controller.hasMoreJobs.value + ? const Padding( + padding: EdgeInsets.symmetric(vertical: 16), + child: Center(child: CircularProgressIndicator()), + ) + : const SizedBox.shrink(); + } + + final job = controller.filteredJobList[index]; + + return Stack( + children: [ + AbsorbPointer( + absorbing: controller.showArchivedJobs + .value, + child: InkWell( + onTap: () { + if (!controller.showArchivedJobs.value) { + Get.to(() => JobDetailsScreen(jobId: job.id , projectName : widget.projectName)); + } + }, + child: Card( + elevation: 3, + shadowColor: Colors.black26, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + MyText.titleMedium(job.title, fontWeight: 700), + MySpacing.height(6), + MyText.bodySmall( + job.description.isNotEmpty + ? job.description + : "No description provided", + color: Colors.grey[700], + ), + if (job.tags != null && job.tags!.isNotEmpty) + Padding( + padding: const EdgeInsets.only(top: 2), + child: Wrap( + spacing: 2, + runSpacing: 4, + children: job.tags!.map((tag) { + return Chip( + label: Text( + tag.name, + style: + const TextStyle(fontSize: 12), + ), + backgroundColor: Colors.grey[200], + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(5), + ), + ); + }).toList(), + ), + ), + MySpacing.height(8), + Row( + children: [ + if (job.assignees != null && + job.assignees!.isNotEmpty) + ...job.assignees!.map((assignee) { + return Padding( + padding: + const EdgeInsets.only(right: 6), + child: Avatar( + firstName: assignee.firstName, + lastName: assignee.lastName, + size: 24, + imageUrl: assignee.photo.isNotEmpty + ? assignee.photo + : null, + ), + ); + }).toList(), + ], + ), + MySpacing.height(8), + Row( + children: [ + const Icon(Icons.calendar_today_outlined, + size: 14, color: Colors.grey), + MySpacing.width(4), + Text( + "${DateTimeUtils.convertUtcToLocal(job.startDate, format: 'dd MMM yyyy')} to " + "${DateTimeUtils.convertUtcToLocal(job.dueDate, format: 'dd MMM yyyy')}", + style: const TextStyle( + fontSize: 12, color: Colors.grey), + ), + const Spacer(), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: job.status.name.toLowerCase() == + 'completed' + ? Colors.green[100] + : Colors.orange[100], + borderRadius: BorderRadius.circular(5), + ), + child: Text( + job.status.displayName, + style: TextStyle( + fontSize: 12, + color: + job.status.name.toLowerCase() == + 'completed' + ? Colors.green[800] + : Colors.orange[800], + fontWeight: FontWeight.w600, + ), + ), + ), + ], + ), + ], + ), + ), + ), + ), + ), + Obx(() { + final isArchivedJob = controller.showArchivedJobs.value; + if (job.status.id != JobStatus.closed && + job.status.id != JobStatus.reviewDone) { + return const SizedBox.shrink(); + } + + return Positioned( + top: 10, + right: 10, + child: GestureDetector( + onTap: () async { + final confirmed = await showDialog( + context: context, + builder: (_) => ConfirmDialog( + title: isArchivedJob + ? "Restore Job?" + : "Archive Job?", + message: isArchivedJob + ? "Are you sure you want to restore this job?" + : "Are you sure you want to archive this job?", + confirmText: "Yes", + cancelText: "Cancel", + icon: isArchivedJob + ? Icons.restore + : Icons.archive_outlined, + confirmColor: Colors.green, + confirmIcon: Icons.check, + onConfirm: () async { + final operations = [ + { + "op": "replace", + "path": "/isArchive", + "value": isArchivedJob ? false : true + } + ]; + + final success = + await ApiService.editServiceProjectJobApi( + jobId: job.id , + operations: operations, + ); + + if (success) { + showAppSnackbar( + title: "Success", + message: isArchivedJob + ? "Job restored successfully" + : "Job archived successfully", + type: SnackbarType.success, + ); + controller.fetchProjectJobs(refresh: true); + } else { + showAppSnackbar( + title: "Error", + message: isArchivedJob + ? "Failed to restore job. Please try again." + : "Failed to archive job. Please try again.", + type: SnackbarType.error, + ); + } + }, + ), + ); + + if (confirmed != true) return; + }, + child: Container( + padding: const EdgeInsets.all(6), + decoration: BoxDecoration( + color: isArchivedJob ? Colors.blue : Colors.red, + shape: BoxShape.circle, + ), + child: Icon( + isArchivedJob + ? Icons.restore + : Icons.archive_outlined, + size: 20, + color: Colors.white, + ), + ), + ), + ); + }), + ], + ); + }, + ); + }), + ), + ], + ); + } +} diff --git a/lib/view/service_project/service_project_details_screen.dart b/lib/view/service_project/service_project_details_screen.dart index 01895bf..9a3d6d5 100644 --- a/lib/view/service_project/service_project_details_screen.dart +++ b/lib/view/service_project/service_project_details_screen.dart @@ -1,23 +1,25 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; -import 'package:marco/controller/service_project/service_project_details_screen_controller.dart'; -import 'package:marco/helpers/utils/launcher_utils.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/model/service_project/add_service_project_job_bottom_sheet.dart'; -import 'package:marco/helpers/utils/date_time_utils.dart'; -import 'package:marco/view/service_project/service_project_job_detail_screen.dart'; -import 'package:marco/helpers/widgets/custom_app_bar.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/model/service_project/service_project_allocation_bottomsheet.dart'; -import 'package:marco/model/employees/employee_model.dart'; +import 'package:on_field_work/controller/service_project/service_project_details_screen_controller.dart'; +import 'package:on_field_work/helpers/utils/launcher_utils.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/model/service_project/add_service_project_job_bottom_sheet.dart'; +import 'package:on_field_work/helpers/widgets/custom_app_bar.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/model/service_project/service_project_allocation_bottomsheet.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/view/service_project/jobs_tab.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; class ServiceProjectDetailsScreen extends StatefulWidget { final String projectId; + final String? projectName; - const ServiceProjectDetailsScreen({super.key, required this.projectId}); + const ServiceProjectDetailsScreen( + {super.key, required this.projectId, this.projectName}); @override State createState() => @@ -174,13 +176,20 @@ class _ServiceProjectDetailsScreenState Widget _buildProfileTab() { final project = controller.projectDetail.value; + if (project == null) { return Center(child: MyText.bodyMedium("No project data")); } - return Padding( - padding: MySpacing.all(12), + return MyRefreshIndicator( + onRefresh: () async { + await controller.fetchProjectDetail(); + }, + backgroundColor: Colors.indigo, + color: Colors.white, child: SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + padding: MySpacing.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ @@ -319,253 +328,112 @@ class _ServiceProjectDetailsScreenState ); } - Widget _buildJobsTab() { + Widget _buildTeamsTab() { return Obx(() { - if (controller.isJobLoading.value && controller.jobList.isEmpty) { + if (controller.isTeamLoading.value) { return const Center(child: CircularProgressIndicator()); } - if (controller.jobErrorMessage.value.isNotEmpty && - controller.jobList.isEmpty) { + if (controller.teamErrorMessage.value.isNotEmpty && + controller.teamList.isEmpty) { return Center( - child: MyText.bodyMedium(controller.jobErrorMessage.value)); + child: MyText.bodyMedium(controller.teamErrorMessage.value)); } - if (controller.jobList.isEmpty) { - return Center(child: MyText.bodyMedium("No jobs found")); + if (controller.teamList.isEmpty) { + return Center(child: MyText.bodyMedium("No team members found")); } - return ListView.separated( - controller: _jobScrollController, - padding: const EdgeInsets.fromLTRB(12, 12, 12, 80), - itemCount: controller.jobList.length + 1, - separatorBuilder: (_, __) => const SizedBox(height: 12), - itemBuilder: (context, index) { - if (index == controller.jobList.length) { - return controller.hasMoreJobs.value - ? const Padding( - padding: EdgeInsets.symmetric(vertical: 16), - child: Center(child: CircularProgressIndicator()), - ) - : const SizedBox.shrink(); - } + // Group team members by role + final Map roleGroups = {}; + for (var team in controller.teamList) { + roleGroups.putIfAbsent(team.teamRole.id, () => []).add(team); + } - final job = controller.jobList[index]; - return InkWell( - onTap: () { - Get.to(() => JobDetailsScreen(jobId: job.id)); - }, - child: Card( + return MyRefreshIndicator( + onRefresh: () async { + await controller.fetchProjectTeams(); + }, + backgroundColor: Colors.indigo, + color: Colors.white, + child: ListView.separated( + padding: const EdgeInsets.all(12), + itemCount: roleGroups.keys.length, + separatorBuilder: (_, __) => const SizedBox(height: 12), + itemBuilder: (context, index) { + final roleId = roleGroups.keys.elementAt(index); + final teamMembers = roleGroups[roleId]!; + final roleName = teamMembers.first.teamRole.name; + + return Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8)), elevation: 3, shadowColor: Colors.black26, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5)), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - MyText.titleMedium(job.title, fontWeight: 700), - MySpacing.height(6), - MyText.bodySmall( - job.description.isNotEmpty - ? job.description - : "No description provided", - color: Colors.grey[700], + // Role header + MyText.bodyLarge( + roleName, + fontWeight: 700, + color: Colors.black87, ), - - // Tags - if (job.tags != null && job.tags!.isNotEmpty) - Padding( - padding: const EdgeInsets.only(top: 2), - child: Wrap( - spacing: 2, - runSpacing: 4, - children: job.tags!.map((tag) { - return Chip( - label: Text( - tag.name, - style: const TextStyle(fontSize: 12), - ), - backgroundColor: Colors.grey[200], - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5), - ), - ); - }).toList(), - ), - ), - - MySpacing.height(8), - - // Assignees & Status - Row( - children: [ - if (job.assignees != null && job.assignees!.isNotEmpty) - ...job.assignees!.map((assignee) { - return Padding( - padding: const EdgeInsets.only(right: 6), - child: Avatar( - firstName: assignee.firstName, - lastName: assignee.lastName, - size: 24, - imageUrl: assignee.photo.isNotEmpty - ? assignee.photo - : null, - ), - ); - }).toList(), - ], - ), - - MySpacing.height(8), - - // Date Row with Status Chip - Row( - children: [ - // Dates (same as existing) - const Icon(Icons.calendar_today_outlined, - size: 14, color: Colors.grey), - MySpacing.width(4), - Text( - "${DateTimeUtils.convertUtcToLocal(job.startDate, format: 'dd MMM yyyy')} to " - "${DateTimeUtils.convertUtcToLocal(job.dueDate, format: 'dd MMM yyyy')}", - style: - const TextStyle(fontSize: 12, color: Colors.grey), - ), - - const Spacer(), - - // Status Chip - Container( - padding: const EdgeInsets.symmetric( - horizontal: 8, vertical: 4), - decoration: BoxDecoration( - color: job.status.name.toLowerCase() == 'completed' - ? Colors.green[100] - : Colors.orange[100], - borderRadius: BorderRadius.circular(5), - ), - child: Text( - job.status.displayName, - style: TextStyle( - fontSize: 12, - color: - job.status.name.toLowerCase() == 'completed' - ? Colors.green[800] - : Colors.orange[800], - fontWeight: FontWeight.w600, + const Divider(height: 20, thickness: 1), + // List of team members inside this role card + ...teamMembers.map((team) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + children: [ + Avatar( + firstName: team.employee.firstName, + lastName: team.employee.lastName, + size: 32, + imageUrl: + (team.employee.photo?.isNotEmpty ?? false) + ? team.employee.photo + : null, ), - ), + MySpacing.width(12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + MyText.titleMedium( + "${team.employee.firstName} ${team.employee.lastName}", + fontWeight: 600, + ), + MyText.bodySmall( + "Status: ${team.isActive ? 'Active' : 'Inactive'}", + color: Colors.grey[700], + ), + ], + ), + ), + ], ), - ], - ), + ); + }).toList(), ], ), ), - ), - ); - }, + ); + }, + ), ); }); } - Widget _buildTeamsTab() { - return Obx(() { - if (controller.isTeamLoading.value) { - return const Center(child: CircularProgressIndicator()); - } - - if (controller.teamErrorMessage.value.isNotEmpty && - controller.teamList.isEmpty) { - return Center(child: MyText.bodyMedium(controller.teamErrorMessage.value)); - } - - if (controller.teamList.isEmpty) { - return Center(child: MyText.bodyMedium("No team members found")); - } - - // Group team members by their role ID - final Map roleGroups = {}; - for (var team in controller.teamList) { - roleGroups.putIfAbsent(team.teamRole.id, () => []).add(team); - } - - return ListView.separated( - padding: const EdgeInsets.all(12), - itemCount: roleGroups.keys.length, - separatorBuilder: (_, __) => const SizedBox(height: 12), - itemBuilder: (context, index) { - final roleId = roleGroups.keys.elementAt(index); - final teamMembers = roleGroups[roleId]!; - final roleName = teamMembers.first.teamRole.name; - - return Card( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), - elevation: 3, - shadowColor: Colors.black26, - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Role header - MyText.bodyLarge( - roleName, - fontWeight: 700, - color: Colors.black87, - ), - const Divider(height: 20, thickness: 1), - // List of team members inside this role card - ...teamMembers.map((team) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Row( - children: [ - Avatar( - firstName: team.employee.firstName, - lastName: team.employee.lastName, - size: 32, - imageUrl: (team.employee.photo?.isNotEmpty ?? false) - ? team.employee.photo - : null, - ), - MySpacing.width(12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - MyText.titleMedium( - "${team.employee.firstName} ${team.employee.lastName}", - fontWeight: 600, - ), - MyText.bodySmall( - "Status: ${team.isActive ? 'Active' : 'Inactive'}", - color: Colors.grey[700], - ), - ], - ), - ), - ], - ), - ); - }).toList(), - ], - ), - ), - ); - }, - ); - }); -} - - @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF5F5F5), appBar: CustomAppBar( title: "Service Project Details", + projectName: widget.projectName, onBackPressed: () => Get.toNamed('/dashboard/service-projects'), ), body: SafeArea( @@ -606,7 +474,10 @@ class _ServiceProjectDetailsScreenState controller: _tabController, children: [ _buildProfileTab(), - _buildJobsTab(), + JobsTab( + scrollController: _jobScrollController, + projectName: widget.projectName ?? '', + ), _buildTeamsTab(), ], ); diff --git a/lib/view/service_project/service_project_job_detail_screen.dart b/lib/view/service_project/service_project_job_detail_screen.dart index d689b97..977c323 100644 --- a/lib/view/service_project/service_project_job_detail_screen.dart +++ b/lib/view/service_project/service_project_job_detail_screen.dart @@ -1,26 +1,28 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/controller/service_project/service_project_details_screen_controller.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/utils/date_time_utils.dart'; +import 'package:on_field_work/controller/service_project/service_project_details_screen_controller.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/utils/date_time_utils.dart'; import 'package:timeline_tile/timeline_tile.dart'; -import 'package:marco/model/service_project/service_project_job_detail_model.dart'; -import 'package:marco/helpers/widgets/custom_app_bar.dart'; -import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/helpers/widgets/date_range_picker.dart'; -import 'package:marco/model/employees/multiple_select_bottomsheet.dart'; -import 'package:marco/model/employees/employee_model.dart'; -import 'package:marco/model/expense/comment_bottom_sheet.dart'; +import 'package:on_field_work/model/service_project/service_project_job_detail_model.dart'; +import 'package:on_field_work/helpers/widgets/custom_app_bar.dart'; +import 'package:on_field_work/helpers/services/api_service.dart'; +import 'package:on_field_work/helpers/widgets/date_range_picker.dart'; +import 'package:on_field_work/model/employees/multiple_select_bottomsheet.dart'; +import 'package:on_field_work/model/employees/employee_model.dart'; +import 'package:on_field_work/model/expense/comment_bottom_sheet.dart'; import 'package:image_picker/image_picker.dart'; import 'dart:io'; -import 'package:marco/helpers/widgets/my_confirmation_dialog.dart'; +import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; class JobDetailsScreen extends StatefulWidget { final String jobId; - const JobDetailsScreen({super.key, required this.jobId}); + final String? projectName; + const JobDetailsScreen({super.key, required this.jobId, this.projectName}); @override State createState() => _JobDetailsScreenState(); @@ -28,6 +30,8 @@ class JobDetailsScreen extends StatefulWidget { class _JobDetailsScreenState extends State with UIMixin { late final ServiceProjectDetailsController controller; + final RxBool isAttendanceExpanded = false.obs; + RxBool isAttendanceLogLoading = false.obs; final TextEditingController _titleController = TextEditingController(); final TextEditingController _descriptionController = TextEditingController(); @@ -47,15 +51,16 @@ class _JobDetailsScreenState extends State with UIMixin { controller.fetchJobDetail(widget.jobId).then((_) { final job = controller.jobDetail.value?.data; if (job != null) { - _titleController.text = job.title; - _descriptionController.text = job.description; + _titleController.text = job.title ?? ''; + _descriptionController.text = job.description ?? ''; _startDateController.text = DateTimeUtils.convertUtcToLocal( - job.startDate, + job.startDate ?? DateTime.now().toIso8601String(), format: "yyyy-MM-dd"); - _dueDateController.text = - DateTimeUtils.convertUtcToLocal(job.dueDate, format: "yyyy-MM-dd"); - _selectedAssignees.value = job.assignees; - _selectedTags.value = job.tags; + _dueDateController.text = DateTimeUtils.convertUtcToLocal( + job.dueDate ?? '', + format: "yyyy-MM-dd"); + _selectedAssignees.value = job.assignees ?? []; + _selectedTags.value = job.tags ?? []; } }); } @@ -111,14 +116,14 @@ class _JobDetailsScreenState extends State with UIMixin { } final originalAssignees = job.assignees; - final assigneesPayload = originalAssignees.map((a) { + final assigneesPayload = originalAssignees?.map((a) { final isSelected = _selectedAssignees.any((s) => s.id == a.id); return {"employeeId": a.id, "isActive": isSelected}; }).toList(); for (var s in _selectedAssignees) { - if (!originalAssignees.any((a) => a.id == s.id)) { - assigneesPayload.add({"employeeId": s.id, "isActive": true}); + if (!(originalAssignees?.any((a) => a.id == s.id) ?? false)) { + assigneesPayload?.add({"employeeId": s.id, "isActive": true}); } } @@ -126,8 +131,7 @@ class _JobDetailsScreenState extends State with UIMixin { {"op": "replace", "path": "/assignees", "value": assigneesPayload}); final originalTags = job.tags; - - final replaceTagsPayload = originalTags.map((t) { + final replaceTagsPayload = originalTags?.map((t) { final isSelected = _selectedTags.any((s) => s.id == t.id); return {"id": t.id, "name": t.name, "isActive": isSelected}; }).toList(); @@ -137,7 +141,7 @@ class _JobDetailsScreenState extends State with UIMixin { .map((t) => {"name": t.name, "isActive": true}) .toList(); - if (replaceTagsPayload.isNotEmpty) { + if ((replaceTagsPayload?.isNotEmpty ?? false)) { operations .add({"op": "replace", "path": "/tags", "value": replaceTagsPayload}); } @@ -147,19 +151,30 @@ class _JobDetailsScreenState extends State with UIMixin { } if (operations.isEmpty) { - Get.snackbar("Info", "No changes detected to save."); + showAppSnackbar( + title: "Info", + message: "No changes detected to save.", + type: SnackbarType.info); return; } final success = await ApiService.editServiceProjectJobApi( - jobId: job.id, operations: operations); + jobId: job.id ?? "", + operations: operations, + ); if (success) { - Get.snackbar("Success", "Job updated successfully"); + showAppSnackbar( + title: "Success", + message: "Job updated successfully", + type: SnackbarType.success); await controller.fetchJobDetail(widget.jobId); isEditing.value = false; } else { - Get.snackbar("Error", "Failed to update job. Check inputs or try again."); + showAppSnackbar( + title: "Error", + message: "Failed to update job. Check inputs or try again.", + type: SnackbarType.error); } } @@ -167,16 +182,13 @@ class _JobDetailsScreenState extends State with UIMixin { final job = controller.jobDetail.value?.data; if (job == null) return; - // Determine action based on current/next tagging state final action = job.nextTaggingAction; - File? attachmentFile; - // Step 1: Ask for comment first (optional) final comment = await showCommentBottomSheet( context, action == 0 ? "Tag In" : "Tag Out"); + if (comment == null) return; - // Step 2: Ask for image optionally using your custom ConfirmDialog await showDialog( context: context, builder: (_) => ConfirmDialog( @@ -196,13 +208,21 @@ class _JobDetailsScreenState extends State with UIMixin { ), ); - // Step 3: Perform attendance using controller await controller.updateJobAttendance( - jobId: job.id, + jobId: job.id ?? "", action: action == 0 ? 0 : 1, - comment: comment ?? "", + comment: comment, attachment: attachmentFile, ); + + final msg = controller.attendanceMessage.value; + if (msg.toLowerCase().contains("failed") || + msg.toLowerCase().contains("error")) { + showAppSnackbar(title: "Error", message: msg, type: SnackbarType.error); + return; + } + + showAppSnackbar(title: "Success", message: msg, type: SnackbarType.success); } Widget _buildSectionCard({ @@ -334,14 +354,14 @@ class _JobDetailsScreenState extends State with UIMixin { onTap: () async { final initiallySelected = assignees.map((a) { return EmployeeModel( - id: a.id, - employeeId: a.id, - firstName: a.firstName, - lastName: a.lastName, + id: a.id ?? '', + employeeId: a.id ?? '', + firstName: a.firstName ?? '', + lastName: a.lastName ?? '', name: "${a.firstName} ${a.lastName}", - designation: a.jobRoleName, - jobRole: a.jobRoleName, - jobRoleID: a.jobRoleId, + designation: a.jobRoleName ?? '', + jobRole: a.jobRoleName ?? '', + jobRoleID: a.jobRoleId ?? '', email: a.email ?? '', phoneNumber: '', activity: 0, @@ -444,10 +464,11 @@ class _JobDetailsScreenState extends State with UIMixin { return Obx(() { final job = controller.jobDetail.value?.data; final isLoading = controller.isTagging.value; - final action = job?.nextTaggingAction ?? 0; - final RxBool isExpanded = false.obs; + final action = job?.nextTaggingAction; final logs = controller.attendanceLog.value?.data ?? []; + if (job == null) return const SizedBox(); + return Card( elevation: 3, shadowColor: Colors.black12, @@ -468,61 +489,70 @@ class _JobDetailsScreenState extends State with UIMixin { const Spacer(), Obx(() => IconButton( icon: Icon( - isExpanded.value + isAttendanceExpanded.value ? Icons.expand_less : Icons.expand_more, color: Colors.grey[600], ), onPressed: () async { - isExpanded.value = !isExpanded.value; - // Fetch attendance logs only when expanded - if (isExpanded.value && job != null) { - await controller.fetchJobAttendanceLog(job.attendanceId ?? ''); + isAttendanceExpanded.value = + !isAttendanceExpanded.value; + if (isAttendanceExpanded.value) { + await controller + .fetchJobAttendanceLog(job.attendanceId ?? ''); } }, - )), + )) ], ), const SizedBox(height: 8), const Divider(), // Tag In/Tag Out Button - Align( - alignment: Alignment.center, - child: SizedBox( - height: 36, - child: ElevatedButton.icon( - icon: isLoading - ? SizedBox( - height: 16, - width: 16, - child: CircularProgressIndicator( - color: Colors.white, - strokeWidth: 2, - ), - ) - : Icon(action == 0 ? Icons.login : Icons.logout), - label: MyText.bodyMedium( - action == 0 ? "Tag In" : "Tag Out", - fontWeight: 600, - color: Colors.white, - ), - onPressed: - isLoading || job == null ? null : _handleTagAction, - style: ElevatedButton.styleFrom( - padding: const EdgeInsets.symmetric(horizontal: 20), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5), + if (action != null) + Align( + alignment: Alignment.center, + child: SizedBox( + height: 36, + child: ElevatedButton.icon( + icon: isLoading + ? SizedBox( + height: 16, + width: 16, + child: CircularProgressIndicator( + color: Colors.white, + strokeWidth: 2, + ), + ) + : Icon(action == 0 ? Icons.login : Icons.logout), + label: MyText.bodyMedium( + action == 0 ? "Tag In" : "Tag Out", + fontWeight: 600, + color: Colors.white, + ), + onPressed: isLoading ? null : _handleTagAction, + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(horizontal: 20), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), + ), + backgroundColor: + action == 0 ? Colors.green : Colors.red, ), - backgroundColor: action == 0 ? Colors.green : Colors.red, ), ), ), - ), - // Attendance Logs List + // Attendance Logs Obx(() { - if (!isExpanded.value) return Container(); + if (!isAttendanceExpanded.value) return Container(); + + if (isAttendanceLogLoading.value) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 12), + child: Center(child: CircularProgressIndicator()), + ); + } if (logs.isEmpty) { return Padding( @@ -539,125 +569,142 @@ class _JobDetailsScreenState extends State with UIMixin { physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsets.only(top: 12), itemCount: logs.length, - separatorBuilder: (_, __) => const SizedBox(height: 12), + separatorBuilder: (_, __) => const SizedBox(height: 8), itemBuilder: (_, index) { final log = logs[index]; final employeeName = "${log.employee.firstName} ${log.employee.lastName}"; + final date = DateTimeUtils.convertUtcToLocal( + log.markedAt.toIso8601String(), + format: 'd MMM yyyy'); + final time = DateTimeUtils.convertUtcToLocal( + log.markedAt.toIso8601String(), + format: 'hh:mm a'); - return Container( - decoration: BoxDecoration( - color: Colors.grey.shade50, - borderRadius: BorderRadius.circular(12), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.05), - blurRadius: 6, - offset: const Offset(0, 2), - ), - ], - ), - padding: const EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Header: Icon + Employee + Date + Time - Row( - children: [ - Icon( - log.action == 0 ? Icons.login : Icons.logout, - color: - log.action == 0 ? Colors.green : Colors.red, - ), - const SizedBox(width: 8), - Expanded( - child: MyText.bodyMedium( - "$employeeName | ${DateTimeUtils.convertUtcToLocal(log.markedAt.toIso8601String(), format: 'd MMM yyyy')}", - fontWeight: 600, + return Card( + elevation: 1, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8)), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Top Row: Icon, Employee, Date, Time + Row( + children: [ + Icon( + log.action == 0 ? Icons.login : Icons.logout, + color: log.action == 0 + ? Colors.green + : Colors.red, + size: 18, + ), + const SizedBox(width: 6), + Expanded( + child: Text( + employeeName, + style: const TextStyle( + fontWeight: FontWeight.w600), + ), + ), + Text( + "$date | $time", + style: TextStyle( + fontSize: 12, color: Colors.grey[700]), + ), + ], + ), + const SizedBox(height: 4), + + // Comment + if (log.comment?.isNotEmpty == true) + Padding( + padding: const EdgeInsets.only(top: 4), + child: Text( + log.comment!, + style: const TextStyle(fontSize: 13), ), ), - MyText.bodySmall( - "Time: ${DateTimeUtils.convertUtcToLocal(log.markedAt.toIso8601String(), format: 'hh:mm a')}", - color: Colors.grey[700], - ), - ], - ), - const SizedBox(height: 8), - const Divider(height: 1, color: Colors.grey), - const SizedBox(height: 8), - // Comment / Description - MyText.bodySmall( - "Description: ${log.comment?.isNotEmpty == true ? log.comment : 'No description provided'}", - ), - const SizedBox(height: 8), - - // Location - if (log.latitude != null && log.longitude != null) - GestureDetector( - onTap: () async { - final lat = - double.tryParse(log.latitude!) ?? 0.0; - final lon = - double.tryParse(log.longitude!) ?? 0.0; - final url = - 'https://www.google.com/maps/search/?api=1&query=$lat,$lon'; - if (await canLaunchUrl(Uri.parse(url))) { - await launchUrl(Uri.parse(url), - mode: LaunchMode.externalApplication); - } - }, - child: Row( - children: [ - Icon(Icons.location_on, - size: 16, color: Colors.blue), - const SizedBox(width: 4), - MyText.bodySmall( - "View Location", - color: Colors.blue, - decoration: TextDecoration.underline, + // Location + if (log.latitude != null && log.longitude != null) + GestureDetector( + onTap: () async { + final lat = + double.tryParse(log.latitude!) ?? 0.0; + final lon = + double.tryParse(log.longitude!) ?? 0.0; + final url = + 'https://www.google.com/maps/search/?api=1&query=$lat,$lon'; + if (await canLaunchUrl(Uri.parse(url))) { + await launchUrl(Uri.parse(url), + mode: LaunchMode.externalApplication); + } + }, + child: Padding( + padding: const EdgeInsets.only(top: 4), + child: Row( + mainAxisSize: MainAxisSize.min, + children: const [ + Icon(Icons.location_on, + size: 14, color: Colors.blue), + SizedBox(width: 4), + Text( + "View Location", + style: TextStyle( + fontSize: 12, + color: Colors.blue, + decoration: + TextDecoration.underline), + ), + ], ), - ], + ), ), - ), - const SizedBox(height: 8), - // Attached Image - if (log.document != null) - GestureDetector( - onTap: () => showDialog( - context: context, - builder: (_) => Dialog( - child: Image.network( - log.document!.preSignedUrl, - fit: BoxFit.cover, - height: 400, - errorBuilder: (_, __, ___) => const Icon( - Icons.broken_image, - size: 50, - color: Colors.grey, + // Attached Image + if (log.document != null) + Padding( + padding: const EdgeInsets.only(top: 4), + child: GestureDetector( + onTap: () => showDialog( + context: context, + builder: (_) => Dialog( + child: Image.network( + log.document!.preSignedUrl, + fit: BoxFit.cover, + height: 250, + errorBuilder: (_, __, ___) => + const Icon( + Icons.broken_image, + size: 50, + color: Colors.grey, + ), + ), + ), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(6), + child: Image.network( + log.document!.thumbPreSignedUrl.isNotEmpty + ? log.document!.thumbPreSignedUrl + : log.document!.preSignedUrl, + height: 50, + width: 50, + fit: BoxFit.cover, + errorBuilder: (_, __, ___) => const Icon( + Icons.broken_image, + size: 40, + color: Colors.grey, + ), ), ), ), ), - child: ClipRRect( - borderRadius: BorderRadius.circular(8), - child: Image.network( - log.document!.thumbPreSignedUrl.isNotEmpty - ? log.document!.thumbPreSignedUrl - : log.document!.preSignedUrl, - height: 60, - width: 60, - fit: BoxFit.cover, - errorBuilder: (_, __, ___) => const Icon( - Icons.broken_image, - size: 40, - color: Colors.grey, - ), - ), - ), - ), - ], + ], + ), ), ); }, @@ -670,13 +717,50 @@ class _JobDetailsScreenState extends State with UIMixin { }); } + Widget _rowItem(String label, String value) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 3, + child: MyText.bodySmall(label, + fontWeight: 600, color: Colors.grey.shade700), + ), + Expanded( + flex: 5, + child: MyText.bodyMedium(value, fontWeight: 500), + ), + ], + ); + } + + Widget _branchDisplay() { + final job = controller.jobDetail.value?.data; + final branch = job?.projectBranch; + if (branch == null) { + return MyText.labelMedium("No branch assigned"); + } + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _rowItem("Branch Name", branch.branchName ?? "-"), + MySpacing.height(8), + _rowItem("Branch Type", branch.branchType ?? "-"), + ], + ); + } + @override Widget build(BuildContext context) { + final projectName = widget.projectName; return Scaffold( backgroundColor: const Color(0xFFF5F5F5), appBar: CustomAppBar( - title: "Service Project Job Details", - onBackPressed: () => Get.back()), + title: "Job Details Screen", + onBackPressed: () => Get.back(), + projectName: projectName, + ), floatingActionButton: Obx(() => FloatingActionButton.extended( onPressed: isEditing.value ? _editJob : () => isEditing.value = true, @@ -719,6 +803,12 @@ class _JobDetailsScreenState extends State with UIMixin { ], ), MySpacing.height(12), + _buildSectionCard( + title: "Project Branch", + titleIcon: Icons.account_tree_outlined, + children: [_branchDisplay()], + ), + MySpacing.height(16), _buildSectionCard( title: "Assignees", titleIcon: Icons.person_outline, @@ -729,11 +819,11 @@ class _JobDetailsScreenState extends State with UIMixin { titleIcon: Icons.label_outline, children: [_tagEditor()]), MySpacing.height(16), - if (job.updateLogs.isNotEmpty) + if ((job.updateLogs?.isNotEmpty ?? false)) _buildSectionCard( title: "Update Logs", titleIcon: Icons.history, - children: [JobTimeline(logs: job.updateLogs)]), + children: [JobTimeline(logs: job.updateLogs ?? [])]), MySpacing.height(80), ], ), @@ -761,12 +851,14 @@ class JobTimeline extends StatelessWidget { itemBuilder: (_, index) { final log = reversedLogs[index]; final statusName = log.status?.displayName ?? "Created"; - final nextStatusName = log.nextStatus.displayName; - final comment = log.comment; + final nextStatusName = log.nextStatus?.displayName ?? "N/A"; + final comment = log.comment ?? ''; final updatedBy = - "${log.updatedBy.firstName} ${log.updatedBy.lastName}"; + "${log.updatedBy?.firstName ?? ''} ${log.updatedBy?.lastName ?? ''}"; + final f = log.updatedBy?.firstName ?? ''; + final l = log.updatedBy?.lastName ?? ''; final initials = - "${log.updatedBy.firstName.isNotEmpty ? log.updatedBy.firstName[0] : ''}${log.updatedBy.lastName.isNotEmpty ? log.updatedBy.lastName[0] : ''}"; + "${f.isNotEmpty ? f[0] : ''}${l.isNotEmpty ? l[0] : ''}"; return TimelineTile( alignment: TimelineAlign.start, diff --git a/lib/view/service_project/service_project_screen.dart b/lib/view/service_project/service_project_screen.dart index 50bdee7..bf07d58 100644 --- a/lib/view/service_project/service_project_screen.dart +++ b/lib/view/service_project/service_project_screen.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; -import 'package:marco/controller/service_project/service_project_screen_controller.dart'; -import 'package:marco/model/service_project/service_projects_list_model.dart'; -import 'package:marco/helpers/utils/date_time_utils.dart'; -import 'package:marco/view/service_project/service_project_details_screen.dart'; -import 'package:marco/helpers/widgets/custom_app_bar.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/controller/service_project/service_project_screen_controller.dart'; +import 'package:on_field_work/model/service_project/service_projects_list_model.dart'; +import 'package:on_field_work/helpers/utils/date_time_utils.dart'; +import 'package:on_field_work/view/service_project/service_project_details_screen.dart'; +import 'package:on_field_work/helpers/widgets/custom_app_bar.dart'; class ServiceProjectScreen extends StatefulWidget { const ServiceProjectScreen({super.key}); @@ -50,7 +50,10 @@ class _ServiceProjectScreenState extends State borderRadius: BorderRadius.circular(14), onTap: () { // Navigate to ServiceProjectDetailsScreen - Get.to(() => ServiceProjectDetailsScreen(projectId: project.id)); + Get.to(() => ServiceProjectDetailsScreen( + projectId: project.id, + projectName: project.name, + )); }, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 14), @@ -196,6 +199,7 @@ class _ServiceProjectScreenState extends State backgroundColor: const Color(0xFFF5F5F5), appBar: CustomAppBar( title: "Service Projects", + projectName: 'All Service Projects', onBackPressed: () => Get.toNamed('/dashboard'), ), body: Column( @@ -246,62 +250,6 @@ class _ServiceProjectScreenState extends State ), ), ), - MySpacing.width(8), - Container( - height: 35, - width: 35, - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.grey.shade300), - borderRadius: BorderRadius.circular(5), - ), - child: IconButton( - icon: - const Icon(Icons.tune, size: 20, color: Colors.black87), - onPressed: () { - // TODO: Open filter bottom sheet - }, - ), - ), - MySpacing.width(10), - Container( - height: 35, - width: 35, - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.grey.shade300), - borderRadius: BorderRadius.circular(5), - ), - child: PopupMenuButton( - padding: EdgeInsets.zero, - icon: const Icon(Icons.more_vert, - size: 20, color: Colors.black87), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5)), - itemBuilder: (context) => [ - const PopupMenuItem( - enabled: false, - height: 30, - child: Text( - "Actions", - style: TextStyle( - fontWeight: FontWeight.bold, color: Colors.grey), - ), - ), - const PopupMenuItem( - value: 1, - child: Row( - children: [ - SizedBox(width: 10), - Expanded(child: Text("Manage Projects")), - Icon(Icons.chevron_right, - size: 20, color: Colors.indigo), - ], - ), - ), - ], - ), - ), ], ), ), diff --git a/lib/view/splash_screen.dart b/lib/view/splash_screen.dart index 67552b6..7f84b21 100644 --- a/lib/view/splash_screen.dart +++ b/lib/view/splash_screen.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:marco/images.dart'; +import 'package:on_field_work/images.dart'; class SplashScreen extends StatefulWidget { final String? message; diff --git a/lib/view/taskPlanning/daily_progress_report.dart b/lib/view/taskPlanning/daily_progress_report.dart index 8f85883..74d6cc0 100644 --- a/lib/view/taskPlanning/daily_progress_report.dart +++ b/lib/view/taskPlanning/daily_progress_report.dart @@ -1,22 +1,22 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/utils/my_shadow.dart'; -import 'package:marco/helpers/widgets/my_card.dart'; -import 'package:marco/helpers/widgets/my_container.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/controller/task_planning/daily_task_controller.dart'; -import 'package:marco/model/dailyTaskPlanning/daily_progress_report_filter.dart'; -import 'package:marco/helpers/widgets/avatar.dart'; -import 'package:marco/controller/project_controller.dart'; -import 'package:marco/model/dailyTaskPlanning/task_action_buttons.dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; -import 'package:marco/helpers/utils/permission_constants.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/utils/my_shadow.dart'; +import 'package:on_field_work/helpers/widgets/my_card.dart'; +import 'package:on_field_work/helpers/widgets/my_container.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/controller/task_planning/daily_task_controller.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/daily_progress_report_filter.dart'; +import 'package:on_field_work/helpers/widgets/avatar.dart'; +import 'package:on_field_work/controller/project_controller.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/task_action_buttons.dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; class DailyProgressReportScreen extends StatefulWidget { const DailyProgressReportScreen({super.key}); diff --git a/lib/view/taskPlanning/daily_task_planning.dart b/lib/view/taskPlanning/daily_task_planning.dart index 65bf438..7e35ef5 100644 --- a/lib/view/taskPlanning/daily_task_planning.dart +++ b/lib/view/taskPlanning/daily_task_planning.dart @@ -1,20 +1,20 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/theme/app_theme.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_card.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/controller/permission_controller.dart'; -import 'package:marco/controller/task_Planning/daily_task_Planning_controller.dart'; -import 'package:marco/controller/project_controller.dart'; +import 'package:on_field_work/helpers/theme/app_theme.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_card.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/controller/permission_controller.dart'; +import 'package:on_field_work/controller/task_Planning/daily_task_Planning_controller.dart'; +import 'package:on_field_work/controller/project_controller.dart'; import 'package:percent_indicator/percent_indicator.dart'; -import 'package:marco/model/dailyTaskPlanning/assign_task_bottom_sheet .dart'; -import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; -import 'package:marco/helpers/utils/permission_constants.dart'; -import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; -import 'package:marco/controller/tenant/service_controller.dart'; -import 'package:marco/helpers/widgets/tenant/service_selector.dart'; +import 'package:on_field_work/model/dailyTaskPlanning/assign_task_bottom_sheet .dart'; +import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; +import 'package:on_field_work/helpers/utils/permission_constants.dart'; +import 'package:on_field_work/helpers/widgets/my_refresh_indicator.dart'; +import 'package:on_field_work/controller/tenant/service_controller.dart'; +import 'package:on_field_work/helpers/widgets/tenant/service_selector.dart'; class DailyTaskPlanningScreen extends StatefulWidget { DailyTaskPlanningScreen({super.key}); diff --git a/lib/view/tenant/tenant_selection_screen.dart b/lib/view/tenant/tenant_selection_screen.dart index 7fe1875..21c8283 100644 --- a/lib/view/tenant/tenant_selection_screen.dart +++ b/lib/view/tenant/tenant_selection_screen.dart @@ -1,14 +1,14 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:marco/helpers/services/api_endpoints.dart'; -import 'package:marco/helpers/services/storage/local_storage.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_text.dart'; -import 'package:marco/images.dart'; -import 'package:marco/controller/tenant/tenant_selection_controller.dart'; -import 'package:marco/view/splash_screen.dart'; -import 'package:marco/helpers/widgets/wave_background.dart'; +import 'package:on_field_work/helpers/services/api_endpoints.dart'; +import 'package:on_field_work/helpers/services/storage/local_storage.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_text.dart'; +import 'package:on_field_work/images.dart'; +import 'package:on_field_work/controller/tenant/tenant_selection_controller.dart'; +import 'package:on_field_work/view/splash_screen.dart'; +import 'package:on_field_work/helpers/widgets/wave_background.dart'; class TenantSelectionScreen extends StatefulWidget { const TenantSelectionScreen({super.key}); diff --git a/lib/widgets/custom_pop_menu.dart b/lib/widgets/custom_pop_menu.dart index 6272216..1bdf01b 100644 --- a/lib/widgets/custom_pop_menu.dart +++ b/lib/widgets/custom_pop_menu.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; enum CustomPopupMenuPlacement { left, right, top, bottom } diff --git a/lib/widgets/custom_switch.dart b/lib/widgets/custom_switch.dart index 8cf890f..442fd79 100644 --- a/lib/widgets/custom_switch.dart +++ b/lib/widgets/custom_switch.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; -import 'package:marco/helpers/widgets/my_spacing.dart'; +import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart'; +import 'package:on_field_work/helpers/widgets/my_spacing.dart'; class CustomSwitch extends StatefulWidget { final bool value; diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index fa2be66..77a63e1 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -4,7 +4,7 @@ project(runner LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. -set(BINARY_NAME "marco") +set(BINARY_NAME "on field work") # The unique GTK application identifier for this application. See: # https://wiki.gnome.org/HowDoI/ChooseApplicationID set(APPLICATION_ID "com.marcoonfieldwork.aiot") diff --git a/linux/my_application.cc b/linux/my_application.cc index a3508cf..dd1759e 100644 --- a/linux/my_application.cc +++ b/linux/my_application.cc @@ -40,11 +40,11 @@ static void my_application_activate(GApplication* application) { if (use_header_bar) { GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); gtk_widget_show(GTK_WIDGET(header_bar)); - gtk_header_bar_set_title(header_bar, "marco"); + gtk_header_bar_set_title(header_bar, "on field work"); gtk_header_bar_set_show_close_button(header_bar, TRUE); gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); } else { - gtk_window_set_title(window, "marco"); + gtk_window_set_title(window, "on field work"); } gtk_window_set_default_size(window, 1280, 720); diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index a89772a..a8c5309 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -64,7 +64,7 @@ 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* marco.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "marco.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* on field work.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "on field work.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -131,7 +131,7 @@ 33CC10EE2044A3C60003C045 /* Products */ = { isa = PBXGroup; children = ( - 33CC10ED2044A3C60003C045 /* marco.app */, + 33CC10ED2044A3C60003C045 /* on field work.app */, 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, ); name = Products; @@ -217,7 +217,7 @@ ); name = Runner; productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* marco.app */; + productReference = 33CC10ED2044A3C60003C045 /* on field work.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index d640941..88b79b5 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -15,7 +15,7 @@ @@ -31,7 +31,7 @@ @@ -65,7 +65,7 @@ @@ -82,7 +82,7 @@ diff --git a/macos/Runner/Configs/AppInfo.xcconfig b/macos/Runner/Configs/AppInfo.xcconfig index 52293a5..1ec6933 100644 --- a/macos/Runner/Configs/AppInfo.xcconfig +++ b/macos/Runner/Configs/AppInfo.xcconfig @@ -5,7 +5,7 @@ // 'flutter create' template. // The application's name. By default this is also the title of the Flutter window. -PRODUCT_NAME = marco +PRODUCT_NAME = on field work // The application's bundle identifier PRODUCT_BUNDLE_IDENTIFIER = com.marcoonfieldwork.aiot diff --git a/pubspec.yaml b/pubspec.yaml index 9b88f89..4a2723e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,4 +1,4 @@ -name: marco +name: on_field_work description: "A new Flutter project." # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.0.0+13 +version: 1.0.0+16 environment: sdk: ^3.5.3 @@ -118,7 +118,6 @@ flutter: - assets/logo/loading_logo.png - assets/social/ - assets/service-account.json - - assets/service-account.json # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg diff --git a/test/widget_test.dart b/test/widget_test.dart index 50cec9b..bb64fa5 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:marco/main.dart'; +import 'package:on_field_work/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { diff --git a/web/index.html b/web/index.html index 9eb53ab..6b63db2 100644 --- a/web/index.html +++ b/web/index.html @@ -23,13 +23,13 @@ - + - marco + on field work diff --git a/web/manifest.json b/web/manifest.json index d19d002..e53c254 100644 --- a/web/manifest.json +++ b/web/manifest.json @@ -1,6 +1,6 @@ { - "name": "marco", - "short_name": "marco", + "name": "on field work", + "short_name": "ofw", "start_url": ".", "display": "standalone", "background_color": "#0175C2", diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt index 6a78c93..0d6ac17 100644 --- a/windows/CMakeLists.txt +++ b/windows/CMakeLists.txt @@ -1,10 +1,10 @@ # Project-level configuration. cmake_minimum_required(VERSION 3.14) -project(marco LANGUAGES CXX) +project(on field work LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. -set(BINARY_NAME "marco") +set(BINARY_NAME "on field work") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. diff --git a/windows/runner/Runner.rc b/windows/runner/Runner.rc index 17bd9de..7b1327d 100644 --- a/windows/runner/Runner.rc +++ b/windows/runner/Runner.rc @@ -90,12 +90,12 @@ BEGIN BLOCK "040904e4" BEGIN VALUE "CompanyName", "com.example" "\0" - VALUE "FileDescription", "marco" "\0" + VALUE "FileDescription", "on field work" "\0" VALUE "FileVersion", VERSION_AS_STRING "\0" - VALUE "InternalName", "marco" "\0" + VALUE "InternalName", "on field work" "\0" VALUE "LegalCopyright", "Copyright (C) 2024 com.example. All rights reserved." "\0" - VALUE "OriginalFilename", "marco.exe" "\0" - VALUE "ProductName", "marco" "\0" + VALUE "OriginalFilename", "on field work.exe" "\0" + VALUE "ProductName", "on field work" "\0" VALUE "ProductVersion", VERSION_AS_STRING "\0" END END diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp index 166739a..da1d2a4 100644 --- a/windows/runner/main.cpp +++ b/windows/runner/main.cpp @@ -27,7 +27,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, FlutterWindow window(project); Win32Window::Point origin(10, 10); Win32Window::Size size(1280, 720); - if (!window.Create(L"marco", origin, size)) { + if (!window.Create(L"on field work", origin, size)) { return EXIT_FAILURE; } window.SetQuitOnClose(true);