1/** 2 * ProParcel İlk Ãyelik HoÅgeldin Modalı 3 * ====================================== 4 * 5 * İlk üyelik sonrası kullanıcıya Tepe Coin kullanım bilgisi gösteren modal. 6 * window.PP_USER_HAS_SEEN_WELCOME === false ise otomatik açılır. 7 * Kapatılınca POST /api/auth/dismiss-welcome/ çaÄrılır. 8 * Ardından "Bedava Tepe Coin Kazan" modalı açılır (8 sn zorunlu, accounts_giftcoinreward). 9 */ 10 11(function () { 12 'use strict'; 13 14 var MODAL_ID = 'pp-welcome-modal'; 15 var STYLE_ID = 'pp-welcome-modal-css'; 16 var COIN_EARN_MODAL_ID = 'pp-coin-earn-modal'; 17 var COIN_EARN_STYLE_ID = 'pp-coin-earn-modal-css'; 18 var COIN_EARN_MIN_SECONDS = 8; 19 20 /* âââ CSS Injection âââ */ 21 22 function injectStyles() { 23 if (document.getElementById(STYLE_ID)) return; 24 var css = document.createElement('style'); 25 css.id = STYLE_ID; 26 css.textContent = [ 27 /* Overlay */ 28 '#' + MODAL_ID + ' {', 29 ' position:fixed; inset:0; z-index:5000000;', 30 ' display:none; align-items:center; justify-content:center;', 31 ' background:rgba(15,23,42,.5); backdrop-filter:blur(6px);', 32 ' padding:20px;', 33 '}', 34 '#' + MODAL_ID + '.is-open { display:flex; }', 35 36 /* Card */ 37 '.' + MODAL_ID + '__card {', 38 ' background:#fff; border-radius:18px; width:min(520px,95vw);', 39 ' max-height:90vh; overflow:hidden;', 40 ' box-shadow:0 24px 64px rgba(0,0,0,.22);', 41 ' animation: ppWelcomeFadeIn .25s ease;', 42 ' display:flex; flex-direction:column;', 43 '}', 44 '@keyframes ppWelcomeFadeIn { from{opacity:0;transform:scale(.95) translateY(10px)} to{opacity:1;transform:scale(1) translateY(0)} }', 45 46 /* Header - Turuncu */ 47 '.' + MODAL_ID + '__header {', 48 ' background:linear-gradient(135deg,#f97316 0%,#ea580c 100%);', 49 ' padding:20px 24px;', 50 ' display:flex; align-items:center; gap:12px;', 51 ' position:relative;', 52 '}', 53 '.' + MODAL_ID + '__header-icon {', 54 ' width:44px; height:44px; border-radius:12px;', 55 ' background:rgba(255,255,255,.2);', 56 ' display:flex; align-items:center; justify-content:center;', 57 ' font-size:20px; color:#fff; flex-shrink:0;', 58 '}', 59 '.' + MODAL_ID + '__header-text {', 60 ' flex:1;', 61 '}', 62 '.' + MODAL_ID + '__header-title {', 63 ' font-size:20px; font-weight:800; color:#fff;', 64 ' letter-spacing:1px;', 65 '}', 66 '.' + MODAL_ID + '__header-subtitle {', 67 ' font-size:13px; color:rgba(255,255,255,.85); margin-top:2px;', 68 '}', 69 '.' + MODAL_ID + '__close-btn {', 70 ' position:absolute; top:12px; right:12px;', 71 ' width:32px; height:32px; border-radius:50%;', 72 ' background:rgba(255,255,255,.2); border:none; cursor:pointer;', 73 ' display:flex; align-items:center; justify-content:center;', 74 ' color:#fff; font-size:16px; transition:background .15s;', 75 '}', 76 '.' + MODAL_ID + '__close-btn:hover { background:rgba(255,255,255,.35); }', 77 78 /* Body */ 79 '.' + MODAL_ID + '__body {', 80 ' padding:20px 24px; overflow-y:auto; flex:1;', 81 '}', 82 83 /* Warning text */ 84 '.' + MODAL_ID + '__warning {', 85 ' background:#fff7ed; border:1px solid #fed7aa; border-radius:12px;', 86 ' padding:14px 16px; margin-bottom:18px;', 87 ' font-size:14px; color:#9a3412; line-height:1.6; font-weight:500;', 88 ' display:flex; align-items:flex-start; gap:10px;', 89 '}', 90 '.' + MODAL_ID + '__warning-icon {', 91 ' font-size:18px; color:#f97316; flex-shrink:0; margin-top:1px;', 92 '}', 93 94 /* Packages grid */ 95 '.' + MODAL_ID + '__packages-title {', 96 ' font-size:13px; font-weight:700; color:#64748b;', 97 ' text-transform:uppercase; letter-spacing:.5px;', 98 ' margin-bottom:12px;', 99 '}', 100 '.' + MODAL_ID + '__grid {', 101 ' display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr));', 102 ' gap:10px; margin-bottom:18px;', 103 '}', 104 '.' + MODAL_ID + '__pkg {', 105 ' background:#f8fafc; border:1px solid #e2e8f0; border-radius:12px;', 106 ' padding:14px 16px; display:flex; align-items:center; gap:12px;', 107 ' transition:border-color .15s, box-shadow .15s;', 108 '}', 109 '.' + MODAL_ID + '__pkg:hover {', 110 ' border-color:#f97316; box-shadow:0 2px 8px rgba(249,115,22,.12);', 111 '}', 112 '.' + MODAL_ID + '__pkg-icon {', 113 ' width:40px; height:40px; border-radius:10px;', 114 ' background:linear-gradient(135deg,#eff6ff,#dbeafe);', 115 ' display:flex; align-items:center; justify-content:center;', 116 ' font-size:16px; color:#1e40af; flex-shrink:0;', 117 '}', 118 '.' + MODAL_ID + '__pkg-info { flex:1; min-width:0; }', 119 '.' + MODAL_ID + '__pkg-name {', 120 ' font-size:13px; font-weight:600; color:#1e293b;', 121 ' white-space:nowrap; overflow:hidden; text-overflow:ellipsis;', 122 '}', 123 '.' + MODAL_ID + '__pkg-cost {', 124 ' font-size:12px; color:#f97316; font-weight:700; margin-top:2px;', 125 '}', 126 127 /* Footer */ 128 '.' + MODAL_ID + '__footer {', 129 ' padding:16px 24px 20px; border-top:1px solid #f1f5f9;', 130 ' background:#fafafa;', 131 '}', 132 '.' + MODAL_ID + '__footer-text {', 133 ' font-size:13px; color:#64748b; line-height:1.5;', 134 ' text-align:center; margin-bottom:14px;', 135 '}', 136 '.' + MODAL_ID + '__btn {', 137 ' display:block; width:100%; padding:13px 24px;', 138 ' border-radius:12px; font-size:15px; font-weight:700;', 139 ' cursor:pointer; border:none; font-family:inherit;', 140 ' background:linear-gradient(135deg,#f97316 0%,#ea580c 100%);', 141 ' color:#fff; transition:all .15s ease; text-align:center;', 142 '}', 143 '.' + MODAL_ID + '__btn:hover { box-shadow:0 4px 16px rgba(249,115,22,.35); transform:translateY(-1px); }', 144 145 /* Loading skeleton */ 146 '.' + MODAL_ID + '__loading {', 147 ' text-align:center; padding:30px 0; color:#94a3b8; font-size:13px;', 148 '}', 149 150 /* Responsive */ 151 '@media (max-width:480px) {', 152 ' .' + MODAL_ID + '__grid { grid-template-columns:1fr; }', 153 ' .' + MODAL_ID + '__header { padding:16px 18px; }', 154 ' .' + MODAL_ID + '__body { padding:16px 18px; }', 155 ' .' + MODAL_ID + '__footer { padding:14px 18px 18px; }', 156 '}', 157 '', 158 '/* âââ Coin Earn Modal âââ */', 159 '#' + COIN_EARN_MODAL_ID + ' {', 160 ' position:fixed; inset:0; z-index:5000001;', 161 ' display:none; align-items:center; justify-content:center;', 162 ' background:rgba(15,23,42,.5); backdrop-filter:blur(6px);', 163 ' padding:20px;', 164 '}', 165 '#' + COIN_EARN_MODAL_ID + '.is-open { display:flex; }', 166 '.' + COIN_EARN_MODAL_ID + '__card {', 167 ' background:#fff; border-radius:18px; width:min(560px,95vw);', 168 ' max-height:90vh; overflow:hidden;', 169 ' box-shadow:0 24px 64px rgba(0,0,0,.22);', 170 ' animation: ppWelcomeFadeIn .25s ease;', 171 ' display:flex; flex-direction:column;', 172 '}', 173 '.' + COIN_EARN_MODAL_ID + '__header {', 174 ' background:linear-gradient(135deg,#16a34a 0%,#15803d 100%);', 175 ' padding:20px 24px;', 176 ' display:flex; align-items:center; gap:12px;', 177 ' position:relative;', 178 '}', 179 '.' + COIN_EARN_MODAL_ID + '__header-icon {', 180 ' width:44px; height:44px; border-radius:12px;', 181 ' background:rgba(255,255,255,.2);', 182 ' display:flex; align-items:center; justify-content:center;', 183 ' font-size:20px; color:#fff; flex-shrink:0;', 184 '}', 185 '.' + COIN_EARN_MODAL_ID + '__header-title { font-size:20px; font-weight:800; color:#fff; }', 186 '.' + COIN_EARN_MODAL_ID + '__close-btn {', 187 ' position:absolute; top:12px; right:12px;', 188 ' width:32px; height:32px; border-radius:50%;', 189 ' background:rgba(255,255,255,.2); border:none; cursor:pointer;', 190 ' display:flex; align-items:center; justify-content:center;', 191 ' color:#fff; font-size:16px; transition:background .15s;', 192 '}', 193 '.' + COIN_EARN_MODAL_ID + '__close-btn:hover { background:rgba(255,255,255,.35); }', 194 '.' + COIN_EARN_MODAL_ID + '__close-btn:disabled {', 195 ' opacity:0.6; cursor:not-allowed; pointer-events:none;', 196 '}', 197 '.' + COIN_EARN_MODAL_ID + '__body { padding:20px 24px; overflow-y:auto; flex:1; }', 198 '.' + COIN_EARN_MODAL_ID + '__subtitle {', 199 ' font-size:14px; color:#64748b; line-height:1.5; margin-bottom:18px; text-align:center;', 200 '}', 201 '.' + COIN_EARN_MODAL_ID + '__grid {', 202 ' display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr));', 203 ' gap:12px; margin-bottom:8px;', 204 '}', 205 '.' + COIN_EARN_MODAL_ID + '__card-item {', 206 ' background:#f8fafc; border:1px solid #e2e8f0; border-radius:12px;', 207 ' padding:16px; display:flex; align-items:flex-start; gap:12px;', 208 ' transition:border-color .15s, box-shadow .15s;', 209 '}', 210 '.' + COIN_EARN_MODAL_ID + '__card-item:hover {', 211 ' border-color:#16a34a; box-shadow:0 2px 8px rgba(22,163,74,.12);', 212 '}', 213 '.' + COIN_EARN_MODAL_ID + '__card-icon {', 214 ' width:40px; height:40px; border-radius:10px;', 215 ' background:linear-gradient(135deg,#dcfce7,#bbf7d0);', 216 ' display:flex; align-items:center; justify-content:center;', 217 ' font-size:16px; color:#15803d; flex-shrink:0;', 218 '}', 219 '.' + COIN_EARN_MODAL_ID + '__card-info { flex:1; min-width:0; }', 220 '.' + COIN_EARN_MODAL_ID + '__card-name {', 221 ' font-size:14px; font-weight:600; color:#1e293b; margin-bottom:4px;', 222 '}', 223 '.' + COIN_EARN_MODAL_ID + '__card-cost { font-size:13px; color:#16a34a; font-weight:700; }', 224 '.' + COIN_EARN_MODAL_ID + '__card-desc { font-size:12px; color:#64748b; margin-top:6px; line-height:1.4; }', 225 '.' + COIN_EARN_MODAL_ID + '__footer {', 226 ' padding:16px 24px 20px; border-top:1px solid #f1f5f9;', 227 ' background:#fafafa; display:flex; align-items:center; justify-content:space-between; gap:12px;', 228 '}', 229 '.' + COIN_EARN_MODAL_ID + '__countdown {', 230 ' font-size:13px; color:#64748b; font-weight:600;', 231 '}', 232 '.' + COIN_EARN_MODAL_ID + '__btn {', 233 ' padding:12px 24px; border-radius:12px; font-size:15px; font-weight:700;', 234 ' cursor:pointer; border:none; font-family:inherit;', 235 ' background:linear-gradient(135deg,#16a34a 0%,#15803d 100%);', 236 ' color:#fff; transition:all .15s ease;', 237 '}', 238 '.' + COIN_EARN_MODAL_ID + '__btn:hover:not(:disabled) { box-shadow:0 4px 16px rgba(22,163,74,.35); }', 239 '.' + COIN_EARN_MODAL_ID + '__btn:disabled { opacity:0.6; cursor:not-allowed; }', 240 '@media (max-width:480px) { .' + COIN_EARN_MODAL_ID + '__grid { grid-template-columns:1fr; } }' 241 ].join('\n'); 242 document.head.appendChild(css); 243 } 244 245 /* âââ Modal DOM âââ */ 246 247 function buildModal() { 248 injectStyles(); 249 if (document.getElementById(MODAL_ID)) return; 250
251 var overlay = document.createElement('div'); 252 overlay.id = MODAL_ID; 253 overlay.innerHTML = [ 254 '<div class="' + MODAL_ID + '__card">', 255 ' <div class="' + MODAL_ID + '__header">', 256 ' <div class="' + MODAL_ID + '__header-icon"><i class="fas fa-exclamation-triangle"></i></div>', 257 ' <div class="' + MODAL_ID + '__header-text">', 258 ' <div class="' + MODAL_ID + '__header-title">DİKKAT</div>', 259 ' <div class="' + MODAL_ID + '__header-subtitle">İlk Ãyelik Tepe Coin Bilgilendirmesi</div>', 260 ' </div>', 261 ' <button class="' + MODAL_ID + '__close-btn" id="pp-welcome-close-x"><i class="fas fa-times"></i></button>', 262 ' </div>', 263 ' <div class="' + MODAL_ID + '__body">', 264 ' <div class="' + MODAL_ID + '__warning">', 265 ' <span class="' + MODAL_ID + '__warning-icon"><i class="fas fa-info-circle"></i></span>', 266 ' <span>Lütfen ilk üyeliÄinize özel ücretsiz <strong>Tepe Coin</strong>\'lerinizi dikkatli kullanın.</span>', 267 ' </div>', 268 ' <div class="' + MODAL_ID + '__packages-title">Kullanım Paketleri</div>', 269 ' <div class="' + MODAL_ID + '__grid" id="pp-welcome-packages">', 270 ' <div class="' + MODAL_ID + '__loading"><i class="fas fa-spinner fa-spin"></i> Yükleniyor...</div>', 271 ' </div>', 272 ' </div>', 273 ' <div class="' + MODAL_ID + '__footer">', 274 ' <div class="' + MODAL_ID + '__footer-text">Bunları deÄerlendirdikten sonra kalan coinlerinizi istediÄiniz gibi kullanabilirsiniz.</div>', 275 ' <button class="' + MODAL_ID + '__btn" id="pp-welcome-close-btn">Anladım</button>', 276 ' </div>', 277 '</div>' 278 ].join(''); 279 280 document.body.appendChild(overlay); 281 282 /* Event listeners */ 283 document.getElementById('pp-welcome-close-btn').addEventListener('click', closeModal); 284 document.getElementById('pp-welcome-close-x').addEventListener('click', closeModal); 285 overlay.addEventListener('click', function (e) { 286 if (e.target === overlay) closeModal(); 287 }); 288 document.addEventListener('keydown', function (e) { 289 if (e.key === 'Escape' && overlay.classList.contains('is-open')) closeModal(); 290 }); 291 } 292 293 /* âââ Coin Earn Modal âââ */ 294 295 var coinEarnCountdownInterval = null; 296 var coinEarnSecondsLeft = 0; 297 298 function buildCoinEarnModal() { 299 injectStyles(); 300 if (document.getElementById(COIN_EARN_MODAL_ID)) return; 301 302 var overlay = document.createElement('div'); 303 overlay.id = COIN_EARN_MODAL_ID; 304 overlay.innerHTML = [ 305 '<div class="' + COIN_EARN_MODAL_ID + '__card">', 306 ' <div class="' + COIN_EARN_MODAL_ID + '__header">', 307 ' <div class="' + COIN_EARN_MODAL_ID + '__header-icon"><i class="fas fa-gift"></i></div>', 308 ' <div class="' + COIN_EARN_MODAL_ID + '__header-text">', 309 ' <div class="' + COIN_EARN_MODAL_ID + '__header-title">Bedava Tepe Coin Kazan</div>', 310 ' </div>', 311 ' <button class="' + COIN_EARN_MODAL_ID + '__close-btn" id="pp-coin-earn-close-x" disabled><i class="fas fa-times"></i></button>', 312 ' </div>', 313 ' <div class="' + COIN_EARN_MODAL_ID + '__body">', 314 ' <p class="' + COIN_EARN_MODAL_ID + '__subtitle">Programı ücretsiz kullanmaya devam etmek için coin kazanma yöntemlerini kullanabilirsiniz.</p>', 315 ' <div class="' + COIN_EARN_MODAL_ID + '__grid" id="pp-coin-earn-cards">', 316 ' <div class="' + MODAL_ID + '__loading"><i class="fas fa-spinner fa-spin"></i> Yükleniyor...</div>', 317 ' </div>', 318 ' </div>', 319 ' <div class="' + COIN_EARN_MODAL_ID + '__footer">', 320 ' <span class="' + COIN_EARN_MODAL_ID + '__countdown" id="pp-coin-earn-countdown">Kapatmak için 8 saniye bekleyin</span>', 321 ' <button class="' + COIN_EARN_MODAL_ID + '__btn" id="pp-coin-earn-close-btn" disabled>Kapat</button>', 322 ' </div>', 323 '</div>' 324 ].join(''); 325 326 document.body.appendChild(overlay); 327 328 document.getElementById('pp-coin-earn-close-btn').addEventListener('click', closeCoinEarnModal); 329 document.getElementById('pp-coin-earn-close-x').addEventListener('click', closeCoinEarnModal); 330 overlay.addEventListener('click', function (e) { 331 if (e.target === overlay && coinEarnSecondsLeft <= 0) closeCoinEarnModal(); 332 });
333 document.addEventListener('keydown', function coinEarnKeyHandler(e) { 334 if (e.key === 'Escape' && overlay.classList.contains('is-open') && coinEarnSecondsLeft <= 0) { 335 closeCoinEarnModal(); 336 } 337 }); 338 } 339 340 function loadGiftRewards() { 341 var container = document.getElementById('pp-coin-earn-cards'); 342 if (!container) return; 343 344 fetch('/api/credit/gift-rewards/') 345 .then(function (r) { return r.json(); }) 346 .then(function (data) { 347 var items = data.items || []; 348 renderGiftRewardCards(container, items); 349 }) 350 .catch(function () { 351 container.innerHTML = '<div style="color:#94a3b8;font-size:13px;text-align:center;">Coin kazanma yöntemleri yüklenemedi.</div>'; 352 }); 353 } 354 355 function renderGiftRewardCards(container, items) { 356 if (!items.length) { 357 container.innerHTML = '<div style="color:#94a3b8;font-size:13px;">Henüz coin kazanma yöntemi tanımlanmamıÅ.</div>'; 358 return; 359 } 360 var html = items.map(function (item) { 361 var faClass = item.icon_fa || 'fa-gift'; 362 var badge = item.is_coming_soon ? ' <span style="font-size:11px;color:#94a3b8;font-weight:500;">(Yakında)</span>' : ''; 363 var cardId = (item.event_type && /^[a-z0-9_]+$/i.test(item.event_type)) ? item.event_type : ''; 364 var idAttr = cardId ? ' id="' + escapeHtml(cardId) + '"' : ''; 365 return [ 366 '<div class="' + COIN_EARN_MODAL_ID + '__card-item"' + idAttr + '>', 367 ' <div class="' + COIN_EARN_MODAL_ID + '__card-icon"><i class="fas ' + faClass + '"></i></div>', 368 ' <div class="' + COIN_EARN_MODAL_ID + '__card-info">', 369 ' <div class="' + COIN_EARN_MODAL_ID + '__card-name">' + escapeHtml(item.display_name) + badge + '</div>', 370 ' <div class="' + COIN_EARN_MODAL_ID + '__card-cost">' + item.credits + ' Coin</div>', 371 (item.description ? '<div class="' + COIN_EARN_MODAL_ID + '__card-desc">' + escapeHtml(item.description) + '</div>' : ''), 372 ' </div>', 373 '</div>' 374 ].join(''); 375 }).join(''); 376 container.innerHTML = html; 377 } 378 379 function openCoinEarnModal() { 380 buildCoinEarnModal(); 381 loadGiftRewards(); 382 var el = document.getElementById(COIN_EARN_MODAL_ID); 383 if (el) el.classList.add('is-open'); 384 document.body.style.overflow = 'hidden'; 385 386 coinEarnSecondsLeft = COIN_EARN_MIN_SECONDS; 387 var countdownEl = document.getElementById('pp-coin-earn-countdown'); 388 var closeBtn = document.getElementById('pp-coin-earn-close-btn'); 389 var closeX = document.getElementById('pp-coin-earn-close-x'); 390 391 function updateCountdown() { 392 if (coinEarnSecondsLeft > 0) { 393 countdownEl.textContent = 'Kapatmak için ' + coinEarnSecondsLeft + ' saniye bekleyin'; 394 closeBtn.textContent = 'Kapat (' + coinEarnSecondsLeft + ')'; 395 closeBtn.disabled = true; 396 closeX.disabled = true; 397 coinEarnSecondsLeft--; 398 } else { 399 clearInterval(coinEarnCountdownInterval); 400 coinEarnCountdownInterval = null; 401 countdownEl.textContent = ''; 402 closeBtn.textContent = 'Kapat'; 403 closeBtn.disabled = false; 404 closeX.disabled = false; 405 } 406 } 407 408 if (coinEarnCountdownInterval) clearInterval(coinEarnCountdownInterval); 409 updateCountdown(); 410 coinEarnCountdownInterval = setInterval(updateCountdown, 1000); 411 } 412 413 function closeCoinEarnModal() { 414 if (coinEarnCountdownInterval) { 415 clearInterval(coinEarnCountdownInterval); 416 coinEarnCountdownInterval = null; 417 } 418 var el = document.getElementById(COIN_EARN_MODAL_ID); 419 if (el) el.classList.remove('is-open'); 420 document.body.style.overflow = ''; 421 try { 422 if (window.PPAppTourOverlay && typeof window.PPAppTourOverlay.maybeShow === 'function') { 423 setTimeout(function () { window.PPAppTourOverlay.maybeShow(); }, 300); 424 } 425 } catch (_) {} 426 } 427 428 /* âââ Load Packages âââ */ 429 430 function loadPackages() { 431 var container = document.getElementById('pp-welcome-packages'); 432 if (!container) return; 433 434 fetch('/api/credit/costs/') 435 .then(function (r) { return r.json(); }) 436 .then(function (data) { 437 var items = data.items || []; 438 if (!items.length) { 439 /* API yanıtı: items boÅsa costs/action_types objelerinden kart üret */ 440 var costs = data.costs || {}; 441 var names = data.action_types || {};
442 Object.keys(costs).forEach(function (key) { 443 items.push({ 444 action_type: key, 445 display_name: names[key] || key, 446 credits: costs[key], 447 icon_fa: 'fa-circle', 448 description: '' 449 }); 450 }); 451 } 452 renderPackages(container, items); 453 }) 454 .catch(function () { 455 container.innerHTML = '<div style="color:#94a3b8;font-size:13px;text-align:center;">Paket bilgileri yüklenemedi.</div>'; 456 }); 457 } 458 459 function renderPackages(container, items) { 460 if (!items.length) { 461 container.innerHTML = '<div style="color:#94a3b8;font-size:13px;">Henüz paket tanımlanmamıÅ.</div>'; 462 return; 463 } 464 var html = items.map(function (item) { 465 var faClass = item.icon_fa || 'fa-circle'; 466 return [ 467 '<div class="' + MODAL_ID + '__pkg">', 468 ' <div class="' + MODAL_ID + '__pkg-icon"><i class="fas ' + faClass + '"></i></div>', 469 ' <div class="' + MODAL_ID + '__pkg-info">', 470 ' <div class="' + MODAL_ID + '__pkg-name">' + escapeHtml(item.display_name) + '</div>', 471 ' <div class="' + MODAL_ID + '__pkg-cost">' + item.credits + ' Tepe Coin</div>', 472 ' </div>', 473 '</div>' 474 ].join(''); 475 }).join(''); 476 container.innerHTML = html; 477 } 478 479 function escapeHtml(str) { 480 var div = document.createElement('div'); 481 div.textContent = str || ''; 482 return div.innerHTML; 483 } 484 485 /* âââ Open / Close âââ */ 486 487 function openModal() { 488 buildModal(); 489 loadPackages(); 490 var el = document.getElementById(MODAL_ID); 491 if (el) el.classList.add('is-open'); 492 document.body.style.overflow = 'hidden'; 493 } 494 495 function closeModal() { 496 var el = document.getElementById(MODAL_ID); 497 if (el) el.classList.remove('is-open'); 498 dismissWelcome(); 499 /* HoÅgeldin modalı kapandıktan sonra "Bedava Tepe Coin Kazan" modalını aç */ 500 try { 501 openCoinEarnModal(); 502 } catch (err) { 503 console.error('[PPWelcomeModal] Coin earn modal açılamadı:', err); 504 document.body.style.overflow = ''; 505 } 506 } 507 508 function dismissWelcome() { 509 window.PP_USER_HAS_SEEN_WELCOME = true; 510 511 /* CSRF token al */ 512 var csrfToken = ''; 513 var csrfMeta = document.querySelector('meta[name="csrf-token"]'); 514 if (csrfMeta) { 515 csrfToken = csrfMeta.getAttribute('content') || ''; 516 } 517 if (!csrfToken) { 518 var csrfCookie = document.cookie.split(';').find(function (c) { 519 return c.trim().startsWith('csrftoken='); 520 }); 521 if (csrfCookie) csrfToken = csrfCookie.split('=')[1] || ''; 522 } 523 524 fetch('/api/auth/dismiss-welcome/', { 525 method: 'POST', 526 headers: { 527 'Content-Type': 'application/json', 528 'X-CSRFToken': csrfToken 529 }, 530 credentials: 'same-origin' 531 }).catch(function () { 532 /* Sessiz hata - kritik deÄil */ 533 }); 534 } 535 536 /* âââ Auto-trigger âââ */ 537 538 function maybeShowWelcome() { 539 if (!window.PP_USER_AUTHENTICATED) return; 540 if (window.PP_USER_HAS_SEEN_WELCOME === true) return; 541 /* Kısa gecikme ile göster (sayfa yüklenmesini engelleme) */ 542 setTimeout(openModal, 800); 543 } 544 545 /* Public API */ 546 window.PPWelcomeModal = { 547 open: openModal, 548 close: closeModal, 549 check: maybeShowWelcome, 550 openCoinEarn: openCoinEarnModal 551 }; 552 553 /* Sayfa yüklendiÄinde otomatik kontrol */ 554 if (document.readyState === 'loading') { 555 document.addEventListener('DOMContentLoaded', maybeShowWelcome); 556 } else { 557 setTimeout(maybeShowWelcome, 400); 558 } 559})();
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.