Merge branch 'master_mohemm_flutter' into development_haroon

# Conflicts:
#	lib/app_state/app_state.dart
merge-requests/3/head
haroon amjad 2 years ago
commit f5957144d5

@ -90,7 +90,7 @@ class AppState {
String get getHuaweiPushToken => _huaweiPushToken;
final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 33, versionID: 4.6, mobileType: Platform.isAndroid ? "android" : "ios");
final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 33, versionID: 4.8, mobileType: Platform.isAndroid ? "android" : "ios");
void setPostParamsInitConfig() {
isAuthenticated = false;

@ -5,6 +5,7 @@
import 'dart:convert';
import 'package:mohem_flutter_app/models/itg/advertisement.dart';
import 'package:mohem_flutter_app/models/itg/survey_model.dart';
MohemmItgResponseItem mohemmItgResponseItemFromJson(String str) => MohemmItgResponseItem.fromJson(json.decode(str));
@ -103,7 +104,7 @@ class ItgResponseData {
final bool? isDeleted;
final bool? showDelete;
final Advertisement? advertisement;
final dynamic survey;
final SurveyModel? survey;
final dynamic isActive;
final dynamic pageSize;
final dynamic pageNo;
@ -126,7 +127,7 @@ class ItgResponseData {
isDeleted: json["isDeleted"] == null ? null : json["isDeleted"],
showDelete: json["showDelete"] == null ? null : json["showDelete"],
advertisement: json["advertisement"] == null ? null : Advertisement.fromJson(json["advertisement"]),
survey: json["survey"],
survey: json["survey"] == null ? null : SurveyModel.fromJson(json["survey"]),
isActive: json["isActive"],
pageSize: json["pageSize"],
pageNo: json["pageNo"],

@ -0,0 +1,148 @@
class SurveyModel {
int? surveyId;
String? referenceNo;
String? title;
String? description;
List<Questions>? questions;
bool? isActive;
Null? pageSize;
Null? pageNo;
Null? languageId;
SurveyModel({this.surveyId, this.referenceNo, this.title, this.description, this.questions, this.isActive, this.pageSize, this.pageNo, this.languageId});
SurveyModel.fromJson(Map<String, dynamic> json) {
surveyId = json['surveyId'];
referenceNo = json['referenceNo'];
title = json['title'];
description = json['description'];
if (json['questions'] != null) {
questions = <Questions>[];
json['questions'].forEach((v) {
questions!.add(new Questions.fromJson(v));
});
}
isActive = json['isActive'];
pageSize = json['pageSize'];
pageNo = json['pageNo'];
languageId = json['languageId'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['surveyId'] = this.surveyId;
data['referenceNo'] = this.referenceNo;
data['title'] = this.title;
data['description'] = this.description;
if (this.questions != null) {
data['questions'] = this.questions!.map((v) => v.toJson()).toList();
}
data['isActive'] = this.isActive;
data['pageSize'] = this.pageSize;
data['pageNo'] = this.pageNo;
data['languageId'] = this.languageId;
return data;
}
}
class Questions {
int? questionId;
String? title;
bool? isRequired;
String? type;
int? sequenceNo;
Null? surveyId;
List<Options>? options;
Null? rspPercentage;
Null? isActive;
Null? pageSize;
Null? pageNo;
Null? languageId;
Questions({this.questionId, this.title, this.isRequired, this.type, this.sequenceNo, this.surveyId, this.options, this.rspPercentage, this.isActive, this.pageSize, this.pageNo, this.languageId});
Questions.fromJson(Map<String, dynamic> json) {
questionId = json['questionId'];
title = json['title'];
isRequired = json['isRequired'];
type = json['type'];
sequenceNo = json['sequenceNo'];
surveyId = json['surveyId'];
if (json['options'] != null) {
options = <Options>[];
json['options'].forEach((v) {
options!.add(new Options.fromJson(v));
});
}
rspPercentage = json['rspPercentage'];
isActive = json['isActive'];
pageSize = json['pageSize'];
pageNo = json['pageNo'];
languageId = json['languageId'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['questionId'] = this.questionId;
data['title'] = this.title;
data['isRequired'] = this.isRequired;
data['type'] = this.type;
data['sequenceNo'] = this.sequenceNo;
data['surveyId'] = this.surveyId;
if (this.options != null) {
data['options'] = this.options!.map((v) => v.toJson()).toList();
}
data['rspPercentage'] = this.rspPercentage;
data['isActive'] = this.isActive;
data['pageSize'] = this.pageSize;
data['pageNo'] = this.pageNo;
data['languageId'] = this.languageId;
return data;
}
}
class Options {
int? optionId;
String? title;
bool? isCommentsRequired;
int? sequenceNo;
int? questionId;
Null? rspPercentage;
Null? count;
Null? isActive;
Null? pageSize;
Null? pageNo;
Null? languageId;
Options({this.optionId, this.title, this.isCommentsRequired, this.sequenceNo, this.questionId, this.rspPercentage, this.count, this.isActive, this.pageSize, this.pageNo, this.languageId});
Options.fromJson(Map<String, dynamic> json) {
optionId = json['optionId'];
title = json['title'];
isCommentsRequired = json['isCommentsRequired'];
sequenceNo = json['sequenceNo'];
questionId = json['questionId'];
rspPercentage = json['rspPercentage'];
count = json['count'];
isActive = json['isActive'];
pageSize = json['pageSize'];
pageNo = json['pageNo'];
languageId = json['languageId'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['optionId'] = this.optionId;
data['title'] = this.title;
data['isCommentsRequired'] = this.isCommentsRequired;
data['sequenceNo'] = this.sequenceNo;
data['questionId'] = this.questionId;
data['rspPercentage'] = this.rspPercentage;
data['count'] = this.count;
data['isActive'] = this.isActive;
data['pageSize'] = this.pageSize;
data['pageNo'] = this.pageNo;
data['languageId'] = this.languageId;
return data;
}
}

@ -162,7 +162,20 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
if (val!.result!.data != null) {
print("-------------------- Survey ----------------------------");
if (val.result!.data!.notificationType == "Survey") {
Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data);
DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then(
(value) {
if (value!.mohemmItgResponseItem!.statusCode == 200) {
if (value.mohemmItgResponseItem!.result!.data != null) {
// Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data);
Navigator.pushNamed(context, AppRoutes.survey, arguments: value.mohemmItgResponseItem!.result!.data);
// Navigator.pushNamed(context, AppRoutes.advertisement, arguments: {
// "masterId": val.result!.data!.notificationMasterId,
// "advertisement": value.mohemmItgResponseItem!.result!.data!.advertisement,
// });
}
}
},
);
} else {
print("------------------------------------------- Ads --------------------");
DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then(

@ -1,5 +1,3 @@
import 'dart:convert';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
@ -7,15 +5,14 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/itg/itg_main_response.dart';
import 'package:mohem_flutter_app/models/itg/itg_response_model.dart';
import 'package:mohem_flutter_app/models/itg/survey_model.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart';
class SurveyScreen extends StatefulWidget {
const SurveyScreen({Key? key}) : super(key: key);
@ -27,78 +24,50 @@ class SurveyScreen extends StatefulWidget {
class _SurveyScreenState extends State<SurveyScreen> {
String reviewText = "";
double starRating = 1;
int _selectedIndex = 5;
int _selectedIndex = 0;
ItgResponseData? itgResponseData;
List<String> answeredQuestions = [];
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback(
(_) => initAnswersList(),
);
super.initState();
}
@override
Widget build(BuildContext context) {
if (itgResponseData == null) itgResponseData = ModalRoute.of(context)!.settings.arguments as ItgResponseData;
itgResponseData ??= ModalRoute.of(context)!.settings.arguments as ItgResponseData;
return Scaffold(
backgroundColor: MyColors.backgroundColor,
body: Column(
children: [
Expanded(
child: ListView(
scrollDirection: Axis.vertical,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
124.height,
LocaleKeys.feedbackUserExperience.tr().toText19(),
27.height,
LocaleKeys.rateUI.tr().toText16(),
22.height,
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
RatingBar.builder(
initialRating: 3,
minRating: starRating,
direction: Axis.horizontal,
allowHalfRating: false,
itemCount: 5,
itemPadding: EdgeInsets.symmetric(horizontal: 8),
itemBuilder: (context, _) => Icon(
Icons.star,
color: Colors.amber,
),
onRatingUpdate: (rating) {
starRating = rating;
},
)
],
).paddingOnly(left: 22, right: 22, top: 12, bottom: 12).objectContainerView(disablePadding: true),
39.height,
LocaleKeys.rateUI2.tr().toText16(),
10.height,
GridView(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 5, crossAxisSpacing: 7, mainAxisSpacing: 7),
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.only(top: 0),
shrinkWrap: true,
children: [
optionUI("poor.svg", 1),
optionUI("bad.svg", 2),
optionUI("normal.svg", 3),
optionUI("good.svg", 4),
optionUI("xcellent.svg", 5),
],
),
27.height,
DynamicTextFieldWidget(
LocaleKeys.description.tr(),
LocaleKeys.typeHere.tr(),
lines: 3,
onChange: (v) {
reviewText = v;
},
),
150.height
],
).paddingOnly(left: 21, right: 21),
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
32.height,
itgResponseData?.survey?.title?.toText24() ?? const Text(""),
8.height,
itgResponseData?.survey?.description?.toText16() ?? const Text(""),
ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: itgResponseData?.survey?.questions?.length,
itemBuilder: (cxt, index) {
return answeredQuestions.isNotEmpty ? getSurveyWidget(itgResponseData?.survey?.questions![index], index) : Container();
},
),
],
).paddingOnly(left: 21, right: 21),
),
],
)),
DefaultButton(
@ -111,7 +80,7 @@ class _SurveyScreenState extends State<SurveyScreen> {
));
}
Widget optionUI(String icon, int index) {
Widget optionUI(String icon, int? index, int answerIndex) {
return (_selectedIndex == index
? SvgPicture.asset(
'assets/images/' + icon,
@ -126,22 +95,121 @@ class _SurveyScreenState extends State<SurveyScreen> {
disablePadding: true,
))
.onPress(() {
_selectedIndex = index;
_selectedIndex = index!;
answeredQuestions[answerIndex] = _selectedIndex.toString();
setState(() {});
});
}
void initAnswersList() {
answeredQuestions.clear();
itgResponseData?.survey?.questions?.forEach((element) {
if (element.type != "Stars") {
if(element.type == "Faces") {
_selectedIndex = element.options![0].optionId!;
}
answeredQuestions.add(element.options![0].optionId.toString());
} else {
answeredQuestions.add("4");
}
});
setState(() {});
}
Widget getSurveyWidget(Questions? question, int parentIndex) {
if (question?.type == "Expressions") {
// Expressions = radio buttons
return Column(
children: [
24.height,
question?.title?.toText18() ?? const Text(""),
16.height,
GridView.builder(
padding: EdgeInsets.zero,
itemCount: question?.options?.length,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return radioOption(question?.options?[index].title ?? "", question?.options?[index].optionId.toString() ?? "", answeredQuestions[parentIndex], parentIndex);
},
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: (4.0),
),
).paddingOnly(left: 22, right: 22, top: 12, bottom: 12).objectContainerView(disablePadding: true),
],
);
} else if (question?.type == "Stars") {
// Stars = star rating
return Column(
mainAxisSize: MainAxisSize.min,
children: [
24.height,
question?.title?.toText18() ?? Text(""),
16.height,
RatingBar.builder(
initialRating: 3,
minRating: starRating,
direction: Axis.horizontal,
allowHalfRating: false,
itemCount: 5,
itemPadding: const EdgeInsets.symmetric(horizontal: 8),
itemBuilder: (context, _) => const Icon(
Icons.star,
color: Colors.amber,
),
onRatingUpdate: (rating) {
starRating = rating;
answeredQuestions[parentIndex] = rating.toInt().toString();
},
).paddingOnly(left: 22, right: 22, top: 12, bottom: 12).objectContainerView(disablePadding: true),
],
);
} else if (question?.type == "Faces") {
// Faces = face rating
return Column(
mainAxisSize: MainAxisSize.min,
children: [
24.height,
question?.title?.toText18() ?? Text("asdasdasdasd"),
16.height,
GridView(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 5, crossAxisSpacing: 7, mainAxisSpacing: 7),
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.only(top: 0),
shrinkWrap: true,
children: [
optionUI("poor.svg", question?.options?[0].optionId, parentIndex),
optionUI("bad.svg", question?.options?[1].optionId, parentIndex),
optionUI("normal.svg", question?.options?[2].optionId, parentIndex),
optionUI("good.svg", question?.options?[3].optionId, parentIndex),
optionUI("xcellent.svg", question?.options?[4].optionId, parentIndex),
],
),
],
);
} else {
return Container();
}
return Container();
}
void performAPI() async {
Utils.showLoading(context);
List<Map<String, dynamic>> itgAnswersList = [];
int index = 0;
try {
ItgMainRes? res = await DashboardApiClient().submitItgForm(
comment: reviewText,
masterId: itgResponseData!.notificationMasterId ?? "",
itgList: [
{"questionId": "1", "optionId": null, "starRating": starRating},
{"questionId": "2", "optionId": "4", "starRating": _selectedIndex}
],
serviceId: itgResponseData!.serviceId ?? 0);
answeredQuestions.forEach((element) {
itgAnswersList.add({
"questionId": itgResponseData?.survey?.questions![index].questionId,
"optionId": itgResponseData?.survey?.questions![index].type != "Stars" ? answeredQuestions[index] : null,
"starRating": itgResponseData?.survey?.questions![index].type == "Stars" ? answeredQuestions[index] : null
});
index++;
});
ItgMainRes? res = await DashboardApiClient()
.submitItgForm(comment: reviewText, masterId: itgResponseData!.notificationMasterId ?? "", itgList: itgAnswersList, serviceId: itgResponseData!.survey!.surveyId ?? 0);
Utils.hideLoading(context);
if (res!.mohemmItgResponseItem!.statusCode == 200) {
@ -157,4 +225,41 @@ class _SurveyScreenState extends State<SurveyScreen> {
});
}
}
Widget radioOption(String title, String value, String groupValue, int answerIndex) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 24,
height: 24,
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(color: MyColors.borderColor, width: 1),
borderRadius: const BorderRadius.all(
Radius.circular(100),
),
),
padding: const EdgeInsets.all(4),
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
color: value == answeredQuestions[answerIndex] ? MyColors.greenColor : Colors.transparent,
borderRadius: const BorderRadius.all(
Radius.circular(100),
),
),
),
),
6.width,
title.toText12(color: MyColors.grey57Color),
12.width
],
).onPress(() {
answeredQuestions[answerIndex] = value;
setState(() {});
});
}
}

@ -329,7 +329,18 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
actionHistory.nAME!.toText16(),
if ((actionHistory.nOTE ?? "").isNotEmpty) "Note: ${actionHistory.nOTE!}".toText12(color: MyColors.grey57Color),
if ((actionHistory.nOTE ?? "").isNotEmpty)
SelectableText(
actionHistory.nOTE!,
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: MyColors.grey57Color,
letterSpacing: -0.72,
),
),
// "Note: ${actionHistory.nOTE!}".toText12(color: MyColors.grey57Color),
4.height,
Row(
children: [

@ -82,7 +82,20 @@ class ActionsFragment extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
actionHistory.nAME!.toText16(),
if ((actionHistory.nOTE ?? "").isNotEmpty) "Note: ${actionHistory.nOTE!}".toText12(color: MyColors.grey57Color),
if ((actionHistory.nOTE ?? "").isNotEmpty)
SelectableText(
actionHistory.nOTE!,
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: MyColors.grey57Color,
letterSpacing: -0.72,
),
),
// if ((actionHistory.nOTE ?? "").isNotEmpty) "Note: ${actionHistory.nOTE!}".toText12(color: MyColors.grey57Color),
4.height,
Row(
children: [

@ -26,6 +26,7 @@ import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart';
import 'package:mohem_flutter_app/widgets/qr_scanner_dialog.dart';
import 'package:nfc_manager/nfc_manager.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:platform_device_id/platform_device_id.dart';
import 'package:wifi_iot/wifi_iot.dart';
class MarkAttendanceWidget extends StatefulWidget {
@ -53,6 +54,8 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
}
void checkAttendanceAvailability() async {
String? deviceID = await PlatformDeviceId.getDeviceId;
print("Platform Device ID: $deviceID");
bool isAvailable = await NfcManager.instance.isAvailable();
setState(() {
AppState().privilegeListModel!.forEach((PrivilegeListModel element) {
@ -131,7 +134,7 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
children: <Widget>[
// if (isNfcEnabled)
attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () {
if (isNfcLocationEnabled) {
// if (isNfcLocationEnabled) {
if (AppState().getIsHuawei) {
checkHuaweiLocationPermission("NFC");
} else {
@ -143,13 +146,13 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
}
}, context);
}
} else {
performNfcAttendance(widget.model);
}
// } else {
// performNfcAttendance(widget.model);
// }
}),
if (isWifiEnabled)
attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () {
if (isWifiLocationEnabled) {
// if (isWifiLocationEnabled) {
if (AppState().getIsHuawei) {
checkHuaweiLocationPermission("WIFI");
} else {
@ -161,13 +164,13 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
}
}, context);
}
} else {
performWifiAttendance(widget.model);
}
// } else {
// performWifiAttendance(widget.model);
// }
}),
if (isQrEnabled)
attendanceMethod("QR", "assets/images/ic_qr.svg", isQrEnabled, () async {
if (isQrLocationEnabled) {
// if (isQrLocationEnabled) {
if (AppState().getIsHuawei) {
checkHuaweiLocationPermission("QR");
} else {
@ -179,9 +182,9 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
}
}, context);
}
} else {
performQrCodeAttendance(widget.model);
}
// } else {
// performQrCodeAttendance(widget.model);
// }
// performQrCodeAttendance(model);
}),
],

Loading…
Cancel
Save