1"use strict"; 2 3var profile = { 4 postLoginActionUrl: '', 5 data: {}, 6 isLoggedIn: function() { 7 var me = this; 8 if (app.ls.profile.guid) { 9 if (app.ls.profile.guid.length > 5) { 10 return true; 11 } 12 } 13 return false; 14 }, 15 modalAnimate: function($newForm, $oldForm) { 16 var me = this; 17 18 var $newH = $newForm.height(); 19 if ($newH < 150) { 20 $newH = 290; 21 } 22 if ($newForm.data("height")) { 23 $newH = $newForm.data("height"); 24 } 25 if (me.$oldForm) { 26 var $oldH = me.$oldForm.height(); 27 me.$divForms.css("height", $oldH); 28 29 me.$oldForm.fadeToggle(me.$modalAnimateTime, function() { 30 me.$divForms.animate({ 31 height: $newH 32 }, me.$modalAnimateTime, function() { 33 $newForm.fadeToggle(me.$modalAnimateTime); 34 }); 35 }); 36 } else { 37 me.$divForms.animate({ 38 height: $newH 39 }, me.$modalAnimateTime, function() { 40 $newForm.fadeIn(me.$modalAnimateTime); 41 }); 42 } 43 44 me.$oldForm = $newForm; 45 }, 46 msgFade: function($msgId, $msgText) { 47 var me = this; 48 $msgId.fadeOut(me.$msgAnimateTime, function() { 49 $(this).text($msgText).fadeIn(me.$msgAnimateTime); 50 }); 51 }, 52 msgChange: function($divTag, $iconTag, $textTag, $divClass, $iconClass, $msgText) { 53 var $msgOld = $divTag.text(); 54 var me = this; 55 profile.msgFade($textTag, $msgText); 56 $divTag.addClass($divClass); 57 $iconTag.removeClass("glyphicon-chevron-right"); 58 $iconTag.addClass($iconClass + " " + $divClass); 59 setTimeout(function() { 60 profile.msgFade($textTag, $msgOld); 61 $divTag.removeClass($divClass); 62 $iconTag.addClass("glyphicon-chevron-right"); 63 $iconTag.removeClass($iconClass + " " + $divClass); 64 }, me.$msgShowTime); 65 }, 66 init: function() { 67 var me = this; 68 me.$formLogin = $('#login-form'); 69 me.$formLost = $('#lost-form'); 70 me.$formRegister = $('#register-form'); 71 me.$formCartLogin = $('#cart-login'); 72 me.$divForms = $('#div-forms'); 73 me.$modalAnimateTime = 300; 74 me.$msgAnimateTime = 150; 75 me.$msgShowTime = 2000; 76 me.$oldForm = null; 77 78 $(".fnc-show-account-login").off().on("click", function(e) { 79 profile.modalAnimate(profile.$formLogin); 80 if ($(this).attr("data-login-success-url")) { 81 profile.postLoginActionUrl = $(this).attr("data-login-success-url"); 82 } else { 83 profile.postLoginActionUrl = ""; 84 } 85 if (utils.isBS5()) { 86 var loginModal = new bootstrap.Modal(document.getElementById('login-modal'), {}); 87 loginModal.show(); 88 } else { 89 $("#login-modal").modal(); 90 } 91 app.loadPickupSelectLists(); 92 e.preventDefault(); 93 return false; 94 }); 95 96 $(".fnc-show-account-register").off().on("click", function(e) { 97 profile.modalAnimate(profile.$formRegister); 98 if (utils.isBS5()) { 99 var loginModal = new bootstrap.Modal(document.getElementById('login-modal'), {}); 100 loginModal.show(); 101 } else { 102 $("#login-modal").modal(); 103 } 104 e.preventDefault(); 105 return false; 106 }); 107 108 $(".fnc-account-logout").off().on("click", function(e) { 109 if (utils.isBS5()) { 110 var logoutModal = new bootstrap.Modal(document.getElementById('dialog-logout'), {}); 111 logoutModal.show(); 112 } else { 113 $("#dialog-logout").modal(); 114 } 115 e.preventDefault(); 116 return false; 117 }); 118 119 $(".fnc-account-logout-confirm").off().on("click", function(e) { 120 profile.logout(); 121 return false; 122 }); 123 124 $(".fnc-account-index").off().on("click", function() { 125 window.location = "/account/welcome"; 126 }); 127 128 $(".fnc-account-save-profile").parents("form").off().on("submit", function(e) { 129 e.preventDefault(); 130 me.saveProfile("#account-profile"); 131 $('.fnc-account-save-profile').prop('disabled', true); 132 }); 133 134 $(".fnc-account-save-profile").off().on("click", function(e) { 135 $(".fnc-account-save-profile").parents("form").submit(); 136 }); 137 138 $(".fnc-account-login").parents("form").off().on("submit", function(e) { 139 var input = this; 140 var loginForm = corridor(input); 141 142 if ($(this).attr("data-login-success-url")) { 143 profile.postLoginActionUrl = $(this).attr("data-login-success-url"); 144 } 145 146 $.ajax({ 147 type: "POST", 148 url: "/account/login", 149 data: JSON.stringify(loginForm), 150 headers: { 151 'Content-Type': 'application/json', 152 'x-csrf-token': csrf_token 153 }, 154 success: function(data) { 155 profile.login(data, app.loginCallback); 156 }, 157 failure: function(data) { 158 console.log("Login failed", JSON.stringify(data)); 159 } 160 }); 161 e.preventDefault(); 162 return false; 163 }); 164 165 $(".fnc-account-impersonate").parents("form").off().on("submit", function(e) { 166 var input = this; 167 var loginForm = corridor(input); 168 loginForm._crsf = csrf_token; 169 $.ajax({ 170 type: "POST", 171 url: "/api/impersonate", 172 data: JSON.stringify(loginForm), 173 headers: { 174 'Content-Type': 'application/json', 175 'x-csrf-token': csrf_token 176 }, 177 success: function(data) { 178 var currentState = app.getLocalState("s"); 179 app.setLocalState(currentState, "imp"); 180 profile.login(data, function() { 181 //console.log("impersonate complete") 182 }); 183 } 184 }); 185 e.preventDefault(); 186 return false;
187 }); 188 189 $(".fnc-account-undo-impersonate").off().on("click", function(e) { 190 var currentState = app.getLocalState("imp"); 191 app.setLocalState(currentState, "s"); 192 if (currentState) { 193 var impersonateReq = { 194 impersonateGuid: currentState.profile.guid 195 } 196 197 $.ajax({ 198 type: "POST", 199 url: "/api/impersonate", 200 data: JSON.stringify(impersonateReq), 201 headers: { 202 'Content-Type': 'application/json', 203 'x-csrf-token': csrf_token 204 }, 205 success: function(data) { 206 var currentState = app.getLocalState("s"); 207 app.setLocalState(currentState, "imp"); 208 Cookies.set("imp", null); 209 profile.login(data, function() { 210 //console.log("impersonate undo complete") 211 }); 212 } 213 }); 214 } 215 e.preventDefault(); 216 return false; 217 }); 218 219 $(".fnc-account-forgot-password").parents("form").off().on("submit", function(e) { 220 var input = this; 221 var passwordForm = corridor(input); 222 passwordForm._crsf = csrf_token; 223 $.ajax({ 224 type: "POST", 225 url: "/account/passwordreset", 226 data: JSON.stringify(passwordForm), 227 headers: { 228 'Content-Type': 'application/json', 229 'x-csrf-token': csrf_token 230 }, 231 success: function(data) { 232 if (data.success) { 233 app.notify("Please check your email for the password reset link.", "info"); 234 } else { 235 app.notify(data.message, "error"); 236 } 237 $("#login-modal").modal("hide"); 238 } 239 }); 240 e.preventDefault(); 241 return false; 242 }); 243 244 $(".fnc-account-reset-password").on("click", function(e) { 245 var input = document.querySelector('#reset-password'); 246 var passwordForm = corridor(input); 247 passwordForm._crsf = csrf_token; 248 $.ajax({ 249 type: "POST", 250 url: "/account/submitpasswordreset", 251 data: JSON.stringify(passwordForm), 252 headers: { 253 'Content-Type': 'application/json', 254 'x-csrf-token': csrf_token 255 }, 256 success: function(data) { 257 app.notify("Your password was updated successfully.", "info"); 258 $("#login-modal").modal("hide"); 259 setTimeout(function() { 260 window.location = "/login"; 261 }, 1000); 262 } 263 }); 264 e.preventDefault(); 265 }); 266 267 $(".fnc-account-register").parents("form").off().on("submit", function(e) { 268 var input = this; //document.querySelector('#register-form'); 269 var registerForm = {}; 270 $.each($(input).serializeArray(), function(i, field) { 271 registerForm[field.name] = field.value; 272 }); 273 // var registerForm = corridor(input); 274 registerForm._crsf = csrf_token; 275 276 if (profile.validateRegisterForm(input.id)) { 277 // everything looks good! 278 registerForm.code = profile.formatLinkName(registerForm.email); 279 profile.registerProfile(registerForm, function(err, result) { 280 //display result 281 if (err) { 282 app.notify("Registration error: " + result.message, "error"); 283 } 284 if (result) { 285 if (result.success) { 286 window.location = "/"; 287 } else { 288 app.notify("Registration error: " + result.message, "error"); 289 } 290 } 291 }); 292 } 293 e.preventDefault(); 294 return false; 295 }); 296 297 $(".fnc-account-submit-login-form").parents("form").off().on("submit", function() { 298 var input = document.querySelector('#contact-form'); 299 var docId = "history_" + app.g(0); 300 var contactForm = corridor(input); 301 contactForm._id = docId; 302 contactForm.pdb = m.sessionDbName; 303 contactForm._crsf = csrf_token; 304 var doc = { 305 _id: docId, 306 url: window.location.host, 307 contactEmail: contactForm.email, 308 subject: contactForm.subject, 309 type: 7, // custom form 310 metadata: JSON.stringify(contactForm) 311 } 312 app.db.put(doc, function callback(err, result) { 313 if (!err) { 314 app.sync(); 315 } 316 }); 317 return false;
318 }); 319 320 $("#login-modal form").submit(function() { 321 switch (this.id) { 322 case "login-form": 323 var $lg_username = $('#login_username').val(); 324 var $lg_password = $('#login_password').val(); 325 326 return false; 327 break; 328 case "lost-form": 329 var $ls_email = $('#lost_email').val(); 330 if ($ls_email == "ERROR") { 331 //profile.msgChange($('#div-lost-msg'), $('#icon-lost-msg'), $('#text-lost-msg'), "error", "glyphicon-remove", "Send error"); 332 } else { 333 //profile.msgChange($('#div-lost-msg'), $('#icon-lost-msg'), $('#text-lost-msg'), "success", "glyphicon-ok", "Send OK"); 334 } 335 return false; 336 break; 337 case "register-form": 338 var $rg_username = $('#register_username').val(); 339 var $rg_email = $('#register_email').val(); 340 var $rg_password = $('#register_password').val(); 341 if ($rg_username == "ERROR") { 342 //profile.msgChange($('#div-register-msg'), $('#icon-register-msg'), $('#text-register-msg'), "error", "glyphicon-remove", "Register error"); 343 } else { 344 //profile.msgChange($('#div-register-msg'), $('#icon-register-msg'), $('#text-register-msg'), "success", "glyphicon-ok", "Register OK"); 345 } 346 return false; 347 break; 348 default: 349 return false; 350 } 351 profile.renderWatchlistDropdown(); 352 return false; 353 }); 354 355 $('#login_register_btn').click(function() { 356 $("#acc-country").val(app.ls.geoCountry); 357 profile.modalAnimate(me.$formRegister) 358 }); 359 $('#register_login_btn').click(function() { 360 profile.modalAnimate(me.$formLogin); 361 }); 362 $('#login_lost_btn').click(function() { 363 profile.modalAnimate(me.$formLost); 364 }); 365 $('#lost_login_btn').click(function() { 366 profile.modalAnimate(me.$formLogin); 367 }); 368 $('#lost_register_btn').click(function() { 369 $("#acc-country").val(app.ls.geoCountry); 370 profile.modalAnimate(me.$formRegister); 371 }); 372 $('#register_lost_btn').click(function() { 373 profile.modalAnimate(me.$formLost); 374 }); 375 376 if (app.ls.syncDue) { 377 setTimeout(function() { 378 app.sync(function() { 379 app.ls.syncDue = false; 380 me.refreshLocalProfile(); 381 }); 382 }, 2000); 383 } 384 385 if (app.ls.profileDbName) { 386 app.pdb = new PouchDB(app.ls.profileDbName); 387 app.pdb.setMaxListeners(20); 388 } 389 390 // WATCHLIST SECTION 391 $(".fnc-add-to-watchlist").off().on("click", function(e) { 392 var product = app.resolveItemToSaleline($(this)); 393 app.requireLogin("To add this item to your watchlist, please login or register.", function(userProfile) { 394 profile.addWatchListItem(product, function(msg, type) { 395 app.notify(msg, type); 396 }); 397 }); 398 e.preventDefault(); 399 return false; 400 }); 401 402 403 // ITEMLIST SECTION 404 $(".fnc-itemlink-delete").off().on("click", function(e) { 405 var itlId = $(this).attr("data-itl-id").split("_")[2]; 406 if (itlId > 0) { 407 $.ajax({ 408 type: "POST", 409 url: '/account/itemlink', 410 data: JSON.stringify({ 411 itlId: itlId, 412 action: "delete" 413 }), 414 headers: { 415 'Content-Type': 'application/json', 416 'x-csrf-token': csrf_token 417 }, 418 success: function(data) { 419 if (data.success) { 420 app.notify("The link was deleted. Please refresh the page to see updated information.", "info"); 421 422 } else { 423 app.notify(data.message, "error"); 424 } 425 } 426 }); 427 } 428 }); 429 430 431 $(".add-itemlink-form").off().on("submit", function(e) { 432 var input = this; //document.querySelector('#lost-form'); 433 var linkForm = corridor(input); 434 435 if (!linkForm.sourceId) { 436 linkForm.sourceId = app.ls.profile.custId; 437 } 438 439 var ipToInt = function(ip) { 440 // Split IP into octets and convert to numbers 441 const octets = ip.split('.').map(Number); 442 443 // Combine octets using bitwise operations 444 return octets[0] << 24 | octets[1] << 16 | octets[2] << 8 | octets[3]; 445 } 446 447 if (parseInt(linkForm.type) == 45) { 448 linkForm.metadata = {"notes":linkForm.notes,"ipaddress":linkForm.description}; 449 linkForm.targetId = ipToInt(linkForm.description); 450 } 451 452 $.ajax({ 453 type: "POST", 454 url: '/account/itemlink', 455 data: JSON.stringify(linkForm), 456 headers: { 457 'Content-Type': 'application/json', 458 'x-csrf-token': csrf_token 459 }, 460 success: function(data) { 461 if (data.success) { 462 app.notify("The link was added. Please refresh the page to see updated information.", "info"); 463 } else { 464 app.notify(data.message, "error"); 465 } 466 } 467 }); 468 e.preventDefault(); 469 return false;
470 }); 471 profile.refreshLocalProfile(); 472 profile.renderWatchlistDropdown(); 473 }, 474 refreshLocalProfile: function() { 475 var options = { 476 startkey: "user", 477 endkey: "user", 478 include_docs: true, 479 attachments: true 480 }; 481 482 if (app.pdb) { 483 app.pdb.allDocs(options).then(function(result) { 484 if (result.rows[0]) { 485 var profileDoc = result.rows[0].doc; 486 app.ls.profile = profileDoc; 487 if(typeof store !== 'undefined'){ 488 store.profile.set(app.ls.profile); 489 } 490 app.setLocalState(app.ls); 491 } 492 profile.updateProfileDisplay(); 493 }).catch(function(err) { 494 console.log(err); 495 }); 496 } else { 497 profile.updateProfileDisplay(); 498 } 499 }, 500 formatLinkName: function(st) { 501 var lIndex = 0; 502 var sOut = []; 503 var cTemp = ""; 504 var lChar = 0; 505 var bskip = false; 506 507 st = st.toLowerCase().trim(); 508 if (st.length > 0) { 509 for (lIndex = 0; lIndex < st.length; lIndex++) { 510 cTemp = st.substr(lIndex, 1); 511 lChar = cTemp.charCodeAt(0); 512 switch (lChar) { 513 // convert space 514 case 32: 515 { 516 if (!bskip) { 517 if (lIndex > 2) { 518 sOut.push("-"); 519 } 520 bskip = true; 521 } 522 break; 523 } 524 // convert dash 525 case 45: 526 { 527 if (!bskip) { 528 if (lIndex > 2) { 529 sOut.push("-"); 530 } 531 bskip = true; 532 } 533 break; 534 } 535 // convert forwardslash 536 case 47: 537 { 538 if (!bskip) { 539 if (lIndex > 2) { 540 sOut.push("-"); 541 } 542 bskip = true; 543 } 544 break; 545 } 546 case 46: 547 { // . 548 if (!bskip) { 549 if (lIndex < 3) {} else { 550 sOut.push(cTemp); 551 } 552 } 553 bskip = true; 554 break; 555 } 556 // allow a-z, 0-9, @ 557 default: 558 { 559 if (lChar == 64) { 560 sOut.push('_at_'); 561 bskip = false; 562 } 563 if ((lChar >= 97) && (lChar <= 122)) { 564 sOut.push(cTemp); 565 bskip = false; 566 } 567 if ((lChar >= 48) && (lChar <= 57)) { 568 sOut.push(cTemp); 569 bskip = false; 570 } 571 } 572 } 573 } 574 return sOut.join(""); 575 } else { 576 return ""; 577 } 578 }, 579 580 updateProfileDisplay: function() { 581 var pitems = document.querySelectorAll(".account-status"); 582 var loggedIn = false; 583 if (app.ls.profile) { 584 if (app.ls.profile.guid) { 585 loggedIn = true; 586 } 587 } 588 // debugger; 589 for (var i = 0; i < pitems.length; i++) { 590 switch (pitems[i].getAttribute("data-type")) { 591 case "public": 592 if (!app.ls.profile.guid) { 593 if (pitems[i].getAttribute("data-style")) { 594 pitems[i].style.display = pitems[i].getAttribute("data-style"); 595 } else { 596 pitems[i].style.display = "inline-block"; 597 } 598 pitems[i].classList.remove("hidden-default"); 599 } else { 600 pitems[i].style.display = "none"; 601 } 602 break; 603 case "authenticated": 604 if (loggedIn) { 605 if (pitems[i].getAttribute("data-style")) { 606 pitems[i].style.display = pitems[i].getAttribute("data-style"); 607 } else { 608 pitems[i].style.display = "inline-block"; 609 } 610 pitems[i].classList.remove("hidden-default"); 611 } else { 612 //debugger; 613 if (pitems[i].getAttribute("data-login-page-id")) { 614 $(pitems[i]).children("a").attr("href","/?pageid=" + pitems[i].getAttribute("data-login-page-id")); 615 } else { 616 pitems[i].style.display = "none"; 617 } 618 } 619 break; 620 case "impersonate": 621 if (app.getLocalState("imp")) { 622 if (pitems[i].getAttribute("data-style")) { 623 pitems[i].style.display = pitems[i].getAttribute("data-style"); 624 } else { 625 pitems[i].style.display = "inline-block"; 626 } 627 pitems[i].classList.remove("hidden-default"); 628 } else { 629 pitems[i].style.display = "none"; 630 } 631 break; 632 } 633 } 634 if (loggedIn) { 635 var pflds = $(".profile"); 636 for (var i = 0; i < pflds.length; i++) { 637 var fld = $(pflds[i]); 638 if (fld.attr("name")) { 639 if (fld.val() == "") { 640 if (app.ls.profile[fld.attr("name")]) { 641 fld.val(app.ls.profile[fld.attr("name")]); 642 } 643 } 644 } else { 645 if (app.ls.profile[fld.attr("data-field")]) { 646 fld.text(app.ls.profile[fld.attr("data-field")]); 647 } 648 } 649 } 650 } 651 }, 652 //updateLocalProfile: function () { 653 // app.sync(function () { 654 // var options = { 655 // startkey: "user", 656 // endkey: "user", 657 // include_docs: true, 658 // attachments: true 659 // }; 660 661 // app.pdb.allDocs(options).then(function (result) { 662 // var profileDoc = result.rows[0].doc; 663 // app.ls.profile = JSON.parse(sjcl.decrypt(app.ls.key, profileDoc.content)); // JSON.parse(profileDoc.content); // 664 // app.setLocalState(app.ls); 665 // }).catch(function (err) { 666 // console.log(err); 667 // }); 668 // }); 669 //}, 670 671 672 // PROFILE SECTION 673 validateRegisterForm: function(formId) { 674 var form = document.querySelector('#' + formId); 675 $("#" + formId + " .error").removeClass("error"); 676 var cf = null; 677 var isValid = true; 678 679 var invalidField = function(formId, name, note) { 680 var fld = $("#" + formId + " input[name='" + name + "']"); 681 if (fld) { 682 fld.addClass("error"); 683 fld.attr("title", note); 684 isValid = false;
685 } else { 686 fld = $("#" + formId + " select[name='" + name + "']"); 687 if (fld) { 688 fld.addClass("error"); 689 fld.attr("title", note); 690 isValid = false; 691 } 692 } 693 }; 694 695 var validateEmail = function(value) { 696 var input = document.createElement('input'); 697 input.type = 'email'; 698 input.value = value; 699 return typeof input.checkValidity == 'function' ? input.checkValidity() : /\S+@\S+\.\S+/.test(value); 700 }; 701 702 if (form) { 703 cf = corridor(form); 704 if (cf.firstname.length < 2) 705 invalidField(formId, "firstname", "Please enter your full first name."); 706 707 if (cf.lastname.length < 2) 708 invalidField(formId, "lastname", "Please enter your full last name."); 709 710 if (!validateEmail(cf.email) || cf.email.length < 3) 711 invalidField(formId, "email", "Please enter a valid email address."); 712 713 if (cf.address1) if (cf.address1.length < 2) invalidField(formId, "address1", "Please enter an address."); 714 715 if (cf.phone) if (cf.phone.length < 2) invalidField(formId, "phone", "Please enter a phone number."); 716 717 if (cf.city) if (cf.city.length < 2) invalidField(formId, "city", "Please enter a city name."); 718 719 if (cf.postcode) if (cf.postcode.length < 4) invalidField(formId, "postcode", "Please enter a valid post code."); 720 721 if (cf.country) if (cf.country.length < 2) invalidField(formId, "country", "Please choose a valid country."); 722 723 if (String(cf.password).length > 4) { 724 if (cf.password != cf.password2) { 725 invalidField(formId, "password", "The two password fields must match."); 726 invalidField(formId, "password2", "The two password fields must match."); 727 } 728 } else { 729 invalidField(formId, "password", "The password must be longer than 4 letters."); 730 } 731 return isValid; 732 } 733 return false; 734 }, 735 736 737 registerProfile: function(registerForm, callback) { 738 registerForm._crsf = csrf_token; 739 $.ajax({ 740 type: "POST", 741 url: "/account/register", 742 data: JSON.stringify(registerForm), 743 headers: { 744 'Content-Type': 'application/json', 745 'x-csrf-token': csrf_token 746 }, 747 success: function(data) { 748 if (data.success) { 749 window.location = "/"; 750 } else { 751 if (data.message) { 752 callback("Registration error", data); 753 } else { 754 callback("Registration error", { 755 success: false, 756 message: "Registration failed, please try again." 757 }); 758 } 759 } 760 } 761 }); 762 }, 763 registerContact: function(cust) { 764 765 }, 766 767 completeLogin: function(callback) { 768 var options = { 769 startkey: "user", 770 endkey: "user", 771 include_docs: true, 772 attachments: true 773 }; 774 775 app.pdb.allDocs(options).then(function(result) { 776 if (result.rows) { 777 profile.msgChange($('#div-login-msg'), $('#icon-login-msg'), $('#text-login-msg'), "success", "glyphicon-ok", "Login OK"); 778 } else { 779 profile.msgChange($('#div-login-msg'), $('#icon-login-msg'), $('#text-login-msg'), "error", "glyphicon-remove", "Login error."); 780 } 781 782 if (result.rows[0]) { 783 app.ls.profile = result.rows[0].doc; 784 if (app.ls.profile) { 785 if (!app.ls.profile.priceLevel) app.ls.profile.priceLevel = app.ls.profile.pricelevel; 786 } 787 app.setLocalState(app.ls); 788 try { 789 $("#login-modal").modal("hide"); 790 } 791 catch(e) {} 792 793 app.applyProfileDetailsToSale('shopping-cart-details', function() { 794 profile.updateProfileDisplay(); 795 if (callback) { 796 callback(app.ls.profile); 797 } 798 799 app.checkCartDraftOrders(function(err, res) { 800 if (profile.postLoginActionUrl != "") { 801 setTimeout(function() { 802 switch (profile.postLoginActionUrl) { 803 case "_current": 804 profile.postLoginActionUrl = window.location.pathname + '?nc=1'; 805 break; 806 default: 807 // it's already a URL 808 break; 809 } 810 window.location = profile.postLoginActionUrl; 811 profile.postLoginActionUrl = ""; 812 }, 500); 813 $("body").fadeOut(1000); 814 } else { 815 $("body").fadeOut(1000); 816 setTimeout(function() { 817 window.location = '/account/welcome?_dc='+Math.random(); 818 }, 500); 819 } 820 }); 821 }); 822 } else { 823 console.log("User record not found"); 824 } 825 }).catch(function(err) { 826 console.log(err); 827 }); 828 }, 829 830 login: function(data, callback) { 831 var dbName = ""; 832 833 if (data.success) { 834 if (data.key) { 835 app.ls.key = data.key; 836 app.ls.profileDbName = data.profile; 837 } 838 app.ls.currency = data.data.currency; 839 app.ls.baseCurrency = data.data.currency; 840 841 app.setLocalState(app.ls); 842 if (PouchDB) { 843 app.pdb = new PouchDB(app.ls.profileDbName); 844 app.pdb.setMaxListeners(20); 845 setTimeout(function() { 846 app.pdb.info(function(err, info) { 847 if (!err) { 848 if (app.ls.profileDbName) { 849 app.pdb.get('user').then(function(doc) { 850 data.data._rev = doc._rev; 851 return app.pdb.put(data.data); 852 }).then(function(response) { 853 profile.completeLogin(callback); 854 }).catch(function (err) { 855 if (err) console.log("ERROR: ", err); 856 app.pdb.put(data.data).then(function (response) { 857 profile.completeLogin(callback); 858 }); 859 }); 860 } 861 } else { 862 console.log("login PDB error: " + err) 863 } 864 }); 865 }, 200); 866 return dbName; 867 } else { 868 profile.completeLogin(callback); 869 } 870 } else { 871 profile.msgChange($('#div-login-msg'), $('#icon-login-msg'), $('#text-login-msg'), "error", "glyphicon-remove", "Login error - please try again"); 872 return ""; 873 } 874 }, 875 forgotPassword: function(email) {}, 876 877 logout: function() { 878 app.ls.profileDbName = ""; 879 app.ls.profile = {}; 880 $.ajax({ 881 type: "POST", 882 url: "/account/logout", 883 headers: { 884 'Content-Type': 'application/json', 885 'x-csrf-token': csrf_token 886 }, 887 contentType: 'application/json', 888 success: function(data) { 889 // console.log("Logout resp", JSON.stringify(data)); 890 app.cartClear(true, function() { 891 app.setLocalState(app.ls); 892 window.location = "/?_dc="+Math.random(); 893 }); 894 } 895 }); 896 }, 897 898 refreshProfile: function() { 899 console.log("Profile Refresh"); 900 }, 901 902 loadProfile: function() { 903 // return cust obj 904 }, 905 saveProfile: function(formId) { 906 var profileForm = corridor(document.querySelector(formId)); 907 profileForm._csrf = csrf_token; 908 $.ajax({ 909 type: "POST", 910 url: "/account/saveprofile", 911 headers: { 912 'Content-Type': 'application/json', 913 'x-csrf-token': csrf_token 914 }, 915 data: JSON.stringify(profileForm), 916 success: function(data) { 917 app.notify("Your profile was updated successfully.", "info"); 918 delete profileForm._csrf; 919 if (data.success) { 920 var options = { 921 startkey: "user", 922 endkey: "user", 923 include_docs: true, 924 attachments: true 925 }; 926 927 app.pdb = new PouchDB(app.ls.profileDbName); 928 app.pdb.allDocs(options).then(function(result) { 929 var profileDoc = result.rows[0].doc; 930 var profileRec = $.extend({}, profileDoc, profileForm); // merge plaintext profile with form data 931 // update local profile 932 app.ls.profile = profileRec; 933 934 // encrypt for sync 935 app.pdb.put(profileRec, function callback(err, result) { 936 if (!err) { 937 setTimeout(function() { 938 window.location = "/account/welcome"; 939 }, 3000); 940 } else { 941 console.log(err); 942 } 943 }); 944 }); 945 } else { 946 if (data.message) { 947 callback("Registration error", data); 948 } else { 949 callback("Registration error", { 950 success: false, 951 message: "Registration failed, please try again." 952 }); 953 } 954 } 955 } 956 }); 957 }, 958 deleteProfile: function() { 959 960 }, 961 962 startImpersonate: function(impersonateCustGuid) { 963 964 }, 965 stopImpersonate: function() { 966 967 }, 968 969 // SALES SECTION 970 saveCurrentSale: function() {}, 971 loadSavedSale: function(saleGuid) {}, 972 renderPastSales: function() { 973 var m = app; 974 var options = { 975 startkey: "sale", 976 endkey: "sale", 977 include_docs: true 978 }; 979 980 m.pdb.allDocs(options, function(err, doc) { 981 if (!err) { 982 m.renderTotals(); 983 dust.render("templates/components/client/account/sales/history/report", doc, function(err, out) { 984 if (err) { 985 console.error(err); 986 } else { 987 $(".sales-report").html(out); 988 prices.initPrices(m.ls.currency); 989 m.registerCartEvents(); 990 } 991 }); 992 } 993 }); 994 }, 995 996 // WATCHLIST SECTION 997 addWatchListItem: function(product, cb) { 998 var m = this; 999 var itemlinkGuid = app.g(0); 1000 var currline = { 1001 "_id": "itemlink_" + itemlinkGuid, 1002 "contentType": "itemlink", 1003 "url": window.location.href, 1004 "prdId": product.prdId, 1005 "pmmId": product.pmmId, 1006 "picId": product.picId, 1007 "custId": app.ls.profile.custId, 1008 "outletId": product.outletId, 1009 "picFileName": product.picFileName, 1010 "schema": product.schema, 1011 "grpIdTree": product.grpIdTree, 1012 "code": product.code, 1013 "name": product.name, 1014 "type": product.type, 1015 "description": product.description, 1016 "loyaltyCost": 0, 1017 "loyaltyReward": 0, 1018 "price": product.price, 1019 "priceCurr": product.priceCurr, 1020 "priceTax": product.priceTax, 1021 "rrp": product.rrp, 1022 "discount": product.discount 1023 }; 1024 1025 $.ajax({ 1026 url: '/account/itemlink', 1027 type: 'POST', 1028 headers: { 1029 'Content-Type': 'application/json', 1030 'x-csrf-token': csrf_token 1031 }, 1032 data: JSON.stringify({ 1033 _csrf: csrf_token, 1034 targetId: product.prdId, 1035 sourceId: currline.custId, 1036 metadata: currline, 1037 type: "2", 1038 description: product.code + ": " + product.name, 1039 flags: 0, 1040 action: "save" 1041 }), 1042 dataType: 'json', 1043 success: function(d) { 1044 if (cb) { 1045 cb("Added " + product.name + " to your watchlist.", "info"); 1046 setTimeout(function() { 1047 profile.renderWatchlistDropdown(); 1048 }, 10000); 1049 } 1050 }, 1051 failure: function(d) { 1052 if (cb) { 1053 //cb(product.name + "<br>was already in your watchlist", "info"); 1054 } 1055 } 1056 }); 1057 }, 1058 removeWatchListItem: function(domEl) { 1059 1060 }, 1061 registerWatchlistEvents: function() { 1062 $(".fnc-watchlist-delete-line").off().on("click", function(e) { 1063 var $elm = $($(this).parents(".watchlist-item")[0]); 1064 var prdId = $elm.attr("data-prd-id"); 1065 var pmmId = $elm.attr("data-pmm-id"); 1066 1067 $.ajax({ 1068 url: '/account/itemlink', 1069 type: 'POST', 1070 headers: { 1071 'Content-Type': 'application/json', 1072 'x-csrf-token': csrf_token 1073 }, 1074 data: JSON.stringify({ 1075 _csrf: csrf_token, 1076 itlId: 0, //$elm.attr("data-id").split("_")[2], 1077 targetId: prdId, 1078 sourceId: app.ls.profile.custId, 1079 metadata: null, 1080 type: "2", 1081 description: "", 1082 flags: 0, 1083 action: "delete" 1084 }), 1085 dataType: 'json', 1086 success: function(d) { 1087 $elm.css("display", "none"); 1088 setTimeout(function() { 1089 profile.renderWatchlistDropdown(); 1090 }, 10000); 1091 }, 1092 failure: function(d) { 1093 } 1094 }); 1095 1096 e.preventDefault(); 1097 return false;
1098 }); 1099 }, 1100 1101 renderWatchlistDropdown: function() { 1102 var m = app; 1103 $.ajax({ 1104 url: '/account/itemlinks?type=2&_dc=' + Math.random(), 1105 type: 'GET', 1106 contentType: 'application/json', 1107 dataType: 'json', 1108 success: function(d) { 1109 let doc = { 1110 rows: { 1111 doc: d.data 1112 } 1113 } 1114 1115 dust.render("templates/components/client/watchlist/dropdown", doc, function(err, out) { 1116 if (err) { 1117 console.error(err) 1118 } else { 1119 $(".watchlist-item-list").html(out); 1120 1121 if (app.ls.total) { 1122 if (doc.rows.doc) { 1123 app.ls.total.watchlistCount = doc.rows.doc.length; 1124 } else { 1125 app.ls.total.watchlistCount = 0; 1126 } 1127 } 1128 1129 // hide or statuses based on if there are things in the watchlist 1130 var pitems = document.querySelectorAll(".watchlist-status"); 1131 for (var i = 0; i < pitems.length; i++) { 1132 var type = pitems[i].getAttribute("data-type"); 1133 1134 if (type == "empty") { 1135 if (m.ls.total.watchlistCount > 0) { 1136 pitems[i].style.display = "none"; 1137 } else { 1138 if (pitems[i].getAttribute("data-style")) { 1139 pitems[i].style.display = pitems[i].getAttribute("data-style"); 1140 } else { 1141 pitems[i].style.display = "block"; 1142 } 1143 } 1144 } else { 1145 if (m.ls.total.watchlistCount > 0) { 1146 if (pitems[i].getAttribute("data-style")) { 1147 pitems[i].style.display = pitems[i].getAttribute("data-style"); 1148 } else { 1149 pitems[i].style.display = "block"; 1150 } 1151 } else { 1152 pitems[i].style.display = "none"; 1153 } 1154 } 1155 } 1156 1157 profile.registerWatchlistEvents(); 1158 } 1159 }); 1160 1161 }, 1162 failure: function(d) { 1163 } 1164 }); 1165 }, 1166 1167 findWatchlistLine: function(prod, cb) { 1168 var currline = null; 1169 var options = { 1170 startkey: "itemlink_", 1171 endkey: "itemlink_\uffff", 1172 include_docs: true 1173 }; 1174 1175 app.pdb.allDocs(options, function(err, doc) { 1176 if (!err) { 1177 if (doc.rows.length == 0) { 1178 cb(err, null); 1179 return; 1180 } 1181 doc.rows.forEach(function(item) { 1182 var wll = item.doc; 1183 if (wll._id.indexOf("itemlink_") > -1) { 1184 if (wll.prdId == prod.prdId) { 1185 if (typeof prod.pmmId != "undefined") { 1186 if (wll.pmmId == prod.pmmId) { 1187 currline = item.doc; 1188 } 1189 } else { 1190 // found item line 1191 currline = item.doc; 1192 } 1193 } 1194 } 1195 }); 1196 } 1197 1198 if (currline) { 1199 cb(err, currline); 1200 } else { 1201 cb(err, null); 1202 } 1203 return; 1204 }); 1205 }, 1206 itemLinkAction: function(item, cb) { 1207 // set the "item.action" property to "save" or "delete" 1208 /* obj: 1209 targetId: 1210 sourceId: 1211 metadata: 1212 type: 1213 description: 1214 flags: 1215 action: 1216 */ 1217 1218 $.ajax({ 1219 url: '/account/itemlink', 1220 type: 'POST', 1221 headers: { 1222 'Content-Type': 'application/json', 1223 'x-csrf-token': csrf_token 1224 }, 1225 data: JSON.stringify(item), 1226 dataType: 'json', 1227 success: function(d) { 1228 if (cb) { 1229 cb(false, "OK"); 1230 } 1231 }, 1232 failure: function(d) { 1233 if (cb) { 1234 cb("ERR"); 1235 } 1236 } 1237 }); 1238 }, 1239 sd: function() { 1240 app.db.allDocs({ 1241 include_docs: true 1242 }).then(function(res) { 1243 console.dir(res) 1244 }); 1245 }, 1246 pd: function() { 1247 app.pdb.allDocs({ 1248 include_docs: true 1249 }).then(function(res) { 1250 console.dir(res) 1251 }); 1252 }, 1253 dr: function(id) { 1254 app.pdb.get(id).then(function(doc) { 1255 return app.pdb.remove(doc); 1256 }).then(function(result) { 1257 console.log("Deleted " + id); 1258 }).catch(function(err) { 1259 console.log(err); 1260 }); 1261 } 1262}
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.