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.
		
		
		
		
		
			
		
			
				
	
	
		
			267 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			267 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Dart
		
	
import 'package:flutter/material.dart';
 | 
						|
import 'package:hijri_gregorian_calendar/hijri_gregorian_calendar.dart';
 | 
						|
import 'package:hmg_patient_app_new/core/app_assets.dart';
 | 
						|
import 'package:hmg_patient_app_new/core/app_export.dart';
 | 
						|
import 'package:hmg_patient_app_new/core/app_state.dart';
 | 
						|
import 'package:hmg_patient_app_new/core/enums.dart';
 | 
						|
import 'package:hmg_patient_app_new/core/utils/utils.dart';
 | 
						|
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
 | 
						|
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
 | 
						|
import 'package:hmg_patient_app_new/theme/colors.dart';
 | 
						|
import 'package:hmg_patient_app_new/widgets/dropdown/country_dropdown_widget.dart';
 | 
						|
import 'package:keyboard_actions/keyboard_actions.dart';
 | 
						|
 | 
						|
import '../core/dependencies.dart';
 | 
						|
 | 
						|
// TODO: Import AppColors if bgRedColor is defined there
 | 
						|
// import 'package:hmg_patient_app_new/core/ui_utils/app_colors.dart';
 | 
						|
 | 
						|
class TextInputWidget extends StatelessWidget {
 | 
						|
  final String labelText;
 | 
						|
  final String hintText;
 | 
						|
  final TextEditingController? controller;
 | 
						|
  final Function(String?)? onChange;
 | 
						|
  final Function(bool)? onCalendarTypeChanged;
 | 
						|
  final String? prefix;
 | 
						|
  final bool isEnable;
 | 
						|
  final bool isBorderAllowed;
 | 
						|
  final bool isAllowRadius;
 | 
						|
  final bool isReadOnly;
 | 
						|
  final TextInputType keyboardType;
 | 
						|
  final FocusNode? focusNode;
 | 
						|
  final bool autoFocus;
 | 
						|
  final EdgeInsetsGeometry? padding;
 | 
						|
  final bool isAllowLeadingIcon;
 | 
						|
  final String? leadingIcon;
 | 
						|
  final bool isCountryDropDown;
 | 
						|
  final bool hasError;
 | 
						|
  final String? errorMessage;
 | 
						|
  Function(CountryEnum)? onCountryChange;
 | 
						|
  final SelectionTypeEnum? selectionType;
 | 
						|
  final num? fontSize;
 | 
						|
  final bool? isWalletAmountInput;
 | 
						|
  final Widget? suffix;
 | 
						|
 | 
						|
  // final List<Country> countryList;
 | 
						|
  // final Function(Country)? onCountryChange;
 | 
						|
 | 
						|
  TextInputWidget({
 | 
						|
    super.key,
 | 
						|
    required this.labelText,
 | 
						|
    required this.hintText,
 | 
						|
    this.controller,
 | 
						|
    this.onChange,
 | 
						|
    this.onCalendarTypeChanged,
 | 
						|
    this.prefix,
 | 
						|
    this.isEnable = true,
 | 
						|
    this.isBorderAllowed = true,
 | 
						|
    this.isAllowRadius = true,
 | 
						|
    this.isReadOnly = false,
 | 
						|
    this.keyboardType = TextInputType.number,
 | 
						|
    this.focusNode,
 | 
						|
    this.autoFocus = false,
 | 
						|
    this.padding,
 | 
						|
    this.isAllowLeadingIcon = false,
 | 
						|
    this.leadingIcon,
 | 
						|
    this.isCountryDropDown = false,
 | 
						|
    this.hasError = false,
 | 
						|
    this.errorMessage,
 | 
						|
    this.onCountryChange,
 | 
						|
    this.selectionType,
 | 
						|
    this.fontSize = 14,
 | 
						|
    this.isWalletAmountInput = false,
 | 
						|
    this.suffix,
 | 
						|
    // this.countryList = const [],
 | 
						|
    // this.onCountryChange,
 | 
						|
  });
 | 
						|
 | 
						|
  final FocusNode _focusNode = FocusNode();
 | 
						|
 | 
						|
  // KeyboardActionsConfig get _keyboardActionsConfig {
 | 
						|
  //   return KeyboardActionsConfig(
 | 
						|
  //     keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
 | 
						|
  //     keyboardBarColor: const Color(0xFFCAD1D9), //Apple keyboard color
 | 
						|
  //     actions: [
 | 
						|
  //       KeyboardActionsItem(
 | 
						|
  //         focusNode: focusNode ?? _focusNode,
 | 
						|
  //         toolbarButtons: [
 | 
						|
  //           (node) {
 | 
						|
  //             return GestureDetector(
 | 
						|
  //               onTap: () => node.unfocus(),
 | 
						|
  //               child: Container(
 | 
						|
  //                 padding: const EdgeInsets.all(12.0),
 | 
						|
  //                 child: "Done".toText16(weight: FontWeight.w500, color: AppColors.infoColor),
 | 
						|
  //               ),
 | 
						|
  //             );
 | 
						|
  //           }
 | 
						|
  //         ],
 | 
						|
  //       ),
 | 
						|
  //     ],
 | 
						|
  //   );
 | 
						|
  // }
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    AppState appState = getIt.get<AppState>();
 | 
						|
    final errorColor = AppColors.primaryRedColor;
 | 
						|
    return Column(
 | 
						|
      mainAxisSize: MainAxisSize.min,
 | 
						|
      crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
      children: [
 | 
						|
        Container(
 | 
						|
          padding: padding,
 | 
						|
          alignment: Alignment.center,
 | 
						|
          decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
 | 
						|
            color: Colors.white,
 | 
						|
            borderRadius: isAllowRadius ? 12 : null,
 | 
						|
            side: isBorderAllowed ? BorderSide(color: hasError ? errorColor : const Color(0xffefefef), width: 1) : null,
 | 
						|
          ),
 | 
						|
          child: Row(
 | 
						|
            textDirection: Directionality.of(context),
 | 
						|
            children: [
 | 
						|
              if (isAllowLeadingIcon && leadingIcon != null && !isCountryDropDown) _buildLeadingIcon(context),
 | 
						|
              isCountryDropDown
 | 
						|
                  ? CustomCountryDropdown(
 | 
						|
                      countryList: CountryEnum.values,
 | 
						|
                      onCountryChange: onCountryChange,
 | 
						|
                      isRtl: Directionality.of(context) == TextDirection.rtl,
 | 
						|
                      isFromBottomSheet: isCountryDropDown,
 | 
						|
                      isEnableTextField: true,
 | 
						|
                      onPhoneNumberChanged: onChange,
 | 
						|
                      // textField: _buildTextField(context),
 | 
						|
                    )
 | 
						|
                  : Expanded(
 | 
						|
                      child: Column(
 | 
						|
                        mainAxisSize: MainAxisSize.min,
 | 
						|
                        crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
                        children: [
 | 
						|
                          _buildLabelText().paddingOnly(right: (appState.getLanguageCode() == "ar" ? 10 : 0)),
 | 
						|
                          _buildTextField(context),
 | 
						|
                        ],
 | 
						|
                      ),
 | 
						|
                    ),
 | 
						|
              if (selectionType == SelectionTypeEnum.calendar) _buildTrailingIcon(context),
 | 
						|
              if (selectionType == SelectionTypeEnum.search) _buildTrailingIconForSearch(context),
 | 
						|
            ],
 | 
						|
          ),
 | 
						|
        ),
 | 
						|
        if (hasError && errorMessage != null)
 | 
						|
          Padding(
 | 
						|
            padding: EdgeInsets.only(top: 4.h, left: 12.h), // Adjust padding as needed
 | 
						|
            child: Text(
 | 
						|
              errorMessage!,
 | 
						|
              style: TextStyle(
 | 
						|
                color: errorColor,
 | 
						|
                fontSize: 12.fSize,
 | 
						|
              ),
 | 
						|
            ),
 | 
						|
          ),
 | 
						|
      ],
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  Widget _buildLeadingIcon(BuildContext context) {
 | 
						|
    return Container(
 | 
						|
        height: 40.h,
 | 
						|
        width: 40.h,
 | 
						|
        margin: EdgeInsets.only(right: 10.h),
 | 
						|
        padding: EdgeInsets.all(8.h),
 | 
						|
        decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
 | 
						|
          borderRadius: 10.h,
 | 
						|
          color: AppColors.greyColor,
 | 
						|
        ),
 | 
						|
        child: Utils.buildSvgWithAssets(icon: leadingIcon!));
 | 
						|
  }
 | 
						|
 | 
						|
  Widget _buildTrailingIcon(BuildContext context) {
 | 
						|
    final AppState appState = getIt.get<AppState>();
 | 
						|
    return Container(
 | 
						|
      height: 40.h,
 | 
						|
      width: 40.h,
 | 
						|
      margin: EdgeInsets.zero,
 | 
						|
      padding: EdgeInsets.all(8.h),
 | 
						|
      decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 10.h, color: AppColors.whiteColor),
 | 
						|
      child: GestureDetector(
 | 
						|
        onTap: () async {
 | 
						|
          bool isGregorian = true;
 | 
						|
          final picked = await showHijriGregBottomSheet(context,
 | 
						|
              isShowTimeSlots: true,
 | 
						|
              switcherIcon: Utils.buildSvgWithAssets(icon: AppAssets.language, width: 24.h, height: 24.h),
 | 
						|
              language: appState.getLanguageCode()!,
 | 
						|
              initialDate: DateTime.now(),
 | 
						|
              okWidget: Padding(padding: EdgeInsets.only(right: 8.h), child: Utils.buildSvgWithAssets(icon: AppAssets.confirm, width: 24.h, height: 24.h)),
 | 
						|
              cancelWidget: Padding(padding: EdgeInsets.only(right: 8.h), child: Utils.buildSvgWithAssets(icon: AppAssets.cancel, iconColor: Colors.white, width: 24.h, height: 24.h)),
 | 
						|
              onCalendarTypeChanged: (bool value) {
 | 
						|
            isGregorian = value;
 | 
						|
          });
 | 
						|
          if (picked != null && onChange != null) {
 | 
						|
            if (onCalendarTypeChanged != null) {
 | 
						|
              onCalendarTypeChanged!.call(isGregorian);
 | 
						|
            }
 | 
						|
            onChange!(picked.toString());
 | 
						|
          }
 | 
						|
        },
 | 
						|
        child: Utils.buildSvgWithAssets(icon: AppAssets.calendar),
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  Widget _buildLabelText() {
 | 
						|
    return Text(
 | 
						|
      labelText,
 | 
						|
      style: TextStyle(
 | 
						|
        fontSize: 12.fSize,
 | 
						|
        fontWeight: FontWeight.w500,
 | 
						|
        color: AppColors.inputLabelTextColor,
 | 
						|
        letterSpacing: -0.2,
 | 
						|
        height: 18 / 12,
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  Widget _buildTextField(BuildContext context) {
 | 
						|
    return TextField(
 | 
						|
      enabled: isEnable,
 | 
						|
      scrollPadding: EdgeInsets.zero,
 | 
						|
      keyboardType: keyboardType,
 | 
						|
      controller: controller,
 | 
						|
      readOnly: isReadOnly,
 | 
						|
      textAlignVertical: TextAlignVertical.top,
 | 
						|
      textAlign: TextAlign.left,
 | 
						|
      textDirection: TextDirection.ltr,
 | 
						|
      onChanged: onChange,
 | 
						|
      focusNode: focusNode ?? _focusNode,
 | 
						|
      autofocus: autoFocus,
 | 
						|
      textInputAction: TextInputAction.done,
 | 
						|
      cursorHeight: isWalletAmountInput! ? 40.h : 20.h,
 | 
						|
      onTapOutside: (event) {
 | 
						|
        FocusManager.instance.primaryFocus?.unfocus();
 | 
						|
      },
 | 
						|
      style: TextStyle(fontSize: fontSize!.fSize, height: isWalletAmountInput! ? 1 / 4 : 21 / 14, fontWeight: FontWeight.w500, color: AppColors.textColor, letterSpacing: -0.2),
 | 
						|
      decoration: InputDecoration(
 | 
						|
        isDense: true,
 | 
						|
        hintText: hintText,
 | 
						|
        hintStyle: TextStyle(fontSize: 14.fSize, height: 21 / 16, fontWeight: FontWeight.w500, color: Color(0xff898A8D), letterSpacing: -1),
 | 
						|
        prefixIconConstraints: BoxConstraints(minWidth: 30.h),
 | 
						|
        prefixIcon: prefix == null ? null : "+${prefix!}".toText14(letterSpacing: -1, color: AppColors.textColor, weight: FontWeight.w500),
 | 
						|
        contentPadding: EdgeInsets.zero,
 | 
						|
        border: InputBorder.none,
 | 
						|
        focusedBorder: InputBorder.none,
 | 
						|
        enabledBorder: InputBorder.none,
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  _buildTrailingIconForSearch(BuildContext context) {
 | 
						|
    final AppState appState = getIt.get<AppState>();
 | 
						|
    return Container(
 | 
						|
      height: 40.h,
 | 
						|
      width: 40.h,
 | 
						|
      margin: EdgeInsets.zero,
 | 
						|
      padding: EdgeInsets.all(8.h),
 | 
						|
      decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 10.h, color: AppColors.whiteColor),
 | 
						|
      child: Utils.buildSvgWithAssets(icon: AppAssets.search_icon),
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 |