diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 2fc39547..3ef46b03 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -351,4 +351,6 @@ class URLs { //survey static get getQuestionnaire => '$_baseUrl/SurveyQuestionnaire/GetQuestionnaire'; + + static get submitSurvey => '$_baseUrl/SurveyQuestionnaire/SubmitSurvey'; } diff --git a/lib/models/new_models/work_order_detail_model.dart b/lib/models/new_models/work_order_detail_model.dart index febd3d80..25519bd6 100644 --- a/lib/models/new_models/work_order_detail_model.dart +++ b/lib/models/new_models/work_order_detail_model.dart @@ -348,33 +348,46 @@ class AssetGroup { } class WorkOrderAssignedEmployee { - WorkOrderAssignedEmployee({ - required this.userId, - required this.userName, - required this.email, - required this.languageId, - }); - - String userId; + String? userId; String? userName; String? email; + String? employeeId; int? languageId; + String? extensionNo; + String? phoneNumber; + String? positionName; + String? position; + bool? isActive; - factory WorkOrderAssignedEmployee.fromJson(Map json) { - return WorkOrderAssignedEmployee( - userId: json["userId"], - userName: json["userName"], - email: json["email"], - languageId: json["languageId"], - ); + WorkOrderAssignedEmployee({this.userId, this.userName, this.email, this.employeeId, this.languageId, this.extensionNo, this.phoneNumber, this.positionName, this.position, this.isActive}); + + WorkOrderAssignedEmployee.fromJson(Map json) { + userId = json['userId']; + userName = json['userName']; + email = json['email']; + employeeId = json['employeeId']; + languageId = json['languageId']; + extensionNo = json['extensionNo']; + phoneNumber = json['phoneNumber']; + positionName = json['positionName']; + position = json['position']; + isActive = json['isActive']; } - Map toJson() => { - "userId": userId, - "userName": userName, - "email": email, - "languageId": languageId, - }; + Map toJson() { + final Map data = new Map(); + data['userId'] = this.userId; + data['userName'] = this.userName; + data['email'] = this.email; + data['employeeId'] = this.employeeId; + data['languageId'] = this.languageId; + data['extensionNo'] = this.extensionNo; + data['phoneNumber'] = this.phoneNumber; + data['positionName'] = this.positionName; + data['position'] = this.position; + data['isActive'] = this.isActive; + return data; + } } class AssetLoan { diff --git a/lib/modules/cm_module/views/service_request_detail_main_view.dart b/lib/modules/cm_module/views/service_request_detail_main_view.dart index 2431d1ed..cd50f283 100644 --- a/lib/modules/cm_module/views/service_request_detail_main_view.dart +++ b/lib/modules/cm_module/views/service_request_detail_main_view.dart @@ -93,7 +93,8 @@ class _ServiceRequestDetailMainState extends State { IconButton( icon: const Icon(Icons.chat_bubble), onPressed: () { - Navigator.push(context, CupertinoPageRoute(builder: (context) => ChatPage(moduleId: 1, requestId: widget.requestId))); + Navigator.push( + context, CupertinoPageRoute(builder: (context) => ChatPage(moduleId: 1, requestId: widget.requestId, title: _requestProvider.currentWorkOrder?.data?.workOrderNo ?? ""))); }, ), isNurse diff --git a/lib/modules/cx_module/chat/chat_api_client.dart b/lib/modules/cx_module/chat/chat_api_client.dart index 985666c0..b6d5adc8 100644 --- a/lib/modules/cx_module/chat/chat_api_client.dart +++ b/lib/modules/cx_module/chat/chat_api_client.dart @@ -61,8 +61,8 @@ class ChatApiClient { return chatLoginResponse; } - Future loadParticipants(int moduleId, int referenceId,String? assigneeEmployeeNumber) async { - Response response = await ApiClient().getJsonForResponse("${URLs.chatHubUrlApi}/chat/context/$moduleId/$referenceId?assigneeEmployeeNumber=$assigneeEmployeeNumber", token: chatLoginResponse!.token); + Future loadParticipants(int moduleId, int referenceId, String? assigneeEmployeeNumber) async { + Response response = await ApiClient().getJsonForResponse("${URLs.chatHubUrlApi}/chat/context/$moduleId/$referenceId", token: chatLoginResponse!.token); if (!kReleaseMode) { // logger.i("login-res: " + response.body); @@ -74,18 +74,21 @@ class ChatApiClient { } } - Future loadChatHistory(int moduleId, int referenceId, String myId, String otherId) async { + Future> loadChatHistory(int moduleId, int referenceId, String myId, String otherId) async { Response response = await ApiClient().postJsonForResponse( "${URLs.chatHubUrlApi}/UserChatHistory/GetUserChatHistory/$myId/$otherId/0", {"moduleCode": moduleId.toString(), "referenceId": referenceId.toString()}, token: chatLoginResponse!.token); try { if (response.statusCode == 200) { - return UserChatHistoryModel.fromJson(jsonDecode(response.body)); + List data = jsonDecode(response.body); + return data.map((elemet) => ChatHistoryResponse.fromJson(elemet)).toList(); + + // return UserChatHistoryModel.fromJson(jsonDecode(response.body)); } else { - return null; + return []; } } catch (ex) { - return null; + return []; } } diff --git a/lib/modules/cx_module/chat/chat_page.dart b/lib/modules/cx_module/chat/chat_page.dart index 800ebc46..f7e8fb5c 100644 --- a/lib/modules/cx_module/chat/chat_page.dart +++ b/lib/modules/cx_module/chat/chat_page.dart @@ -6,6 +6,8 @@ import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/models/service_request/service_request.dart'; +import 'package:test_sa/modules/cm_module/service_request_detail_provider.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/modules/cx_module/chat/chat_api_client.dart'; import 'package:test_sa/modules/cx_module/chat/chat_provider.dart'; @@ -56,8 +58,9 @@ class _ChatPageState extends State { } void getChatToken() { - String assigneeEmployeeNumber = ""; - Provider.of(context, listen: false).getUserAutoLoginToken(widget.moduleId, widget.requestId + 2, widget.title, context.settingProvider.username, assigneeEmployeeNumber); + String assigneeEmployeeNumber = Provider.of(context, listen: false).currentWorkOrder?.data?.assignedEmployee?.employeeId ?? ""; + Provider.of(context, listen: false).getUserAutoLoginToken(widget.moduleId, widget.requestId, widget.title, + Provider.of(context, listen: false).currentWorkOrder!.data!.workOrderContactPerson.first.employeeId!, assigneeEmployeeNumber); } @override diff --git a/lib/modules/cx_module/chat/chat_provider.dart b/lib/modules/cx_module/chat/chat_provider.dart index 6fa6ecd7..84262c5c 100644 --- a/lib/modules/cx_module/chat/chat_provider.dart +++ b/lib/modules/cx_module/chat/chat_provider.dart @@ -113,7 +113,10 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { ChatParticipantModel? chatParticipantModel; bool userChatHistoryLoading = false; - UserChatHistoryModel? userChatHistory; + + // UserChatHistoryModel? userChatHistory; + + List? userChatHistory; bool messageIsSending = false; @@ -134,7 +137,7 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { ChatApiClient().chatLoginResponse = null; } - Future getUserAutoLoginToken(int moduleId, int requestId, String title, String employeeNumber, String? assigneeEmployeeNumber) async { + Future getUserAutoLoginToken(int moduleId, int requestId, String title, String employeeNumber, String assigneeEmployeeNumber) async { reset(); chatLoginTokenLoading = true; notifyListeners(); @@ -154,7 +157,7 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { // notifyListeners(); // } - Future loadChatHistory(int moduleId, int requestId, String myId, String? assigneeEmployeeNumber) async { + Future loadChatHistory(int moduleId, int requestId, String myId, String assigneeEmployeeNumber) async { userChatHistoryLoading = true; notifyListeners(); try { @@ -169,8 +172,8 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { sender = chatParticipantModel?.participants?.singleWhere((participant) => participant.employeeNumber == myId); recipient = chatParticipantModel?.participants?.singleWhere((participant) => participant.employeeNumber == assigneeEmployeeNumber); } catch (e) {} - userChatHistory = await ChatApiClient().loadChatHistory(moduleId, requestId, myId, "12"); - chatResponseList = userChatHistory?.response ?? []; + userChatHistory = await ChatApiClient().loadChatHistory(moduleId, requestId, myId, assigneeEmployeeNumber); + // chatResponseList = userChatHistory?.response ?? []; userChatHistoryLoading = false; notifyListeners(); diff --git a/lib/modules/cx_module/chat/model/user_chat_history_model.dart b/lib/modules/cx_module/chat/model/user_chat_history_model.dart index 40140c77..84d8a257 100644 --- a/lib/modules/cx_module/chat/model/user_chat_history_model.dart +++ b/lib/modules/cx_module/chat/model/user_chat_history_model.dart @@ -63,3 +63,162 @@ class ChatResponse { return data; } } + +class ChatHistoryResponse { + int? userChatHistoryId; + int? userChatHistoryLineId; + String? contant; + String? contantNo; + String? currentUserId; + String? currentEmployeeNumber; + String? currentUserName; + String? currentUserEmail; + String? currentFullName; + String? targetUserId; + String? targetEmployeeNumber; + String? targetUserName; + String? targetUserEmail; + String? targetFullName; + String? encryptedTargetUserId; + String? encryptedTargetUserName; + int? chatEventId; + String? fileTypeId; + bool? isSeen; + bool? isDelivered; + String? createdDate; + int? chatSource; + String? conversationId; + FileTypeResponse? fileTypeResponse; + String? userChatReplyResponse; + String? deviceToken; + bool? isHuaweiDevice; + String? platform; + String? voipToken; + + ChatHistoryResponse( + {this.userChatHistoryId, + this.userChatHistoryLineId, + this.contant, + this.contantNo, + this.currentUserId, + this.currentEmployeeNumber, + this.currentUserName, + this.currentUserEmail, + this.currentFullName, + this.targetUserId, + this.targetEmployeeNumber, + this.targetUserName, + this.targetUserEmail, + this.targetFullName, + this.encryptedTargetUserId, + this.encryptedTargetUserName, + this.chatEventId, + this.fileTypeId, + this.isSeen, + this.isDelivered, + this.createdDate, + this.chatSource, + this.conversationId, + this.fileTypeResponse, + this.userChatReplyResponse, + this.deviceToken, + this.isHuaweiDevice, + this.platform, + this.voipToken}); + + ChatHistoryResponse.fromJson(Map json) { + userChatHistoryId = json['userChatHistoryId']; + userChatHistoryLineId = json['userChatHistoryLineId']; + contant = json['contant']; + contantNo = json['contantNo']; + currentUserId = json['currentUserId']; + currentEmployeeNumber = json['currentEmployeeNumber']; + currentUserName = json['currentUserName']; + currentUserEmail = json['currentUserEmail']; + currentFullName = json['currentFullName']; + targetUserId = json['targetUserId']; + targetEmployeeNumber = json['targetEmployeeNumber']; + targetUserName = json['targetUserName']; + targetUserEmail = json['targetUserEmail']; + targetFullName = json['targetFullName']; + encryptedTargetUserId = json['encryptedTargetUserId']; + encryptedTargetUserName = json['encryptedTargetUserName']; + chatEventId = json['chatEventId']; + fileTypeId = json['fileTypeId']; + isSeen = json['isSeen']; + isDelivered = json['isDelivered']; + createdDate = json['createdDate']; + chatSource = json['chatSource']; + conversationId = json['conversationId']; + fileTypeResponse = json['fileTypeResponse'] != null ? new FileTypeResponse.fromJson(json['fileTypeResponse']) : null; + userChatReplyResponse = json['userChatReplyResponse']; + deviceToken = json['deviceToken']; + isHuaweiDevice = json['isHuaweiDevice']; + platform = json['platform']; + voipToken = json['voipToken']; + } + + Map toJson() { + final Map data = new Map(); + data['userChatHistoryId'] = this.userChatHistoryId; + data['userChatHistoryLineId'] = this.userChatHistoryLineId; + data['contant'] = this.contant; + data['contantNo'] = this.contantNo; + data['currentUserId'] = this.currentUserId; + data['currentEmployeeNumber'] = this.currentEmployeeNumber; + data['currentUserName'] = this.currentUserName; + data['currentUserEmail'] = this.currentUserEmail; + data['currentFullName'] = this.currentFullName; + data['targetUserId'] = this.targetUserId; + data['targetEmployeeNumber'] = this.targetEmployeeNumber; + data['targetUserName'] = this.targetUserName; + data['targetUserEmail'] = this.targetUserEmail; + data['targetFullName'] = this.targetFullName; + data['encryptedTargetUserId'] = this.encryptedTargetUserId; + data['encryptedTargetUserName'] = this.encryptedTargetUserName; + data['chatEventId'] = this.chatEventId; + data['fileTypeId'] = this.fileTypeId; + data['isSeen'] = this.isSeen; + data['isDelivered'] = this.isDelivered; + data['createdDate'] = this.createdDate; + data['chatSource'] = this.chatSource; + data['conversationId'] = this.conversationId; + if (this.fileTypeResponse != null) { + data['fileTypeResponse'] = this.fileTypeResponse!.toJson(); + } + data['userChatReplyResponse'] = this.userChatReplyResponse; + data['deviceToken'] = this.deviceToken; + data['isHuaweiDevice'] = this.isHuaweiDevice; + data['platform'] = this.platform; + data['voipToken'] = this.voipToken; + return data; + } +} + +class FileTypeResponse { + int? fileTypeId; + String? fileTypeName; + String? fileTypeDescription; + String? fileKind; + String? fileName; + + FileTypeResponse({this.fileTypeId, this.fileTypeName, this.fileTypeDescription, this.fileKind, this.fileName}); + + FileTypeResponse.fromJson(Map json) { + fileTypeId = json['fileTypeId']; + fileTypeName = json['fileTypeName']; + fileTypeDescription = json['fileTypeDescription']; + fileKind = json['fileKind']; + fileName = json['fileName']; + } + + Map toJson() { + final Map data = new Map(); + data['fileTypeId'] = this.fileTypeId; + data['fileTypeName'] = this.fileTypeName; + data['fileTypeDescription'] = this.fileTypeDescription; + data['fileKind'] = this.fileKind; + data['fileName'] = this.fileName; + return data; + } +} diff --git a/lib/modules/cx_module/survey/questionnaire_model.dart b/lib/modules/cx_module/survey/questionnaire_model.dart new file mode 100644 index 00000000..9528cf87 --- /dev/null +++ b/lib/modules/cx_module/survey/questionnaire_model.dart @@ -0,0 +1,169 @@ +class Questionnaire { + int? questionnaireId; + int? surveySubmissionId; + SurveyType? surveyType; + String? surveyName; + String? surveyDescription; + ServiceRequestDetails? serviceRequestDetails; + List? surveyQuestions; + + Questionnaire({this.questionnaireId, this.surveySubmissionId, this.surveyType, this.surveyName, this.surveyDescription, this.serviceRequestDetails, this.surveyQuestions}); + + Questionnaire.fromJson(Map json) { + questionnaireId = json['questionnaireId']; + surveySubmissionId = json['surveySubmissionId']; + surveyType = json['surveyType'] != null ? new SurveyType.fromJson(json['surveyType']) : null; + surveyName = json['surveyName']; + surveyDescription = json['surveyDescription']; + serviceRequestDetails = json['serviceRequestDetails'] != null ? new ServiceRequestDetails.fromJson(json['serviceRequestDetails']) : null; + if (json['surveyQuestions'] != null) { + surveyQuestions = []; + json['surveyQuestions'].forEach((v) { + surveyQuestions!.add(new SurveyQuestions.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['questionnaireId'] = this.questionnaireId; + data['surveySubmissionId'] = this.surveySubmissionId; + if (this.surveyType != null) { + data['surveyType'] = this.surveyType!.toJson(); + } + data['surveyName'] = this.surveyName; + data['surveyDescription'] = this.surveyDescription; + if (this.serviceRequestDetails != null) { + data['serviceRequestDetails'] = this.serviceRequestDetails!.toJson(); + } + if (this.surveyQuestions != null) { + data['surveyQuestions'] = this.surveyQuestions!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class SurveyType { + int? id; + String? name; + int? value; + + SurveyType({this.id, this.name, this.value}); + + SurveyType.fromJson(Map json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['name'] = this.name; + data['value'] = this.value; + return data; + } +} + +class ServiceRequestDetails { + int? serviceRequestTypeId; + String? serviceRequestType; + String? serviceRequestNo; + + ServiceRequestDetails({this.serviceRequestTypeId, this.serviceRequestType, this.serviceRequestNo}); + + ServiceRequestDetails.fromJson(Map json) { + serviceRequestTypeId = json['serviceRequestTypeId']; + serviceRequestType = json['serviceRequestType']; + serviceRequestNo = json['serviceRequestNo']; + } + + Map toJson() { + final Map data = new Map(); + data['serviceRequestTypeId'] = this.serviceRequestTypeId; + data['serviceRequestType'] = this.serviceRequestType; + data['serviceRequestNo'] = this.serviceRequestNo; + return data; + } +} + +class SurveyQuestions { + int? questionId; + String? questionText; + SurveyType? questionType; + List? surveyAnswerOptions; + + SurveyQuestions({this.questionId, this.questionText, this.questionType, this.surveyAnswerOptions}); + + SurveyQuestions.fromJson(Map json) { + questionId = json['questionId']; + questionText = json['questionText']; + questionType = json['questionType'] != null ? new SurveyType.fromJson(json['questionType']) : null; + if (json['surveyAnswerOptions'] != null) { + surveyAnswerOptions = []; + json['surveyAnswerOptions'].forEach((v) { + surveyAnswerOptions!.add(new SurveyAnswerOptions.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['questionId'] = this.questionId; + data['questionText'] = this.questionText; + if (this.questionType != null) { + data['questionType'] = this.questionType!.toJson(); + } + if (this.surveyAnswerOptions != null) { + data['surveyAnswerOptions'] = this.surveyAnswerOptions!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class SurveyAnswerOptions { + int? optionId; + String? optionText; + int? displayOrder; + + SurveyAnswerOptions({this.optionId, this.optionText, this.displayOrder}); + + SurveyAnswerOptions.fromJson(Map json) { + optionId = json['optionId']; + optionText = json['optionText']; + displayOrder = json['displayOrder']; + } + + Map toJson() { + final Map data = new Map(); + data['optionId'] = this.optionId; + data['optionText'] = this.optionText; + data['displayOrder'] = this.displayOrder; + return data; + } +} + +class SurveyAnswers { + int? questionId; + int? surveyAnswerOptionId; + String? surveyAnswerText; + int? surveyAnswerRating; + + SurveyAnswers({this.questionId, this.surveyAnswerOptionId, this.surveyAnswerText, this.surveyAnswerRating}); + + SurveyAnswers.fromJson(Map json) { + questionId = json['questionId']; + surveyAnswerOptionId = json['surveyAnswerOptionId']; + surveyAnswerText = json['surveyAnswerText']; + surveyAnswerRating = json['surveyAnswerRating']; + } + + Map toJson() { + final Map data = new Map(); + data['questionId'] = this.questionId; + data['surveyAnswerOptionId'] = this.surveyAnswerOptionId; + data['surveyAnswerText'] = this.surveyAnswerText; + data['surveyAnswerRating'] = this.surveyAnswerRating; + return data; + } +} diff --git a/lib/modules/cx_module/survey/survey_page.dart b/lib/modules/cx_module/survey/survey_page.dart index e6157a7f..75a3a28e 100644 --- a/lib/modules/cx_module/survey/survey_page.dart +++ b/lib/modules/cx_module/survey/survey_page.dart @@ -6,8 +6,10 @@ import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/helper/utils.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/modules/cx_module/chat/chat_rooms_page.dart'; +import 'package:test_sa/modules/cx_module/survey/questionnaire_model.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; @@ -29,18 +31,34 @@ class SurveyPage extends StatefulWidget { } class _SurveyPageState extends State { - int serviceSatisfiedRating = -1; + // int serviceSatisfiedRating = -1; int serviceProvidedRating = -1; String comments = ""; + bool loading = false; + + Questionnaire? questionnaire; + + List answers = []; + @override void initState() { super.initState(); getSurveyQuestion(); } - void getSurveyQuestion() { - Provider.of(context, listen: false).getQuestionnaire(widget.surveyId); + void getSurveyQuestion() async { + loading = true; + setState(() {}); + questionnaire = await Provider.of(context, listen: false).getQuestionnaire(widget.surveyId); + for (int i = 0; i < (questionnaire?.surveyQuestions?.length ?? 0); i++) { + answers.add(SurveyAnswers( + questionId: questionnaire!.surveyQuestions![i].questionId!, + surveyAnswerRating: -1, + )); + } + loading = false; + setState(() {}); } @override @@ -53,98 +71,135 @@ class _SurveyPageState extends State { return Scaffold( backgroundColor: AppColor.neutral100, appBar: const DefaultAppBar(title: "Survey"), - body: Column( - children: [ - SingleChildScrollView( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "How satisfied are you with our services?", - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50), - ), - 12.height, - SizedBox( - height: 32, - child: ListView.separated( - itemBuilder: (cxt, index) => (serviceSatisfiedRating >= index ? 'star_filled'.toSvgAsset() : 'star_empty'.toSvgAsset()).onPress(() { - setState(() { - serviceSatisfiedRating = index; - }); - }), - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - separatorBuilder: (cxt, index) => 8.width, - itemCount: 5, - scrollDirection: Axis.horizontal, - ), - ), - 16.height, - Text( - "Was the service provided promptly by our engineer?", - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50), - ), - 12.height, - SizedBox( - height: 32, - child: ListView.separated( - itemBuilder: (cxt, index) => (serviceProvidedRating >= index ? 'star_filled'.toSvgAsset() : 'star_empty'.toSvgAsset()).onPress(() { - setState(() { - serviceProvidedRating = index; - }); - }), - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - separatorBuilder: (cxt, index) => 8.width, - itemCount: 5, - scrollDirection: Axis.horizontal, - ), - ), - 16.height, - Text( - "Request Type", - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50), - ), - 16.height, - AppTextFormField( - initialValue: "", - textInputType: TextInputType.multiline, - alignLabelWithHint: true, - labelText: "Additional Comments", - backgroundColor: AppColor.fieldBgColor(context), - style: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff3B3D4A)), - labelStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff767676)), - floatingLabelStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff3B3D4A)), - showShadow: false, - onChange: (value) { - comments = value; + body: loading + ? const CircularProgressIndicator(color: AppColor.primary10, strokeWidth: 3).center + : (questionnaire == null) + ? Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + "Failed to get questionnaire", + overflow: TextOverflow.ellipsis, + maxLines: 1, + style: AppTextStyles.heading6.copyWith(color: AppColor.neutral50, fontWeight: FontWeight.w500), + ), + 24.height, + AppFilledButton( + label: "Retry", + maxWidth: true, + buttonColor: AppColor.primary10, + onPressed: () { + getSurveyQuestion(); + }, + ).paddingOnly(start: 48, end: 48) + ], + ).center + : Column( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) { + SurveyQuestions question = questionnaire!.surveyQuestions![index]; + return question.questionType?.value == 4 + ? Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + question.questionText ?? "", + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50), + ), + 12.height, + SizedBox( + height: 32, + child: ListView.separated( + itemBuilder: (cxt, _index) => (answers[index].surveyAnswerRating! >= _index ? 'star_filled'.toSvgAsset() : 'star_empty'.toSvgAsset()).onPress(() { + setState(() { + answers[index].surveyAnswerRating = _index; + // serviceSatisfiedRating = _index; + }); + }), + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + separatorBuilder: (cxt, index) => 8.width, + itemCount: 5, + scrollDirection: Axis.horizontal, + ), + ), + ], + ) + : AppTextFormField( + initialValue: answers[index].surveyAnswerText, + textInputType: TextInputType.multiline, + alignLabelWithHint: true, + labelText: questionnaire!.surveyQuestions![index].questionText, + backgroundColor: AppColor.fieldBgColor(context), + style: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff3B3D4A)), + labelStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff767676)), + floatingLabelStyle: + TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff3B3D4A)), + showShadow: false, + onChange: (value) { + answers[index].surveyAnswerText = value; + }, + ); + }, + separatorBuilder: (cxt, index) => 16.height, + itemCount: questionnaire?.surveyQuestions?.length ?? 0) + .toShadowContainer(context, borderRadius: 20, showShadow: false), + ).expanded, + FooterActionButton.footerContainer( + context: context, + child: AppFilledButton( + label: context.translation.submit, + buttonColor: AppColor.primary10, + onPressed: () async { + FocusScope.of(context).unfocus(); + if (validateAnswers()) { + Map payload = { + "surveySubmissionId": questionnaire!.surveySubmissionId, + "questionnaireId": questionnaire!.questionnaireId, + "submittedUserId": context.userProvider.user!.userID, + "surveySubmissionStatusId": 0, + "surveyAnswers": answers.map((element) => element.toJson()).toList(), + }; + Utils.showLoading(context); + bool isSuccess = await Provider.of(context, listen: false).submitQuestionare(payload); + Utils.hideLoading(context); + if (isSuccess) { + //getSurveyQuestion(); + } //reload Data + } }, ), - ], - ).toShadowContainer(context, borderRadius: 20, showShadow: false)) - .expanded, - FooterActionButton.footerContainer( - context: context, - child: AppFilledButton( - label: context.translation.submit, - buttonColor: AppColor.primary10, - onPressed: () { - if (serviceSatisfiedRating < 0) { - "Provide rate services satisfaction".showToast; - return; - } - if (serviceProvidedRating < 0) { - "Provide rate services provided by engineer".showToast; - return; - } - Navigator.push(context, MaterialPageRoute(builder: (context) => ChatRoomsPage())); - return; - }, - ), - ), - ], - ), + ), + ], + ), ); } + + bool validateAnswers() { + bool status = true; + for (int i = 0; i < answers.length; i++) { + if (questionnaire!.surveyQuestions![i].questionType!.value == 4) { + if (answers[i].surveyAnswerRating! < 0) { + "Please rate (${questionnaire!.surveyQuestions![i].questionText})".showToast; + status = false; + break; + } + } else if (questionnaire!.surveyQuestions![i].questionType!.value == 3) { + answers[i].surveyAnswerRating = null; + if ((answers[i].surveyAnswerText ?? "").isEmpty) { + "Please answer (${questionnaire!.surveyQuestions![i].questionText})".showToast; + status = false; + break; + } + } + } + return status; + } } diff --git a/lib/modules/cx_module/survey/survey_provider.dart b/lib/modules/cx_module/survey/survey_provider.dart index f9674c7c..f1a76a86 100644 --- a/lib/modules/cx_module/survey/survey_provider.dart +++ b/lib/modules/cx_module/survey/survey_provider.dart @@ -1,34 +1,44 @@ import 'dart:async'; +import 'dart:convert'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; + +import 'questionnaire_model.dart'; class SurveyProvider with ChangeNotifier { bool loading = false; void reset() { loading = false; + // questionnaire = null; // ChatApiClient().chatLoginResponse = null; } - Future getQuestionnaire(int surveySubmissionId) async { - reset(); - loading = true; - notifyListeners(); - final response = await ApiManager.instance.get(URLs.getQuestionnaire + "?surveySubmissionId=$surveySubmissionId"); - - loading = false; - - notifyListeners(); + Future getQuestionnaire(int surveySubmissionId) async { + try { + final response = await ApiManager.instance.get("${URLs.getQuestionnaire.toString().replaceFirst("/mobile/", "/api/")}?surveySubmissionId=$surveySubmissionId"); + if (response.statusCode >= 200 && response.statusCode < 300) { + return Questionnaire.fromJson(jsonDecode(response.body)["data"]); + } + } catch (ex) { + "Failed, Retry.".showToast; + } + return null; } -// Future loadChatHistory(int moduleId, int requestId) async { -// // loadChatHistoryLoading = true; -// // notifyListeners(); -// chatLoginResponse = await ChatApiClient().loadChatHistory(moduleId, requestId); -// loadChatHistoryLoading = false; -// notifyListeners(); -// } + Future submitQuestionare(Map payload) async { + try { + final response = await ApiManager.instance.post(URLs.submitSurvey.toString().replaceFirst("/mobile/", "/api/"), body: payload); + if (response.statusCode >= 200 && response.statusCode < 300) { + return true; + } + } catch (ex) { + "Failed, Retry.".showToast; + } + return false; + } }