You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mohemm-flutter-app/lib/ui/landing/itg/survey_screen.dart

275 lines
10 KiB
Dart

import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.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:flutter/widgets.dart' as fw;
class SurveyScreen extends StatefulWidget {
const SurveyScreen({Key? key}) : super(key: key);
@override
_SurveyScreenState createState() => _SurveyScreenState();
}
class _SurveyScreenState extends State<SurveyScreen> {
String reviewText = "";
double starRating = 1;
int _selectedIndex = 0;
ItgResponseData? itgResponseData;
List<String> answeredQuestions = [];
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback(
(_) => initAnswersList(),
);
super.initState();
}
@override
Widget build(BuildContext context) {
itgResponseData ??= ModalRoute.of(context)!.settings.arguments as ItgResponseData;
return Scaffold(
backgroundColor: MyColors.backgroundColor,
body: Column(
children: [
Expanded(
child: Directionality(
textDirection: AppState().isArabic(context) ? fw.TextDirection.rtl : fw.TextDirection.ltr,
child: ListView(
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
32.height,
(AppState().isArabic(context) ? itgResponseData?.survey?.titleAr : itgResponseData?.survey?.title)?.toText24() ?? const Text(""),
8.height,
(AppState().isArabic(context) ? itgResponseData?.survey?.descriptionAr : 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(
LocaleKeys.submitSurvey.tr(),
() {
performAPI();
},
).insideContainer,
],
));
}
Widget optionUI(String icon, int? index, int answerIndex) {
return (_selectedIndex == index
? SvgPicture.asset(
'assets/images/' + icon,
height: 32,
width: 32,
).objectContainerBorderView(disablePadding: true, borderColor: MyColors.textMixColor, disableWidth: true, isAlignment: true)
: SvgPicture.asset(
'assets/images/' + icon,
height: 32,
width: 32,
).objectContainerView(
disablePadding: true,
))
.onPress(() {
_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,
(AppState().isArabic(context) ? question?.titleAr : question?.title)?.toText18() ?? const Text(""),
16.height,
GridView.builder(
padding: EdgeInsets.zero,
itemCount: question?.options?.length ?? 0,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return radioOption((AppState().isArabic(context) ? (question!.options![index].titleAr) : 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,
(AppState().isArabic(context) ? question?.titleAr : 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,
(AppState().isArabic(context) ? question?.titleAr : question?.title)?.toText18() ?? Text(""),
16.height,
GridView(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 5, crossAxisSpacing: 7, mainAxisSpacing: 7),
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.only(top: 0),
shrinkWrap: true,
children: [
for (int i = 0; i < (question?.options?.length ?? 0); i++) optionUI("${question?.options![i].title!.toLowerCase()}.svg", question?.options?[i].optionId, parentIndex),
// optionUI("poor.svg", question?.options?[0].optionId, parentIndex),
// optionUI("fair.svg", question?.options?[1].optionId, parentIndex),
// optionUI("ok.svg", question?.options?[2].optionId, parentIndex),
// optionUI("good.svg", question?.options?[3].optionId, parentIndex),
// optionUI("excellent.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 {
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) {
Utils.showToast("Survey has been submitted successfully");
Navigator.pop(context);
} else {
Utils.showToast(res.mohemmItgResponseItem!.message.toString());
}
} catch (ex) {
Utils.hideLoading(context);
Utils.handleException(ex, context, (msg) {
Utils.confirmDialog(context, msg);
});
}
}
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(() {});
});
}
}