feat: enhance profile input fields with new styling and customization options, and update calendar and location icons

This commit is contained in:
pradeepkumar
2026-03-14 20:59:47 +05:30
parent da45b1ad42
commit ddcc04a446
9 changed files with 866 additions and 289 deletions

View File

@@ -549,15 +549,90 @@ class _AgentCardState extends State<_AgentCard> {
),
),
const SizedBox(width: 4),
Text(
agent.location,
style: const TextStyle(
fontFamily: 'SourceSerif4',
fontSize: 14,
fontWeight: FontWeight.w500,
color: AppColors.primaryDark,
),
),
Builder(builder: (_) {
final allParts = <String>[];
// Extract all cities/states from fieldValues arrays
for (final fv in agent.fieldValues) {
final slug = fv.fieldSlug.toLowerCase();
if (slug == 'city' || slug == 'city_name' ||
slug == 'state' || slug == 'state_name') {
if (fv.jsonValue is List) {
for (final v in (fv.jsonValue as List)) {
final s = v.toString().trim();
if (s.isEmpty) continue;
final display = s
.split('_')
.map((w) => w.isNotEmpty
? '${w[0].toUpperCase()}${w.substring(1).toLowerCase()}'
: '')
.join(' ');
if (!allParts.any((p) =>
p.toLowerCase() == display.toLowerCase())) {
allParts.add(display);
}
}
} else if (fv.textValue != null &&
fv.textValue!.isNotEmpty) {
allParts.add(fv.textValue!);
}
}
}
// Fallback to agent.location + serviceAreas
if (allParts.isEmpty) {
final locParts = agent.location
.split(',')
.map((s) => s.trim())
.where((s) => s.isNotEmpty);
allParts.addAll(locParts);
for (final area in agent.serviceAreas) {
final trimmed = area.trim();
if (trimmed.isNotEmpty &&
!allParts.any((p) =>
p.toLowerCase() ==
trimmed.toLowerCase())) {
allParts.add(trimmed);
}
}
}
final firstPart = allParts.isNotEmpty
? allParts.first
: agent.location;
final remaining = allParts.length - 1;
return Row(
mainAxisSize: MainAxisSize.min,
children: [
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 90),
child: Text(
firstPart,
style: const TextStyle(
fontFamily: 'SourceSerif4',
fontSize: 14,
fontWeight: FontWeight.w500,
color: AppColors.primaryDark,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
if (remaining > 0)
GestureDetector(
onTap: () =>
_showLocationModal(context, allParts),
child: Text(
' +$remaining more',
style: const TextStyle(
fontFamily: 'SourceSerif4',
fontSize: 14,
fontWeight: FontWeight.w500,
color: AppColors.accentOrange,
),
),
),
],
);
}),
const SizedBox(width: 16),
],
SvgPicture.asset(
@@ -646,6 +721,70 @@ class _AgentCardState extends State<_AgentCard> {
}
void _showLocationModal(BuildContext context, List<String> parts) {
showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
backgroundColor: Colors.white,
builder: (_) => Padding(
padding: const EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'All Locations',
style: TextStyle(
fontFamily: 'Fractul',
fontSize: 18,
fontWeight: FontWeight.w700,
color: AppColors.primaryDark,
),
),
GestureDetector(
onTap: () => Navigator.pop(context),
child: const Icon(Icons.close, size: 20),
),
],
),
const SizedBox(height: 16),
Wrap(
spacing: 8,
runSpacing: 8,
children: parts
.map((p) => Container(
padding: const EdgeInsets.symmetric(
horizontal: 12, vertical: 6),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: AppColors.primaryDark.withValues(alpha: 0.2),
),
),
child: Text(
p,
style: const TextStyle(
fontFamily: 'SourceSerif4',
fontSize: 14,
fontWeight: FontWeight.w500,
color: AppColors.primaryDark,
),
),
))
.toList(),
),
const SizedBox(height: 20),
],
),
),
);
}
Widget _buildTag(String label) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),