From fcfb3827baad6eb277621df1edd2a7d2b713a7c5 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Wed, 18 Mar 2026 13:04:10 +0530 Subject: [PATCH] feat: Enable agents to set a custom headline and manage location via distinct city, state, and country fields, and enhance contract count display logic. --- .../settings/ProfileSettingsForm.tsx | 32 +++++++++++-------- src/services/agents.service.ts | 4 +++ src/utils/profileDataMapper.ts | 28 +++++++++++----- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/components/settings/ProfileSettingsForm.tsx b/src/components/settings/ProfileSettingsForm.tsx index ed54441..6f270ee 100644 --- a/src/components/settings/ProfileSettingsForm.tsx +++ b/src/components/settings/ProfileSettingsForm.tsx @@ -78,10 +78,10 @@ export function ProfileSettingsForm({ const profileData = { firstName: profile.firstName || '', lastName: profile.lastName || '', - career: profile.agentType?.name || 'Real Estate Agent', + career: profile.headline || profile.agentType?.name || 'Real Estate Agent', email: profile.email || session?.user?.email || '', phone: profile.phone || '', - location: profile.serviceAreas?.[0] || '', + location: [profile.city, profile.state, profile.country].filter(Boolean).join(', '), }; setFormData(profileData); setOriginalData(profileData); // Store original for cancel @@ -287,16 +287,20 @@ export function ProfileSettingsForm({ const role = (session?.user as any)?.role; // Update profile based on role (email is not editable - tied to auth) + // Parse location into city, state, country + const locationParts = formData.location.split(',').map(s => s.trim()); + if (role === 'AGENT') { await agentsService.updateProfile({ firstName: formData.firstName, lastName: formData.lastName, phone: formData.phone, - serviceAreas: formData.location ? [formData.location] : [], + headline: formData.career, + city: locationParts[0] || '', + state: locationParts[1] || '', + country: locationParts[2] || '', }); } else { - // Parse location into city, state, country for users - const locationParts = formData.location.split(',').map(s => s.trim()); await usersService.updateProfile({ firstName: formData.firstName, lastName: formData.lastName, @@ -307,15 +311,15 @@ export function ProfileSettingsForm({ }); } - // Update session with new name - const fullName = `${formData.firstName} ${formData.lastName}`.trim(); - await updateSession({ - ...session, - user: { - ...session?.user, - name: fullName, - }, - }); + // Update session name without causing a page refresh + try { + const fullName = `${formData.firstName} ${formData.lastName}`.trim(); + await updateSession({ + user: { name: fullName }, + }); + } catch { + // Session update can fail silently - profile is already saved + } // Dispatch event to notify header and other components to refresh profile data window.dispatchEvent(new Event('profile-updated')); diff --git a/src/services/agents.service.ts b/src/services/agents.service.ts index fedc24b..9726f1e 100644 --- a/src/services/agents.service.ts +++ b/src/services/agents.service.ts @@ -17,12 +17,16 @@ export interface AgentProfile { email: string | null; phone: string | null; bio: string | null; + headline: string | null; avatar: string | null; licenseNumber: string | null; experience: number | null; specializations: string[]; languages: string[]; serviceAreas: string[]; + city: string | null; + state: string | null; + country: string | null; rating: number | null; reviewCount: number; isVerified: boolean; diff --git a/src/utils/profileDataMapper.ts b/src/utils/profileDataMapper.ts index 62f557c..de97f5b 100644 --- a/src/utils/profileDataMapper.ts +++ b/src/utils/profileDataMapper.ts @@ -38,18 +38,30 @@ function mapYearsValueToLabel(value: string | undefined): string { } // Helper to format contracts count +// Backend stores this as a RADIO field with range labels: "<3", "3-10", "10-20", "20-50", "50+" function formatContractsCount(value: unknown): string { if (!value) return '-'; - const num = typeof value === 'number' ? value : parseInt(String(value), 10); - if (isNaN(num)) return '-'; + const str = String(value).trim(); + if (!str) return '-'; - if (num >= 100) return '100+ Contracts'; - if (num >= 50) return '50+ Contracts'; - if (num >= 20) return '20+ Contracts'; - if (num >= 10) return '10+ Contracts'; - if (num >= 5) return '5+ Contracts'; - return `${num} Contract${num !== 1 ? 's' : ''}`; + // Map known range labels to display strings + const rangeMapping: Record = { + '<3': 'Less than 3 Contracts', + '3-10': '3-10 Contracts', + '10-20': '10-20 Contracts', + '20-50': '20-50 Contracts', + '50+': '50+ Contracts', + }; + + if (rangeMapping[str]) return rangeMapping[str]; + + // Fallback: if it's a plain number, format it + const num = parseInt(str, 10); + if (!isNaN(num)) return `${num} Contract${num !== 1 ? 's' : ''}`; + + // Fallback: return the raw value as-is (e.g. "Less than 3") + return str; } // Parse expertise areas with years (format: "Area Name - X yrs" or just "Area Name")