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.
		
		
		
		
		
			
		
			
				
	
	
		
			275 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			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(() {});
 | |
|     });
 | |
|   }
 | |
| }
 |