1/** 2 * VIP DoÄrulama modalı â konum + arsa/tarla/ticari verified durumu. 3 * ESC / backdrop kapatmaz; İptal â false, Devam â true. 4 */ 5 6function pickValue(source, keys) { 7 try { 8 for (let i = 0; i < keys.length; i++) { 9 const k = keys[i]; 10 const v = source ? source[k] : null; 11 if (v !== null && v !== undefined && String(v).trim() !== '') return String(v).trim(); 12 } 13 } catch (_) {} 14 return ''; 15} 16 17function formatArea(value) { 18 if (value === null || value === undefined || value === '') return ''; 19 try { 20 if (typeof window.formatAreaM2Label === 'function') { 21 const t = window.formatAreaM2Label(value); 22 if (t) return t; 23 } 24 if (typeof window.parseLocaleNumberTr === 'function') { 25 const nTr = window.parseLocaleNumberTr(value); 26 if (Number.isFinite(nTr) && nTr > 0) { 27 return `${nTr.toLocaleString('tr-TR', { minimumFractionDigits: 0, maximumFractionDigits: 2 })} m²`; 28 } 29 } 30 } catch (_) {} 31 return ''; 32} 33 34function getCsrfToken() { 35 try { 36 const m = document.cookie.match(/(?:^|; )csrftoken=([^;]+)/); 37 return m ? decodeURIComponent(m[1]) : ''; 38 } catch (_) { 39 return ''; 40 } 41} 42 43function statusLabel(status) { 44 const s = String(status || '').toLowerCase(); 45 if (s === 'verified') return { text: 'DoÄrulandı', color: '#15803d', bg: '#dcfce7', border: '#86efac' }; 46 if (s === 'unverified') return { text: 'DoÄrulanmadı', color: '#c2410c', bg: '#ffedd5', border: '#fdba74' }; 47 return { text: 'Veri yok', color: '#475569', bg: '#f1f5f9', border: '#cbd5e1' }; 48} 49 50function buildStatusRowHtml(label, status) { 51 const st = statusLabel(status); 52 return ( 53 `<div style="display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 10px;border:1px solid #e2e8f0;background:#fff;margin-bottom:6px;">` 54 + `<span style="font-weight:700;color:#0f172a;font-size:13px;">${label}</span>` 55 + `<span style="font-weight:700;font-size:12px;padding:4px 10px;border:1px solid ${st.border};background:${st.bg};color:${st.color};">${st.text}</span>` 56 + `</div>` 57 ); 58} 59 60async function fetchVerificationStatus(tkgmData) { 61 const props = (tkgmData && tkgmData.properties) ? tkgmData.properties : {}; 62 const payload = { 63 proparcel_value: props.Proparcel_value ?? props.proparcel_value ?? null, 64 mahalleId: props.mahalleId ?? props.mahalleTkgmValue ?? props.mahalle_tkgm_value ?? null, 65 properties: { 66 Proparcel_value: props.Proparcel_value ?? props.proparcel_value ?? null, 67 mahalleId: props.mahalleId ?? null, 68 mahalleAd: props.mahalleAd ?? props.mahalle ?? null, 69 ilAd: props.ilAd ?? props.il ?? null, 70 ilceAd: props.ilceAd ?? props.ilce ?? null, 71 }, 72 }; 73 74 const headers = { 'Content-Type': 'application/json', Accept: 'application/json' }; 75 const csrf = getCsrfToken(); 76 if (csrf) headers['X-CSRFToken'] = csrf; 77 78 const res = await fetch('/api/quarter_price_verification_status/', { 79 method: 'POST', 80 credentials: 'same-origin', 81 headers, 82 body: JSON.stringify(payload), 83 }); 84 const data = await res.json().catch(() => ({})); 85 if (!res.ok || !data || data.success !== true) { 86 throw new Error((data && data.error) || 'Durum alınamadı'); 87 } 88 return data; 89} 90 91export function openProQueryVerificationModal(tkgmData) { 92 return new Promise((resolve) => { 93 try { 94 const existing = document.getElementById('ppProVerificationModal'); 95 if (existing) existing.remove(); 96 } catch (_) {} 97 98 const loadingSnapshot = (function () { 99 const snap = { 100 legacyVisible: false, 101 legacyText: null, 102 }; 103 try { 104 const el = document.getElementById('loading-overlay'); 105 if (el) { 106 const disp = String(el.style.display || '').toLowerCase(); 107 snap.legacyVisible = disp !== 'none'; 108 try { 109 const t = el.querySelector('div:last-child'); 110 if (t && t.textContent) snap.legacyText = String(t.textContent); 111 } catch (_) {} 112 } 113 } catch (_) {} 114 return snap; 115 })(); 116 117 try { 118 if (window.ProParcelLoader && typeof window.ProParcelLoader.isVisible === 'function' && window.ProParcelLoader.isVisible()) { 119 // leave animated loader
120 } else if (window.proParcelApp && typeof window.proParcelApp.hideLoading === 'function') { 121 window.proParcelApp.hideLoading(); 122 } else if (typeof window.hideLoading === 'function') { 123 window.hideLoading(); 124 } else { 125 const el = document.getElementById('loading-overlay'); 126 if (el) el.style.display = 'none'; 127 } 128 } catch (_) {} 129 130 const props = (tkgmData && tkgmData.properties) ? tkgmData.properties : {}; 131 const il = pickValue(props, ['ilAd', 'il', 'cityName', 'CityName']); 132 const ilce = pickValue(props, ['ilceAd', 'ilce', 'townName', 'TownName']); 133 const mahalle = pickValue(props, ['mahalleAd', 'mahalle', 'quarterName', 'QuarterName']); 134 const ada = pickValue(props, ['adaNo', 'ada', 'Ada']); 135 const parsel = pickValue(props, ['parselNo', 'parsel', 'Parsel']); 136 const alanRaw = 137 (props ? (props.alan ?? props.yuzolcum ?? props.Yuzolcum ?? props.area ?? props.Area ?? props.area_m2) : null) ?? 138 (tkgmData ? (tkgmData.alan ?? tkgmData.yuzolcum ?? tkgmData.Area) : null); 139 const alan = formatArea(alanRaw); 140 const row1 = [il, ilce, mahalle].filter(Boolean).join(' / ') || '-'; 141 const row2Left = (ada && parsel) ? `${ada}/${parsel}` : (ada || parsel || ''); 142 const row2 = [row2Left, alan].filter(Boolean).join(' ⢠') || '-'; 143 144 const overlay = document.createElement('div'); 145 overlay.id = 'ppProVerificationModal'; 146 overlay.style.position = 'fixed'; 147 overlay.style.left = '0'; 148 overlay.style.top = '0'; 149 overlay.style.width = '100%'; 150 overlay.style.height = '100%'; 151 overlay.style.background = 'transparent'; 152 overlay.style.zIndex = '100001'; 153 154 overlay.innerHTML = ` 155<div id="ppProVerificationDialog" style="position:absolute;right:24px;top:50%;transform:translateY(-50%);background:#fff;border-radius:0;min-width:360px;max-width:92vw;box-shadow:0 12px 32px rgba(0,0,0,0.35);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;"> 156 <div id="ppProVerificationHeader" style="padding:18px 22px 10px 22px;border-bottom:1px solid #eee;cursor:move;user-select:none;"> 157 <div style="font-weight:800;color:#0f172a;font-size:16px;margin-bottom:8px;">DoÄrulama Durumu</div> 158 <div style="font-weight:600;color:#334155;line-height:1.45;font-size:13.5px;white-space:pre-line;">${row1}</div> 159 <div style="font-weight:600;color:#334155;line-height:1.45;font-size:13.5px;white-space:pre-line;margin-top:4px;">${row2}</div> 160 </div> 161 <div style="padding:14px 22px 6px 22px;"> 162 <div id="ppProVerificationStatusBody" style="background:#f8fafc;border:1px solid #e2e8f0;padding:12px;"> 163 <div style="font-weight:600;color:#64748b;font-size:13px;">Kontrol ediliyorâ¦</div> 164 </div> 165 </div> 166 <div style="padding:12px 22px 18px 22px;display:flex;gap:10px;justify-content:space-between;"> 167 <button id="ppProVerificationCancel" class="btn" style="flex:1;border:1px solid #cbd5e1;background:#f1f5f9;border-radius:0;padding:10px 12px;font-weight:800;color:#334155;">İptal</button> 168 <button id="ppProVerificationOk" class="btn btn-primary" style="flex:1;border:1px solid #2563eb;background:#3b82f6;border-radius:0;padding:10px 12px;font-weight:800;color:#fff;">Devam</button> 169 </div> 170</div>`; 171 172 const cleanup = () => { 173 try { overlay.remove(); } catch (_) {} 174 try { document.removeEventListener('keydown', onKeyDown, { capture: true }); } catch (_) {} 175 try { document.removeEventListener('mousemove', onMove, true); } catch (_) {} 176 try { document.removeEventListener('mouseup', onUp, true); } catch (_) {} 177 try { 178 if (window.ProParcelLoader && typeof window.ProParcelLoader.isVisible === 'function' && window.ProParcelLoader.isVisible()) { 179 // keep 180 } else if (loadingSnapshot.legacyVisible) { 181 const msg = loadingSnapshot.legacyText || 'Parsel sorgulanıyor...'; 182 if (window.proParcelApp && typeof window.proParcelApp.showLoading === 'function') { 183 window.proParcelApp.showLoading(msg); 184 } else if (typeof window.showLoading === 'function') { 185 window.showLoading(msg); 186 } else { 187 const el = document.getElementById('loading-overlay'); 188 if (el) el.style.display = 'flex'; 189 } 190 } 191 } catch (_) {} 192 }; 193 194 const onKeyDown = (ev) => { 195 if (ev && ev.key === 'Escape') return; 196 }; 197 198 const onClick = (ev) => { 199 const t = ev && ev.target; 200 if (!t) return; 201 if (t.id === 'ppProVerificationCancel') { 202 cleanup(); 203 resolve(false); 204 return; 205 } 206 if (t.id === 'ppProVerificationOk') { 207 cleanup(); 208 resolve(true); 209 return; 210 } 211 }; 212 213 overlay.addEventListener('click', onClick, false); 214 document.addEventListener('keydown', onKeyDown, { capture: true });
215 document.body.appendChild(overlay); 216 217 const dialog = overlay.querySelector('#ppProVerificationDialog'); 218 const header = overlay.querySelector('#ppProVerificationHeader'); 219 const drag = { active: false, startX: 0, startY: 0, origLeft: 0, origTop: 0 }; 220 const onMove = (ev) => { 221 if (!drag.active || !dialog) return; 222 const dx = ev.clientX - drag.startX; 223 const dy = ev.clientY - drag.startY; 224 dialog.style.left = `${drag.origLeft + dx}px`; 225 dialog.style.top = `${drag.origTop + dy}px`; 226 }; 227 const onUp = () => { 228 drag.active = false; 229 try { document.removeEventListener('mousemove', onMove, true); } catch (_) {} 230 try { document.removeEventListener('mouseup', onUp, true); } catch (_) {} 231 }; 232 if (header && dialog) { 233 header.addEventListener('mousedown', (ev) => { 234 if (ev.button !== 0) return; 235 ev.preventDefault(); 236 drag.active = true; 237 drag.startX = ev.clientX; 238 drag.startY = ev.clientY; 239 const rect = dialog.getBoundingClientRect(); 240 dialog.style.position = 'fixed'; 241 dialog.style.transform = 'none'; 242 dialog.style.left = `${rect.left}px`; 243 dialog.style.top = `${rect.top}px`; 244 drag.origLeft = rect.left; 245 drag.origTop = rect.top; 246 document.addEventListener('mousemove', onMove, true); 247 document.addEventListener('mouseup', onUp, true); 248 }, false); 249 } 250 251 const bodyEl = overlay.querySelector('#ppProVerificationStatusBody'); 252 fetchVerificationStatus(tkgmData) 253 .then((data) => { 254 if (!bodyEl) return; 255 const p = (data && data.properties) || {}; 256 const arsa = (p.arsa && p.arsa.status) || 'missing'; 257 const tarla = (p.tarla && p.tarla.status) || 'missing'; 258 const ticari = (p.ticari && p.ticari.status) || 'missing'; 259 bodyEl.innerHTML = 260 `<div style="font-weight:700;color:#0f172a;font-size:13px;margin-bottom:10px;">Mahalle birim fiyat durumu</div>` 261 + buildStatusRowHtml('Arsa', arsa) 262 + buildStatusRowHtml('Tarla', tarla) 263 + buildStatusRowHtml('Ticari', ticari); 264 }) 265 .catch(() => { 266 if (!bodyEl) return; 267 bodyEl.innerHTML = 268 `<div style="font-weight:600;color:#b45309;font-size:13px;line-height:1.45;">Durum alınamadı. İsterseniz yine de devam edebilirsiniz.</div>`; 269 }); 270 }); 271}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.