chat connection improvements

design_3.0_cx_module
Sikander Saleem 2 months ago
parent 1cc5ebd9fb
commit 9d7c3a38b2

@ -351,4 +351,6 @@ class URLs {
//survey
static get getQuestionnaire => '$_baseUrl/SurveyQuestionnaire/GetQuestionnaire';
static get submitSurvey => '$_baseUrl/SurveyQuestionnaire/SubmitSurvey';
}

@ -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<String, dynamic> 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<String, dynamic> 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<String, dynamic> toJson() => {
"userId": userId,
"userName": userName,
"email": email,
"languageId": languageId,
};
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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 {

@ -93,7 +93,8 @@ class _ServiceRequestDetailMainState extends State<ServiceRequestDetailMain> {
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

@ -61,8 +61,8 @@ class ChatApiClient {
return chatLoginResponse;
}
Future<ChatParticipantModel?> 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<ChatParticipantModel?> 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<UserChatHistoryModel?> loadChatHistory(int moduleId, int referenceId, String myId, String otherId) async {
Future<List<ChatHistoryResponse>> 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 [];
}
}

@ -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<ChatPage> {
}
void getChatToken() {
String assigneeEmployeeNumber = "";
Provider.of<ChatProvider>(context, listen: false).getUserAutoLoginToken(widget.moduleId, widget.requestId + 2, widget.title, context.settingProvider.username, assigneeEmployeeNumber);
String assigneeEmployeeNumber = Provider.of<ServiceRequestDetailProvider>(context, listen: false).currentWorkOrder?.data?.assignedEmployee?.employeeId ?? "";
Provider.of<ChatProvider>(context, listen: false).getUserAutoLoginToken(widget.moduleId, widget.requestId, widget.title,
Provider.of<ServiceRequestDetailProvider>(context, listen: false).currentWorkOrder!.data!.workOrderContactPerson.first.employeeId!, assigneeEmployeeNumber);
}
@override

@ -113,7 +113,10 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin {
ChatParticipantModel? chatParticipantModel;
bool userChatHistoryLoading = false;
UserChatHistoryModel? userChatHistory;
// UserChatHistoryModel? userChatHistory;
List<ChatHistoryResponse>? userChatHistory;
bool messageIsSending = false;
@ -134,7 +137,7 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin {
ChatApiClient().chatLoginResponse = null;
}
Future<void> getUserAutoLoginToken(int moduleId, int requestId, String title, String employeeNumber, String? assigneeEmployeeNumber) async {
Future<void> 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<void> loadChatHistory(int moduleId, int requestId, String myId, String? assigneeEmployeeNumber) async {
Future<void> 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();

@ -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<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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<String, dynamic> json) {
fileTypeId = json['fileTypeId'];
fileTypeName = json['fileTypeName'];
fileTypeDescription = json['fileTypeDescription'];
fileKind = json['fileKind'];
fileName = json['fileName'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['fileTypeId'] = this.fileTypeId;
data['fileTypeName'] = this.fileTypeName;
data['fileTypeDescription'] = this.fileTypeDescription;
data['fileKind'] = this.fileKind;
data['fileName'] = this.fileName;
return data;
}
}

@ -0,0 +1,169 @@
class Questionnaire {
int? questionnaireId;
int? surveySubmissionId;
SurveyType? surveyType;
String? surveyName;
String? surveyDescription;
ServiceRequestDetails? serviceRequestDetails;
List<SurveyQuestions>? surveyQuestions;
Questionnaire({this.questionnaireId, this.surveySubmissionId, this.surveyType, this.surveyName, this.surveyDescription, this.serviceRequestDetails, this.surveyQuestions});
Questionnaire.fromJson(Map<String, dynamic> 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 = <SurveyQuestions>[];
json['surveyQuestions'].forEach((v) {
surveyQuestions!.add(new SurveyQuestions.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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<String, dynamic> json) {
id = json['id'];
name = json['name'];
value = json['value'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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<String, dynamic> json) {
serviceRequestTypeId = json['serviceRequestTypeId'];
serviceRequestType = json['serviceRequestType'];
serviceRequestNo = json['serviceRequestNo'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['serviceRequestTypeId'] = this.serviceRequestTypeId;
data['serviceRequestType'] = this.serviceRequestType;
data['serviceRequestNo'] = this.serviceRequestNo;
return data;
}
}
class SurveyQuestions {
int? questionId;
String? questionText;
SurveyType? questionType;
List<SurveyAnswerOptions>? surveyAnswerOptions;
SurveyQuestions({this.questionId, this.questionText, this.questionType, this.surveyAnswerOptions});
SurveyQuestions.fromJson(Map<String, dynamic> json) {
questionId = json['questionId'];
questionText = json['questionText'];
questionType = json['questionType'] != null ? new SurveyType.fromJson(json['questionType']) : null;
if (json['surveyAnswerOptions'] != null) {
surveyAnswerOptions = <SurveyAnswerOptions>[];
json['surveyAnswerOptions'].forEach((v) {
surveyAnswerOptions!.add(new SurveyAnswerOptions.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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<String, dynamic> json) {
optionId = json['optionId'];
optionText = json['optionText'];
displayOrder = json['displayOrder'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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<String, dynamic> json) {
questionId = json['questionId'];
surveyAnswerOptionId = json['surveyAnswerOptionId'];
surveyAnswerText = json['surveyAnswerText'];
surveyAnswerRating = json['surveyAnswerRating'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['questionId'] = this.questionId;
data['surveyAnswerOptionId'] = this.surveyAnswerOptionId;
data['surveyAnswerText'] = this.surveyAnswerText;
data['surveyAnswerRating'] = this.surveyAnswerRating;
return data;
}
}

@ -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<SurveyPage> {
int serviceSatisfiedRating = -1;
// int serviceSatisfiedRating = -1;
int serviceProvidedRating = -1;
String comments = "";
bool loading = false;
Questionnaire? questionnaire;
List<SurveyAnswers> answers = [];
@override
void initState() {
super.initState();
getSurveyQuestion();
}
void getSurveyQuestion() {
Provider.of<SurveyProvider>(context, listen: false).getQuestionnaire(widget.surveyId);
void getSurveyQuestion() async {
loading = true;
setState(() {});
questionnaire = await Provider.of<SurveyProvider>(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<SurveyPage> {
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<String, dynamic> 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<SurveyProvider>(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;
}
}

@ -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<void> getQuestionnaire(int surveySubmissionId) async {
reset();
loading = true;
notifyListeners();
final response = await ApiManager.instance.get(URLs.getQuestionnaire + "?surveySubmissionId=$surveySubmissionId");
loading = false;
notifyListeners();
Future<Questionnaire?> 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<void> loadChatHistory(int moduleId, int requestId) async {
// // loadChatHistoryLoading = true;
// // notifyListeners();
// chatLoginResponse = await ChatApiClient().loadChatHistory(moduleId, requestId);
// loadChatHistoryLoading = false;
// notifyListeners();
// }
Future<bool> submitQuestionare(Map<String, dynamic> 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;
}
}

Loading…
Cancel
Save