PageSourceSearch

https://asistall.com/b2b/corporate-login/

html asistall.com collected 2026-10-02 00:27:35 UTC 27,157 bytes, 847 lines download raw bytes

1
2<!doctype html>
3<html lang="tr">
4
5<head>
6  <meta charset="UTF-8" />
7  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8  <title>Kurumsal Giriş Yapın - AsistAll</title>
9  <!-- Google Fonts: Inter veya Poppins gibi modern fontlar -->
10  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
11  <!-- Font Awesome -->
12  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
13
14  <style>
15    :root {
16      --primary-bg: #111189;
17      --white: #ffffff;
18      --gray-light: #f3f4f6;
19      --gray-text: #6b7280;
20      --dark-text: #111827;
21      --border-color: #e5e7eb;
22      --primary-blue: #0045a1;
23    }
24
25    body,
26    html {
27      margin: 0;
28      padding: 0;
29      height: 100%;
30      font-family: "Inter", sans-serif;
31      background-color: var(--primary-bg);
32      display: flex;
33      align-items: center;
34      justify-content: center;
35    }
36
37    .login-card {
38      background: var(--white);
39      width: 100%;
40      max-width: 750px;
41      padding: 60px 80px;
42      border-radius: 32px;
43      box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
44      text-align: center;
45      position: relative;
46    }
47
48    .logo-container {
49      margin-bottom: 32px;
50    }
51
52    .logo-container img {
53      height: 65px;
54    }
55
56    h1 {
57      font-size: 1.4rem;
58      font-weight: 700;
59      color: var(--dark-text);
60      margin-bottom: 35px;
61    }
62
63    .lang-selector-container {
64      position: relative;
65      float: left;
66      margin-bottom: 28px;
67      z-index: 100;
68    }
69
70    .lang-selector {
71      display: inline-flex;
72      align-items: center;
73      gap: 8px;
74      background: var(--primary-bg);
75      color: white;
76      padding: 8px 16px;
77      border-radius: 8px;
78      font-size: 0.8rem;
79      cursor: pointer;
80      transition: background 0.2s;
81      border: none;
82      outline: none;
83    }
84
85    .lang-selector:hover {
86      background: #0d0d6b;
87    }
88
89    .lang-dropdown {
90      position: absolute;
91      top: 100%;
92      left: 0;
93      margin-top: 4px;
94      background: white;
95      border: 1px solid var(--border-color);
96      border-radius: 8px;
97      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
98      display: none;
99      min-width: 120px;
100      overflow: hidden;
101    }
102
103    .lang-dropdown.show {
104      display: block;
105    }
106
107    .lang-option {
108      padding: 10px 16px;
109      font-size: 0.85rem;
110      color: var(--dark-text);
111      cursor: pointer;
112      text-align: left;
113      transition: background 0.2s;
114    }
115
116    .lang-option:hover {
117      background: #f3f6f9;
118    }
119
120    .form-group {
121      margin-bottom: 16px;
122      text-align: left;
123      clear: both;
124    }
125
126    .input-wrapper {
127      position: relative;
128    }
129
130    input {
131      width: 100%;
132      padding: 16px 20px;
133      border: 1px solid var(--border-color);
134      background: #f3f6f9;
135      border-radius: 10px;
136      font-size: 0.9rem;
137      color: var(--dark-text);
138      outline: none;
139      box-sizing: border-box;
140      transition: all 0.3s;
141    }
142
143    input:focus {
144      border-color: var(--primary-blue);
145      background: white;
146      box-shadow: 0 0 0 4px rgba(0, 69, 161, 0.08);
147    }
148
149    /* Labelları daha sağlam bir yöntemle gizleyelim veya üste taşıyalım */
150    .input-label {
151      position: absolute;
152      left: 20px;
153      top: 50%;
154      transform: translateY(-50%);
155      color: var(--gray-text);
156      pointer-events: none;
157      transition: all 0.2s;
158      font-size: 0.9rem;
159    }
160
161    /* Input doluysa veya focus ise label'ı tamamen kaldıralım */
162    input:focus+.input-label,
163    input:not(:placeholder-shown)+.input-label,
164    input.has-value+.input-label {
165      opacity: 0;
166      visibility: hidden;
167      transform: translateY(-120%);
168    }
169
170    /* Browser Autofill fix */
171    input:-webkit-autofill,
172    input:-webkit-autofill:hover,
173    input:-webkit-autofill:focus {
174      -webkit-box-shadow: 0 0 0px 1000px #f3f6f9 inset !important;
175      transition: background-color 5000s ease-in-out 0s;
176    }
177
178    .forgot-password {
179      display: block;
180      margin: 12px 0;
181      color: var(--gray-text);
182      font-size: 0.8rem;
183      text-decoration: none;
184      transition: color 0.2s;
185      text-align: center;
186    }
187
188    .forgot-password:hover {
189      color: var(--primary-blue);
190    }
191
192    .login-btn {
193      width: 100%;
194      background-color: var(--primary-blue);
195      color: white;
196      border: none;
197      padding: 14px;
198      border-radius: 8px;
199      font-size: 0.9rem;
200      font-weight: 600;
201      cursor: pointer;
202      margin-top: 24px;
203      transition: background 0.3s;
204    }
205
206    .login-btn:hover {
207      background-color: #003a85;
208    }
209
210    .new-agency {
211      display: block;
212      margin-top: 20px;
213      color: var(--primary-blue);
214      font-weight: 600;
215      font-size: 0.8rem;
216      text-decoration: underline;
217    }
218
219    .footer-info {
220      margin-top: 50px;
221      font-size: 0.75rem;
222      color: var(--dark-text);
223      font-weight: 500;
224    }
225
226    .footer-links {
227      margin-top: 12px;
228    }
229
230    .footer-links a {
231      color: var(--dark-text);
232      text-decoration: underline;
233      font-size: 0.75rem;
234    }
235
236    /* Password Toggle */
237    .password-toggle {
238      position: absolute;
239      right: 18px;
240      top: 50%;
241      transform: translateY(-50%);
242      color: var(--gray-text);
243      cursor: pointer;
244      font-size: 1.1rem;
245      transition: color 0.2s;
246      z-index: 5;
247    }
248
249    .password-toggle:hover {
250      color: var(--primary-blue);
251    }
252
253    @media (max-width: 600px) {
254      .login-card {
255        margin: 20px;
256        padding: 40px 20px;
257      }
258    }
259
260    /* Modal Styles */
261    .modal-overlay {
262      display: none;
263      position: fixed;
264      top: 0;
265      left: 0;
266      width: 100%;
267      height: 100%;
268      background: rgba(0, 0, 0, 0.7);
269      z-index: 1000;
270      justify-content: center;
271      align-items: center;
272      backdrop-filter: blur(5px);
273    }
274
275    .modal-overlay.show {
276      display: flex;
277    }
278
279    .modal-content {
280      background: white;
281      width: 100%;
282      max-width: 800px;
283      max-height: 80vh;
284      border-radius: 20px;
285      padding: 40px;
286      position: relative;
287      overflow-y: auto;
288      text-align: left;
289    }
290
291    .modal-close {
292      position: absolute;
293      top: 20px;
294      right: 20px;
295      font-size: 24px;
296      cursor: pointer;
297      color: #666;
298    }
299
300    .modal-content h2 {
301      color: var(--primary-bg);
302      margin-bottom: 20px;
303      font-size: 1.5rem;
304    }
305
306    .modal-content h3 {
307      color: var(--primary-bg);
308      margin-top: 25px;
309      margin-bottom: 10px;
310      font-size: 1.1rem;
311      font-weight: 700;
312    }
313
314    .modal-content p {
315      font-size: 0.9rem;
316      line-height: 1.6;
317      color: #444;
318      margin-bottom: 15px;
319    }
320  </style>
321</head>
322
323<body>
324  <div class="login-card">
325    <div class="logo-container">
326      <img src="/static/octopusProject/images/asistalllogomavi.webp" alt="AsistAll Logo" />
327    </div>
328
329    <h1 data-tr="Kurumsal Giriş Yapın" data-en="Corporate Login">Kurumsal Giriş Yapın</h1>
330
331    <div class="lang-selector-container">
332      <button class="lang-selector" id="langBtn">
333        <span id="currentLangText">Türkçe</span>
334        <i class="fas fa-chevron-down"></i>
335      </button>
336      <div class="lang-dropdown" id="langDropdown">
337        <div class="lang-option" onclick="changeLang('tr')">Türkçe</div>
338        <div class="lang-option" onclick="changeLang('en')">English</div>
339      </div>
340    </div>
341
342    <div id="errorMessage"
343      style="display: none; color: #ff4d4f; font-size: 0.85rem; margin-bottom: 16px; text-align: center; border: 1px solid #ffccc7; background: #fff2f0; padding: 10px; border-radius: 8px;">
344    </div>
345
346    <form id="loginForm">
347      <div class="form-group">
348        <div class="input-wrapper">
349          <input type="text" id="username" placeholder=" " autocomplete="username" />
350          <label for="username" class="input-label" data-tr="Kullanıcı adı" data-en="Username">Kullanıcı adı</label>
351        </div>
352      </div>
353
354      <div class="form-group">
355        <div class="input-wrapper">
356          <input type="password" id="password" placeholder=" " autocomplete="current-password" />
357          <label for="password" class="input-label" data-tr="Şifre" data-en="Password">Şifre</label>
358          <i class="fas fa-eye password-toggle" id="togglePasswordIcon" onclick="togglePassword()"></i>
359        </div>
360      </div>
361
362      <a href="#" class="forgot-password" onclick="openB2bForgotPasswordModal(); return false;"
363        data-tr="Şifremi unuttum" data-en="Forgot password?">Şifremi unuttum</a>
364
365      <button type="submit" class="login-btn" data-tr="Giriş yap" data-en="Login">Giriş yap</button>
366
367      <a href="/b2b/corporate-register-docs/" class="new-agency" data-tr="Yeni Şirket Üyelik"
368        data-en="New Company Registration">Yeni Şirket Üyelik</a>
369    </form>
370
371    <div class="footer-info">
372      <span data-tr="Tel: +971 52 740 0276" data-en="Phone: +971 52 740 0276 ">Tel: +971 52 740 0276</span>
373    </div>
374
375    <div class="footer-links">
376      <a href="javascript:void(0)" onclick="openTermsModal()" data-tr="Kullanım Koşulları"
377        data-en="Terms of Use">Kullanım Koşulları</a>
378    </div>
379  </div>
380
381  <!-- Forgot Password Modal -->
382  <div class="modal-overlay" id="b2bForgotPasswordModal">
383    <div class="modal-content" style="max-width: 450px;">
384      <span class="modal-close" onclick="closeB2bForgotPasswordModal()">&times;</span>
385      <h2 data-tr="Şifre Yenile" data-en="Reset Password"
386        style="text-align:center; color: var(--dark-text); font-size: 1.3rem;">Şifre Yenile</h2>
387
388      <div id="b2bForgotAlert"
389        style="display: none; margin-bottom: 15px; padding: 12px; border-radius: 8px; font-size: 0.85rem; text-align: center;">
390      </div>
391
392      <div id="b2bForgotStepEmail">
393        <p style="text-align: center; font-size: 0.9rem; color: #666; margin-bottom: 20px;"
394          data-tr="Kayıtlı e-posta adresiniz ile doğrulama kodu alıp yeni şifrenizi belirleyin."
395          data-en="Enter your registered email address to receive a verification code.">
396          Kayıtlı e-posta adresiniz ile doğrulama kodu alıp yeni şifrenizi belirleyin.
397        </p>
398        <div class="form-group">
399          <div class="input-wrapper">
400            <input type="email" id="b2bForgotEmail" placeholder=" " />
401            <label for="b2bForgotEmail" class="input-label" data-tr="E-posta" data-en="Email">E-posta</label>
402          </div>
403        </div>
404        <button type="button" class="login-btn" id="b2bForgotSendCodeBtn" onclick="handleB2bForgotPasswordSendCode()"
405          style="margin-top: 10px;" data-tr="Kod Gönder" data-en="Send Code">Kod Gönder</button>
406      </div>
407
408      <div id="b2bForgotStepCode" style="display: none;">
409        <p style="text-align: center; font-size: 0.9rem; color: #666; margin-bottom: 20px;"
410          data-tr="E-posta adresinize gönderilen 6 haneli kodu girin."
411          data-en="Enter the 6-digit code sent to your email.">
412          E-posta adresinize gönderilen 6 haneli kodu girin.
413        </p>
414        <div class="form-group">
415          <div class="input-wrapper">
416            <input type="text" id="b2bForgotCode" placeholder=" " maxlength="6" inputmode="numeric" />
417            <label for="b2bForgotCode" class="input-label" data-tr="Doğrulama Kodu"
418              data-en="Verification Code">Doğrulama Kodu</label>
419          </div>
420        </div>
421        <div style="display: flex; gap: 10px; margin-top: 10px;">
422          <button type="button" class="login-btn" style="background: #6b7280; margin-top: 0;"
423            onclick="setB2bForgotStep('email')" data-tr="Geri" data-en="Back">Geri</button>
424          <button type="button" class="login-btn" id="b2bForgotVerifyCodeBtn" style="margin-top: 0;"
425            onclick="handleB2bForgotPasswordVerifyCode()" data-tr="Kodu Doğrula" data-en="Verify Code">Kodu
426            Doğrula</button>
427        </div>
428      </div>
429
430      <div id="b2bForgotStepReset" style="display: none;">
431        <p style="text-align: center; font-size: 0.9rem; color: #666; margin-bottom: 20px;"
432          data-tr="Lütfen yeni şifrenizi belirleyin." data-en="Please enter your new password.">
433          Lütfen yeni şifrenizi belirleyin.
434        </p>
435        <div class="form-group">
436          <div class="input-wrapper">
437            <input type="password" id="b2bForgotNewPassword" placeholder=" " />
438            <label for="b2bForgotNewPassword" class="input-label" data-tr="Yeni Şifre" data-en="New Password">Yeni
439              Şifre</label>
440            <i class="fas fa-eye password-toggle" onclick="toggleB2bForgotField(this, 'b2bForgotNewPassword')"></i>
441          </div>
442        </div>
443        <div class="form-group">
444          <div class="input-wrapper">
445            <input type="password" id="b2bForgotConfirmPassword" placeholder=" " />
446            <label for="b2bForgotConfirmPassword" class="input-label" data-tr="Yeni Şifre (Tekrar)"
447              data-en="Confirm New Password">Yeni Şifre (Tekrar)</label>
448            <i class="fas fa-eye password-toggle" onclick="toggleB2bForgotField(this, 'b2bForgotConfirmPassword')"></i>
449          </div>
450        </div>
451        <button type="button" class="login-btn" id="b2bForgotResetBtn" onclick="handleB2bForgotPasswordReset()"
452          style="margin-top: 10px;" data-tr="Şifreyi Güncelle" data-en="Update Password">Şifreyi Güncelle</button>
453      </div>
454    </div>
455  </div>
456
457  <!-- Terms Modal -->
458  <div class="modal-overlay" id="termsModal">
459    <div class="modal-content">
460      <span class="modal-close" onclick="closeTermsModal()">&times;</span>
461      <h2 id="termsModalTitle" data-tr="Kullanım Koşulları" data-en="Terms of Use">Kullanım Koşulları</h2>
462      <div id="termsContent">
463        <!-- Dynamic content goes here -->
464      </div>
465    </div>
466  </div>
467
468  
468<script>
469    async function openTermsModal() {
470      const modal = document.getElementById('termsModal');
471      const content = document.getElementById('termsContent');
472      const title = document.getElementById('termsModalTitle');
473      
474      content.innerHTML = `
475        <div style="text-align: center; padding: 40px;">
476          <i class="fas fa-spinner fa-spin" style="font-size: 2rem; color: var(--primary-blue);"></i>
477          <p style="margin-top: 10px; color: #666;">Yükleniyor / Loading...</p>
478        </div>
479      `;
480      modal.classList.add('show');
481      document.body.style.overflow = 'hidden';
482
483      try {
484        const response = await fetch('/legal/document/global-01-kullanim-kosullari/?format=json');
485        if (response.ok) {
486          const data = await response.json();
487          if (title) title.textContent = data.title;
488          content.innerHTML = data.html_content;
489        } else {
490          content.innerHTML = '<p>İçerik yüklenemedi. / Could not load content.</p>';
491        }
492      } catch (error) {
493        content.innerHTML = '<p>Bağlantı hatası. / Connection error.</p>';
494      }
495    }
496
497    function closeTermsModal() {
498      document.getElementById('termsModal').classList.remove('show');
499      document.body.style.overflow = '';
500    }
501
502    function togglePassword() {
503      const passwordInput = document.getElementById('password');
504      const icon = document.getElementById('togglePasswordIcon');
505
506      if (passwordInput.type === 'password') {
507        passwordInput.type = 'text';
508        icon.classList.remove('fa-eye');
509        icon.classList.add('fa-eye-slash');
510      } else {
511        passwordInput.type = 'password';
512        icon.classList.remove('fa-eye-slash');
513        icon.classList.add('fa-eye');
514      }
515    }
516
517    // Dil Değiştirme Mantığı
518    function changeLang(lang) {
519      document.getElementById('currentLangText').innerText = lang === 'tr' ? 'Türkçe' : 'English';
520      document.getElementById('langDropdown').classList.remove('show');
521
522      // Şehir/Dosya isimlerini bul ve değiştir
523      const elements = document.querySelectorAll('[data-tr]');
524      elements.forEach(el => {
525        el.innerText = el.getAttribute(`data-${lang}`);
526      });
527
528      // HTML lang attribute güncelle
529      document.documentElement.lang = lang;
530
531      // LocalStorage'a kaydet
532      localStorage.setItem('preferredLang', lang);
533    }
534
535    // Dropdown Toggle
536    document.getElementById('langBtn').addEventListener('click', (e) => {
537      e.stopPropagation();
538      document.getElementById('langDropdown').classList.toggle('show');
539    });
540
541    // Dışarı tıklayınca dropdown kapat
542    window.addEventListener('click', () => {
543      document.getElementById('langDropdown').classList.remove('show');
544    });
545
546    // Sayfa yüklendiğinde ve input değiştikçe kontrol et (Autofill overlap hatası için)
547    function checkInputs() {
548      const inputs = document.querySelectorAll('input');
549      inputs.forEach(input => {
550        if (input.value.length > 0) {
551          input.classList.add('has-value');
552        } else {
553          input.classList.remove('has-value');
554        }
555      });
556    }
557
558    window.addEventListener('load', () => {
559      setTimeout(checkInputs, 100);
560
561      // Kayıtlı dil varsa onu yükle
562      const savedLang = localStorage.getItem('preferredLang');
563      if (savedLang) changeLang(savedLang);
564    });
565
566    const ASISTALL_APP_DEEP_LINK = window.ASISTALL_APP_DEEP_LINK || 'asistall://home';
567
568    function isMobileOrTabletDevice() {
569      const ua = navigator.userAgent || navigator.vendor || window.opera || '';
570      const mobileUa = /android|iphone|ipad|ipod|mobile|tablet|silk|kindle|playbook/i.test(ua);
571      const touchMac = navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1;
572      return mobileUa || touchMac || window.innerWidth <= 1024;
573    }
574
575    function tryOpenInstalledApp(fallbackUrl) {
576      const nextUrl = fallbackUrl || window.location.href;
577      if (!isMobileOrTabletDevice() || !ASISTALL_APP_DEEP_LINK) {
578        window.location.href = nextUrl;
579        return;
580      }
581
582      const startedAt = Date.now();
583      let pageHidden = false;
584      let navigated = false;
585
586      const cleanup = () => {
587        window.removeEventListener('pagehide', onPageHide);
588        document.removeEventListener('visibilitychange', onVisibilityChange);
589      };
590
591      const finishWithFallback = () => {
592        if (navigated) return;
593        navigated = true;
594        cleanup();
595        window.location.href = nextUrl;
596      };
597
598      const onPageHide = () => {
599        pageHidden = true;
600        navigated = true;
601        cleanup();
602      };
603
604      const onVisibilityChange = () => {
605        if (document.visibilityState === 'hidden') {
606          pageHidden = true;
607        }
608      };
609
610      window.addEventListener('pagehide', onPageHide, { once: true });
611      document.addEventListener('visibilitychange', onVisibilityChange);
612
613      const probeFrame = document.createElement('iframe');
614      probeFrame.style.display = 'none';
615      probeFrame.setAttribute('aria-hidden', 'true');
616      probeFrame.src = ASISTALL_APP_DEEP_LINK;
617      document.body.appendChild(probeFrame);
618
619      window.setTimeout(() => {
620        if (!pageHidden && Date.now() - startedAt < 2200) {
621          finishWithFallback();
622        } else {
623          cleanup();
624        }
625
626        if (probeFrame.parentNode) {
627          probeFrame.parentNode.removeChild(probeFrame);
628        }
629      }, 1600);
630    }
631
632    document.getElementById('loginForm').addEventListener('submit', async (e) => {
633      e.preventDefault();
634
635      const email = document.getElementById('username').value;
636      const password = document.getElementById('password').value;
637      const errorMessage = document.getElementById('errorMessage');
638      const loginBtn = e.target.querySelector('button[type="submit"]');
639
640      if (!email || !password) {
641        errorMessage.innerText = "Email ve şifre gereklidir.";
642        errorMessage.style.display = 'block';
643        return;
644      }
645
646      loginBtn.disabled = true;
647      loginBtn.innerText = "Giriş yapılıyor...";
648      errorMessage.style.display = 'none';
649
650      try {
651        const response = await fetch('/b2b/api/v1/auth/login', {
652          method: 'POST',
653          headers: {
654            'Content-Type': 'application/json',
655            'X-CSRFToken': 'a7N0v7wMFmqzxZVccrYjTCh1X4HPf1nuJrOxZwKyoHgKTb4dfL2604VIXmaHKVOG'
656          },
657          body: JSON.stringify({ email, password })
658        });
659
660        const data = await response.json();
661
662        if (data.success) {
663          // Giriş başarılı, ana sayfaya yönlendir
664          tryOpenInstalledApp("/");
665        } else {
666          errorMessage.innerText = data.error || "Giriş başarısız.";
667          errorMessage.style.display = 'block';
668        }
669      } catch (error) {
670        console.error('Login error:', error);
671        errorMessage.innerText = "Sunucu ile iletişim kurulamadı.";
672        errorMessage.style.display = 'block';
673      } finally {
674        loginBtn.disabled = false;
675        loginBtn.innerText = "Giriş yap";
676      }
677    });
678
679    document.querySelectorAll('input').forEach(input => {
680      input.addEventListener('input', checkInputs);
681      input.addEventListener('change', checkInputs);
682    });
683
684    // B2B Forgot Password Logic
685    function openB2bForgotPasswordModal() {
686      document.getElementById('b2bForgotAlert').style.display = 'none';
687      setB2bForgotStep('email');
688      b2bResetToken = '';
689      document.getElementById('b2bForgotEmail').value = document.getElementById('username').value;
690      checkInputs();
691      document.getElementById('b2bForgotPasswordModal').classList.add('show');
692      document.body.style.overflow = 'hidden';
693    }
694
695    function closeB2bForgotPasswordModal() {
696      document.getElementById('b2bForgotPasswordModal').classList.remove('show');
697      document.body.style.overflow = '';
698    }
699
700    function toggleB2bForgotField(icon, inputId) {
701      const input = document.getElementById(inputId);
702      if (input.type === 'password') {
703        input.type = 'text';
704        icon.classList.remove('fa-eye');
705        icon.classList.add('fa-eye-slash');
706      } else {
707        input.type = 'password';
708        icon.classList.remove('fa-eye-slash');
709        icon.classList.add('fa-eye');
710      }
711    }
712
713    function setB2bForgotStep(step) {
714      document.getElementById('b2bForgotStepEmail').style.display = step === 'email' ? 'block' : 'none';
715      document.getElementById('b2bForgotStepCode').style.display = step === 'code' ? 'block' : 'none';
716      document.getElementById('b2bForgotStepReset').style.display = step === 'reset' ? 'block' : 'none';
717    }
718
719    function showB2bForgotAlert(message, type = 'error') {
720      const alert = document.getElementById('b2bForgotAlert');
721      alert.style.display = 'block';
722      alert.textContent = message;
723      if (type === 'success') {
724        alert.style.background = '#f6ffed';
725        alert.style.borderColor = '#b7eb8f';
726        alert.style.color = '#389e0d';
727      } else {
728        alert.style.background = '#fff2f0';
729        alert.style.borderColor = '#ffccc7';
730        alert.style.color = '#cf1322';
731      }
732    }
733
734    let b2bResetToken = '';
735
736    async function handleB2bForgotPasswordSendCode() {
737      const email = document.getElementById('b2bForgotEmail').value.trim();
738      if (!email) {
739        showB2bForgotAlert('E-posta gereklidir.');
740        return;
741      }
742
743      const btn = document.getElementById('b2bForgotSendCodeBtn');
744      btn.disabled = true;
745      btn.innerText = 'Gönderiliyor...';
746
747      try {
748        const response = await fetch('/api/v1/auth/forgot-password', {
749          method: 'POST',
750          headers: { 'Content-Type': 'application/json' },
751          body: JSON.stringify({ email })
752        });
753        const data = await response.json();
754        if (data.success) {
755          showB2bForgotAlert(data.message || 'Kod gönderildi.', 'success');
756          setB2bForgotStep('code');
757        } else {
758          showB2bForgotAlert(data.error || 'İşlem başarısız.');
759        }
760      } catch (error) {
761        showB2bForgotAlert('Sunucu hatası.');
762      } finally {
763        btn.disabled = false;
764        const lang = document.documentElement.lang;
765        btn.innerText = lang === 'en' ? 'Send Code' : 'Kod Gönder';
766      }
767    }
768
769    async function handleB2bForgotPasswordVerifyCode() {
770      const email = document.getElementById('b2bForgotEmail').value.trim();
771      const code = document.getElementById('b2bForgotCode').value.trim();
772      if (!code) {
773        showB2bForgotAlert('Lütfen kodu girin.');
774        return;
775      }
776
777      const btn = document.getElementById('b2bForgotVerifyCodeBtn');
778      btn.disabled = true;
779      btn.innerText = 'Doğrulanıyor...';
780
781      try {
782        const response = await fetch('/api/v1/auth/verify-reset-code', {
783          method: 'POST',
784          headers: { 'Content-Type': 'application/json' },
785          body: JSON.stringify({ email, code })
786        });
787        const data = await response.json();
788        if (data.success) {
789          b2bResetToken = data.reset_token;
790          showB2bForgotAlert('Kod doğrulandı. Yeni şifrenizi belirleyin.', 'success');
791          setB2bForgotStep('reset');
792        } else {
793          showB2bForgotAlert(data.error || 'Kod geçersiz.');
794        }
795      } catch (error) {
796        showB2bForgotAlert('Sunucu hatası.');
797      } finally {
798        btn.disabled = false;
799        const lang = document.documentElement.lang;
800        btn.innerText = lang === 'en' ? 'Verify Code' : 'Kodu Doğrula';
801      }
802    }
803
804    async function handleB2bForgotPasswordReset() {
805      const newPassword = document.getElementById('b2bForgotNewPassword').value;
806      const confirmPassword = document.getElementById('b2bForgotConfirmPassword').value;
807
808      if (!newPassword || !confirmPassword) {
809        showB2bForgotAlert('Tüm alanları doldurun.');
810        return;
811      }
812      if (newPassword !== confirmPassword) {
813        showB2bForgotAlert('Şifreler eşleşmiyor.');
814        return;
815      }
816
817      const btn = document.getElementById('b2bForgotResetBtn');
818      btn.disabled = true;
819      btn.innerText = 'Güncelleniyor...';
820
821      try {
822        const response = await fetch('/api/v1/auth/reset-password', {
823          method: 'POST',
824          headers: { 'Content-Type': 'application/json' },
825          body: JSON.stringify({ reset_token: b2bResetToken, new_password: newPassword })
826        });
827        const data = await response.json();
828        if (data.success) {
829          showB2bForgotAlert(data.message || 'Şifreniz güncellendi.', 'success');
830          document.getElementById('password').value = '';
831          checkInputs();
832          setTimeout(closeB2bForgotPasswordModal, 1500);
833        } else {
834          showB2bForgotAlert(data.error || 'İşlem başarısız.');
835        }
836      } catch (error) {
837        showB2bForgotAlert('Sunucu hatası.');
838      } finally {
839        btn.disabled = false;
840        const lang = document.documentElement.lang;
841        btn.innerText = lang === 'en' ? 'Update Password' : 'Şifreyi Güncelle';
842      }
843    }
844  </script>
844
845</body>
846
847</html>

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.