1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 7 <link rel="shortcut icon" href="/static/assets/media/logo/logo.png"/> 8 <title>TravelWalls | Best Tour Packages, Activities & Travel Services in Bangladesh & Worldwide</title> 9 10 <!-- Bootstrap CSS --> 11 <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> 12 13 <!-- Font Awesome for icons --> 14 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"> 15 16 <!-- Bootstrap Datepicker CSS --> 17 <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" 18 rel="stylesheet"> 19 20 <link href="/static/assets/css/customcss/customer_login/login_page.css" rel="stylesheet" type="text/css"/> 21 <link rel="preconnect" href="https://fonts.googleapis.com"> 22 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 23 <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:[email protected]&display=swap" rel="stylesheet"> 24
24<script> 25 window.fbAsyncInit = function() { 26 FB.init({ 27 appId : '1532243734613942', 28 cookie : true, 29 xfbml : true, 30 version : 'v24.0' 31 }); 32 33 FB.AppEvents.logPageView(); 34 35 }; 36 37 (function(d, s, id){ 38 var js, fjs = d.getElementsByTagName(s)[0]; 39 if (d.getElementById(id)) {return;} 40 js = d.createElement(s); js.id = id; 41 js.src = "https://connect.facebook.net/en_US/sdk.js"; 42 fjs.parentNode.insertBefore(js, fjs); 43 }(document, 'script', 'facebook-jssdk')); 44 </script>
44 45 <style> 46 body { 47 font-family: Space Grotesk !important; 48 background-color: #f0f2f5; 49 } 50 .mx-l-auto { 51 /* margin-right: auto !important; */ 52 margin-left: auto !important; 53 } 54 .social-btn.disabled { 55 opacity: 0.6; 56 cursor: not-allowed; 57 pointer-events: none; /* Prevents clicks */ 58 filter: grayscale(100%); /* Optional: makes it black and white */ 59 text-decoration: none; 60 } 61 </style> 62 63 <!-- Menu Issue solve --> 64<style> 65 /* ========================================= 66 DESKTOP VIEW (Perfectly Centered Menu) 67 ========================================= */ 68 @media (min-width: 992px) { 69 .navbar-collapse { 70 display: flex !important; 71 align-items: center; 72 position: relative; /* Required for absolute centering */ 73 width: 100%; 74 } 75 76 /* 1. Center the Main Navigation Menu */ 77 .navbar-collapse > .navbar-nav:first-child { 78 position: absolute; 79 left: 50%; 80 transform: translateX(-50%); /* Perfectly centers it in the middle of the screen */ 81 display: flex; 82 flex-direction: row; 83 } 84 85 /* 2. Push the Login/Signup Menu to the Right */ 86 .navbar-collapse > .navbar-nav:last-child { 87 margin-left: auto !important; /* Forces right alignment */ 88 display: flex; 89 flex-direction: row; 90 } 91 92 /* 3. Override your inline "margin-left: 20%" which was breaking the layout */ 93 .navbar-nav .nav-item.active { 94 margin-left: 0 !important; 95 } 96 } 97 98 /* ========================================= 99 MOBILE VIEW (Dropdown Fix) 100 ========================================= */ 101 @media (max-width: 991px) { 102 .navbar-collapse { 103 background-color: #ffffff; 104 padding: 15px; 105 border-radius: 8px; 106 box-shadow: 0 4px 15px rgba(0,0,0,0.15); 107 position: absolute; /* Drops it down cleanly over content */ 108 top: 100%; 109 left: 15px; 110 right: 15px; 111 z-index: 999; 112 } 113 114 /* Stack links vertically on mobile */ 115 .navbar-nav { 116 text-align: left; 117 flex-direction: column; 118 width: 100%; 119 } 120 121 /* Ensure links have spacing on mobile */ 122 .navbar-nav .nav-item { 123 margin-bottom: 5px; 124 } 125 126 /* Override the inline margin on mobile too */ 127 .navbar-nav .nav-item.active { 128 margin-left: 0 !important; 129 } 130 } 131</style> 132 133<!-- Footer Issue Solve--> 134 <style> 135 /* ========================================= 136 FOOTER: DESKTOP (Single Line) 137 ========================================= */ 138 .wrap { 139 display: flex; 140 justify-content: space-between; /* Pushes copyright to left, links to right */ 141 align-items: center; /* Vertically centers the text */ 142 padding: 5px 0; 143 border-top: 1px solid #eaeaea; /* Optional: adds a nice subtle line above footer */ 144 } 145 146 /* Remove default paragraph margin so it doesn't break alignment */ 147 .copyright { 148 margin: 0 !important; 149 font-size: 14px; 150 color: #555; 151 } 152 153 /* Align the links horizontally with a gap */ 154 .bottom-links { 155 display: flex; 156 gap: 24px; /* Space between the policy links */ 157 align-items: center; 158 } 159 160 .bottom-links a { 161 text-decoration: none; 162 color: #555; 163 font-size: 14px; 164 transition: color 0.2s ease; 165 } 166 167 .bottom-links a:hover { 168 color: #2C7C80; /* Your brand Teal color */ 169 } 170 171 /* ========================================= 172 FOOTER: MOBILE RESPONSIVE (Stacked) 173 ========================================= */ 174 @media (max-width: 767px) { 175 .wrap { 176 flex-direction: column; /* Stacks copyright and links vertically */ 177 justify-content: center; 178 gap: 15px; /* Space between copyright and links on mobile */ 179 text-align: center; 180 } 181 182 .bottom-links { 183 flex-wrap: wrap; /* Allows links to wrap on very small screens */ 184 justify-content: center; 185 gap: 15px; 186 } 187 } 188</style> 189</head> 190<body> 191<!-- Navbar --> 192 193 194<header class="header-nav py-2"> 195 <div class="container"> 196 <nav class="navbar navbar-expand-lg navbar-light p-0"> 197 <!-- Left-aligned TravelWalls Logo --> 198 <a class="navbar-brand font-weight-bold text-success" href="/"> 199 <img src="/static/assets/media/logo/logo.png" style="height:48px"> 200 </a> 201 202 <!-- Navbar Toggler for Mobile --> 203 <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" 204 aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
205 <span class="navbar-toggler-icon"></span> 206 </button> 207 208 <!-- Navbar Collapse Content --> 209 <div class="collapse navbar-collapse" id="navbarNav"> 210 <!-- Center-aligned Navigation Links --> 211 <ul class="navbar-nav mx-l-auto"> 212 <li class="nav-item active"> 213 <a class="nav-link" href="/">Home</a> 214 </li> 215 <li class="nav-item"> 216 <a class="nav-link" href="/nucleus/public/customer-experience-wall/">TravelWalls</a> 217 </li> 218 <li class="nav-item"> 219 <a class="nav-link" href="/nucleus/sp/spcom/cpg/customer-photo-grapher-list/">Photographer</a> 220 </li> 221 <li class="nav-item"> 222 <a class="nav-link" href="/nucleus/hp/cm-list/">Tourist Place</a> 223 </li> 224<!-- <li class="nav-item">--> 225<!-- <a class="nav-link" href="/nucleus/public/cpcom/customer-settings/customer-coming-soon/">Best Time to Travel</a>--> 226<!-- </li>--> 227<!-- <li class="nav-item">--> 228<!-- <a class="nav-link" href="/nucleus/public/cpcom/customer-settings/customer-coming-soon-travel-memories/">Travel Memories</a>--> 229<!-- </li>--> 230<!-- <li class="nav-item">--> 231<!-- <a class="nav-link" href="/nucleus/public/cpcom/customer-settings/customer-coming-soon-travel-tips/">Travel Tips</a>--> 232<!-- </li>--> 233 <li class="nav-item"> 234 <a class="nav-link" href="/nucleus/vs/vscom/cvs/visa-list/">Visa</a> 235 </li> 236 </ul> 237 238 <!-- Right-aligned Navigation Links --> 239 <ul class="navbar-nav ms-auto" id="user_login_success"> 240 <li class="nav-item"> 241 <a class="nav-link" href="#">Invite friends</a> 242 </li> 243 244 <li class="nav-item"> 245 <a class="nav-link" href="/nucleus/otp-manage/customer-login/">Login</a> 246 </li> 247 <li class="nav-item"> 248 <a class="nav-link" href="/nucleus/otp-manage/customer-login/">Sign Up</a> 249 </li> 250 </ul> 251 </div> 252 </nav> 253 </div> 254 </header> 255 256<!-- Hero Section with Sign In Form --> 257<section class="hero-section"> 258 <div class="signin-card"> 259 <h2 id="form-title" class="text-start mb-4">Sign In</h2> 260 <p id="subtext" class="text-start mb-4">New user? <a href="javascript:void(0)" id="toggle-link" class="text-decoration-none fw-bold" style="color: #212529 !important;">Create 261 an account</a></p> 262 263 <form method="post" action="/nucleus/otp-manage/customer-login/" id="loginForm"> 264 <input type="hidden" name="csrfmiddlewaretoken" value="ywmNFB2L4kVZlGMWM2rSlfkOWNlxZ9OCAQ6FJv7kswoeZBKCzmwcsfUKpvChRe3t"> 265 <div class="mb-3"> 266 <input type="text" id="contact" class="form-control form-control-lg" placeholder="Email or Phone Number" 267 name="contact" required> 268 </div> 269<!-- <div id="phoneError" class="text-danger small mt-1" style="display: none;">--> 270<!-- Please enter a valid phone number (e.g., +88017XXXXXXXX or 017XXXXXXXX).--> 271<!-- </div>--> 272 273 <div id="phoneError" class="text-danger small mt-1" style="display: none;">Please enter a valid email or phone number.</div> 274 275 276 277 <div class="d-grid gap-2"> 278 <button type="submit" id="" class="btn btn-primary btn-lg">SignUp/ Login</button> 279 </div> 280 </form> 281 282 <div class="divider">
283 <span>Or</span> 284 </div> 285 286 287 <a href="javascript:void(0)" id="custom-google-btn" class="social-btn btn-google mb-3 w-100 disabled"> 288 <img src="https://img.icons8.com/color/24/000000/google-logo.png" alt="Google" class="me-2"> 289 Continue with Google 290 </a> 291 292 <a href="#" class="social-btn btn-facebook mb-3 w-100 disabled"> 293 <i class="fab fa-facebook-f me-2"></i> 294 Continue with Facebook 295 </a> 296 297 <div class="text-center mt-4"> 298 <a href="/nucleus/otp-manage/client-sign-up/" 299 class="fw-semibold" 300 style="color:#000; text-decoration:underline;"> 301 Become a TravelWalls Partner 302 </a> 303 </div> 304 305<!-- <a href="#" class="social-btn btn-apple w-100">--> 306<!-- <i class="fab fa-apple me-2"></i>--> 307<!-- Continue with Apple--> 308<!-- </a>--> 309 </div> 310</section> 311 312 313<!-- Footer --> 314 315<footer class="footer" aria-labelledby="footer-heading"> 316 <div class="container"> 317 <h2 id="footer-heading" class="visually-hidden">TravelWalls footer</h2> 318 <div class="row"> 319 <!-- Brand & Address --> 320 <div class="col-md-2 mb-3 mb-md-0"> 321<!-- <h5>Travel<span style="color:#22c55e">Walls</span></h5>--> 322 <a href="/" target="_blank" rel="noopener noreferrer"> 323 <img src="/static/assets/media/logo/logo.png" 324 alt="Travel Walls Logo" 325 style="height:50px; width:100px;"> 326 </a> 327 <br><br> 328 <address class="text-muted" style="font-style: normal; font-size:0.85rem"> 329 44/16, West Panthapath<br> 330 North Dhanmondi, Kolabagan<br> 331 Dhaka-1205<br> 332 Bangladesh 333 </address> 334 <nav class="socials" aria-label="Social links"> 335 <a class="social-icon" target="_blank" rel="noopener noreferrer" href="https://www.facebook.com/travelwalls" 336 aria-label="Twitter"><i class="fab fa-facebook" aria-hidden="true"></i></a> 337 <a class="social-icon" target="_blank" rel="noopener noreferrer" href="#" aria-label="Twitter"><i class="fab fa-twitter" aria-hidden="true"></i></a> 338 <a class="social-icon" target="_blank" rel="noopener noreferrer" href="#" aria-label="Instagram"><i class="fab fa-instagram" aria-hidden="true"></i></a> 339 <a class="social-icon" target="_blank" rel="noopener noreferrer" href="#" aria-label="LinkedIn"><i class="fab fa-linkedin-in" aria-hidden="true"></i></a> 340 <a class="social-icon" target="_blank" rel="noopener noreferrer" href="https://www.youtube.com/@travel-walls" 341 aria-label="YouTube"><i class="fab fa-youtube" aria-hidden="true"></i></a> 342 </nav> 343 </div> 344 345 <!-- About Company --> 346 <div class="col-md-2 mb-3 mb-md-0"> 347 <h5>About Company</h5> 348 <ul class="footer-links" aria-label="About Company"> 349 <li> 350 <a href="/nucleus/public/about-us/" target="_blank" rel="noopener noreferrer"> 351 About Travel Walls 352 </a> 353 </li> 354 <li> 355 <a href="/nucleus/tb/tbcom/bc/customer-blog-list-view/" target="_blank" rel="noopener noreferrer"> 356 Read our blog 357 </a> 358 </li> 359 <!-- 360 <li> 361 <a href="/nucleus/tn/tmcom/np/news-list-view/" target="_blank" rel="noopener noreferrer"> 362 News 363 </a> 364 </li> 365 --> 366 <li> 367 <a href="/nucleus/public/customer-service-view/" target="_blank" rel="noopener noreferrer"> 368 Customer Service 369 </a> 370 </li> 371 </ul> 372 </div> 373 374 <!-- Our Service --> 375 <div class="col-md-2 mb-3 mb-md-0"> 376 <h5>Our Service</h5> 377 <ul class="footer-links" aria-label="Our Service"> 378 <li> 379 <a href="/" target="_blank" rel="noopener noreferrer"> 380 Tour Plan 381 </a> 382 </li> 383 <li> 384 <a href="/nucleus/sp/spcom/csp/customer-service-provider-home/" target="_blank" rel="noopener noreferrer"> 385 Tour Guider 386 </a> 387 </li> 388 <li> 389 <a href="/nucleus/th/hmcom/chm/customer_hotels/" target="_blank" rel="noopener noreferrer"> 390 Hotel / Resort Booking 391 </a> 392 </li> 393 </ul> 394 </div> 395 396 <!-- Top Country --> 397 <div class="col-md-2 mb-3 mb-md-0"> 398 <h5>Become a Partner</h5> 399 <ul class="footer-links" aria-label="Top Country"> 400 <li> 401 <a href="/nucleus/otp-manage/client-sign-up/" target="_blank" rel="noopener noreferrer"> 402 Tour Planner 403 </a> 404 </li> 405 <li> 406 <a href="/nucleus/public/faq-view/" target="_blank" rel="noopener noreferrer"> 407 Read FAQs 408 </a> 409 </li> 410 <li> 411 <a href="/nucleus/otp-manage/client-sign-up/" target="_blank" rel="noopener noreferrer"> 412 Photographer 413 </a> 414 </li> 415 </ul> 416 </div> 417 418 <!-- About Us --> 419 <div class="col-md-2 mb-3 mb-md-0"> 420 <h5>About Us</h5> 421 <ul class="footer-links" aria-label="About Us"> 422 <li> 423 <a href="/nucleus/public/faq-view/" target="_blank" rel="noopener noreferrer"> 424 Read FAQs 425 </a> 426 </li> 427 428<!-- <li>--> 429<!-- <a href="/nucleus/public/cpcom/customer-settings/customer-coming-soon/" target="_blank" rel="noopener noreferrer">--> 430<!-- Browser Extension--> 431<!-- </a>-->
431 432 </li> 433 <li> 434 <a target="_blank" href="/nucleus/tn/tmcom/np/news-list-view/">News</a> 435 </li> 436 <li> 437 <a target="_blank" href="/nucleus/tb/tbcom/bc/customer-blog-list-view/">Blogs</a> 438 </li> 439 <li> 440 <a href="/nucleus/public/customer-service-view/" target="_blank" rel="noopener noreferrer"> 441 Contact us 442 </a> 443 </li> 444 </ul> 445 </div> 446 447 <!-- App QR --> 448 <div class="col-md-2 qr-wrap"> 449 <h5>Get the app</h5> 450 <img class="qr-code" src="https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=https://travelwalls.net/" alt="QR code to download the TravelWalls app" loading="lazy"> 451 <p class="mt-2 mb-0 text-muted" style="font-size:0.8rem">Scan here</p> 452 </div> 453 454 </div> 455 456 457 458 </div> 459</footer> 460 461<div class="container"> 462 <div class="row"> 463 <div class="col-md-12 text-center"> 464 <a target="_blank" href="https://www.sslcommerz.com/" title="SSLCommerz"> 465 <img 466 src="https://securepay.sslcommerz.com/public/image/SSLCommerz-Pay-With-logo-All-Size-03.png" 467 alt="SSLCommerz" 468 style="max-width:100%; height:auto;" 469 /> 470 </a> 471 </div> 472 </div> 473</div> 474 475<!-- Bottom bar --> 476<div class="bottom-footer" role="contentinfo" aria-label="Legal and links"> 477 <div class="container"> 478 <div class="wrap"> 479 <p class="copyright">© 2026 Travel Walls</p> 480 <nav class="bottom-links" aria-label="Policy links"> 481 <a href="/nucleus/public/refund-policy/" target="_blank" rel="noopener noreferrer"> 482 Refund policy 483 </a> 484 <a href="/nucleus/public/privacy-policy/" target="_blank" rel="noopener noreferrer"> 485 Privacy policy 486 </a> 487 488 <a href="/nucleus/public/terms-and-conditions/" target="_blank" rel="noopener noreferrer"> 489 Terms & Condition 490 </a> 491<!-- <a href="/nucleus/public/pricing-view/">Pricing</a>--> 492 </nav> 493 </div> 494 </div> 495</div>
496<script src="https://accounts.google.com/gsi/client" async defer></script>
vendor: 1 bytes, line 496
496
497<script> 498 document.getElementById('toggle-link').addEventListener('click', function(e) { 499 e.preventDefault(); // Stop the page from jumping 500 501 const title = document.getElementById('form-title'); 502 const subtext = document.getElementById('subtext'); 503 const link = this; 504 505 // Toggle logic 506 if (title.innerText === "Sign In") { 507 // Change to Sign Up state 508 title.innerText = "Sign Up"; 509 link.innerText = "Sign in here"; 510 subtext.firstChild.textContent = "Already have an account? "; 511 } else { 512 // Change back to Sign In state 513 title.innerText = "Sign In"; 514 link.innerText = "Create an account"; 515 subtext.firstChild.textContent = "New user? "; 516 } 517}); 518</script>
518 519
520<script> 521 522 document.getElementById('loginForm').addEventListener('submit', function(event) { 523 const contactInput = document.getElementById('contact'); 524 const errorDiv = document.getElementById('phoneError'); // You might want to rename this ID to 'contactError' later 525 const contactValue = contactInput.value.trim(); 526 527 // 1. Phone Regex: Supports +8801..., 01..., etc. (10 to 14 digits) 528 const phoneRegex = /^\+?(\d{10,14})$/; 529 530 // 2. Email Regex: Basic standard email validation 531 const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; 532 533 // Check if it matches EITHER the phone regex OR the email regex 534 const isValidPhone = phoneRegex.test(contactValue); 535 const isValidEmail = emailRegex.test(contactValue); 536 537 if (!isValidPhone && !isValidEmail) { 538 // Stop the form if BOTH are false 539 event.preventDefault(); 540 541 // Show error message 542 errorDiv.textContent = "Please enter a valid email or phone number."; 543 errorDiv.style.display = 'block'; 544 contactInput.classList.add('is-invalid'); 545 } else { 546 // Clear errors if valid 547 errorDiv.style.display = 'none'; 548 contactInput.classList.remove('is-invalid'); 549 } 550}); 551 552// Clear error message as the user types 553document.getElementById('contact').addEventListener('input', function() { 554 this.classList.remove('is-invalid'); 555 document.getElementById('phoneError').style.display = 'none'; 556}); 557 558</script>
558 559 560 561<!--
561<script>--> 562<!-- document.getElementById('loginForm').addEventListener('submit', function(event) {--> 563<!-- const phoneInput = document.getElementById('contact');--> 564<!-- const errorDiv = document.getElementById('phoneError');--> 565<!-- const phoneValue = phoneInput.value.trim();--> 566 567<!-- // Regex for basic validation:--> 568<!-- // Supports: +8801..., 01..., etc. (Allows optional +, then 10 to 14 digits)--> 569<!-- const phoneRegex = /^\+?(\d{10,14})$/;--> 570 571<!-- if (!phoneRegex.test(phoneValue)) {--> 572<!-- // 1. Stop the form from submitting--> 573<!-- event.preventDefault();--> 574 575<!-- // 2. Show error message and style the input--> 576<!-- errorDiv.style.display = 'block';--> 577<!-- phoneInput.classList.add('is-invalid');--> 578<!-- } else {--> 579<!-- // Clear errors if valid--> 580<!-- errorDiv.style.display = 'none';--> 581<!-- phoneInput.classList.remove('is-invalid');--> 582<!-- }--> 583<!--});--> 584 585<!--// Optional: Clear error message as the user types--> 586<!--document.getElementById('contact').addEventListener('input', function() {--> 587<!-- this.classList.remove('is-invalid');--> 588<!-- document.getElementById('phoneError').style.display = 'none';--> 589<!--});--> 590<!--</script>
590-->
591<script> 592 let tokenClient; 593 594 function initGoogle() { 595 console.log("1. Initializing Google Client..."); // DEBUG 596 tokenClient = google.accounts.oauth2.initTokenClient({ 597 client_id: '327583009812-ffut188np4a9g3ajbnvqea2ai8k03i8n.apps.googleusercontent.com', 598 scope: 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile', 599 callback: (response) => { 600 console.log("3. Google Popup Closed. Response received:", response); // DEBUG 601 602 if (response.access_token) { 603 console.log("4. Token found. Sending to Backend..."); // DEBUG 604 handleGoogleLogin(response.access_token); 605 } else { 606 console.error("Error: No access token returned", response); 607 } 608 }, 609 }); 610 } 611 612 document.getElementById('custom-google-btn').addEventListener('click', () => { 613 console.log("2. Button Clicked. Opening Popup..."); // DEBUG 614 tokenClient.requestAccessToken(); 615 }); 616 617 function handleGoogleLogin(accessToken) { 618 fetch("/nucleus/otp-manage/api/auth/google/", { 619 method: 'POST', 620 headers: { 621 'Content-Type': 'application/json', 622 'X-CSRFToken': 'ywmNFB2L4kVZlGMWM2rSlfkOWNlxZ9OCAQ6FJv7kswoeZBKCzmwcsfUKpvChRe3t' 623 }, 624 body: JSON.stringify({ access_token: accessToken }) 625 }) 626 .then(res => { 627 // 1. Check if the request was successful 628 if (res.ok) { 629 // 2. Since your backend redirects, 'res.url' will be the target URL (e.g., /home) 630 console.log("Login successful, redirecting to:", res.url); 631 632 // 3. Manually navigate the browser to that URL 633 window.location.href = res.url; 634 } else { 635 console.error("Login failed with status:", res.status); 636 alert("Login failed. Please try again."); 637 } 638 }) 639 .catch(err => { 640 console.error("Network Error:", err); 641 }); 642 } 643 644 window.onload = initGoogle; 645</script>
vendor: 1 bytes, line 645
645
646<script> 647 // Add Event Listener to your existing "Continue with Facebook" button 648 // Assuming your button has class="btn-facebook" or id="facebook-btn" 649 document.querySelector('.btn-facebook').addEventListener('click', function(e) { 650 e.preventDefault(); // Stop valid href navigation 651 652 // 1. Trigger Facebook Popup 653 FB.login(function(response) { 654 if (response.authResponse) { 655 console.log('Facebook Login Success, sending to backend...'); 656 657 // 2. Get the Access Token 658 const accessToken = response.authResponse.accessToken; 659 660 // 3. Send to your Django Backend 661 handleFacebookLogin(accessToken); 662 } else { 663 console.log('User cancelled login or did not fully authorize.'); 664 } 665 }, {scope: 'public_profile,email'}); // Important: Request email permission 666 }); 667 668 function handleFacebookLogin(accessToken) { 669 console.log('handleFacebookLogin, sending to backend...'); 670 fetch("/nucleus/otp-manage/api/auth/facebook/", { 671 method: 'POST', 672 headers: { 673 'Content-Type': 'application/json', 674 'X-CSRFToken': 'ywmNFB2L4kVZlGMWM2rSlfkOWNlxZ9OCAQ6FJv7kswoeZBKCzmwcsfUKpvChRe3t' 675 }, 676 body: JSON.stringify({ access_token: accessToken }) 677 }) 678 .then(res => { 679 if (res.ok) { 680 console.log("Facebook Login successful, redirecting to:", res.url); 681 // 4. Handle the Redirect (Same as Google) 682 window.location.href = res.url; 683 684 } else { 685 console.error("Facebook Login failed"); 686 alert("Facebook login failed."); 687 } 688 }) 689 .catch(err => console.error("Network Error:", err)); 690 } 691</script>
691 692<!-- Bootstrap JS and Popper.js -->
693<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"></script>
vendor: 1 bytes, line 693
693
694<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
694 695 696<!-- jQuery (required for Bootstrap Datepicker) -->
697<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
697 698 699<!-- Bootstrap Datepicker JS -->
700<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
700 701</body> 702</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.