/** * @fileoverview Contact Record Editor & Modal Controller * @module controllers/contacts-editor-controller * @description وحدة التحكم في نافذة إنشاء وتعديل العملاء، إدارة الأرقام المتعددة، والحقول المخصصة. */ (global => { 'use strict'; /** * تنظيف وتنسيق رقم الهاتف عبر المحرك المعتمد * @param {string} phone * @returns {string} */ function normalizePhone(phone) { if (global.FritreeContactsResolver && typeof global.FritreeContactsResolver.normalize === 'function') { return global.FritreeContactsResolver.normalize(phone); } return phone ? String(phone).replace(/[^0-9+]/g, '') : ''; } /** * وحدة التحكم في محرر جهات الاتصال */ const ContactEditorController = { /** * إضافة سطر إدخال رقم هاتف ديناميكي مع تحديد نوع الرقم * @param {string} phoneVal * @param {string} phoneType ('mobile' | 'whatsapp' | 'work' | 'home' | 'other') */ addPhoneInputRow: function(phoneVal = '', phoneType = 'mobile') { const container = document.getElementById('pe2oiv9nvs'); if (!container) return; const row = document.createElement('div'); row.className = 'qp7emstoll'; row.style.cssText = 'display:flex; gap:6px; align-items:center; margin-bottom:6px;'; const typeSelect = document.createElement('select'); typeSelect.className = 'xy26ymifmf f0jy0nh7wu'; typeSelect.style.cssText = 'width:130px; padding:8px; font-size:11px; border-radius:6px; background:#fff; font-weight:bold;'; typeSelect.innerHTML = ` `; const input = document.createElement('input'); input.type = 'text'; input.className = 'xy26ymifmf kljqnbvx11'; input.placeholder = 'مثال: +201069794840'; input.value = phoneVal; input.style.cssText = 'flex:1; padding:8px 12px; direction:ltr; text-align:left;'; const removeBtn = document.createElement('button'); removeBtn.type = 'button'; removeBtn.className = 'btn-danger'; removeBtn.style.cssText = 'padding:6px 10px; font-size:11px; height:36px; border-radius:6px; background:#fee2e2; color:#ef4444; border:1px solid #fca5a5;'; removeBtn.innerHTML = ' '; removeBtn.title = 'حذف الرقم ده'; removeBtn.onclick = () => { if (container.querySelectorAll('.qp7emstoll').length > 1) { row.remove(); } else { input.value = ''; } }; row.appendChild(typeSelect); row.appendChild(input); row.appendChild(removeBtn); container.appendChild(row); // إضافة سطر جديد تلقائياً عند البدء في كتابة رقم بالسطر الأخير input.addEventListener('input', () => { const rows = container.querySelectorAll('.kljqnbvx11'); const lastInput = rows[rows.length - 1]; if (input === lastInput && input.value.trim().length > 0) { this.addPhoneInputRow('', 'mobile'); } const val = input.value.trim(); if (val.length >= 8 && global.FritreeContacts) { const match = global.FritreeContacts.lookup(val); if (match) { this.populateFormFields(match); } } }); }, /** * إضافة سطر حقل مخصص جديد * @param {string} key * @param {string} val */ addCustomFieldRow: function(key = '', val = '') { const container = document.getElementById('du5h7y5kct'); if (!container) return; const row = document.createElement('div'); row.className = 'tupbvypcqw'; row.style.cssText = 'display:flex; gap:6px; align-items:center; margin-bottom:6px;'; const keyInput = document.createElement('input'); keyInput.type = 'text'; keyInput.className = 'xy26ymifmf h83d317lfm'; keyInput.placeholder = 'اسم الحقل (زي: الميزانية)'; keyInput.value = key; keyInput.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;'; const valInput = document.createElement('input'); valInput.type = 'text'; valInput.className = 'xy26ymifmf cv3mq1mhux'; valInput.placeholder = 'القيمة (زي: 50,000 ج.م)'; valInput.value = val; valInput.style.cssText = 'flex:1.5; padding:6px 10px; font-size:11px;'; const removeBtn = document.createElement('button'); removeBtn.type = 'button'; removeBtn.className = 'btn-danger'; removeBtn.style.cssText = 'padding:4px 8px; font-size:10px; height:32px; border:2px solid var(--border);'; removeBtn.innerHTML = ' '; removeBtn.onclick = () => row.remove(); row.appendChild(keyInput); row.appendChild(valInput); row.appendChild(removeBtn); container.appendChild(row); }, /** * ملء حقول النموذج ببيانات العميل المطابق * @param {Object} match */ populateFormFields: function(match) { document.getElementById('qfv7jp577g').value = match.id || ''; document.getElementById('sdd0e5bwjh').value = match.name || ''; document.getElementById('n8v43cmfzp').value = match.email || ''; document.getElementById('bluyqoyzyu').value = match.company || ''; document.getElementById('hns86xlu9u').value = match.jobTitle || ''; document.getElementById('tai1zux829').value = match.department || ''; document.getElementById('foockjmk6s').value = match.lifecycle || 'lead'; document.getElementById('g1oufrwen8').value = match.priority || 'medium'; document.getElementById('x1cb3ek74e').value = match.source || 'direct'; document.getElementById('s2admrtim1').value = match.nextFollowupDate ? match.nextFollowupDate.slice(0, 10) : ''; document.getElementById('ftiovdh9zk').value = match.preferredChannel || 'whatsapp'; document.getElementById('m6m8pmqk2g').value = match.preferredTime || 'any'; document.getElementById('kgb8k4l7x8').value = match.address || ''; document.getElementById('c4aemm27ll').value = match.website || ''; document.getElementById('abqk9m5uxg').value = match.tags ? match.tags.join(', ') : ''; document.getElementById('ab9w3psogf').value = match.notes || ''; document.getElementById('baysuwhq61').checked = !!match.blacklisted; if (match.customFields && typeof match.customFields === 'object') { const customContainer = document.getElementById('du5h7y5kct'); if (customContainer) { customContainer.innerHTML = ''; Object.entries(match.customFields).forEach(([k, v]) => { this.addCustomFieldRow(k, v); }); } } const title = document.getElementById('kvcvcii0b6'); if (title) title.textContent = `تعديل بيانات العميل: ${match.name}`; const badge = document.getElementById('o497sju1mo'); if (badge) { badge.style.display = 'inline-flex'; badge.innerHTML = `تم جلب بيانات العميل: ${match.name}`; } ['sdd0e5bwjh', 'n8v43cmfzp', 'bluyqoyzyu', 'hns86xlu9u', 'abqk9m5uxg', 'ab9w3psogf'].forEach(id => { const el = document.getElementById(id); if (el) { el.style.backgroundColor = '#dcfce7'; setTimeout(() => { el.style.backgroundColor = ''; }, 1800); } }); }, /** * فتح نافذة تحرير العميل (جديد أو تعديل) * @param {string|null} contactId */ openModal: function(contactId = null) { const modal = document.getElementById('g2vl6bip8z'); const title = document.getElementById('kvcvcii0b6'); const phoneContainer = document.getElementById('pe2oiv9nvs'); const customContainer = document.getElementById('du5h7y5kct'); const badge = document.getElementById('o497sju1mo'); if (!modal || !phoneContainer) return; phoneContainer.innerHTML = ''; if (customContainer) customContainer.innerHTML = ''; if (badge) badge.style.display = 'none'; const contacts = global.FritreeContacts ? global.FritreeContacts.getContacts() : []; if (contactId) { const c = contacts.find(x => x.id === contactId); if (!c) return; this.populateFormFields(c); this.addPhoneInputRow(c.phone, 'mobile'); if (c.altPhones && Array.isArray(c.altPhones)) { c.altPhones.forEach(ph => { const pVal = typeof ph === 'object' ? ph.phone : ph; const pType = typeof ph === 'object' ? ph.type : 'work'; this.addPhoneInputRow(pVal, pType); }); } this.addPhoneInputRow('', 'mobile'); } else { document.getElementById('qfv7jp577g').value = ''; document.getElementById('sdd0e5bwjh').value = ''; document.getElementById('n8v43cmfzp').value = ''; document.getElementById('bluyqoyzyu').value = ''; document.getElementById('hns86xlu9u').value = ''; document.getElementById('tai1zux829').value = ''; document.getElementById('foockjmk6s').value = 'lead'; document.getElementById('x1cb3ek74e').value = 'direct'; document.getElementById('g1oufrwen8').value = 'medium'; document.getElementById('s2admrtim1').value = ''; document.getElementById('ftiovdh9zk').value = 'whatsapp'; document.getElementById('m6m8pmqk2g').value = 'any'; document.getElementById('kgb8k4l7x8').value = ''; document.getElementById('c4aemm27ll').value = ''; document.getElementById('abqk9m5uxg').value = ''; document.getElementById('ab9w3psogf').value = ''; document.getElementById('baysuwhq61').checked = false; if (title) title.textContent = 'إضافة عميل جديد بكامل البيانات'; this.addPhoneInputRow('', 'mobile'); } modal.style.display = 'flex'; }, /** * حفظ بيانات العميل في الخزنة المشفرة وتحديث التقويم */ saveContactSubmit: async function() { const core = global.FritreeContacts; if (!core || !core.state) return; const state = core.state; const id = document.getElementById('qfv7jp577g').value; const name = document.getElementById('sdd0e5bwjh').value.trim(); const email = document.getElementById('n8v43cmfzp').value.trim(); const company = document.getElementById('bluyqoyzyu').value.trim(); const jobTitle = document.getElementById('hns86xlu9u').value.trim(); const department = document.getElementById('tai1zux829').value.trim(); const lifecycle = document.getElementById('foockjmk6s').value; const source = document.getElementById('x1cb3ek74e').value; const priority = document.getElementById('g1oufrwen8').value; const nextFollowupDate = document.getElementById('s2admrtim1').value; const preferredChannel = document.getElementById('ftiovdh9zk').value; const preferredTime = document.getElementById('m6m8pmqk2g').value; const address = document.getElementById('kgb8k4l7x8').value.trim(); const website = document.getElementById('c4aemm27ll').value.trim(); const tagsStr = document.getElementById('abqk9m5uxg').value; const notes = document.getElementById('ab9w3psogf').value.trim(); const blacklisted = document.getElementById('baysuwhq61').checked; const phoneRows = document.querySelectorAll('.qp7emstoll'); const phoneList = []; phoneRows.forEach(row => { const f = row.querySelector('.kljqnbvx11'); const t = row.querySelector('.f0jy0nh7wu'); if (f && f.value) { const norm = normalizePhone(f.value); if (norm && norm.length >= 7 && !phoneList.some(p => p.phone === norm)) { phoneList.push({ phone: norm, type: t ? t.value : 'mobile' }); } } }); if (phoneList.length === 0) { alert('اكتب رقم موبايل صحيح واحد على الأقل بالمفتاح الدولي!'); return; } const customFields = {}; const customRows = document.querySelectorAll('.tupbvypcqw'); customRows.forEach(cr => { const kEl = cr.querySelector('.h83d317lfm'); const vEl = cr.querySelector('.cv3mq1mhux'); if (kEl && kEl.value.trim()) { customFields[kEl.value.trim()] = vEl ? vEl.value.trim() : ''; } }); const mainPhone = phoneList[0].phone; const altPhones = phoneList.slice(1); const tags = tagsStr.split(',').map(t => t.trim()).filter(t => t); if (id) { const idx = state.contacts.findIndex(c => c.id === id); if (idx !== -1) { state.contacts[idx] = { ...state.contacts[idx], name: name || 'المستلم', phone: mainPhone, altPhones: altPhones, email: email, company: company, jobTitle: jobTitle, department: department, lifecycle: lifecycle, source: source, priority: priority, nextFollowupDate: nextFollowupDate, preferredChannel: preferredChannel, preferredTime: preferredTime, address: address, website: website, customFields: customFields, tags: tags, notes: notes, blacklisted: blacklisted, updatedAt: new Date().toISOString() }; } } else { const newContact = { id: 'cnt_' + Date.now() + '_' + Math.random().toString(36).substr(2, 4), name: name || 'المستلم', phone: mainPhone, altPhones: altPhones, email: email, company: company, jobTitle: jobTitle, department: department, lifecycle: lifecycle, source: source, priority: priority, nextFollowupDate: nextFollowupDate, preferredChannel: preferredChannel, preferredTime: preferredTime, address: address, website: website, customFields: customFields, tags: tags, notes: notes, blacklisted: blacklisted, createdAt: new Date().toISOString() }; state.contacts.unshift(newContact); } await core.save(); core.refreshUI(); document.getElementById('g2vl6bip8z').style.display = 'none'; // تسجيل المتابعة تلقائياً في التقويم الذكي if (global.FritreeCalendar && typeof global.FritreeCalendar.logActivity === 'function') { global.FritreeCalendar.logActivity({ title: id ? `[تحديث عميل] ${name || 'عميل'}` : `[إضافة عميل جديد] ${name || 'عميل'} (${mainPhone})`, type: 'followup', category: 'followup', notes: `الهاتف: ${mainPhone} | الشركة: ${company || '-'} | المسمى: ${jobTitle || '-'} | تاريخ المتابعة: ${nextFollowupDate || 'غير محدد'}`, contactId: id || '', contactName: name, priority: priority === 'urgent' ? 'urgent' : (priority === 'high' ? 'high' : 'medium'), timestamp: nextFollowupDate ? new Date(nextFollowupDate).toISOString() : new Date().toISOString() }); } if (typeof window.addLog === 'function') { window.addLog(`تم بنجاح حفظ بيانات العميل: ${name || 'جديد'} (${mainPhone})`, 'success'); } }, /** * ربط أحداث أزرار نافذة التحرير */ bindEvents: function() { const btnAddModal = document.getElementById('lndjiz92pl'); const btnCloseEditor = document.getElementById('z9jjbpxjm0'); const btnSaveContact = document.getElementById('du3bb5vayt'); const btnAddCustomField = document.getElementById('duv92vxgty'); if (btnAddModal) btnAddModal.onclick = () => this.openModal(null); if (btnCloseEditor) btnCloseEditor.onclick = () => document.getElementById('g2vl6bip8z').style.display = 'none'; if (btnSaveContact) btnSaveContact.onclick = () => this.saveContactSubmit(); if (btnAddCustomField) btnAddCustomField.onclick = () => this.addCustomFieldRow(); } }; /** * تصدير وحدة تحكم محرر جهات الاتصال */ global.FritreeContactsEditor = ContactEditorController; })(typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : this);