refactor: update agent location display logic to prioritize state over city across UI and models

This commit is contained in:
pradeepkumar
2026-04-11 22:52:13 +05:30
parent 9c63ee70d9
commit 1ef02383a6
4 changed files with 57 additions and 36 deletions

View File

@@ -96,10 +96,10 @@ class AgentProfile {
} }
String get location { String get location {
// Direct fields first // Direct fields first (state first, then city)
if (city != null && state != null) return '$city, $state'; if (city != null && state != null) return '$state, $city';
if (city != null) return city!;
if (state != null) return state!; if (state != null) return state!;
if (city != null) return city!;
// Fallback: extract from fieldValues (matches web getLocationString) // Fallback: extract from fieldValues (matches web getLocationString)
String? fvCity; String? fvCity;
@@ -112,7 +112,7 @@ class AgentProfile {
fvState = _extractFieldString(fv); fvState = _extractFieldString(fv);
} }
} }
final parts = [fvCity, fvState].where((s) => s != null && s.isNotEmpty); final parts = [fvState, fvCity].where((s) => s != null && s.isNotEmpty);
if (parts.isNotEmpty) return parts.join(', '); if (parts.isNotEmpty) return parts.join(', ');
if (country != null && country!.isNotEmpty) return country!; if (country != null && country!.isNotEmpty) return country!;

View File

@@ -165,7 +165,8 @@ class AgentDetailState {
// ── Location (from fieldValues, matching web profileDataMapper) ── // ── Location (from fieldValues, matching web profileDataMapper) ──
/// All location parts as individual items (for "+N more" display). /// All location parts as individual items (for "+N more" display).
/// Sources: detail fieldValues city/state arrays → agent model → serviceAreas /// Sources: detail fieldValues state/city arrays → agent model → serviceAreas
/// Order: state first, then city.
List<String> get locationParts { List<String> get locationParts {
final parts = <String>[]; final parts = <String>[];
@@ -180,23 +181,23 @@ class AgentDetailState {
fvStates = _extractAllValuesAsList(fv); fvStates = _extractAllValuesAsList(fv);
} }
} }
if (fvCities != null) parts.addAll(fvCities); if (fvStates != null) parts.addAll(fvStates);
if (fvStates != null) { if (fvCities != null) {
for (final s in fvStates) { for (final c in fvCities) {
if (!parts.any((p) => p.toLowerCase() == s.toLowerCase())) { if (!parts.any((p) => p.toLowerCase() == c.toLowerCase())) {
parts.add(s); parts.add(c);
} }
} }
} }
// 2. Fallback: agent model direct city/state // 2. Fallback: agent model direct state/city
if (parts.isEmpty && agent != null) { if (parts.isEmpty && agent != null) {
if (agent!.city != null && agent!.city!.isNotEmpty) {
parts.add(agent!.city!);
}
if (agent!.state != null && agent!.state!.isNotEmpty) { if (agent!.state != null && agent!.state!.isNotEmpty) {
parts.add(agent!.state!); parts.add(agent!.state!);
} }
if (agent!.city != null && agent!.city!.isNotEmpty) {
parts.add(agent!.city!);
}
} }
// 3. Fallback: serviceAreas // 3. Fallback: serviceAreas

View File

@@ -594,29 +594,49 @@ class _AgentCardState extends State<_AgentCard> {
const SizedBox(width: 4), const SizedBox(width: 4),
Builder(builder: (_) { Builder(builder: (_) {
final allParts = <String>[]; final allParts = <String>[];
// Extract all cities/states from fieldValues arrays // Extract states first, then cities (state-first display)
List<String> extractValues(dynamic fv) {
final out = <String>[];
if (fv.jsonValue is List) {
for (final v in (fv.jsonValue as List)) {
final s = v.toString().trim();
if (s.isEmpty) continue;
out.add(s
.split('_')
.map((w) => w.isNotEmpty
? '${w[0].toUpperCase()}${w.substring(1).toLowerCase()}'
: '')
.join(' '));
}
} else if (fv.textValue != null &&
(fv.textValue as String).isNotEmpty) {
out.add(fv.textValue as String);
}
return out;
}
void addUnique(String value) {
if (!allParts.any((p) =>
p.toLowerCase() == value.toLowerCase())) {
allParts.add(value);
}
}
// 1. States first
for (final fv in agent.fieldValues) { for (final fv in agent.fieldValues) {
final slug = fv.fieldSlug.toLowerCase(); final slug = fv.fieldSlug.toLowerCase();
if (slug == 'city' || slug == 'city_name' || if (slug == 'state' || slug == 'state_name') {
slug == 'state' || slug == 'state_name') { for (final v in extractValues(fv)) {
if (fv.jsonValue is List) { addUnique(v);
for (final v in (fv.jsonValue as List)) { }
final s = v.toString().trim(); }
if (s.isEmpty) continue; }
final display = s // 2. Cities next
.split('_') for (final fv in agent.fieldValues) {
.map((w) => w.isNotEmpty final slug = fv.fieldSlug.toLowerCase();
? '${w[0].toUpperCase()}${w.substring(1).toLowerCase()}' if (slug == 'city' || slug == 'city_name') {
: '') for (final v in extractValues(fv)) {
.join(' '); addUnique(v);
if (!allParts.any((p) =>
p.toLowerCase() == display.toLowerCase())) {
allParts.add(display);
}
}
} else if (fv.textValue != null &&
fv.textValue!.isNotEmpty) {
allParts.add(fv.textValue!);
} }
} }
} }

View File

@@ -121,7 +121,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
const Padding( const Padding(
padding: EdgeInsets.symmetric(horizontal: 16), padding: EdgeInsets.symmetric(horizontal: 16),
child: Text( child: Text(
'Login or create an account to enjoy FREE consultation on all property inquiries.', 'Login or create an account',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontFamily: 'SourceSerif4', fontFamily: 'SourceSerif4',