feat: add input validation to search, update agent card layout, and extend ProfileFormField with input constraints

This commit is contained in:
pradeepkumar
2026-04-20 09:39:10 +05:30
parent 7cacc19c8e
commit 2e789aaf47
3 changed files with 34 additions and 10 deletions

View File

@@ -1598,9 +1598,13 @@ class _SpecializationCardWidgetState extends State<_SpecializationCardWidget> {
: widget.card.values.take(_initialCount).toList();
final hasMore = widget.card.values.length > _initialCount;
// Consistent minimum height across all cards so the layout stays uniform
// regardless of how many values each card has (icon + title + up to 3
// rows + show more button fits comfortably).
return Container(
width: 298,
padding: const EdgeInsets.symmetric(vertical: 16),
constraints: const BoxConstraints(minHeight: 240),
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 12),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
@@ -1611,11 +1615,13 @@ class _SpecializationCardWidgetState extends State<_SpecializationCardWidget> {
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Icon(_icon, size: 32, color: AppColors.accentOrange),
const SizedBox(height: 8),
Text(
widget.card.name,
textAlign: TextAlign.center,
style: const TextStyle(
fontFamily: 'Fractul',
fontSize: 14,

View File

@@ -187,6 +187,7 @@ class _AgentSearchScreenState extends ConsumerState<AgentSearchScreen> {
),
),
onSubmitted: (value) {
if (value.trim().isEmpty) return;
ref.read(searchAgentsProvider.notifier).search(value);
},
),
@@ -196,13 +197,24 @@ class _AgentSearchScreenState extends ConsumerState<AgentSearchScreen> {
const SizedBox(width: 0),
GestureDetector(
onTap: () {
ref
.read(searchAgentsProvider.notifier)
.search(_searchController.text);
final query = _searchController.text.trim();
if (query.isEmpty) {
// No input — don't trigger a refresh
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Please enter a keyword'),
behavior: SnackBarBehavior.floating,
duration: Duration(seconds: 2),
),
);
return;
}
ref.read(searchAgentsProvider.notifier).search(query);
},
child: Container(
width: 62,
height: 42,
alignment: Alignment.center,
decoration: BoxDecoration(
color: AppColors.accentOrange,
border: Border.all(
@@ -211,12 +223,10 @@ class _AgentSearchScreenState extends ConsumerState<AgentSearchScreen> {
),
borderRadius: BorderRadius.circular(7),
),
child: Center(
child: SvgPicture.string(
'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="white"/></svg>',
width: 24,
height: 24,
),
child: const Icon(
Icons.search,
color: Colors.white,
size: 24,
),
),
),

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:real_estate_mobile/core/constants/app_colors.dart';
class ProfileFormField extends StatelessWidget {
@@ -10,6 +11,8 @@ class ProfileFormField extends StatelessWidget {
final TextCapitalization textCapitalization;
final bool obscureText;
final Widget? suffixIcon;
final List<TextInputFormatter>? inputFormatters;
final int? maxLength;
const ProfileFormField({
super.key,
@@ -21,6 +24,8 @@ class ProfileFormField extends StatelessWidget {
this.textCapitalization = TextCapitalization.words,
this.obscureText = false,
this.suffixIcon,
this.inputFormatters,
this.maxLength,
});
@override
@@ -53,6 +58,8 @@ class ProfileFormField extends StatelessWidget {
keyboardType: keyboardType,
textCapitalization: textCapitalization,
obscureText: obscureText,
inputFormatters: inputFormatters,
maxLength: maxLength,
textAlignVertical: TextAlignVertical.center,
style: const TextStyle(
fontFamily: 'SourceSerif4',
@@ -62,6 +69,7 @@ class ProfileFormField extends StatelessWidget {
),
decoration: InputDecoration(
isDense: true,
counterText: '',
contentPadding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
border: border,