From a4da9db6c371f2ce504c734ffb1f905c19cf8f87 Mon Sep 17 00:00:00 2001 From: aamir-csol Date: Tue, 2 Sep 2025 08:55:19 +0300 Subject: [PATCH] register & changes --- lib/extensions/string_extensions.dart | 27 +- lib/main.dart | 7 +- lib/presentation/authantication/login.dart | 2 +- lib/presentation/authantication/register.dart | 385 ++++++++++++++++++ 4 files changed, 405 insertions(+), 16 deletions(-) create mode 100644 lib/presentation/authantication/register.dart diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 2722901..1fdd9e7 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -165,18 +165,15 @@ extension EmailValidator on String { int? maxlines, TextAlign? textAlign, }) => - Text( - this, - maxLines: maxlines, - textAlign: isCenter ? TextAlign.center : null, - style: TextStyle( - color: color ?? AppColors.blackColor, - fontSize: 16.fSize, - letterSpacing: 0.64, - fontWeight: isBold ? FontWeight.bold : FontWeight.normal, - decoration: isUnderLine ? TextDecoration.underline : null, - ), - ); + Text(this, + maxLines: maxlines, + textAlign: isCenter ? TextAlign.center : null, + style: TextStyle( + color: color ?? AppColors.blackColor, + fontSize: 16.fSize, + letterSpacing: 0.64, + fontWeight: isBold ? FontWeight.bold : FontWeight.normal, + decoration: isUnderLine ? TextDecoration.underline : null)); Widget toText17({Color? color, bool isBold = false, bool isCenter = false}) => Text( this, @@ -219,6 +216,12 @@ extension EmailValidator on String { style: TextStyle(height: 23 / 24, color: color ?? AppColors.blackColor, fontSize: 24.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), ); + Widget toText28({Color? color, bool isBold = false, bool isCenter = false}) => Text( + this, + textAlign: isCenter ? TextAlign.center : null, + style: TextStyle(height: 23 / 28, color: color ?? AppColors.blackColor, fontSize: 28.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.w600 : FontWeight.normal), + ); + Widget toText32({Color? color, bool isBold = false, bool isCenter = false}) => Text( this, textAlign: isCenter ? TextAlign.center : null, diff --git a/lib/main.dart b/lib/main.dart index 1996653..ee8beaa 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,6 +6,7 @@ import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/utils/size_config.dart'; import 'package:hmg_patient_app_new/providers/authentication_view_model.dart'; import 'package:hmg_patient_app_new/routes/app_routes.dart'; import 'package:hmg_patient_app_new/theme/app_theme.dart'; @@ -77,20 +78,20 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return SafeArea( - top: false, // Set to true if you want to avoid the notch area as well + top: false, bottom: Platform.isIOS ? false : true, child: LayoutBuilder( builder: (context, constraints) { return Sizer( builder: (context, orientation, deviceType) { - // SizeConfig().init(constraints, orientation); + SizeConfig().init(constraints, orientation); return MaterialApp( title: 'Dr. AlHabib', builder: (context, mchild) { return MediaQuery( data: MediaQuery.of(context).copyWith( textScaler: TextScaler.linear(1.0), - ), //set desired text scale factor here + ), child: mchild!); }, showSemanticsDebugger: false, diff --git a/lib/presentation/authantication/login.dart b/lib/presentation/authantication/login.dart index 84e1da3..ac599b0 100644 --- a/lib/presentation/authantication/login.dart +++ b/lib/presentation/authantication/login.dart @@ -54,7 +54,7 @@ class _LoginScreen extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Utils.showLottie(context: context, assetPath: AppAnimations.login, width: 45.h, height: 22.h, repeat: true, fit: BoxFit.cover), - SizedBox(height: 19.h), // Adjusted to sizer unit + SizedBox(height: 20.h), // Adjusted to sizer unit LocaleKeys.welcomeToDrSulaiman.tr().toText24(), SizedBox(height: 4.h), // Adjusted to sizer unit (approx 32px) TextInputWidget( diff --git a/lib/presentation/authantication/register.dart b/lib/presentation/authantication/register.dart new file mode 100644 index 0000000..bd4cb78 --- /dev/null +++ b/lib/presentation/authantication/register.dart @@ -0,0 +1,385 @@ +import 'dart:convert'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart'; +import 'package:hmg_patient_app_new/widgets/input_widget.dart'; +import 'package:provider/provider.dart'; + +class Register extends StatefulWidget { + final Function? changePageViewIndex; + + const Register({Key? key, this.changePageViewIndex}) : super(key: key); + + @override + _Register createState() => _Register(); +} + +class _Register extends State { + @override + void initState() { + getPatientOccupationList(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar( + onBackPressed: () {}, + onLanguageChanged: (String value) {}, + ), + body: Column( + children: [ + Expanded( + child: ListView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + children: [ + SizedBox(height: 10), + Padding( + padding: EdgeInsets.all(10), + child: Text( + LocaleKeys.enterNationalId.tr(), + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16), + )), + SizedBox(height: 10), + PhoneNumberSelectorWidget(onNumberChange: (value) => {}, onCountryChange: (value) => ), + SizedBox(height: 12), + TextInputWidget(labelText: LocaleKeys.nationalIdNumber.tr(), hintText: "Xxxxxxxxx", controller: TextEditingController()), + SizedBox(height: 20), + Row( + children: [ + Expanded( + child: Row( + children: [ + Radio( + value: 1, + groupValue: isHijri, + onChanged: (value) { + }, + ), + Text(LocaleKeys.hijriDate.tr()), + ], + ), + ), + Expanded( + child: Row( + children: [ + Radio( + value: 0, + groupValue: isHijri, + onChanged: (value) { + }, + ), + Text(LocaleKeys.gregorianDate.tr()), + ], + ), + ), + ], + ), + Row(children: [ + Container( + width: SizeConfig.realScreenWidth! * .89, + child: isHijri == 1 + ? Directionality( + textDirection: TextDirection.ltr, + child: inputWidget(TranslationBase.of(context).dob, "DD/MM/YYYYY", dob, + isNumber: false, + suffix: Icon( + Icons.calendar_today, + size: 16, + ))) + : Container( + child: InkWell( + onTap: () { + if (isHijri != null) _selectDate(context); + }, + child: Directionality( + textDirection: TextDirection.ltr, + child: inputWidget(TranslationBase.of(context).dob, "DD/MM/YYYYY", dobEn, + isNumber: false, + isEnable: false, + suffix: Icon( + Icons.calendar_today, + size: 16, + )))))), + ]) + ], + ), + ), + Container( + width: double.maxFinite, + // height: 80.0, + color: Colors.white, + // margin: EdgeInsets.only(bottom: 50.0), + child: Row( + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.all(10), + child: DefaultButton(TranslationBase.of(context).cancel, () { + Navigator.of(context).pop(); + locator().loginRegistration.registration_cancel(step: 'enter details'); + }, textColor: Colors.white, color: Color(0xffD02127))), + ), + Expanded( + child: Padding( + padding: EdgeInsets.all(10), + child: DefaultButton(TranslationBase.of(context).next, () { + startRegistration(); + locator().loginRegistration.registration_enter_details(); + }, textColor: Colors.white, color: isButtonDisabled == true ? Colors.grey : Color(0xff359846))), + ), + ], + ), + ) + ], + ), + ); + } + + Future _selectDate(BuildContext context) async { + DatePicker.showDatePicker( + context, + showTitleActions: true, + minTime: DateTime(DateTime.now().year - 100, 1, 1), + maxTime: DateTime.now(), + onConfirm: (date) { + selectedDate = date; + setState(() { + final intl.DateFormat dateFormat = intl.DateFormat('dd/MM/yyyy'); + dobEn.text = dateFormat.format(date); + }); + }, + currentTime: DateTime.now(), + ); + } + + Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String? prefix, bool isEnable = true, bool hasSelection = false, bool isNumber = true, Icon? suffix}) { + return Container( + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: InkWell( + onTap: hasSelection ? () {} : null, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _labelText, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, + keyboardType: isNumber ? TextInputType.numberWithOptions(signed: true) : TextInputType.datetime, + controller: _controller, + onChanged: (value) => {validateForm()}, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + decoration: InputDecoration( + isDense: true, + hintText: _hintText, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + prefixIconConstraints: BoxConstraints(minWidth: 50), + prefixIcon: prefix == null + ? null + : Text( + "+" + prefix, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w500, + color: Color(0xff2E303A), + letterSpacing: -0.56, + ), + ), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + ), + ], + ), + ), + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), + if (suffix != null) suffix + ], + ), + ), + ); + } + + startRegistration() { + final intl.DateFormat dateFormat = intl.DateFormat('dd/MM/yyyy'); + if (isButtonDisabled == false) { + var request = CheckPatientForRegistration(); + request.patientMobileNumber = int.parse(mobileNo); + request.zipCode = countryCode; + request.patientOutSA = countryCode == '966' ? 0 : 1; + + request.patientIdentificationID = int.parse(nationalIDorFile.text); + request.patientID = 0; + request.isRegister = true; + request.dob = isHijri == 1 ? dob.text : dateFormat.format(selectedDate); + request.isHijri = isHijri; + this.checkPatientForRegisteration(request); + } + } + + checkPatientForRegisteration(request) { + int languageID = Provider.of(context, listen: false).isArabic ? 1 : 2; + GifLoaderDialogUtils.showMyDialog(context); + this.authService.checkPatientForRegisteration(request, languageID).then((response) => {checkUserStatus(response, request)}).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: err, + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () => { + ConfirmDialog.closeAlertDialog(context), + Navigator.of(context).push(FadePage(page: Register())), + }, + cancelFunction: () => {ConfirmDialog.closeAlertDialog(context)}); + dialog.showAlertDialog(context); + }); + } + + void validateForm() { + if (util.validateIDBox(nationalIDorFile.text, loginType) == true && + mobileNo.length >= 9 && + util.isSAUDIIDValid(nationalIDorFile.text, loginType) == true && + isHijri != null && + (dobEn.text != null || dob.text != null)) { + setState(() { + isButtonDisabled = false; + }); + } else { + setState(() { + isButtonDisabled = true; + }); + } + } + + checkUserStatus(response, CheckPatientForRegistration request) async { + GifLoaderDialogUtils.hideDialog(context); + if (response is Map) { + var nRequest = request.toJson(); + nRequest['LogInTokenID'] = response['LogInTokenID']; + if (response['hasFile'] == true) { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: response['ErrorEndUserMessage'], + okText: TranslationBase.of(context).ok, + cancelText: TranslationBase.of(context).cancel, + okFunction: () { + AlertDialogBox.closeAlertDialog(context); + sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, nRequest); + LoginRegistration.loginMethod = 1; // 1=NationalID, by default from Registration + Navigator.of(context).push(FadePage(page: Login())); + }, + cancelFunction: () {}) + .showAlertDialog(context); + } else { + final intl.DateFormat dateFormat = intl.DateFormat('dd/MM/yyyy'); + nRequest['forRegister'] = true; + nRequest['isRegister'] = true; + nRequest["PatientIdentificationID"] = nRequest["PatientIdentificationID"].toString(); + nRequest['dob'] = isHijri == 1 ? dob.text : dateFormat.format(selectedDate); + nRequest['isHijri'] = isHijri; + sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, nRequest); + sharedPref.setString(LOGIN_TOKEN_ID, response['LogInTokenID']); + if (request.patientOutSA == 0) { + this.chekUserData(response['LogInTokenID']); + } else { + Navigator.of(context).push(FadePage(page: ConfirmLogin(changePageViewIndex: widget.changePageViewIndex, fromRegistration: true, isDubai: true))); + } + } + } else { + // if (response['ErrorCode'] == '-986') { + //AppToast.showErrorToast(message: response); + AlertDialogBox( + context: context, + confirmMessage: response, + okText: TranslationBase.of(context).ok, + okFunction: () { + AlertDialogBox.closeAlertDialog(context); + Navigator.of(context).pop(); + }).showAlertDialog(context); + //} + } + } + + chekUserData(loginToken) { + // let m = hijri(this.dateOfBirth).locale('en'); + // // const dateHijri = m.format('iDD/iMM/iYYYY'); + // const request = { + // PatientIdentificationID: this.id.toString(), + // // TokenID: token, + // DOB: this.dateOption === '1' ? this.dateOfBirth : moment(this.dateOfBirth).format('DD/MM/YYYY'), + // IsHijri: Number(this.dateOption) + // } + + final intl.DateFormat dateFormat = intl.DateFormat('dd/MM/yyyy'); + GifLoaderDialogUtils.showMyDialog(context); + var request = CheckUserStatusRequest(); + request.patientIdentificationID = nationalIDorFile.text; + request.dOB = isHijri == 1 ? dob.text : dateFormat.format(selectedDate); + request.isHijri = isHijri; + request.patientOutSA = countryCode == '966' ? 0 : 1; + this.authService.checkUserStatus(request).then((result) => { + GifLoaderDialogUtils.hideDialog(context), + if (result is Map) + { + result = CheckUserStatusResponse.fromJson(result as Map), + sharedPref.setObject(NHIC_DATA, result), + // widget.changePageViewIndex!(1), + Navigator.of(context).push(FadePage(page: ConfirmLogin(changePageViewIndex: widget.changePageViewIndex, fromRegistration: true))), + } + else + { + AppToast.showErrorToast(message: result != null ? result : TranslationBase.of(context).somethingWentWrong), + } + }); + } + + getPatientOccupationList() async { + patientOccupationList.clear(); + await authService.getPatientOccupationList().then((result) { + sharedPref.setString(PATIENT_OCCUPATION_LIST, json.encode(result['GetOccupationLst'])); + }).catchError((err) { + AppToast.showErrorToast(message: err); + }); + } +}