diff --git a/assets/audio/success_tone_android.mp3 b/assets/audio/success_tone_android.mp3 new file mode 100644 index 0000000..b8ad93f Binary files /dev/null and b/assets/audio/success_tone_android.mp3 differ diff --git a/assets/audio/success_tone_ios.caf b/assets/audio/success_tone_ios.caf new file mode 100644 index 0000000..f2bcbaf Binary files /dev/null and b/assets/audio/success_tone_ios.caf differ diff --git a/assets/icons/ic_alarm.png b/assets/icons/ic_alarm.png new file mode 100644 index 0000000..5bc71e7 Binary files /dev/null and b/assets/icons/ic_alarm.png differ diff --git a/assets/images/attendance.svg b/assets/images/attendance.svg new file mode 100644 index 0000000..974fba3 --- /dev/null +++ b/assets/images/attendance.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/images/marathon_banner_bg.svg b/assets/images/marathon_banner_bg.svg index 9053afc..767a78c 100644 --- a/assets/images/marathon_banner_bg.svg +++ b/assets/images/marathon_banner_bg.svg @@ -28,87 +28,91 @@ - + + + + + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - + + - + - + - + @@ -117,121 +121,121 @@ - - + + - + - + - - - - - - - - - - + + + + + + + + + + - - + + - + - - - - + + + + - - + + - + - - + + - + - - - + + + - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - + - - + + - + - - - + + + - + - + - + @@ -239,19 +243,19 @@ - - - - - - - - + + + + + + + + - - + + - + @@ -271,10 +275,10 @@ - + - - + + @@ -302,8 +306,8 @@ - - + + diff --git a/assets/images/monthly_attendance.svg b/assets/images/monthly_attendance.svg index c84a9a1..b77ccc3 100644 --- a/assets/images/monthly_attendance.svg +++ b/assets/images/monthly_attendance.svg @@ -7,9 +7,9 @@ - - - + + + diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 66b1941..f72ea36 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -494,5 +494,9 @@ "fingersCrossed": "تشابك الاصابع!!!", "congrats": "مبروك !!!", "allQuestionsCorrect": "لقد أجبت على جميع الأسئلة بشكل صحيح.", + "otp": "OTP", + "verification": "تَحَقّق", + "resend": "إعادة إرسال", + "codeExpire": "انتهت صلاحية رمز التحقق", "typeheretoreply": "اكتب هنا للرد" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 9ed1190..e0b9019 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -284,7 +284,7 @@ "add": "Add", "edit": "Edit", "myProfile": "My Profile", - "mowadhafhi": "Mowadhafhi", + "mowadhafhi": "Mowadhafi", "searchAnnouncements": "Search Announcements", "announcements": "Announcements", "swipeRequest": "Swipe Request", @@ -493,6 +493,10 @@ "winnerSelectedRandomly": "The winner will be selected randomly among the qualifiers.", "fingersCrossed": "Fingers Crossed!!!", "congrats": "Congratulations!!!", + "otp": "OTP", + "verification": "Verification", + "resend": "Resend", + "codeExpire": "The verification code has been expired", "allQuestionsCorrect": "You have answered all questions correct", "typeheretoreply": "Type here to reply" } \ No newline at end of file diff --git a/assets/lottie/loading.json b/assets/lottie/loading.json index 8190459..ea7bff3 100644 --- a/assets/lottie/loading.json +++ b/assets/lottie/loading.json @@ -1 +1 @@ -{"v":"5.8.1","fr":30,"ip":0,"op":60,"w":300,"h":300,"nm":"loading_6","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":60,"s":[360]}],"ix":10},"p":{"a":0,"k":[150.00000000000003,150.00000000000003,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[30.000000000000004,30.000000000000004,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.12941176470588237,0.7411764705882353,0.7764705882352941,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[0]},{"t":60,"s":[99]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[1]},{"t":50,"s":[100]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":60,"s":[3]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":30,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150.00000000000003,150.00000000000003,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[30.000000000000004,30.000000000000004,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.7450980392156863,0.9254901960784314,0.9372549019607843,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0}],"markers":[]} \ No newline at end of file +{"v":"5.8.1","fr":30,"ip":0,"op":60,"w":100,"h":100,"nm":"loading_6","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":60,"s":[360]}],"ix":10},"p":{"a":0,"k":[50.00000000000002,50.00000000000002,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[10.000000000000004,10.000000000000004,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.12941176470588237,0.7411764705882353,0.7764705882352941,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[0]},{"t":60,"s":[99]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[1]},{"t":50,"s":[100]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":60,"s":[3]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":30,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50.00000000000002,50.00000000000002,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[10.000000000000004,10.000000000000004,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.7450980392156863,0.9254901960784314,0.9372549019607843,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/lib/classes/colors.dart b/lib/classes/colors.dart index e670bbc..b77e7b1 100644 --- a/lib/classes/colors.dart +++ b/lib/classes/colors.dart @@ -29,6 +29,7 @@ class MyColors { static const Color darkWhiteColor = Color(0xffE0E0E0); static const Color redColor = Color(0xffD02127); static const Color pinkColor = Color(0xffEBA9A9); + static const Color pinkDarkColor = Color(0xffe3797d); static const Color yellowColor = Color(0xffF4E31C); static const Color orange = Color(0xFFCC9B14); static const Color yellowFavColor = Color(0xffEAC321); @@ -58,4 +59,5 @@ class MyColors { static const Color greyC4Color = Color(0xffC4C4C4); static const Color grey35Color = Color(0xff535353); static const Color grey9DColor = Color(0xff9D9D9D); + static const Color darkDigitColor = Color(0xff2D2F39); } diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index e82c30a..eea2481 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,7 +1,7 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server - static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - // static String baseUrl = "https://hmgwebservices.com"; // Live server + // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; diff --git a/lib/dialogs/otp_dialog.dart b/lib/dialogs/otp_dialog.dart index 23c7c67..3952e70 100644 --- a/lib/dialogs/otp_dialog.dart +++ b/lib/dialogs/otp_dialog.dart @@ -7,7 +7,9 @@ import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/otp_widget.dart'; +import 'package:sizer/sizer.dart'; class OtpDialog { final int type; @@ -15,6 +17,7 @@ class OtpDialog { final Function(String) onSuccess; final Function onFailure; final BuildContext context; + final Function onResendCode; int remainingTime = 120; @@ -24,13 +27,7 @@ class OtpDialog { static bool? _loading; - OtpDialog( - this.context, - this.type, - this.mobileNo, - this.onSuccess, - this.onFailure, - ); + OtpDialog(this.context, this.type, this.mobileNo, this.onSuccess, this.onFailure, {required this.onResendCode}); GlobalKey? verifyAccountForm = GlobalKey(); @@ -69,7 +66,7 @@ class OtpDialog { // projectProvider = Provider.of(context); return Dialog( backgroundColor: Colors.white, - shape: const RoundedRectangleBorder(), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), insetPadding: const EdgeInsets.only(left: 21, right: 21), child: StatefulBuilder(builder: (context, setState) { if (displayTime == '') { @@ -77,37 +74,26 @@ class OtpDialog { } return Container( - padding: EdgeInsets.only(left: 21, right: 18, top: 39, bottom: 59), + padding: EdgeInsets.all(21), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SvgPicture.asset( - type == 1 - ? "assets/images/login/verify_sms.svg" - : type == 2 - ? "assets/images/login/verify_whatsapp.svg" - : type == 3 - ? "assets/images/login/verify_face.svg" - : 'assets/images/login/verify_thumb.svg', - height: 50, - width: 50, - ), - IconButton( - padding: EdgeInsets.zero, - icon: const Icon(Icons.close), - constraints: const BoxConstraints(), - onPressed: () { - stopTimer = true; - onFailure(); - }) - ], + SvgPicture.asset( + type == 1 + ? "assets/images/login/verify_sms.svg" + : type == 2 + ? "assets/images/login/verify_whatsapp.svg" + : type == 3 + ? "assets/images/login/verify_face.svg" + : 'assets/images/login/verify_thumb.svg', + height: 50, + width: 50, ), - 22.height, + 12.height, + LocaleKeys.otp.tr().toText14(), + LocaleKeys.verification.tr().toText24(isBold: true), + 6.height, (LocaleKeys.pleaseEnterTheVerificationCodeSentTo.tr() + ' xxxxxxxx' + mobileNo.toString().substring(mobileNo.toString().length - 3)).toText16(), 18.height, Directionality( @@ -132,18 +118,55 @@ class OtpDialog { ), ), ), - 30.height, - RichText( - text: TextSpan( - text: LocaleKeys.theVerificationCodeWillExpireIn.tr() + '\n', - style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.darkTextColor, letterSpacing: -0.48), - children: [ - TextSpan( - text: displayTime, - style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.textMixColor, letterSpacing: -0.48), + 10.height, + stopTimer + ? Row( + children: [ + Expanded( + child: LocaleKeys.codeExpire.tr().toText16( + color: MyColors.redColor, + ), + ), + 12.width, + Image.asset( + "assets/icons/ic_alarm.png", + width: 20, + height: 20, + color: MyColors.redColor, + ), + ], + ) + : RichText( + text: TextSpan( + text: LocaleKeys.theVerificationCodeWillExpireIn.tr() + '\n', + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.darkTextColor, letterSpacing: -0.48), + children: [ + TextSpan( + text: displayTime, + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.textMixColor, letterSpacing: -0.48), + ), + ], + ), ), - ], - ), + 18.height, + DefaultButton( + stopTimer ? LocaleKeys.resend.tr() : LocaleKeys.cancel.tr(), + () async { + if (stopTimer) { + hideSMSBox(context); + onResendCode(); + } else { + stopTimer = true; + // onFailure(); + hideSMSBox(context); + } + }, + colors: stopTimer + ? null + : [ + MyColors.pinkDarkColor, + MyColors.pinkDarkColor, + ], ), ], ), @@ -208,7 +231,9 @@ class OtpDialog { if (remainingTime > 0) { startTimer(setState); } else { - Navigator.pop(context); + setState(() { + stopTimer = true; + }); } }); } diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 6b702f8..e9dd08c 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -509,7 +509,12 @@ class CodegenLoader extends AssetLoader{ "winnerSelectedRandomly": "سيتم اختيار الفائز عشوائياً من بين التصفيات.", "fingersCrossed": "تشابك الاصابع!!!", "congrats": "مبروك !!!", - "allQuestionsCorrect": "لقد أجبت على جميع الأسئلة بشكل صحيح." + "allQuestionsCorrect": "لقد أجبت على جميع الأسئلة بشكل صحيح.", + "otp": "OTP", + "verification": "تَحَقّق", + "resend": "إعادة إرسال", + "codeExpire": "انتهت صلاحية رمز التحقق", + "typeheretoreply": "اكتب هنا للرد" }; static const Map en_US = { "mohemm": "Mohemm", @@ -797,7 +802,7 @@ static const Map en_US = { "add": "Add", "edit": "Edit", "myProfile": "My Profile", - "mowadhafhi": "Mowadhafhi", + "mowadhafhi": "Mowadhafi", "searchAnnouncements": "Search Announcements", "announcements": "Announcements", "swipeRequest": "Swipe Request", @@ -809,7 +814,7 @@ static const Map en_US = { "relatedTopic": "Related Topic", "selectTopic": "Select Topic", "supportingDocument": "Supporting Document", - "mowadhafhiRequest": "Mowadhafhi Request", + "mowadhafhiRequest": "Mowadhafi Request", "ticketReference": "Ticket Reference", "section": "Section", "topic": "Topic", @@ -1006,7 +1011,12 @@ static const Map en_US = { "winnerSelectedRandomly": "The winner will be selected randomly among the qualifiers.", "fingersCrossed": "Fingers Crossed!!!", "congrats": "Congratulations!!!", - "allQuestionsCorrect": "You have answered all questions correct" + "otp": "OTP", + "verification": "Verification", + "resend": "Resend", + "codeExpire": "The verification code has been expired", + "allQuestionsCorrect": "You have answered all questions correct", + "typeheretoreply": "Type here to reply" }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index b2f3efe..f52bb89 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -480,6 +480,10 @@ abstract class LocaleKeys { static const fingersCrossed = 'fingersCrossed'; static const congrats = 'congrats'; static const allQuestionsCorrect = 'allQuestionsCorrect'; + static const otp = 'otp'; + static const verification = 'verification'; + static const resend = 'resend'; + static const codeExpire = 'codeExpire'; static const typeheretoreply = 'typeheretoreply'; } diff --git a/lib/ui/attendance/monthly_attendance_screen.dart b/lib/ui/attendance/monthly_attendance_screen.dart index 439a5f4..de35da0 100644 --- a/lib/ui/attendance/monthly_attendance_screen.dart +++ b/lib/ui/attendance/monthly_attendance_screen.dart @@ -287,7 +287,6 @@ class _MonthlyAttendanceScreenState extends State { cellBorderColor: Colors.white, selectionDecoration: BoxDecoration( border: Border.all(color: MyColors.white, width: 10), - borderRadius: const BorderRadius.all(Radius.circular(100)), shape: BoxShape.circle, ), dataSource: MeetingDataSource(_getDataSource()), diff --git a/lib/ui/dialogs/success_dialog.dart b/lib/ui/dialogs/success_dialog.dart index 8e1de54..5150110 100644 --- a/lib/ui/dialogs/success_dialog.dart +++ b/lib/ui/dialogs/success_dialog.dart @@ -1,11 +1,41 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; +import 'package:just_audio/just_audio.dart'; import 'package:lottie/lottie.dart'; -class SuccessDialog extends StatelessWidget { +class SuccessDialog extends StatefulWidget { bool isFromDashboard; SuccessDialog(this.isFromDashboard); + @override + State createState() => _SuccessDialogState(); +} + +class _SuccessDialogState extends State with TickerProviderStateMixin { + late AnimationController _controller; + + @override + void initState() { + _controller = AnimationController(vsync: this); + + super.initState(); + } + + Future playSuccessSound() async { + AudioPlayer player = AudioPlayer(); + String audioAsset = ""; + if (Platform.isAndroid) { + audioAsset = "assets/audio/success_tone_android.mp3"; + } else { + audioAsset = "assets/audio/success_tone_ios.caf"; + } + await player.setAsset(audioAsset); + await player.load(); + player.play(); + } + @override Widget build(BuildContext context) { double size = MediaQuery.of(context).size.width / 1.8; @@ -18,13 +48,22 @@ class SuccessDialog extends StatelessWidget { width: size, height: size, child: Card( - child: Lottie.asset('assets/lottie/lt_success.json', repeat: false, reverse: false, onLoaded: (v) { - print("calling_lottie " + v.seconds.toString()); - Future.delayed(Duration(seconds: 2)).then((value) { - Navigator.pop(context); - if (isFromDashboard) Navigator.pop(context); - }); - }), + child: Lottie.asset( + 'assets/lottie/lt_success.json', + repeat: false, + reverse: false, + controller: _controller, + onLoaded: (LottieComposition v) async { + print("calling_lottie " + v.seconds.toString()); + await playSuccessSound(); + _controller + ..duration = v.duration + ..forward().whenComplete(() async { + Navigator.pop(context); + if (widget.isFromDashboard) Navigator.pop(context); + }); + }, + ), ), ), ], diff --git a/lib/ui/landing/widget/services_widget.dart b/lib/ui/landing/widget/services_widget.dart index d822920..0b257c5 100644 --- a/lib/ui/landing/widget/services_widget.dart +++ b/lib/ui/landing/widget/services_widget.dart @@ -22,8 +22,8 @@ class ServicesWidget extends StatelessWidget { "assets/images/monthly_attendance.svg", "assets/images/monthly_attendance.svg", "assets/images/ticket_request.svg", - "assets/images/ticket_request.svg", - "assets/images/ticket_request.svg", + "assets/images/ticket_bal.svg", + "assets/images/vacation_rule.svg", "assets/images/ticket_request.svg", "assets/images/ticket_request.svg", "assets/images/ticket_request.svg" diff --git a/lib/ui/leave_balance/add_leave_balance_screen.dart b/lib/ui/leave_balance/add_leave_balance_screen.dart index 864a507..85337aa 100644 --- a/lib/ui/leave_balance/add_leave_balance_screen.dart +++ b/lib/ui/leave_balance/add_leave_balance_screen.dart @@ -92,7 +92,7 @@ class _AddLeaveBalanceScreenState extends State { } void validateAbsenceTransaction() async { - // try { + try { Utils.showLoading(context); Map dffDataMap = {}; for (int i = 1; i <= 20; i++) { @@ -100,7 +100,8 @@ class _AddLeaveBalanceScreenState extends State { for (int dffIndex = 0; dffIndex < getabsenceDffStructureList.length; dffIndex++) { if ("ATTRIBUTE$i" == getabsenceDffStructureList[dffIndex].aPPLICATIONCOLUMNNAME) { if (getabsenceDffStructureList[dffIndex].fORMATTYPE == "X") { - dffDataMap["P_ATTRIBUTE$i"] = getabsenceDffStructureList[dffIndex].eSERVICESDV!.pIDCOLUMNNAME != null ? Utils.formatDate(getabsenceDffStructureList[dffIndex].eSERVICESDV!.pIDCOLUMNNAME!) : ""; + dffDataMap["P_ATTRIBUTE$i"] = + getabsenceDffStructureList[dffIndex].eSERVICESDV!.pIDCOLUMNNAME != null ? Utils.formatDate(getabsenceDffStructureList[dffIndex].eSERVICESDV!.pIDCOLUMNNAME!) : ""; } else { dffDataMap["P_ATTRIBUTE$i"] = getabsenceDffStructureList[dffIndex].eSERVICESDV?.pIDCOLUMNNAME; } @@ -108,9 +109,17 @@ class _AddLeaveBalanceScreenState extends State { } } } - await LeaveBalanceApiClient().validateAbsenceTransaction(selectedAbsenceType!.dESCFLEXCONTEXTCODE!, "HR_LOA_SS", selectedAbsenceType!.aBSENCEATTENDANCETYPEID!, - selectedReplacementEmployee != null ? selectedReplacementEmployee!.userName! : "", DateUtil.getFormattedDate(startDateTime!, "MM/dd/yyyy"), DateUtil.getFormattedDate(endDateTime!, "MM/dd/yyyy"), -999, dffDataMap, - comments: comment); + await LeaveBalanceApiClient() + .validateAbsenceTransaction( + selectedAbsenceType!.dESCFLEXCONTEXTCODE!, + "HR_LOA_SS", + selectedAbsenceType!.aBSENCEATTENDANCETYPEID!, + selectedReplacementEmployee != null ? selectedReplacementEmployee!.userName! : "", + DateUtil.getFormattedDate(startDateTime!, "MM/dd/yyyy"), + DateUtil.getFormattedDate(endDateTime!, "MM/dd/yyyy"), + -999, + dffDataMap, + comments: comment); SumbitAbsenceTransactionList submit = await LeaveBalanceApiClient().submitAbsenceTransaction( selectedAbsenceType!.dESCFLEXCONTEXTCODE!, @@ -126,13 +135,13 @@ class _AddLeaveBalanceScreenState extends State { Utils.hideLoading(context); await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submit.pTRANSACTIONID!, "", "add_leave_balance")); - // Utils.showLoading(context); + Utils.showLoading(context); await LeaveBalanceApiClient().cancelHrTransaction(submit.pTRANSACTIONID!); - // Utils.hideLoading(context); - // } catch (ex) { - // Utils.hideLoading(context); - // Utils.handleException(ex, context, null); - // } + Utils.hideLoading(context); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } } @override @@ -221,7 +230,7 @@ class _AddLeaveBalanceScreenState extends State { onTap: () { showMyBottomSheet( context, - callBackFunc: (){}, + callBackFunc: () {}, child: SearchEmployeeBottomSheet( title: LocaleKeys.searchForEmployee.tr(), apiMode: LocaleKeys.delegate.tr(), diff --git a/lib/ui/login/forgot_password_screen.dart b/lib/ui/login/forgot_password_screen.dart index f058d43..6c1868e 100644 --- a/lib/ui/login/forgot_password_screen.dart +++ b/lib/ui/login/forgot_password_screen.dart @@ -65,11 +65,14 @@ class _ForgotPasswordScreenState extends State { () => { Navigator.pop(context), }, + onResendCode: () { + performForgotPassword(); + }, ).displayDialog(context); } catch (ex) { print(ex); Utils.hideLoading(context); - Utils.handleException(ex, context, null); + Utils.handleException(ex, context, null); } } diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 0c4e268..20fa8bc 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -145,8 +145,8 @@ class _LoginScreenState extends State { // username.text = "15153"; // Tamer User // password.text = "Abcd@12345"; - username.text = "210038"; // Hashim User - password.text = "123"; + // username.text = "206535"; // Hashim User + // password.text = "Namira786"; } if (isAppOpenBySystem!) checkFirebaseToken(); } diff --git a/lib/ui/login/verify_last_login_screen.dart b/lib/ui/login/verify_last_login_screen.dart index 4d653ed..6e51e51 100644 --- a/lib/ui/login/verify_last_login_screen.dart +++ b/lib/ui/login/verify_last_login_screen.dart @@ -57,30 +57,21 @@ class _VerifyLastLoginScreenState extends State { @override Widget build(BuildContext context) { - mobileLoginInfoListModel ??= ModalRoute.of(context)!.settings.arguments - as GetMobileLoginInfoListModel; - String empName = AppState().isArabic(context) - ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr! - : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn!; + mobileLoginInfoListModel ??= ModalRoute.of(context)!.settings.arguments as GetMobileLoginInfoListModel; + String empName = AppState().isArabic(context) ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr! : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn!; return Scaffold( appBar: AppBar( backgroundColor: Colors.transparent, automaticallyImplyLeading: false, title: (mobileLoginInfoListModel?.businessCardPrivilege ?? false) - ? LocaleKeys.viewBusinessCard - .tr() - .toText12(color: MyColors.textMixColor, isUnderLine: true) - .onPress(() { + ? LocaleKeys.viewBusinessCard.tr().toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() { showMDialog(context, child: BusinessCardDialog()); }) : null, actions: [ Center( - child: LocaleKeys.employeeDigitalID - .tr() - .toText12(color: MyColors.textMixColor, isUnderLine: true) - .onPress(() { + child: LocaleKeys.employeeDigitalID.tr().toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() { showMDialog(context, child: EmployeeDigitialIdDialog()); })), 21.width @@ -99,12 +90,9 @@ class _VerifyLastLoginScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.welcomeBack.tr().toText12(), - mobileLoginInfoListModel!.employeeName! - .toText24(isBold: true), + mobileLoginInfoListModel!.employeeName!.toText24(isBold: true), 10.height, - LocaleKeys.wouldYouLikeToLoginWithCurrentUsername - .tr() - .toText16(), + LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText16(), Container( height: 72, margin: const EdgeInsets.only(top: 23, bottom: 23), @@ -126,42 +114,26 @@ class _VerifyLastLoginScreenState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ LocaleKeys.lastLoginDetails.tr().toText16(), - DateUtil.formatDateToDate( - DateUtil.convertStringToDate( - mobileLoginInfoListModel!.editedOn!), - false) - .toText12(), + DateUtil.formatDateToDate(DateUtil.convertStringToDate(mobileLoginInfoListModel!.editedOn!), false).toText12(), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ - LocaleKeys.verificationType - .tr() - .toText10(color: MyColors.grey57Color), - getVerificationType( - mobileLoginInfoListModel!.loginType!) - .toText12(), + LocaleKeys.verificationType.tr().toText10(color: MyColors.grey57Color), + getVerificationType(mobileLoginInfoListModel!.loginType!).toText12(), Expanded(child: SizedBox()), - DateUtil.formatDateToTime( - DateUtil.convertStringToDate( - mobileLoginInfoListModel!.editedOn!)) - .toText12(), + DateUtil.formatDateToTime(DateUtil.convertStringToDate(mobileLoginInfoListModel!.editedOn!)).toText12(), ], ) ], ), ), LocaleKeys.pleaseVerify.tr().toText16(), - if (isNeedVerifyWithFaceIDAndBiometrics) - LocaleKeys.pleaseVerifyForBio.tr().toText12(), + if (isNeedVerifyWithFaceIDAndBiometrics) LocaleKeys.pleaseVerifyForBio.tr().toText12(), GridView( - gridDelegate: - const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - crossAxisSpacing: 13, - mainAxisSpacing: 9), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsets.only(top: 9), shrinkWrap: true, @@ -214,9 +186,7 @@ class _VerifyLastLoginScreenState extends State { DefaultButton( LocaleKeys.useAnotherAccount.tr(), () { - Navigator.pushNamedAndRemoveUntil( - context, AppRoutes.login, (Route route) => false, - arguments: false); + Navigator.pushNamedAndRemoveUntil(context, AppRoutes.login, (Route route) => false, arguments: false); }, ).insideContainer, ], @@ -248,19 +218,11 @@ class _VerifyLastLoginScreenState extends State { } Future loginWithFaceIDAndBiometrics() async { - IOSAuthMessages iosStrings = const IOSAuthMessages( - cancelButton: 'cancel', - goToSettingsButton: 'settings', - goToSettingsDescription: 'Please set up your Touch ID.', - lockOut: 'Please reenable your Touch ID'); + IOSAuthMessages iosStrings = + const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); bool authenticated = false; try { - authenticated = await auth.authenticate( - localizedReason: 'Scan your fingerprint to authenticate', - useErrorDialogs: true, - stickyAuth: true, - biometricOnly: true, - iOSAuthStrings: iosStrings); + authenticated = await auth.authenticate(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, biometricOnly: true, iOSAuthStrings: iosStrings); } on PlatformException catch (e) { print(e); Utils.hideLoading(context); @@ -269,11 +231,8 @@ class _VerifyLastLoginScreenState extends State { return authenticated; } - Widget _loginOptionButton( - String _title, String _icon, int _flag, int? _loginIndex) { - bool isDisable = ((_flag == 3 && - !checkBiometricIsAvailable(BiometricType.face)) || - (_flag == 4 && !checkBiometricIsAvailable(BiometricType.fingerprint))); + Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) { + bool isDisable = ((_flag == 3 && !checkBiometricIsAvailable(BiometricType.face)) || (_flag == 4 && !checkBiometricIsAvailable(BiometricType.fingerprint))); return InkWell( onTap: isDisable ? null @@ -284,21 +243,18 @@ class _VerifyLastLoginScreenState extends State { }); } else { if (_flag == 3 || _flag == 4) { - bool authenticateWithFaceAndTouchID = - await loginWithFaceIDAndBiometrics(); + bool authenticateWithFaceAndTouchID = await loginWithFaceIDAndBiometrics(); if (!authenticateWithFaceAndTouchID) { return; } else { - if (mobileLoginInfoListModel!.loginType == 3 || - mobileLoginInfoListModel!.loginType == 4) { + if (mobileLoginInfoListModel!.loginType == 3 || mobileLoginInfoListModel!.loginType == 4) { // bool authenticateWithFaceAndTouchID = await loginWithFaceIDAndBiometrics(); // if (!authenticateWithFaceAndTouchID) { // return; // } else { // performApiCall(_title, _icon, _flag, isDirectLogin: true); // } - performApiCall(_title, _icon, _flag, _flag, - isDirectLogin: true); + performApiCall(_title, _icon, _flag, _flag, isDirectLogin: true); } else { isNeedVerifyWithFaceIDAndBiometrics = true; selectedFlag = _flag; @@ -316,8 +272,7 @@ class _VerifyLastLoginScreenState extends State { } }, child: Container( - padding: - const EdgeInsets.only(left: 20, right: 20, bottom: 15, top: 28), + padding: const EdgeInsets.only(left: 20, right: 20, bottom: 15, top: 28), decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: isDisable ? Colors.grey.withOpacity(0.3) : Colors.white, @@ -343,23 +298,13 @@ class _VerifyLastLoginScreenState extends State { Widget getButton(int flag) { switch (flag) { case 1: - return _loginOptionButton(LocaleKeys.verifyThroughSMS.tr(), - 'assets/images/login/verify_sms.svg', flag, null); + return _loginOptionButton(LocaleKeys.verifyThroughSMS.tr(), 'assets/images/login/verify_sms.svg', flag, null); case 2: - return _loginOptionButton(LocaleKeys.verifyThroughWhatsapp.tr(), - 'assets/images/login/verify_whatsapp.svg', flag, null); + return _loginOptionButton(LocaleKeys.verifyThroughWhatsapp.tr(), 'assets/images/login/verify_whatsapp.svg', flag, null); case 3: - return _loginOptionButton( - LocaleKeys.verifyThroughFace.tr(), - 'assets/images/login/verify_face.svg', - flag, - BiometricType.face.index); + return _loginOptionButton(LocaleKeys.verifyThroughFace.tr(), 'assets/images/login/verify_face.svg', flag, BiometricType.face.index); case 4: - return _loginOptionButton( - LocaleKeys.verifyThroughFingerprint.tr(), - 'assets/images/login/verify_thumb.svg', - flag, - BiometricType.fingerprint.index); + return _loginOptionButton(LocaleKeys.verifyThroughFingerprint.tr(), 'assets/images/login/verify_thumb.svg', flag, BiometricType.fingerprint.index); default: return const SizedBox(); } @@ -376,9 +321,7 @@ class _VerifyLastLoginScreenState extends State { return isAvailable; } - Future performApiCall( - String _title, String _icon, int _flag, int sendVerificationFlat, - {bool isDirectLogin = false}) async { + Future performApiCall(String _title, String _icon, int _flag, int sendVerificationFlat, {bool isDirectLogin = false}) async { try { if (isDirectLogin) setState(() { @@ -387,16 +330,10 @@ class _VerifyLastLoginScreenState extends State { else Utils.showLoading(context); await LoginApiClient().checkMobileAppVersion(); - await LoginApiClient() - .memberLogin(AppState().getUserName!, AppState().password!); + await LoginApiClient().memberLogin(AppState().getUserName!, AppState().password!); if (!isDirectLogin) BasicMemberInformationModel? memberInformationModel = - await LoginApiClient() - .mohemmSendActivationCodeByOTPNotificationType( - 0, - AppState().memberLoginList?.pMOBILENUMBER, - sendVerificationFlat, - AppState().getUserName); + await LoginApiClient().mohemmSendActivationCodeByOTPNotificationType(0, AppState().memberLoginList?.pMOBILENUMBER, sendVerificationFlat, AppState().getUserName); if (isDirectLogin) performDirectApiCall(_title, _icon, _flag, ""); if (!isDirectLogin) Utils.hideLoading(context); if (!isDirectLogin) @@ -411,6 +348,9 @@ class _VerifyLastLoginScreenState extends State { () => { Navigator.pop(context), }, + onResendCode: () { + performApiCall(_title, _icon, _flag, sendVerificationFlat, isDirectLogin: isDirectLogin); + }, ).displayDialog(context); } catch (ex) { Utils.hideLoading(context); @@ -418,34 +358,26 @@ class _VerifyLastLoginScreenState extends State { } } - Future performDirectApiCall( - String _title, String _icon, int _flag, String value, - {bool isDirectLogin = false}) async { + Future performDirectApiCall(String _title, String _icon, int _flag, String value, {bool isDirectLogin = false}) async { try { - GenericResponseModel? genericResponseModel = await LoginApiClient() - .checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, - value, AppState().getUserName); - GenericResponseModel? genericResponseModel1 = await LoginApiClient() - .insertMobileLoginInfoNEW( - AppState().memberLoginList?.pEMAILADDRESS ?? "", - genericResponseModel?.pSESSIONID ?? 0, - genericResponseModel?.memberInformationList![0].eMPLOYEENAME ?? - "", - _flag, - AppState().memberLoginList?.pMOBILENUMBER ?? "", - AppState().getUserName!, - mobileLoginInfoListModel!.deviceToken!, - Platform.isAndroid ? "android" : "ios"); - AppState().setMemberInformationListModel = - genericResponseModel!.memberInformationList?.first; + GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName); + GenericResponseModel? genericResponseModel1 = await LoginApiClient().insertMobileLoginInfoNEW( + AppState().memberLoginList?.pEMAILADDRESS ?? "", + genericResponseModel?.pSESSIONID ?? 0, + genericResponseModel?.memberInformationList![0].eMPLOYEENAME ?? "", + _flag, + AppState().memberLoginList?.pMOBILENUMBER ?? "", + AppState().getUserName!, + mobileLoginInfoListModel!.deviceToken!, + Platform.isAndroid ? "android" : "ios"); + AppState().setMemberInformationListModel = genericResponseModel!.memberInformationList?.first; if (genericResponseModel?.errorMessage != null) { Utils.showToast(genericResponseModel?.errorMessage ?? ""); // Navigator.pop(context); } Utils.hideLoading(context); Navigator.pop(context); - Navigator.pushNamedAndRemoveUntil( - context, AppRoutes.dashboard, (Route route) => false); + Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route route) => false); } catch (ex) { Utils.hideLoading(context); Utils.handleException(ex, context, null); diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart index f31311f..8dba16c 100644 --- a/lib/ui/login/verify_login_screen.dart +++ b/lib/ui/login/verify_login_screen.dart @@ -511,7 +511,6 @@ class _VerifyLoginScreenState extends State { // } // - Future loginWithFaceIDAndBiometrics() async { IOSAuthMessages iosStrings = const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); @@ -550,9 +549,9 @@ class _VerifyLoginScreenState extends State { } } else { if (isNeedVerifyWithFaceIDAndBiometrics) - performApiCall(_title, _icon, selectedFlag,_flag); + performApiCall(_title, _icon, selectedFlag, _flag); else - performApiCall(_title, _icon, _flag,_flag); + performApiCall(_title, _icon, _flag, _flag); } } }, @@ -606,13 +605,13 @@ class _VerifyLoginScreenState extends State { return isAvailable; } - Future performApiCall(String _title, String _icon, int _flag,int sendVerificationFlat) async { + Future performApiCall(String _title, String _icon, int _flag, int sendVerificationFlat) async { try { Utils.showLoading(context); await LoginApiClient().checkMobileAppVersion(); await LoginApiClient().memberLogin(AppState().getUserName!, AppState().password!); - BasicMemberInformationModel? memberInformationModel = await LoginApiClient() - .mohemmSendActivationCodeByOTPNotificationType(0, AppState().memberLoginList?.pMOBILENUMBER, sendVerificationFlat, AppState().getUserName); + BasicMemberInformationModel? memberInformationModel = + await LoginApiClient().mohemmSendActivationCodeByOTPNotificationType(0, AppState().memberLoginList?.pMOBILENUMBER, sendVerificationFlat, AppState().getUserName); Utils.hideLoading(context); OtpDialog( context, @@ -633,8 +632,6 @@ class _VerifyLoginScreenState extends State { Platform.isAndroid ? "android" : "ios"); if (genericResponseModel?.errorMessage != null) { Utils.showToast(genericResponseModel?.errorMessage ?? ""); - - } else { AppState().setPrivilegeListModel = genericResponseModel!.privilegeList ?? []; AppState().setMemberInformationListModel = genericResponseModel.memberInformationList?.first; @@ -662,6 +659,9 @@ class _VerifyLoginScreenState extends State { () => { Navigator.pop(context), }, + onResendCode: () { + performApiCall(_title, _icon, _flag, sendVerificationFlat); + }, ).displayDialog(context); } catch (ex) { Utils.hideLoading(context); diff --git a/lib/ui/marathon/marathon_screen.dart b/lib/ui/marathon/marathon_screen.dart index d548122..a02733f 100644 --- a/lib/ui/marathon/marathon_screen.dart +++ b/lib/ui/marathon/marathon_screen.dart @@ -16,6 +16,7 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/custom_status_widget.dart' import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:provider/provider.dart'; +import 'package:sizer/sizer.dart'; import 'package:steps_indicator/steps_indicator.dart'; class MarathonScreen extends StatelessWidget { @@ -109,7 +110,7 @@ class _MarathonProgressContainerState extends State { Container( decoration: BoxDecoration( color: MyColors.greenColor, - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular(5), ), padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 8), child: "${widget.provider.currentQuestionNumber.toString()} / ${widget.provider.totalQuestions.toString()} ${LocaleKeys.question.tr()}".toText12(color: MyColors.white), @@ -120,7 +121,7 @@ class _MarathonProgressContainerState extends State { ), 15.height, StepsIndicator( - lineLength: 21, + lineLength: SizerUtil.deviceType == DeviceType.tablet ? MediaQuery.of(context).size.width * 0.077 : MediaQuery.of(context).size.width * 0.054, nbSteps: 10, selectedStep: widget.provider.currentQuestionNumber, doneLineColor: MyColors.greenColor, @@ -130,6 +131,8 @@ class _MarathonProgressContainerState extends State { selectedStepSize: 10, unselectedStepSize: 10, doneStepSize: 10, + selectedStepBorderSize: 0, + unselectedStepBorderSize: 0, selectedStepColorIn: MyColors.greenColor, selectedStepColorOut: MyColors.greenColor, unselectedStepColorIn: MyColors.lightGreyDeColor, diff --git a/lib/ui/marathon/widgets/countdown_timer.dart b/lib/ui/marathon/widgets/countdown_timer.dart index 557cfd3..93db057 100644 --- a/lib/ui/marathon/widgets/countdown_timer.dart +++ b/lib/ui/marathon/widgets/countdown_timer.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:auto_size_text/auto_size_text.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_countdown_timer/current_remaining_time.dart'; @@ -13,27 +14,24 @@ class BuildCountdownTimer extends StatelessWidget { final MarathonProvider provider; final int screenFlag; - const BuildCountdownTimer({ + BuildCountdownTimer({ Key? key, required this.provider, required this.timeToMarathon, required this.screenFlag, }) : super(key: key); - final TextStyle styleTextHome = const TextStyle( - fontSize: 7, - color: MyColors.greyACColor, + final TextStyle styleTextHome = TextStyle( + color: MyColors.grey3AColor.withOpacity(0.45), fontStyle: FontStyle.italic, - fontWeight: FontWeight.w600, + fontWeight: FontWeight.w800, letterSpacing: -0.4, ); final TextStyle styleDigitHome = const TextStyle( height: 23 / 27, - color: MyColors.white, - fontSize: 24, + color: MyColors.darkDigitColor, fontStyle: FontStyle.italic, - fontFamily: "Poppins", letterSpacing: -1.44, fontWeight: FontWeight.bold, ); @@ -62,12 +60,16 @@ class BuildCountdownTimer extends StatelessWidget { children: [ Column( children: [ - Text( + AutoSizeText( "00", + maxFontSize: 24, + minFontSize: 20, style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, ), - Text( + AutoSizeText( LocaleKeys.days.tr(), + minFontSize: 7, + maxFontSize: 8, style: screenFlag == 0 ? styleTextHome : styleTextMarathon, ), ], @@ -75,12 +77,16 @@ class BuildCountdownTimer extends StatelessWidget { buildSeparator(), Column( children: [ - Text( + AutoSizeText( "00", + maxFontSize: 24, + minFontSize: 20, style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, ), - Text( + AutoSizeText( LocaleKeys.hours.tr(), + minFontSize: 7, + maxFontSize: 8, style: screenFlag == 0 ? styleTextHome : styleTextMarathon, ), ], @@ -88,12 +94,16 @@ class BuildCountdownTimer extends StatelessWidget { buildSeparator(), Column( children: [ - Text( + AutoSizeText( "00", + maxFontSize: 24, + minFontSize: 20, style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, ), - Text( + AutoSizeText( LocaleKeys.minutes.tr(), + minFontSize: 7, + maxFontSize: 8, style: screenFlag == 0 ? styleTextHome : styleTextMarathon, ), ], @@ -101,12 +111,16 @@ class BuildCountdownTimer extends StatelessWidget { buildSeparator(), Column( children: [ - Text( + AutoSizeText( "00", + maxFontSize: 24, + minFontSize: 20, style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, ), - Text( + AutoSizeText( LocaleKeys.seconds.tr(), + minFontSize: 7, + maxFontSize: 8, style: screenFlag == 0 ? styleTextHome : styleTextMarathon, ), ], @@ -116,8 +130,10 @@ class BuildCountdownTimer extends StatelessWidget { } Widget buildSeparator() { - return Text( + return AutoSizeText( " : ", + maxFontSize: 24, + minFontSize: 20, style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, ); } @@ -140,16 +156,22 @@ class BuildCountdownTimer extends StatelessWidget { Column( children: [ time.days == null - ? Text( + ? AutoSizeText( "00", + maxFontSize: 24, + minFontSize: 20, style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, ) - : Text( + : AutoSizeText( time.days! < 10 ? "0${time.days.toString()}" : time.days.toString(), + maxFontSize: 24, + minFontSize: 20, style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, ), - Text( + AutoSizeText( LocaleKeys.days.tr(), + minFontSize: 7, + maxFontSize: 8, style: screenFlag == 0 ? styleTextHome : styleTextMarathon, ), ], @@ -158,16 +180,22 @@ class BuildCountdownTimer extends StatelessWidget { Column( children: [ time.hours == null - ? Text( + ? AutoSizeText( "00", + maxFontSize: 24, + minFontSize: 20, style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, ) - : Text( + : AutoSizeText( time.hours! < 10 ? "0${time.hours.toString()}" : time.hours.toString(), + maxFontSize: 24, + minFontSize: 20, style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, ), - Text( + AutoSizeText( LocaleKeys.hours.tr(), + minFontSize: 7, + maxFontSize: 8, style: screenFlag == 0 ? styleTextHome : styleTextMarathon, ), ], @@ -176,16 +204,22 @@ class BuildCountdownTimer extends StatelessWidget { Column( children: [ time.min == null - ? Text( + ? AutoSizeText( "00", + maxFontSize: 24, + minFontSize: 20, style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, ) - : Text( + : AutoSizeText( time.min! < 10 ? "0${time.min.toString()}" : time.min.toString(), + maxFontSize: 24, + minFontSize: 20, style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, ), - Text( + AutoSizeText( LocaleKeys.minutes.tr(), + minFontSize: 7, + maxFontSize: 8, style: screenFlag == 0 ? styleTextHome : styleTextMarathon, ), ], @@ -194,16 +228,22 @@ class BuildCountdownTimer extends StatelessWidget { Column( children: [ time.sec == null - ? Text( + ? AutoSizeText( "00", + maxFontSize: 24, + minFontSize: 20, style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, ) - : Text( + : AutoSizeText( time.sec! < 10 ? "0${time.sec.toString()}" : time.sec.toString(), + maxFontSize: 24, + minFontSize: 20, style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, ), - Text( + AutoSizeText( LocaleKeys.seconds.tr(), + minFontSize: 7, + maxFontSize: 8, style: screenFlag == 0 ? styleTextHome : styleTextMarathon, ), ], diff --git a/lib/ui/marathon/widgets/marathon_banner.dart b/lib/ui/marathon/widgets/marathon_banner.dart index be06e35..10fe17d 100644 --- a/lib/ui/marathon/widgets/marathon_banner.dart +++ b/lib/ui/marathon/widgets/marathon_banner.dart @@ -23,7 +23,8 @@ class MarathonBanner extends StatelessWidget { MarathonProvider provider = context.read(); return Container( decoration: MyDecorations.shadowDecoration, - height: 90, + height: MediaQuery.of(context).size.height * 0.11, + clipBehavior: Clip.antiAlias, child: Stack( children: [ Transform( @@ -33,8 +34,20 @@ class MarathonBanner extends StatelessWidget { ), child: SvgPicture.asset( "assets/images/marathon_banner_bg.svg", - fit: BoxFit.cover, - width: MediaQuery.of(context).size.width - 40, + fit: BoxFit.fill, + width: double.infinity, + ), + ), + Positioned( + left: -20, + top: -10, + child: Transform.rotate( + angle: 15, + child: Container( + width: 65, + height: 32, + color: MyColors.darkDigitColor, + ), ), ), SizedBox( @@ -55,7 +68,7 @@ class MarathonBanner extends StatelessWidget { width: double.infinity, height: double.infinity, child: Row( - mainAxisAlignment: MainAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.start, children: [ Column( mainAxisAlignment: MainAxisAlignment.center, @@ -65,21 +78,22 @@ class MarathonBanner extends StatelessWidget { AppState().isArabic(context) ? 0.height : 5.height, AutoSizeText( LocaleKeys.getReadyForContest.tr(), - style: const TextStyle( + minFontSize: 08, + maxFontSize: 11, + style: TextStyle( fontStyle: FontStyle.italic, - fontSize: 12, fontWeight: FontWeight.w600, - color: MyColors.lightGreyEFColor, + color: MyColors.grey3AColor.withOpacity(0.8), letterSpacing: -0.4, ), ), - const AutoSizeText( + AutoSizeText( "Saudi Arabia", style: TextStyle( fontStyle: FontStyle.italic, fontSize: 19, fontWeight: FontWeight.bold, - color: MyColors.lightGreyEFColor, + color: MyColors.grey3AColor.withOpacity(0.8), height: 32 / 22, ), ), @@ -91,16 +105,54 @@ class MarathonBanner extends StatelessWidget { ), ], ).paddingOnly( - left: AppState().isArabic(context) ? 12 : 0, - right: AppState().isArabic(context) ? 0 : 12, + left: AppState().isArabic(context) ? 12 : 3, + right: AppState().isArabic(context) ? 3 : 12, ) ], - ).paddingOnly(right: 20), + ), ), ), ], ), ), + Align( + alignment: Alignment.topLeft, + child: SizedBox( + height: 20, + width: 35, + child: Transform.rotate( + angle: -math.pi / 4.5, + child: Text( + LocaleKeys.brainMarathon.tr(), + textAlign: TextAlign.center, + maxLines: 2, + style: const TextStyle( + color: MyColors.kWhiteColor, + fontWeight: FontWeight.bold, + fontSize: 6, + height: 1.2, + ), + ), + ), + ), + ).paddingOnly(top: 5), + !AppState().isArabic(context) + ? Positioned( + right: 0, + bottom: 0, + child: RotatedBox( + quarterTurns: 4, + child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.darkDigitColor), + ).paddingAll(15), + ) + : Positioned( + bottom: 0, + left: 0, + child: RotatedBox( + quarterTurns: 2, + child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.darkDigitColor), + ).paddingAll(15), + ), ], ).onPress( () => Navigator.pushNamed(context, AppRoutes.marathonIntroScreen), diff --git a/lib/ui/marathon/widgets/question_card.dart b/lib/ui/marathon/widgets/question_card.dart index d5f6bce..a3fe720 100644 --- a/lib/ui/marathon/widgets/question_card.dart +++ b/lib/ui/marathon/widgets/question_card.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/decorations_helper.dart'; import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/models/marathon_question_model.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:provider/provider.dart'; @@ -48,7 +49,7 @@ class _QuestionCardState extends State { Widget build(BuildContext context) { return CupertinoPageScaffold( child: SizedBox( - height: 420, + height: 440, width: double.infinity, child: Consumer( builder: (BuildContext context, MarathonProvider provider, _) { @@ -200,8 +201,6 @@ class _AnswerContentState extends State { updateOption(0, true); }, child: Container( - height: 60, - width: MediaQuery.of(context).size.width - 75, alignment: Alignment.centerLeft, decoration: getContainerColor(0), child: Center( @@ -212,7 +211,7 @@ class _AnswerContentState extends State { fontWeight: FontWeight.w600, fontSize: 16, ), - ), + ).paddingOnly(top: 17, bottom: 17), ), ), ), @@ -231,8 +230,6 @@ class _AnswerContentState extends State { updateOption(1, true); }, child: Container( - height: 60, - width: MediaQuery.of(context).size.width - 75, alignment: Alignment.centerLeft, decoration: getContainerColor(1), child: Center( @@ -243,7 +240,7 @@ class _AnswerContentState extends State { fontWeight: FontWeight.w600, fontSize: 16, ), - ), + ).paddingOnly(top: 17, bottom: 17), ), ), ), @@ -262,8 +259,6 @@ class _AnswerContentState extends State { updateOption(2, true); }, child: Container( - height: 60, - width: MediaQuery.of(context).size.width - 75, alignment: Alignment.centerLeft, decoration: getContainerColor(2), child: Center( @@ -274,7 +269,7 @@ class _AnswerContentState extends State { fontWeight: FontWeight.w600, fontSize: 16, ), - ), + ).paddingOnly(top: 17, bottom: 17), ), ), ), @@ -293,8 +288,6 @@ class _AnswerContentState extends State { updateOption(3, true); }, child: Container( - height: 60, - width: MediaQuery.of(context).size.width - 75, alignment: Alignment.centerLeft, decoration: getContainerColor(3), child: Center( @@ -305,7 +298,7 @@ class _AnswerContentState extends State { fontWeight: FontWeight.w600, fontSize: 16, ), - ), + ).paddingOnly(top: 17, bottom: 17), ), ), ), diff --git a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart index 0a6c9d4..519bb6c 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart @@ -448,7 +448,7 @@ class _DynamicInputScreenState extends State { return DynamicTextFieldWidget( (model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""), model.eSERVICESDV?.pIDCOLUMNNAME ?? "", - isReadOnly: model.rEADONLY == "Y", + // isReadOnly: model.rEADONLY == "Y", isInputTypeNum: true, onChange: (text) { model.fieldAnswer = text; diff --git a/lib/ui/my_team/view_attendance.dart b/lib/ui/my_team/view_attendance.dart index c77b1b4..90414d1 100644 --- a/lib/ui/my_team/view_attendance.dart +++ b/lib/ui/my_team/view_attendance.dart @@ -283,7 +283,6 @@ class _ViewAttendanceState extends State { cellBorderColor: Colors.white, selectionDecoration: BoxDecoration( border: Border.all(color: MyColors.white, width: 10), - borderRadius: const BorderRadius.all(Radius.circular(100)), shape: BoxShape.circle, ), dataSource: MeetingDataSource(_getDataSource()), diff --git a/lib/ui/profile/dynamic_screens/dynamic_input_address_screen.dart b/lib/ui/profile/dynamic_screens/dynamic_input_address_screen.dart index ecc2426..6933a28 100644 --- a/lib/ui/profile/dynamic_screens/dynamic_input_address_screen.dart +++ b/lib/ui/profile/dynamic_screens/dynamic_input_address_screen.dart @@ -266,6 +266,7 @@ class _DynamicInputScreenState extends State { if (e.fORMATTYPE == "X") { // for date format type, date format is changed tempVar = e.eSERVICESDV?.pVALUECOLUMNNAME ?? ""; + if (tempVar.isNotEmpty) { DateTime date = DateFormat('yyyy-MM-dd').parse(tempVar); tempVar = DateFormat('dd-MMM-yyy').format(date); @@ -274,7 +275,7 @@ class _DynamicInputScreenState extends State { } } } else if (e.eSERVICESVS?.isNotEmpty ?? false) { - tempVar = e.getEmployeeAddressList!.vARCHAR2VALUE ?? ""; + e.getEmployeeAddressList!.vARCHAR2VALUE != null ? tempVar = e.getEmployeeAddressList!.vARCHAR2VALUE! : tempVar = ""; if (e.aPPLICATIONCOLUMNNAME == null) { countryCode = tempVar; } diff --git a/lib/ui/profile/widgets/profile_panel.dart b/lib/ui/profile/widgets/profile_panel.dart index 5018171..440fbb3 100644 --- a/lib/ui/profile/widgets/profile_panel.dart +++ b/lib/ui/profile/widgets/profile_panel.dart @@ -44,12 +44,16 @@ class ProfilePanel extends StatelessWidget { Widget profileImage() => memberInformationList.eMPLOYEEIMAGE == null ? SvgPicture.asset( - "assets/images/user.svg", - height: 68, - width: 68,) - : CircleAvatar( - radius: 68, - backgroundImage: MemoryImage(Utils.dataFromBase64String(memberInformationList.eMPLOYEEIMAGE!)), - backgroundColor: Colors.black, - ); + "assets/images/user.svg", + height: 68, + width: 68, + ) + : ClipOval( + child: Image.memory( + Utils.dataFromBase64String(memberInformationList.eMPLOYEEIMAGE!), + width: 75, + height: 75, + fit: BoxFit.fill, + ), + ); } diff --git a/lib/ui/work_list/itg_detail_screen.dart b/lib/ui/work_list/itg_detail_screen.dart index 0f45648..84bd9bd 100644 --- a/lib/ui/work_list/itg_detail_screen.dart +++ b/lib/ui/work_list/itg_detail_screen.dart @@ -66,7 +66,9 @@ class _ItgDetailScreenState extends State { isRejectAvailable = itgRequest!.allowedActions!.any((element) => element.action == "Reject"); } Utils.hideLoading(context); - setState(() {}); + setState(() { + controller.jumpToPage(0); + }); } catch (ex) { Utils.hideLoading(context); Utils.handleException(ex, context, null); @@ -264,12 +266,12 @@ class _ItgDetailScreenState extends State { switch (action.action) { case "Delegate": showMyBottomSheet(context, callBackFunc: reloadITG, - child: DelegateSheet(title: LocaleKeys.delegate.tr(), apiMode: action.action!, notificationID: null, actionHistoryList: null, wFHistory: itgRequest?.wFHistory ?? [])); + child: DelegateSheet(title: LocaleKeys.delegate.tr(), apiMode: action.action!, notificationID: null, actionHistoryList: null, wFHistory: itgRequest?.wFHistory ?? [], callBackFunc: reloadITG,)); break; case "RequestInformation": showMyBottomSheet(context, callBackFunc: reloadITG, - child: DelegateSheet(title: LocaleKeys.request_info.tr(), apiMode: action.action!, notificationID: null, actionHistoryList: null, wFHistory: itgRequest?.wFHistory ?? [])); + child: DelegateSheet(title: LocaleKeys.request_info.tr(), apiMode: action.action!, notificationID: null, actionHistoryList: null, wFHistory: itgRequest?.wFHistory ?? [], callBackFunc: reloadITG,)); break; case "RFC": @@ -279,6 +281,9 @@ class _ItgDetailScreenState extends State { // do something else break; } + setState(() { + showFabOptions = false; + }); } Widget myTab(String title, int index) { diff --git a/lib/ui/work_list/sheets/delegate_sheet.dart b/lib/ui/work_list/sheets/delegate_sheet.dart index 28a90e6..bd3b010 100644 --- a/lib/ui/work_list/sheets/delegate_sheet.dart +++ b/lib/ui/work_list/sheets/delegate_sheet.dart @@ -28,8 +28,9 @@ class DelegateSheet extends StatefulWidget { String title, apiMode; List? actionHistoryList; List? wFHistory; + VoidCallback callBackFunc; - DelegateSheet({required this.title, required this.apiMode, this.notificationID, this.actionHistoryList, this.wFHistory}); + DelegateSheet({required this.title, required this.apiMode, this.notificationID, this.actionHistoryList, this.wFHistory, required this.callBackFunc}); @override State createState() => _DelegateSheetState(); @@ -392,8 +393,9 @@ class _DelegateSheetState extends State { Widget showItem(GetActionHistoryList actionHistory) { return InkWell( onTap: () { + Navigator.pop(context); showMyBottomSheet(context, - callBackFunc: (){}, + callBackFunc: widget.callBackFunc, child: SelectedItemSheet( "Comment", apiMode: widget.apiMode, @@ -438,8 +440,9 @@ class _DelegateSheetState extends State { Widget showItgItem(WFHistory wfHistory) { return InkWell( onTap: () { + Navigator.pop(context); showMyBottomSheet(context, - callBackFunc: (){}, + callBackFunc: widget.callBackFunc, child: SelectedItgItemSheet( "Comment", apiMode: widget.apiMode, @@ -463,8 +466,9 @@ class _DelegateSheetState extends State { Widget showFavUserItem(GetFavoriteReplacements actionHistory) { return InkWell( onTap: () { + Navigator.pop(context); showMyBottomSheet(context, - callBackFunc: (){}, + callBackFunc: widget.callBackFunc, child: SelectedItemSheet( "Comment", apiMode: widget.apiMode, @@ -509,8 +513,9 @@ class _DelegateSheetState extends State { Widget showInputUserItem(ReplacementList actionHistory) { return InkWell( onTap: () { + Navigator.pop(context); showMyBottomSheet(context, - callBackFunc: (){}, + callBackFunc: widget.callBackFunc, child: SelectedItemSheet( LocaleKeys.comments.tr(), apiMode: widget.apiMode, diff --git a/lib/ui/work_list/sheets/selected_itg_item_sheet.dart b/lib/ui/work_list/sheets/selected_itg_item_sheet.dart index 7381d59..f44ca04 100644 --- a/lib/ui/work_list/sheets/selected_itg_item_sheet.dart +++ b/lib/ui/work_list/sheets/selected_itg_item_sheet.dart @@ -128,8 +128,8 @@ class SelectedItgItemSheet extends StatelessWidget { .informationITGRequest(requestDetails.requestType!, requestDetails.iD!, requestDetails.itemID!, AppState().memberInformationList?.eMPLOYEENUMBER ?? "", wfHistory.employeeID!, comment); } Utils.hideLoading(context); - Navigator.pop(context); - Navigator.pop(context); + // Navigator.pop(context); + // Navigator.pop(context); Navigator.pop(context, "delegate_reload"); } catch (ex) { Utils.hideLoading(context); diff --git a/lib/ui/work_list/worklist_detail_screen.dart b/lib/ui/work_list/worklist_detail_screen.dart index ec02631..de7c152 100644 --- a/lib/ui/work_list/worklist_detail_screen.dart +++ b/lib/ui/work_list/worklist_detail_screen.dart @@ -388,20 +388,20 @@ class _WorkListDetailScreenState extends State { case "DELEGATE": showMyBottomSheet(context, callBackFunc: reloadWorkList, - child: DelegateSheet(title: LocaleKeys.delegate.tr(), apiMode: notificationButton.bUTTONACTION!, notificationID: workListData!.nOTIFICATIONID, actionHistoryList: actionHistoryList)); + child: DelegateSheet(title: LocaleKeys.delegate.tr(), apiMode: notificationButton.bUTTONACTION!, notificationID: workListData!.nOTIFICATIONID, actionHistoryList: actionHistoryList, callBackFunc: reloadWorkList,)); break; case "REQUEST_INFO": // do something else showMyBottomSheet(context, callBackFunc: reloadWorkList, - child: DelegateSheet(title: LocaleKeys.request_info.tr(), apiMode: "REQUEST_INFO", notificationID: workListData!.nOTIFICATIONID, actionHistoryList: actionHistoryList)); + child: DelegateSheet(title: LocaleKeys.request_info.tr(), apiMode: "REQUEST_INFO", notificationID: workListData!.nOTIFICATIONID, actionHistoryList: actionHistoryList, callBackFunc: reloadWorkList,)); break; case "TRANSFER_INFO": // do something else showMyBottomSheet(context, callBackFunc: reloadWorkList, child: - DelegateSheet(title: notificationButton.bUTTONLABEL!, apiMode: notificationButton.bUTTONACTION!, notificationID: workListData!.nOTIFICATIONID, actionHistoryList: actionHistoryList)); + DelegateSheet(title: notificationButton.bUTTONLABEL!, apiMode: notificationButton.bUTTONACTION!, notificationID: workListData!.nOTIFICATIONID, actionHistoryList: actionHistoryList, callBackFunc: reloadWorkList,)); break; case "ANSWER_INFO": performAction(notificationButton.bUTTONACTION!, title: notificationButton.bUTTONLABEL); @@ -417,12 +417,12 @@ class _WorkListDetailScreenState extends State { case "APPROVE_AND_FORWARD": showMyBottomSheet(context, callBackFunc: reloadWorkList, - child: DelegateSheet(title: "Approve and Forward", apiMode: notificationButton.bUTTONACTION!, notificationID: workListData!.nOTIFICATIONID, actionHistoryList: actionHistoryList)); + child: DelegateSheet(title: "Approve and Forward", apiMode: notificationButton.bUTTONACTION!, notificationID: workListData!.nOTIFICATIONID, actionHistoryList: actionHistoryList, callBackFunc: reloadWorkList,)); break; case "FORWARD": showMyBottomSheet(context, callBackFunc: reloadWorkList, - child: DelegateSheet(title: "Forward", apiMode: notificationButton.bUTTONACTION!, notificationID: workListData!.nOTIFICATIONID, actionHistoryList: actionHistoryList)); + child: DelegateSheet(title: "Forward", apiMode: notificationButton.bUTTONACTION!, notificationID: workListData!.nOTIFICATIONID, actionHistoryList: actionHistoryList, callBackFunc: reloadWorkList,)); break; case "REJECT": performNetworkCall(context, email: "", userId: ""); @@ -431,6 +431,9 @@ class _WorkListDetailScreenState extends State { Navigator.pop(context); break; } + setState(() { + showFabOptions = false; + }); } Future performNetworkCall(BuildContext context, {String? email, String? userId}) async { @@ -516,7 +519,6 @@ class _WorkListDetailScreenState extends State { } void performAction(String actionMode, {String? title}) { - TextEditingController textEditingController = TextEditingController(); showDialog( context: context, builder: (cxt) => AcceptRejectInputDialog( @@ -823,6 +825,8 @@ class _WorkListDetailScreenState extends State { void getActionHistory() async { try { + isActionHistoryLoaded = false; + actionHistoryList.clear(); // if (apiCallCount == 0) Utils.showLoading(context); // apiCallCount++; actionHistoryList = await WorkListApiClient().getActionHistory(workListData!.nOTIFICATIONID!); @@ -842,6 +846,8 @@ class _WorkListDetailScreenState extends State { void getAttachments() async { try { + isAttachmentLoaded = false; + getAttachmentList.clear(); // if (apiCallCount == 0) Utils.showLoading(context); // apiCallCount++; getAttachmentList = await WorkListApiClient().getAttachments(workListData!.nOTIFICATIONID!); @@ -864,7 +870,6 @@ class _WorkListDetailScreenState extends State { 'assets/lottie/loading.json', repeat: true, reverse: false, - fit: BoxFit.contain, ); } } diff --git a/lib/widgets/dialogs/accept_reject_input_dialog.dart b/lib/widgets/dialogs/accept_reject_input_dialog.dart index a0faf2c..db9c5d6 100644 --- a/lib/widgets/dialogs/accept_reject_input_dialog.dart +++ b/lib/widgets/dialogs/accept_reject_input_dialog.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.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/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; @@ -89,8 +90,12 @@ class AcceptRejectInputDialog extends StatelessWidget { DefaultButton( actionMode == "REJECTED" ? LocaleKeys.reject.tr() : LocaleKeys.ok.tr(), () { - Navigator.pop(context); - onTap(note); + if(note.isNotEmpty) { + Navigator.pop(context); + onTap(note); + } else { + Utils.showToast(LocaleKeys.pleaseEnterComments.tr()); + } }, colors: actionMode == "REJECTED" ? const [ diff --git a/lib/widgets/item_detail_view_widget.dart b/lib/widgets/item_detail_view_widget.dart index 05495e9..5148389 100644 --- a/lib/widgets/item_detail_view_widget.dart +++ b/lib/widgets/item_detail_view_widget.dart @@ -80,9 +80,13 @@ class ItemDetailViewGridItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ - Flexible(child: "$title:".toText12Auto(isBold: true, color: const Color(0xff2BB8A6))), + title != null ? Flexible(child: "$title:".toText12Auto(isBold: true, color: const Color(0xff2BB8A6))) : Container(), 4.width, - type!.toLowerCase() == "table" ? getStringFromJSON(value!) : Flexible(child: (value!.isEmpty ? "--" : value).toString().toText12Auto(color: MyColors.normalTextColor)), + type != null + ? type!.toLowerCase() == "table" + ? getStringFromJSON(value!) + : Flexible(child: (value!.isEmpty ? "--" : value).toString().toText12Auto(color: MyColors.normalTextColor)) + : Container(), ], ), ); diff --git a/pubspec.yaml b/pubspec.yaml index 633edd7..16c5737 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -92,6 +92,7 @@ dependencies: video_player: ^2.4.7 + just_audio: ^0.9.30 dev_dependencies: flutter_test: @@ -124,6 +125,7 @@ flutter: - assets/langs/ - assets/icons/ - assets/lottie/ + - assets/audio/ - assets/images/ - assets/images/login/ - assets/icons/chat/