Files
frontend/src/utils/profileDataMapper.ts

222 lines
7.4 KiB
TypeScript
Raw Normal View History

2026-01-24 23:10:02 +05:30
import { FieldValueResponse } from '@/services/agents.service';
// Experience data structure expected by ExperienceSection component
export interface ExperienceData {
years: string;
contracts: string;
licensingAreas: string[];
expertiseYears: { area: string; years: string }[];
certifications: { name: string; org: string }[];
}
// Certification entry from repeater field
interface CertificationEntry {
certification_name?: string;
issuing_organization?: string;
issue_date?: string;
expiration_date?: string;
}
// Helper to get field value by slug
function getFieldValue(fieldValues: FieldValueResponse[], slug: string): unknown {
const field = fieldValues.find(f => f.fieldSlug === slug);
return field?.value;
}
// Helper to get label from value for select/radio fields
function mapYearsValueToLabel(value: string | undefined): string {
if (!value) return '-';
const mapping: Record<string, string> = {
'<2': 'Less than 2 years',
'2+': '2+ years',
'5+': '5+ years',
'10+': '10+ years',
};
return mapping[value] || value;
}
// Helper to format contracts count
function formatContractsCount(value: unknown): string {
if (!value) return '-';
const num = typeof value === 'number' ? value : parseInt(String(value), 10);
if (isNaN(num)) 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' : ''}`;
}
// Parse expertise areas with years (format: "Area Name - X yrs" or just "Area Name")
function parseExpertiseAreas(value: unknown): { area: string; years: string }[] {
if (!value || !Array.isArray(value)) return [];
return value.map((item: string) => {
// Check if it contains a year indicator
const yearMatch = item.match(/^(.+?)\s*[-]\s*(\d+)\s*(yrs?|years?)$/i);
if (yearMatch) {
return { area: yearMatch[1].trim(), years: `${yearMatch[2]} yrs` };
}
// Just area name without years
return { area: item.trim(), years: '' };
});
}
// Parse certification entries from repeater field
function parseCertifications(value: unknown): { name: string; org: string }[] {
if (!value) return [];
// If it's an array of certification entries
if (Array.isArray(value)) {
return value
.filter((entry: CertificationEntry) => entry?.certification_name)
.map((entry: CertificationEntry) => ({
name: entry.certification_name || '',
org: entry.issuing_organization || '',
}));
}
return [];
}
/**
* Maps field values from API response to ExperienceData structure
*/
export function mapFieldValuesToExperience(fieldValues: FieldValueResponse[]): ExperienceData {
// Get years in business (could be years_in_business from Professional or Lender experience)
const yearsInBusiness = getFieldValue(fieldValues, 'years_in_business') as string | undefined;
// Get contracts completed
const contractsCompleted = getFieldValue(fieldValues, 'contracts_completed');
// Get licensing areas (could be licensed_areas from Professional or Lender)
const licensedAreas = getFieldValue(fieldValues, 'licensed_areas') as string[] | undefined;
// Get expertise areas with years
const expertiseAreas = getFieldValue(fieldValues, 'expertise_areas') as string[] | undefined;
// Get certification entries from repeater
const certificationEntries = getFieldValue(fieldValues, 'certification_entries');
return {
years: mapYearsValueToLabel(yearsInBusiness),
contracts: formatContractsCount(contractsCompleted),
licensingAreas: licensedAreas || [],
expertiseYears: parseExpertiseAreas(expertiseAreas),
certifications: parseCertifications(certificationEntries),
};
}
/**
* Check if experience data has any meaningful content
*/
export function hasExperienceData(experience: ExperienceData): boolean {
return (
experience.years !== '-' ||
experience.contracts !== '-' ||
experience.licensingAreas.length > 0 ||
experience.expertiseYears.length > 0 ||
experience.certifications.length > 0
);
}
2026-01-24 23:31:32 +05:30
// Profile card data structure
export interface ProfileCardData {
bio: string;
expertise: string[];
serviceAreas: string[];
}
// Availability data structure
export interface AvailabilityData {
type: string;
schedule: string[];
}
// Map availability option values to human-readable labels
const availabilityLabels: Record<string, string> = {
'mf_9_5': 'Monday - Friday, 9 AM - 5 PM',
'mf_8_6': 'Monday - Friday, 8 AM - 6 PM',
'weekends': 'Weekends',
'evenings': 'Evenings',
'flexible': 'Flexible Schedule',
'full_time': 'Full-time',
'part_time': 'Part-time',
'24_7': '24/7 Available',
'by_appointment': 'By Appointment Only',
'monday': 'Monday',
'tuesday': 'Tuesday',
'wednesday': 'Wednesday',
'thursday': 'Thursday',
'friday': 'Friday',
'saturday': 'Saturday',
'sunday': 'Sunday',
};
/**
* Maps field values to availability data
*/
export function mapFieldValuesToAvailability(fieldValues: FieldValueResponse[]): AvailabilityData {
const availabilityValues = getFieldValue(fieldValues, 'availability') as string[] | undefined;
if (!availabilityValues || availabilityValues.length === 0) {
return {
type: '',
schedule: [],
};
}
// Map values to human-readable labels
const schedule = availabilityValues.map(val =>
availabilityLabels[val] || val.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase())
);
// Determine type based on values
let type = 'Available';
if (availabilityValues.includes('full_time') || availabilityValues.includes('mf_9_5') || availabilityValues.includes('mf_8_6')) {
type = 'Full-time';
} else if (availabilityValues.includes('part_time')) {
type = 'Part-time';
} else if (availabilityValues.includes('flexible')) {
type = 'Flexible';
}
return {
type,
schedule,
};
}
/**
* Maps field values to profile card data (bio, expertise, service areas)
*/
export function mapFieldValuesToProfileCard(fieldValues: FieldValueResponse[]): ProfileCardData {
// Get bio/description from various possible fields
const description = getFieldValue(fieldValues, 'description') as string | undefined;
const descrption = getFieldValue(fieldValues, 'descrption') as string | undefined; // typo in field slug
const biography = getFieldValue(fieldValues, 'biography') as string | undefined;
const bio = getFieldValue(fieldValues, 'bio') as string | undefined;
// Get expertise from various possible fields
const aboutMeExpertise = getFieldValue(fieldValues, 'about_me_expertise') as string[] | undefined;
const expertiseAreas = getFieldValue(fieldValues, 'expertise_areas') as string[] | undefined;
const specializations = getFieldValue(fieldValues, 'specializations') as string[] | undefined;
const areasOfExpertise = getFieldValue(fieldValues, 'areas_of_expertise') as string[] | undefined;
// Get service areas from various possible fields
const serviceAreas = getFieldValue(fieldValues, 'service_areas') as string[] | undefined;
const licensedAreas = getFieldValue(fieldValues, 'licensed_areas') as string[] | undefined;
const coverageAreas = getFieldValue(fieldValues, 'coverage_areas') as string[] | undefined;
return {
bio: description || descrption || biography || bio || '',
expertise: aboutMeExpertise || expertiseAreas || specializations || areasOfExpertise || [],
serviceAreas: serviceAreas || licensedAreas || coverageAreas || [],
};
}