diff --git a/lib/model/directory/add_contact_bottom_sheet.dart b/lib/model/directory/add_contact_bottom_sheet.dart index 4c0337c..3cbae01 100644 --- a/lib/model/directory/add_contact_bottom_sheet.dart +++ b/lib/model/directory/add_contact_bottom_sheet.dart @@ -4,6 +4,7 @@ import 'package:marco/controller/directory/add_contact_controller.dart'; import 'package:marco/helpers/widgets/my_spacing.dart'; import 'package:marco/helpers/widgets/my_text.dart'; import 'package:marco/helpers/widgets/my_text_style.dart'; +import 'package:flutter/services.dart'; class AddContactBottomSheet extends StatelessWidget { AddContactBottomSheet({super.key}) { @@ -103,6 +104,7 @@ class AddContactBottomSheet extends StatelessWidget { VoidCallback? onRemove, }) { return Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Column( @@ -111,9 +113,10 @@ class AddContactBottomSheet extends StatelessWidget { MyText.labelMedium(label), MySpacing.height(8), _popupSelector( - hint: "Label", - selectedValue: selectedLabel, - options: options), + hint: "Label", + selectedValue: selectedLabel, + options: options, + ), ], ), ), @@ -124,24 +127,51 @@ class AddContactBottomSheet extends StatelessWidget { children: [ MyText.labelMedium(inputLabel), MySpacing.height(8), - SizedBox( - height: 48, - child: TextFormField( - controller: controller, - keyboardType: inputType, - decoration: _inputDecoration("Enter $inputLabel"), - validator: (value) => value == null || value.trim().isEmpty - ? "$inputLabel is required" - : null, - ), - ), + TextFormField( + controller: controller, + keyboardType: inputType, + maxLength: inputType == TextInputType.phone ? 10 : null, + inputFormatters: inputType == TextInputType.phone + ? [FilteringTextInputFormatter.digitsOnly] + : [], + decoration: _inputDecoration("Enter $inputLabel").copyWith( + counterText: "", // hides length indicator + ), + validator: (value) { + if (value == null || value.trim().isEmpty) { + return "$inputLabel is required"; + } + + final trimmed = value.trim(); + + if (inputType == TextInputType.phone) { + if (!RegExp(r'^\d{10}$').hasMatch(trimmed)) { + return "Enter a valid 10-digit phone number"; + } + if (RegExp(r'^0+$').hasMatch(trimmed)) { + return "Phone number cannot be all zeroes"; + } + } + + if (inputType == TextInputType.emailAddress && + !RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(trimmed)) { + return "Enter a valid email address"; + } + + return null; + }, +), + ], ), ), if (onRemove != null) - IconButton( - icon: const Icon(Icons.remove_circle_outline, color: Colors.red), - onPressed: onRemove, + Padding( + padding: const EdgeInsets.only(top: 24), + child: IconButton( + icon: const Icon(Icons.remove_circle_outline, color: Colors.red), + onPressed: onRemove, + ), ), ], );