feat(directory): enhance input validation and layout in AddContactBottomSheet
This commit is contained in:
parent
606c5e5971
commit
087c77bbd2
@ -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_spacing.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text.dart';
|
import 'package:marco/helpers/widgets/my_text.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text_style.dart';
|
import 'package:marco/helpers/widgets/my_text_style.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
class AddContactBottomSheet extends StatelessWidget {
|
class AddContactBottomSheet extends StatelessWidget {
|
||||||
AddContactBottomSheet({super.key}) {
|
AddContactBottomSheet({super.key}) {
|
||||||
@ -103,6 +104,7 @@ class AddContactBottomSheet extends StatelessWidget {
|
|||||||
VoidCallback? onRemove,
|
VoidCallback? onRemove,
|
||||||
}) {
|
}) {
|
||||||
return Row(
|
return Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -111,9 +113,10 @@ class AddContactBottomSheet extends StatelessWidget {
|
|||||||
MyText.labelMedium(label),
|
MyText.labelMedium(label),
|
||||||
MySpacing.height(8),
|
MySpacing.height(8),
|
||||||
_popupSelector(
|
_popupSelector(
|
||||||
hint: "Label",
|
hint: "Label",
|
||||||
selectedValue: selectedLabel,
|
selectedValue: selectedLabel,
|
||||||
options: options),
|
options: options,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -124,24 +127,51 @@ class AddContactBottomSheet extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
MyText.labelMedium(inputLabel),
|
MyText.labelMedium(inputLabel),
|
||||||
MySpacing.height(8),
|
MySpacing.height(8),
|
||||||
SizedBox(
|
TextFormField(
|
||||||
height: 48,
|
controller: controller,
|
||||||
child: TextFormField(
|
keyboardType: inputType,
|
||||||
controller: controller,
|
maxLength: inputType == TextInputType.phone ? 10 : null,
|
||||||
keyboardType: inputType,
|
inputFormatters: inputType == TextInputType.phone
|
||||||
decoration: _inputDecoration("Enter $inputLabel"),
|
? [FilteringTextInputFormatter.digitsOnly]
|
||||||
validator: (value) => value == null || value.trim().isEmpty
|
: [],
|
||||||
? "$inputLabel is required"
|
decoration: _inputDecoration("Enter $inputLabel").copyWith(
|
||||||
: null,
|
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)
|
if (onRemove != null)
|
||||||
IconButton(
|
Padding(
|
||||||
icon: const Icon(Icons.remove_circle_outline, color: Colors.red),
|
padding: const EdgeInsets.only(top: 24),
|
||||||
onPressed: onRemove,
|
child: IconButton(
|
||||||
|
icon: const Icon(Icons.remove_circle_outline, color: Colors.red),
|
||||||
|
onPressed: onRemove,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user