fc / phone-resolver.js
Althnayi's picture
Upload 56 files
cca0cf3 verified
Raw
History Blame Contribute Delete
5.09 kB
/**
* @fileoverview
* @module utils/phone-resolver
* @description
*/
(global => {
'use strict';
const PhoneResolverEngine = {
/**
* @param {string|number} phone
* @returns {string}
*/
normalize: function(phone) {
if (!phone) return '';
let cleaned = String(phone).trim().replace(/[^0-9+]/g, '');
if (cleaned.startsWith('00')) {
cleaned = '+' + cleaned.slice(2);
}
if (!cleaned.startsWith('+') && cleaned.length >= 10) {
if (cleaned.startsWith('01') && cleaned.length === 11) {
cleaned = '+20' + cleaned.slice(1);
} else if (!cleaned.startsWith('+')) {
cleaned = '+' + cleaned;
}
}
return cleaned;
},
/**
* @param {string} phone
* @returns {{ isValid: boolean, normalized: string, digitsCount: number }}
*/
validatePhoneFormat: function(phone) {
const norm = this.normalize(phone);
const digits = norm.replace(/[^0-9]/g, '');
return {
isValid: digits.length >= 8 && digits.length <= 16,
normalized: norm,
digitsCount: digits.length
};
},
/**
* @param {string} rawPhone
* @param {Array<Object>} contactsList
* @returns {Object|null}
*/
lookupByPhone: function(rawPhone, contactsList = []) {
if (!rawPhone) return null;
const normTarget = this.normalize(rawPhone);
if (!normTarget) return null;
const exactMatch = contactsList.find(c => {
const normC = this.normalize(c.phone);
if (normC === normTarget) return true;
if (c.altPhones && Array.isArray(c.altPhones)) {
return c.altPhones.some(ap => {
const pVal = typeof ap === 'object' ? ap.phone : ap;
return this.normalize(pVal) === normTarget;
});
}
return false;
});
if (exactMatch) return exactMatch;
const digitsOnly = normTarget.replace(/[^0-9]/g, '');
if (digitsOnly.length >= 8) {
const partialMatch = contactsList.find(c => {
const cDigits = (c.phone || '').replace(/[^0-9]/g, '');
return cDigits.endsWith(digitsOnly) || digitsOnly.endsWith(cDigits);
});
if (partialMatch) return partialMatch;
}
return null;
},
bindGlobalAutoResolution: function() {
if (window.__fritreeGlobalPhoneAutoResBound) return;
window.__fritreeGlobalPhoneAutoResBound = true;
document.addEventListener('input', (e) => {
const target = e.target;
if (!target || (target.tagName !== 'INPUT' && target.tagName !== 'TEXTAREA')) return;
if (target.classList.contains('kljqnbvx11')) return;
const val = target.value;
if (!val || val.length < 8) return;
const cleaned = this.normalize(val);
if (cleaned && cleaned.length >= 8) {
const contacts = global.FritreeContacts ? global.FritreeContacts.getContacts() : [];
const match = this.lookupByPhone(cleaned, contacts);
if (match && match.name) {
const parentForm = target.closest('div, form, section') || target.parentNode;
if (parentForm) {
const nameInputs = parentForm.querySelectorAll('input[type="text"]:not([readonly]), input[id*="name"], input[placeholder*="اسم"]');
nameInputs.forEach(input => {
if (input !== target && !input.value) {
input.value = match.name;
input.dispatchEvent(new Event('input', { bubbles: true }));
const originalBg = input.style.backgroundColor;
input.style.backgroundColor = '#dcfce7';
input.style.transition = 'background-color 0.3s ease';
setTimeout(() => {
input.style.backgroundColor = originalBg || '';
}, 1600);
}
});
}
}
}
});
}
};
global.FritreeContactsResolver = PhoneResolverEngine;
})(typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : this);