refactor: update agent location display logic to prioritize state over city across UI and models
This commit is contained in:
@@ -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!;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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!);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
Reference in New Issue
Block a user