1<!DOCTYPE html> <html lang="en"> <head><meta name="description" content=""> <meta charset="utf-8"> <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="msvalidate.01" content="52D8CD5F9EA2B1031F2D2472023A5D34"> <title>MyPortal | Saved Searches</title> <link rel="preconnect" href="https://www.google.com"> <link rel="preconnect" href="https://www.gstatic.com" crossorigin> <link rel="dns-prefetch" href="https://cdn1.brivityidx.com">
1<script> 2 var head = document.getElementsByTagName('head')[0] 3 var insertBefore = head.insertBefore; 4 head.insertBefore = function (newElement, referenceElement) { 5 // intercept style elements for IEs 6 if (newElement.tagName.toLowerCase() === 'style' 7 && newElement.styleSheet 8 && newElement.styleSheet.cssText 9 && newElement.styleSheet.cssText.replace('\r\n', '').indexOf('.gm-style') === 0) { 10 return; 11 } 12 // intercept style elements for other browsers 13 if (newElement.tagName.toLowerCase() === 'style' 14 && newElement.innerHTML 15 && newElement.innerHTML.replace('\r\n', '').indexOf('.gm-style') === 0) { 16 return; 17 } 18 insertBefore.call(head, newElement, referenceElement); 19 }; 20 </script>
20 <link rel="shortcut icon" href="https://cdn1.brivityidx.com/assets/images/uploads/106466/Mike_Mendoza_FAVICON.png" type="image/x-icon"> <link href="https://cdn1.brivityidx.com/assets/css/build-site.min.css?ck=" rel="stylesheet"> <link href="https://cdn1.brivityidx.com/assets/css/build-chatbot-v1.min.css?ck=" rel="stylesheet" media="print" onload="this.media='all'"><noscript><link href="https://cdn1.brivityidx.com/assets/css/build-chatbot-v1.min.css?ck=" rel="stylesheet"></noscript> <link rel="canonical" href="https://www.mendozateam.com/myportal/searches">
20<script> 21 function deferScriptOnLoad(url, sleep = 0) { 22 window.addEventListener('load', function () { 23 deferScript(url, sleep); 24 }); 25 } 26 function deferScript(url, sleep = 0) { 27 if (sleep > 0) { 28 setTimeout(() => { 29 deferScript(url); 30 }, sleep); 31 return; 32 } 33 let s = document.createElement('script'); 34 s.type = 'text/javascript'; 35 s.async = true; 36 s.src = url; 37 let x = document.getElementsByTagName('head')[0]; 38 x.appendChild(s); 39 } 40 41 /* PLACE_COMPONENTS_LOADER_START */ 42 window.sitebuilderPlaceComponents = (function () { 43 var DEFAULT_URL = 'https://mobile-component-services-library-dev.brivity.com/web-components.min.js?ck=1'; 44 var BUNDLE_URLS = { default: DEFAULT_URL }; 45 var loadPromises = {}; 46 var LOAD_TIMEOUT_MS = 10000; 47 48 function urlForTag(tagName) { 49 return BUNDLE_URLS[tagName] || BUNDLE_URLS.default; 50 } 51 52 function ensureLoaded(tagName) { 53 var url = urlForTag(tagName); 54 if (loadPromises[url]) { 55 return loadPromises[url]; 56 } 57 loadPromises[url] = new Promise(function (resolve, reject) { 58 var settled = false; 59 var timer = setTimeout(function () { 60 if (settled) return; 61 settled = true; 62 reject(new Error('web-components load timeout')); 63 }, LOAD_TIMEOUT_MS); 64 var s = document.createElement('script'); 65 s.type = 'text/javascript'; 66 s.async = true; 67 s.src = url; 68 s.onerror = function () { 69 if (settled) return; 70 settled = true; 71 clearTimeout(timer); 72 reject(new Error('web-components script onerror')); 73 }; 74 document.getElementsByTagName('head')[0].appendChild(s); 75 if (window.customElements && customElements.whenDefined) { 76 customElements.whenDefined(tagName).then(function () { 77 if (settled) return; 78 settled = true; 79 clearTimeout(timer); 80 resolve(); 81 }); 82 } 83 }); 84 return loadPromises[url]; 85 } 86 87 var EAGER_SELECTOR = 'place-propertycard, place-searchpagefilter, place-bedbathfiltermodal, ' + 88 'place-listingstatusmodal, place-propertytypemodal, place-savesearchmodal, ' + 89 'place-basicmodal, place-details, place-agentbio, place-agentmessaging, ' + 90 'place-contactyouragent, place-menu, place-collectionpopup, ' + 91 'place-copycollectionmodal, place-removecollectionpopup, place-vs-accumulate'; 92 93 function warmIfEagerTagsPresent() { 94 if (document.querySelector(EAGER_SELECTOR)) { 95 ensureLoaded('place-propertycard').catch(function () {}); 96 } 97 } 98 if (document.readyState === 'loading') { 99 document.addEventListener('DOMContentLoaded', warmIfEagerTagsPresent); 100 } else { 101 warmIfEagerTagsPresent(); 102 } 103 104 var INTERACTION_SELECTOR = 'place-getyourhomecta, place-generictoast, ' + EAGER_SELECTOR + 105 ', [data-needs-place-components]'; 106 function onInteract(e) { 107 var t = e.target; 108 if (t && t.closest && t.closest(INTERACTION_SELECTOR)) { 109 ensureLoaded('place-generictoast').catch(function () {}); 110 } 111 } 112 document.addEventListener('pointerdown', onInteract, true); 113 document.addEventListener('focusin', onInteract, true); 114 115 function idleWarm() { 116 ensureLoaded('place-generictoast').catch(function () {}); 117 } 118 if ('requestIdleCallback' in window) { 119 requestIdleCallback(idleWarm, { timeout: 5000 }); 120 } else { 121 setTimeout(idleWarm, 3000); 122 } 123 124 return { ensureLoaded: ensureLoaded }; 125 })(); 126 /* PLACE_COMPONENTS_LOADER_END */ 127 128 const googleApiKey = 'AIzaSyAjpuNg6WGCMV5rzoJcIP2QmMTVto6hYmc' 129 130 /* Lazy loader for Google Maps API + turf.js. 131 * The TURF_INLINE / MAPS_API_INLINE placeholders below are emitted by 132 * Sitemodel.php only on pages whose blocks actually consume Maps/turf. 133 * On other pages those tags are stripped, and consumers call 134 * sitebuilderMapsApi.ensureLoaded() to inject them on demand. 135 * 136 * Safari fix vs. the prior reverted attempt (commit 0cef3135e): uses 137 * Google's official &callback= parameter, not setTimeout, to detect 138 * Maps readiness. 139 */ 140 window.sitebuilderMapsApi = (function () { 141 var TURF_URL = 'https://cdn.jsdelivr.net/npm/@turf/[email protected]/turf.min.js';
142 var MAPS_URL = 'https://maps.googleapis.com/maps/api/js?libraries=geocoding,places,marker,drawing&key=' + 143 googleApiKey + '&map_ids=85c127b7bf0255d9&callback=__sitebuilderMapsReady'; 144 var LOAD_TIMEOUT_MS = 15000; 145 var loadPromise = null; 146 147 function injectScript(url) { 148 var s = document.createElement('script'); 149 s.type = 'text/javascript'; 150 s.async = true; 151 s.src = url; 152 document.getElementsByTagName('head')[0].appendChild(s); 153 return s; 154 } 155 156 function loadTurf() { 157 return new Promise(function (resolve, reject) { 158 if (window.turf) { resolve(); return; } 159 var s = injectScript(TURF_URL); 160 s.onload = function () { resolve(); }; 161 s.onerror = function () { reject(new Error('turf load failed')); }; 162 }); 163 } 164 165 function loadMaps() { 166 return new Promise(function (resolve, reject) { 167 if (window.google && window.google.maps) { resolve(); return; } 168 window.__sitebuilderMapsReady = function () { resolve(); }; 169 var s = injectScript(MAPS_URL); 170 s.onerror = function () { reject(new Error('maps load failed')); }; 171 }); 172 } 173 174 function ensureLoaded() { 175 if (loadPromise) return loadPromise; 176 if (window.google && window.google.maps && window.turf) { 177 loadPromise = Promise.resolve(); 178 return loadPromise; 179 } 180 loadPromise = new Promise(function (resolve, reject) { 181 var settled = false; 182 var timer = setTimeout(function () { 183 if (settled) return; 184 settled = true; 185 reject(new Error('maps/turf load timeout')); 186 }, LOAD_TIMEOUT_MS); 187 Promise.all([loadTurf(), loadMaps()]).then(function () { 188 if (settled) return; 189 settled = true; 190 clearTimeout(timer); 191 resolve(); 192 }, function (err) { 193 if (settled) return; 194 settled = true; 195 clearTimeout(timer); 196 reject(err); 197 }); 198 }); 199 return loadPromise; 200 } 201 202 return { ensureLoaded: ensureLoaded }; 203 })(); 204 </script>
204 <link href="https://cdn1.brivityidx.com/assets/css/style-headers.min.css" rel="stylesheet"><link href="https://cdn1.brivityidx.com/assets/css/style-premium.min.css" rel="stylesheet"><link href="https://cdn1.brivityidx.com/assets/css/style-footers.css" rel="stylesheet"><link href="https://cdn1.brivityidx.com/idx-sites/2/2/3/22327/site_custom.css?v=1790848380" rel="stylesheet">
204<script type="text/javascript" src="https://cdn1.brivityidx.com/idx-sites/2/2/3/22327/global_js_variables.js?v=1790848380"></script>
204 <div class="modal fade magic-modal" id="getmarketingplan" tabindex="-1" role="dialog" aria-labelledby="getmarketingplan" style="display: none;" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-body"> <button type="button" class="close" data-dismiss="modal" aria-label="Close" data-selector="a.btn, button.btn, button" style="outline: none; cursor: inherit;"><span aria-hidden="true">Ã</span></button> <h4 class="prmry-color" data-selector="h1, h2, h3, h4, h5, h6" style="outline: none; cursor: inherit;">Request property marketing plan</h4> <p data-selector="p" style="outline: none; cursor: inherit;">You're one step away from getting a free marketing plan that shows how we'll sell your home for the most amount of money in the least amount of time - hassle free.</p> <form class="form-contact" id="form-contact6"> <input type="hidden" name="lead_type" value="seller"><input type="hidden" name="tags" value="Marketing_Plan_Requested"> <div class="row"> <div class="col-sm-6"> <div class="form-group"> <input name="contact6_fname" id="contact6_fname" placeholder="First Name" class="form-control" required="" type="text"> </div> </div> <div class="col-sm-6"> <div class="form-group"> <input name="contact6_lname" id="contact6_lname" placeholder="Last Name" class="form-control" required="" type="text"> </div> </div> <div class="col-sm-6"> <div class="form-group"> <input name="contact6_email" id="contact6_email" placeholder="Email Address" class="form-control" required="" type="email"> </div> </div> <div class="col-sm-6"> <div class="form-group"> <input name="contact6_phone" id="contact6_phone" placeholder="Phone Number" class="form-control" required="" type="tel"> </div> </div> <div class="col-sm-6"> <div class="form-group"> <input name="contact6_address" id="contact6_address" placeholder="Address" class="form-control" required="" type="text"> </div> </div> <div class="col-sm-6"> <div class="form-group"> <input name="contact6_city" id="contact6_city" placeholder="City" class="form-control" required="" type="text"> </div> </div> <div class="col-sm-6"> <div class="form-group"> <input name="contact6_state" id="contact6_state" placeholder="State" class="form-control" required="" type="text"> </div> </div> <div class="col-sm-6"> <div class="form-group"> <input name="contact6_zip" id="contact6_zip" placeholder="ZIP" class="form-control" required="" type="text"> </div> </div> <div class="col-sm-12"> <div class="form-group"> <select name="contact6_whenareyouselling" id="contact6_whenareyouselling" class="form-control" placeholder="When are you planning to sell?"> <option value="" disabled="" selected="">When are you planning to sell?</option> <option value="1">Now</option> <option value="2">0-6 months</option> <option value="3">6+ months</option> </select> </div> </div> </div> <button class="btn btn-primary" type="submit" id="cf-submit" name="submit" data-selector="a.btn, button.btn, button" style="outline: none; cursor: inherit;">Send</button> </form> </div> </div> </div> </div>
204<script> 205var propDetailsPixelOnReady = function(){ 206 let propDetFpst = new FbRealEstatePixelTracker({"eventType": "ViewContent", "content_ids": [""]}); 207 propDetFpst.fireEvent(); 208}; 209if (document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll)) { 210 propDetailsPixelOnReady(); 211} else { 212 document.addEventListener("DOMContentLoaded", propDetailsPixelOnReady); 213} 214 215</script>
215
215<script>
vendor: 327 bytes, lines 215-219
215(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 216new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 217j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 218'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 219})(window,document,'script','dataLayer','
219GTM-PC5VGPLN
vendor: 3 bytes, line 219
219');
219</script>
219 <meta property="og:url" content="https://www.mendozateam.com/myportal/searches"> <meta property="og:image" content="http://images.brivityidx.com/assets/images/uploads/106466/Mike_Mendoza_THUMBNAIL.png"> <meta property="og:image:secure_url" content="https://images.brivityidx.com/assets/images/uploads/106466/Mike_Mendoza_THUMBNAIL.png"> <meta property="og:description" content=""> <meta property="og:title" content="MyPortal | Saved Searches"> </head> <body>
vendor: 68 bytes, line 219
219 <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
219GTM-PC5VGPLN
vendor: 83 bytes, line 219
219" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
219<script> 220 window.fbAsyncInit = function() { 221 FB.init({ 222 appId : '1', 223 cookie : true, 224 xfbml : true, 225 version : 'v17.0' 226 }); 227 FB.AppEvents.logPageView(); 228 }; 229 230 setTimeout(() => {(function(d, s, id){ 231 var js, fjs = d.getElementsByTagName(s)[0]; 232 if (d.getElementById(id)) {return;} 233 js = d.createElement(s); js.id = id; 234 js.defer = true; 235 js.xfbml = false; 236 js.src = "//connect.facebook.net/en_US/sdk.js"; 237 fjs.parentNode.insertBefore(js, fjs); 238 }(document, 'script', 'facebook-jssdk'))}, 5000); 239 </script>
239<meta property="fb:app_id" content="1"><meta name="apple-signin-flag" content="1"><meta name="main_sitebuilder_domain" content="https://sitebuilder.brivity.com"> <div id="site-registration-bar" class="collapse"> <input type="hidden" id="huser_id" value=""> <div class="row" style="width: 100%; margin: 0;"> <div class="col-md-12" style="display: none;" id="logged-in"> <div class="topBar flex aiCenter jcBetween"> <div class="topBarLeft flex aiCenter"> <span><topbar_show_agent_name/></span> </div> <div class="topBarRight flex aiCenter"> <a class="topLink flex aiCenter thin favoritesTop" href="/myportal/collections"> <svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#clip0_16761_179132)"> <path d="M14.2659 3.57333C13.9254 3.23267 13.5211 2.96243 13.0761 2.77806C12.6312 2.59368 12.1542 2.49878 11.6726 2.49878C11.1909 2.49878 10.714 2.59368 10.269 2.77806C9.82401 2.96243 9.41973 3.23267 9.07922 3.57333L8.37256 4.28L7.66589 3.57333C6.97809 2.88554 6.04524 2.49914 5.07256 2.49914C4.09987 2.49914 3.16702 2.88554 2.47922 3.57333C1.79143 4.26113 1.40503 5.19398 1.40503 6.16667C1.40503 7.13936 1.79143 8.07221 2.47922 8.76L3.18589 9.46667L8.37256 14.6533L13.5592 9.46667L14.2659 8.76C14.6066 8.4195 14.8768 8.01521 15.0612 7.57024C15.2455 7.12526 15.3404 6.64832 15.3404 6.16667C15.3404 5.68501 15.2455 5.20807 15.0612 4.7631C14.8768 4.31812 14.6066 3.91384 14.2659 3.57333V3.57333Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </g> <defs> <clipPath id="clip0_16761_179132"> <rect width="16" height="16" fill="white" transform="translate(0.372559 0.5)"/> </clipPath> </defs> </svg> <span class="ml6 topLabel">Collections </span> </a> <a class="topLink flex aiCenter thin saveSearchTop" href="/myportal/searches"> <svg width="16" height="16" viewBox="0 4 20 17" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M19 21L12 16L5 21V5C5 4.46957 5.21071 3.96086 5.58579 3.58579C5.96086 3.21071 6.46957 3 7 3H17C17.5304 3 18.0391 3.21071 18.4142 3.58579C18.7893 3.96086 19 4.46957 19 5V21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> </svg> <span class="ml6 topLabel">Saved Searches </span> </a> <a class="topLink flex aiCenter thin market-report-top" style="display:none" href="/myportal/reports"> <svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7.70589 13.1667C10.6514 13.1667 13.0392 10.7789 13.0392 7.83333C13.0392 4.88781 10.6514 2.5 7.70589 2.5C4.76037 2.5 2.37256 4.88781 2.37256 7.83333C2.37256 10.7789 4.76037 13.1667 7.70589 13.1667Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M14.3725 14.5L11.4725 11.6" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> <span class="ml6 topLabel">My Reports </span> </a> <a class="aiCenter flex topBarProfile thin" href="/myportal/profile"> <span class="profileName"></span> </a> <a style="padding-right: 0px" class="aiCenter flex thin" id="topBarLogout" href="javascript:void()"> <svg width="23" height="23" viewBox="0 0 23 23" fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#clip0_16761_179186)"> <path d="M16.4003 16.214C19.0038 13.6106 19.0038 9.38945 16.4003 6.78595C13.7968 4.18246 9.57572 4.18246 6.97222 6.78595C4.36873 9.38945 4.36873 13.6105 6.97222 16.214C9.57572 18.8175 13.7968 18.8175 16.4003 16.214Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M9.80066 9.61438L13.5719 13.3856" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M9.80066 13.3856L13.5719 9.61438" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </g> <defs> <clipPath id="clip0_16761_179186"> <rect width="16" height="16" fill="white" transform="translate(0.372559 11.5) rotate(-45)"/> </clipPath> </defs> </svg> <span class="ml6">Log Out</span> </a> </div> </div> </div> <div id="not-logged-in"> <topbar_agent_info_not_logged_in/> <ul class="list-unstyled list-inline no-margin"> <li class="topBarSignin"><a href="#" onclick="showGoogleOneTap(true);"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-plus-circle mr10"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="16"></line>
239<line x1="8" y1="12" x2="16" y2="12"></line></svg> Sign In</a></li> </ul> </div> </div> </div> <input type="hidden" id="huser_email" value=""> <input type="hidden" id="huser_first_name" value=""> <input type="hidden" id="huser_last_name" value=""> <input type="hidden" id="huser_phone" value=""> <input type="hidden" id="huser_uuid" value=""> <div id="page" class="page"><header id="premium-navigation" style="outline: currentcolor none medium; cursor: inherit;" data-selector="#premium-navigation"> <div class="main-nav"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse" style="outline: currentcolor none medium; cursor: inherit;" data-selector="a.btn, button.btn, button"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/" style="outline: currentcolor none medium; cursor: inherit;"> <img class="img-responsive site_custom_logo_dynamic" src="https://cdn1.brivityidx.com/assets/images/agent-photos/1/3/9/139172497/22327_b1239780d499e778.png" alt="" style="outline: currentcolor none medium; cursor: inherit;" data-selector="img"></a> </div> <div class="collapse navbar-collapse render-menu"><ul class="nav navbar-nav navbar-right"><li class="nav-item"><a class="sec-nav-link-color" href="/search">Search Listings</a></li><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Buying<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/buying">Buying a Home</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/financing">Financing</a></li></ul><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Selling<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/selling">Selling Your Home</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/home_value">Home Value</a></li></ul><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Top Areas<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=85044%7C85048&multi_cat=Zip%7CZip&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=createdAt-&q_offset=0">Ahwatukee Foothills</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Chandler,%20AZ&multi_cat=CityState&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=createdAt-&q_offset=0">Chandler</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Phoenix,%20AZ&multi_cat=CityState&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=createdAt-&q_offset=0">Phoenix</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Scottsdale,%20AZ&multi_cat=CityState&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=createdAt-&q_offset=0">Scottsdale</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Paradise%20Valley,%20AZ&multi_cat=CityState&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&
239mlsId=21&q_sort=createdAt-&q_offset=0">Paradise Valley</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Tempe,%20AZ&multi_cat=CityState&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=createdAt-&q_offset=0">Tempe</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Gilbert,%20AZ&multi_cat=CityState&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=createdAt-&q_offset=0">Gilbert</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=85018%7C85251&multi_cat=Zip%7CZip&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=price-&q_offset=0">Arcadia</a></li></ul><li class="nav-item"><a class="sec-nav-link-color" href="/realestateagent/search">Who We Are</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/reviews">Reviews</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/connect">Connect</a></li></ul></div> </div> </div> </header> <div id="slide-out-nav" class=""> <div class="close-nav"> <svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-x-circle"> <circle cx="12" cy="12" r="10"></circle> <line x1="15" y1="9" x2="9" y2="15"></line> <line x1="9" y1="9" x2="15" y2="15"></line> </svg> </div> <div class="render-menu"><ul class="nav navbar-nav navbar-right"><li class="nav-item"><a class="sec-nav-link-color" href="/search">Search Listings</a></li><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Buying<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/buying">Buying a Home</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/financing">Financing</a></li></ul><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Selling<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/selling">Selling Your Home</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/home_value">Home Value</a></li></ul><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Top Areas<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=85044%7C85048&multi_cat=Zip%7CZip&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=createdAt-&q_offset=0">Ahwatukee Foothills</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Chandler,%20AZ&multi_cat=CityState&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=createdAt-&q_offset=0">Chandler</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Phoenix,%20AZ&multi_cat=CityState&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=createdAt-&q_offset=0">Phoenix</a></li><li class="sec-nav-drop-color">
239<a class="sec-nav-drop-link-color" href="/search?multi_search=Scottsdale,%20AZ&multi_cat=CityState&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=createdAt-&q_offset=0">Scottsdale</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Paradise%20Valley,%20AZ&multi_cat=CityState&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=createdAt-&q_offset=0">Paradise Valley</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Tempe,%20AZ&multi_cat=CityState&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=createdAt-&q_offset=0">Tempe</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Gilbert,%20AZ&multi_cat=CityState&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=createdAt-&q_offset=0">Gilbert</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=85018%7C85251&multi_cat=Zip%7CZip&propertyType=Residential|Commercial+Sale|Vacant+Land|Condo/Townhome|Multi-Family|Manufactured+Home|Residential+Lease&status=1&mlsId=21&q_sort=price-&q_offset=0">Arcadia</a></li></ul><li class="nav-item"><a class="sec-nav-link-color" href="/realestateagent/search">Who We Are</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/reviews">Reviews</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/connect">Connect</a></li></ul></div> </div> <div id="slide-out"> <div class="container-fluid"> <div class="row"> <div class="col-md-12"> <div class="header-flex"> <a class="navbar-brand" href="/" style="outline: none; cursor: inherit;"> <img class="img-responsive site_custom_logo" alt="Logo" src="https://cdn1.brivityidx.com/assets/images/agent-photos/1/3/9/139172497/22327_b1239780d499e778.png" data-selector="img" style="outline: none; cursor: inherit;"></a> <div class="menu-toggle"> <svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"> <line x1="3" y1="12" x2="21" y2="12"></line> <line x1="3" y1="6" x2="21" y2="6"></line> <line x1="3" y1="18" x2="21" y2="18"></line> </svg> </div> </div> </div> </div> </div> </div> <style> 240 .css-1dbjc4n { 241 z-index: unset; 242 } 243 244 .center-modal { 245 display:flex; 246 justify-content: center; 247 align-items:center; 248 position:fixed; 249 background-color:rgba(0,0,0,0.4); 250 left:0; 251 top:0; 252 right:0; 253 bottom:0; 254 z-index: 100; 255 } 256 257 #saved-searches{ 258 gap: 24px 259 } 260 261 .my-feed-parent{ 262 width: 90vw; 263 margin-top: 20px 264 } 265 .page-width-parent{ 266 max-width: 1280px; 267 margin: 0 auto; 268 } 269 @media only screen and (min-width: 1280px) { 270 .collection-page { 271 padding:48px 48px 48px 120px; 272 } 273 274 .my-feed-parent{ 275 max-width: 100%; 276 overflow: hidden; 277 } 278 279 .saved-search-cards{ 280 width:calc(50% - 12px); 281 } 282 } 283 284 @media only screen and (min-width:768px) and (max-width:1279px) { 285 .collection-page { 286 padding:60px 16px 16px 16px; 287 } 288 289 .saved-search-cards{ 290 width:calc(50% - 12px); 291 } 292 } 293 294 @media only screen and (max-width:767px) { 295 .collection-page { 296 padding:60px 16px 16px 16px; 297 } 298 299 .saved-search-cards{ 300 width:100%; 301 } 302 } 303 304 </style>
304<script> 305 window.addEventListener("load", () => { 306 const key = localStorage.getItem('authorization'); 307 308 if( !key) { 309 $("#sign-up-modal").modal('show'); 310 311 $("#sign-up-modal").on("hidden.bs.modal", function () { 312 location.reload(); 313 }); 314 } 315 else{ 316 317 let myPortalPage = document.getElementById('myportal-page'); 318 myPortalPage.style.display = "block"; 319 320 window.location.hash = "" 321 322 class logger extends Collections.BaseLogger { 323 log(e) { 324 console.log(e); 325 } 326 } 327 328 class Pubsub { 329 static events = {}; 330 constructor() { 331 //this.events = {}; 332 } 333 334 static subscription (eventName, func) { 335 return { 336 subscribe: () => { 337 if (this.events[eventName]) { 338 this.events[eventName].push(func); 339 } else { 340 this.events[eventName] = [func]; 341 } 342 }, 343 344 unsubscribe: () => { 345 if(this.events[eventName]){ 346 this.events[eventName] = this.events[eventName].filter((subscriber) => subscriber !== func); 347 } 348 } 349 } 350 } 351 352 353 static publish(eventName, ...args) { 354 const funcs = this.events[eventName]; 355 if (Array.isArray(funcs)) { 356 funcs.forEach((func) => { 357 func.apply(null, args); 358 }); 359 } 360 } 361 } 362 363 class SubHeader { 364 constructor() { 365 this.element = document.querySelector('place-pagesubheader'); 366 367 this.element.addEventListener('button_on_press', (e) => { 368 window.open('../../search.php', '_blank'); 369 }) 370 371 this.element.addEventListener('top_header_on_press', (e) => { 372 Pubsub.publish('top_header_back_pressed', e) 373 }) 374 375 this.element.addEventListener('on_menu_item_pressed', (e) => { 376 Pubsub.publish('top_header_menu_item_pressed', e.detail) 377 }) 378 } 379 380 setTitle(title) { 381 this.element.setAttribute('title', title) 382 } 383 384 setTopHeaderTitle(title){ 385 this.element.setAttribute('top_header_title', title) 386 } 387 388 showTopHeader(){ 389 this.element.setAttribute('show_top_header', true) 390 } 391 392 hideTopHeader(){ 393 this.element.setAttribute('show_top_header', false) 394 } 395 396 showMenuButton() { 397 this.element.setAttribute('show_menu_button', true) 398 } 399 400 hideMenuButton() { 401 this.element.setAttribute('show_menu_button', false) 402 } 403 404 showPrimaryButton() { 405 this.element.setAttribute('show_button', true) 406 } 407 408 hidePrimaryButton() { 409 this.element.setAttribute('show_button', false) 410 } 411 412 hideMenu() { 413 this.element.setAttribute('show_menu', false) 414 } 415 } 416 417 class SaveSearchBlock { 418 constructor() { 419 this.element = document.getElementById('save-search-block'); 420 421 this.element.addEventListener('on_main_press', (e) => { 422 window.open('../../search.php', '_blank'); 423 }) 424 } 425 426 show(collectionUUID, propertyCollectionUUID) { 427 this.element.setAttribute('style', 'display:flex') 428 } 429 430 hide() { 431 this.element.setAttribute('style', 'display:none'); 432 } 433 } 434 435 class BrivityHomeApp { 436 constructor(blueroofMiddlewareApi) { 437 this.element = document.querySelector('place-gethomeapp'); 438 this.blueroofMiddlewareApi = blueroofMiddlewareApi; 439 440 this.element.addEventListener('on_button_pressed', (e) => { 441 this.blueroofMiddlewareApi.getBrivityHomeAppInvite(e.detail).then((data) => { 442 toast.show('Invite has been sent!') 443 }).catch((error) => { 444 toast.show('Error sending invite') 445 }) 446 }) 447 } 448 hide(){ 449 this.element.setAttribute('style', 'display:none') 450 } 451 } 452 453 class SavedSearchCard { 454 constructor(savedSearch) { 455 456 457 this.element = document.createElement('place-savedsearchcard'); 458 459 this.savedSearch = savedSearch; 460 461 this.element.addEventListener(`on_menu_open`, (e) => { 462 this.element.setAttribute("show_menu", e.detail); 463 }); 464 465 this.element.addEventListener('on_search_pressed', (e) => { 466 window.open(`../../${this.savedSearch.searchUrl}`, '_blank'); 467 }) 468 469 this.element.addEventListener('on_updates_pressed', (e) => { 470 window.location.hash = savedSearch.alertId; 471 Pubsub.publish('save_search_block_updates_pressed', savedSearch); 472 }) 473 474 this.element.addEventListener('on_icon_pressed', (e) => { 475 Pubsub.publish('saved_search_block_icon_pressed', {icon:e.detail, savedSearch}); 476 }) 477 478 this.element.addEventListener('on_menu_item_pressed', (e) => { 479 if(e.detail == 'Delete Saved Search'){ 480 481 Pubsub.publish('delete_saved_search_pressed', this?.savedSearch?.alertId); 482 } 483 else if(e.detail == 'Share Saved Search'){ 484 Pubsub.publish('share_saved_search_pressed', this?.savedSearch); 485 } 486 else if(e.detail == 'Manage Alerts'){ 487 Pubsub.publish('manage_alerts_pressed', this?.savedSearch); 488 } 489 490 491 }) 492 493 let data = { 494 city: savedSearch?.cityStates?.length > 0 ? savedSearch?.cityStates[0]?.city : "", 495 state: savedSearch?.cityStates?.length > 0 ? savedSearch?.cityStates[0]?.state : "", 496 bathrooms: savedSearch?.bathsMin || 0, 497 bathrooms_max: savedSearch?.bathsMax || 0, 498 bedrooms: savedSearch?.bedsMin || 0, 499 bedrooms_max: savedSearch?.bedsMax || 0, 500 max_price: savedSearch?.priceMax || 0, 501 min_price: savedSearch?.priceMin || 0, 502 search_name: savedSearch?.searchName, 503 statistics: { 504 total : savedSearch?.statistics?.total || 0, 505 new : savedSearch?.statistics?.new || 0, 506 openHouse : savedSearch?.statistics?.openHouse || 0, 507 sold: savedSearch?.statistics?.statusChange || 0, 508 priceChange:savedSearch?.statistics?.priceChange || 0 509 } 510 } 511 512 this.element.setAttribute('id', savedSearch?.alertId); 513 this.element.setAttribute('saved_search', JSON.stringify(data)); 514 515 516 } 517 518 519 520 show = () => { 521 this.collectionSection.style.display = 'flex' 522 } 523 524 hide = () => { 525 this.collectionSection.style.display = 'none' 526 } 527 } 528 529 class PropertyCard { 530 constructor(property){ 531 this.element = document.createElement('place-propertycard'); 532 533 this.element.addEventListener('on_press_carousel', (e) => { 534 window.open(`/homes-for-sale/${property.state}/${slugify(property.city)}/${slugify(property.postalCode)}/${slugify(property.streetAddress)}/bid-${property.blossorId}`,`_blank`); 535 }); 536 537 this.element.addEventListener('on_menu_item_pressed', (e) => { 538 if(e.detail == 'Share Property'){ 539 let url = this.getPropertyUrl(property); 540 541 property.searchUrl = url; 542 Pubsub.publish('share_property', {property}); 543 } 544 else if(e.detail == 'Add to Collection'){ 545 546 547 548 Pubsub.publish('add_property_to_collection', {property}); 549 550 } 551 552 }) 553 554 this.element.addEventListener('on_favorite_press', (e) => { 555 556 let isAddingFavorite = e.detail 557 558 if(isAddingFavorite){ 559 560 561 Pubsub.publish('add_property_to_collection', {property}); 562 } 563 else{ 564 Pubsub.publish('remove_property_from_collections', {property}); 565 } 566 }); 567 568 this.element.setAttribute('id', property.blossorId); 569 this.element.setAttribute("display_menu", "true"); 570 this.element.setAttribute("show_menu", "false"); 571 this.element.setAttribute("items", '[{"icon":"share-2","text":"Share Property"},{"icon":"layers","text":"Add to Collection"}]'); 572 this.element.setAttribute("property_created_at", property?.listDate); 573 this.element.setAttribute("active_status", "true"); 574 if(property?.priceLastReduced?.length > 0){ 575 const priceLastReduced = new Date(property?.priceLastReduced)?.getTime(); 576 if(priceLastReduced > sevenDaysAgo) this.element.setAttribute('mls_price_history', property?.history[property.history.length-1]?.price); 577 } 578 if(property.openhouses.length > 0){ 579 this.element.setAttribute('open_house','true') 580 this.element.setAttribute('open_house_date', property.openhouses[0].startDate) 581 this.element.setAttribute('open_house_end_time',property.openhouses[0].endDate) 582 }else{ 583 this.element.setAttribute('open_house','false') 584 } 585 this.element.setAttribute('appearance','small') 586 this.element.setAttribute('layout_width', '300') 587 this.element.setAttribute('display_tag', 'true') 588 this.element.setAttribute('display_favorite', 'true') 589 this.element.setAttribute('image_height', '184') 590 this.element.setAttribute('mls',`{ 591 "status":"${property.standardStatus}", 592 "favorite":${property?.favorite}, 593 "image":[{"uri":"${property?.photos[0].url}"}], 594 "price":"${property?.price}", 595 "address":"${property?.streetAddress}", 596 "state":"${property?.state}", 597 "city":"${property?.city}", 598 "postalCode":"${property?.postalCode}", 599 "beds":"${property?.bedrooms}", 600 "baths":"${property?.fullBaths}", 601 "sqft":"${property?.squareFeet}" 602 }`) 603 604 } 605 getPropertyUrl = (property) => { 606 let state = property.state; 607 let city = this.slugify(property.city); 608 let zip = property.postal_code 609 let address = this.slugify(property.streetAddress); 610 let blossorId = property.blossorId; 611 return `homes-for-sale/${state}/${city}/${zip}/${address}/bid-${blossorId}`; 612 } 613 614 slugify(text) { 615 // replace non letter or digits by - 616 text = text.replace(/[^\pL\d]+~u/g, '_'); 617 // transliterate 618 text = text.normalize('NFKD').replace(/[\u0300-\u036F]/g,'') 619 // remove unwanted characters 620 text = text.replace(/[^_\w]+/g, '_'); 621 // trim 622 text = text.trim(); 623 // remove duplicate - 624 text = text.replace(/_+/g, '-'); 625 // lowercase 626 text = text.toLowerCase(); 627 if (!text) { 628 return 'n-a'; 629 } 630 return text 631 } 632 } 633 634 let dateNow = new Date(); 635 dateNow.setDate(dateNow.getDate()-7); 636 dateNow.setHours(0); 637 dateNow.setMinutes(0); 638 dateNow.setSeconds(0); 639 dateNow.setMilliseconds(0); 640 const sevenDaysAgo = dateNow.getTime(); 641 642 class UpdatedListingsSection { 643 constructor(collectionsService) { 644 this.collectionsService = collectionsService; 645 this.element = document.getElementById('updated-listings-section'); 646 this.listingElement = document.getElementById('updated-listings'); 647 } 648 649 async show(properties) { 650 if(properties){ 651 this.properties = properties 652 } 653 this.element.style.display = 'flex' 654 await this.addPropertyCards(); 655 } 656 657 hide() { 658 this.element.style.display = 'none' 659 } 660 661 async addPropertyCards(){ 662 663 this.listingElement.innerHTML = ""; 664 665 let updatedPropertiesBlossorIds = this.properties.map(property => property.blossorId); 666 667 668 let propertiesInCollections = await this.collectionsService.checkIfInCollection(updatedPropertiesBlossorIds) 669
670 this.properties.forEach((property) => { 671 let propertyCardWrapper = document.createElement('div'); 672 property.favorite = propertiesInCollections?.data[property?.blossorId] != null || false 673 let propertyCard = new PropertyCard(property); 674 propertyCardWrapper.appendChild(propertyCard.element); 675 this.listingElement.appendChild(propertyCardWrapper); 676 }) 677 678 679 } 680 681 filterProperties(filter) { 682 683 let filteredProperties; 684 685 686 687 688 if(filter == 'open_house'){ 689 filteredProperties = this.properties.filter((property) => { 690 return property.openhouses.length > 0; 691 }) 692 } 693 else if(filter == 'price_change'){ 694 filteredProperties = this.properties.filter((property) => { 695 if(property?.priceLastReduced?.length > 0){ 696 const priceLastReduced = new Date(property?.priceLastReduced)?.getTime(); 697 return priceLastReduced >= sevenDaysAgo; 698 } 699 else { 700 return false; 701 } 702 }) 703 } 704 else if(filter == 'status_change') { 705 filteredProperties = this.properties.filter((property) => { 706 const listDate = new Date(property?.listDate).getTime(); 707 708 if(property?.lastStatusChangeDate?.length > 0 ){ 709 const lastStatusChangeDate = new Date(property?.lastStatusChangeDate)?.getTime(); 710 return lastStatusChangeDate >= sevenDaysAgo; 711 } 712 else { 713 return false; 714 } 715 }) 716 } 717 else if(filter == 'new'){ 718 filteredProperties = this.properties.filter((property) => { 719 const listDate = new Date(property?.listDate).getTime(); 720 return listDate >= sevenDaysAgo; 721 }) 722 } 723 else { 724 filteredProperties = this.properties; 725 } 726 727 this.listingElement.innerHTML = ""; 728 729 if(filteredProperties.length > 0 ){ 730 filteredProperties.forEach((property) => { 731 let propertyCardWrapper = document.createElement('div'); 732 733 let propertyCard = new PropertyCard(property); 734 propertyCardWrapper.appendChild(propertyCard.element); 735 this.listingElement.appendChild(propertyCardWrapper); 736 }) 737 } 738 } 739 } 740 741 class SavedSearchesSection { 742 constructor() { 743 this.element = document.getElementById('saved-searches'); 744 } 745 746 747 addSavedSearchCards(savedSearches){ 748 this.savedSearches = savedSearches; 749 savedSearches.forEach((savedSearch) => { 750 const savedSearchCard = new SavedSearchCard(savedSearch); 751 const savedSearchCardWrapper = document.createElement('div'); 752 savedSearchCardWrapper.setAttribute('class', 'saved-search-cards'); 753 754 savedSearchCardWrapper.append(savedSearchCard.element); 755 this.element.append(savedSearchCardWrapper); 756 }) 757 } 758 759 removeSavedSearchCard(alertId){ 760 761 const savedSearchCard = document.getElementById(alertId).parentElement; 762 if(savedSearchCard){ 763 savedSearchCard.remove(); 764 } 765 766 767 } 768 769 show() { 770 this.element.style.display = 'flex' 771 } 772 773 hide() { 774 this.element.style.display = 'none' 775 } 776 } 777 778 class ShareSavedSearchModal { 779 constructor() { 780 let _this = this; 781 this.savedSearch = {} 782 this.element = document.getElementById('share-saved-search-modal'); 783 784 this.element.addEventListener("on_primary_press", (e) => { 785 786 navigator.clipboard.writeText(this.link) 787 _this.hide(); 788 toast.show('Link Copied!') 789 790 }); 791 792 this.element.addEventListener("on_close_press", (e) => { 793 _this.hide(); 794 }); 795 } 796 797 show = (savedSearch) => { 798 799 if(savedSearch){ 800 this.savedSearch = savedSearch; 801 } 802 this.link = document.location.origin + "/" + this.savedSearch.searchUrl 803 this.element.setAttribute('share_link_text', this.link) 804 this.element.setAttribute('style', 'display:flex') 805 } 806 807 hide = () => { 808 this.element.setAttribute('style', 'display:none'); 809 } 810 } 811 812 class DeleteSavedSearchModal { 813 constructor(blueroofMiddlewareApi) { 814 815 this.blueroofMiddlewareApi = blueroofMiddlewareApi; 816 this.savedSearch = {} 817 this.element = document.getElementById('delete-saved-search-modal'); 818 819 this.element.addEventListener("on_primary_press", (e) => { 820 this.hide(); 821 this.blueroofMiddlewareApi.deleteSavedListing(this.savedSearch).then((response) => { 822 toast.show('Saved search has been deleted'); 823 }) 824 }); 825 826 this.element.addEventListener("on_tertiary_press", (e) => { 827 this.hide(); 828 }); 829 830 this.element.addEventListener("on_close_press", (e) => { 831 this.hide(); 832 }); 833 } 834 835 show = (savedSearch) => { 836 837 if(savedSearch){ 838 this.savedSearch = savedSearch; 839 } 840 this.element.setAttribute('style', 'display:flex') 841 } 842 843 hide = () => { 844 this.element.setAttribute('style', 'display:none'); 845 } 846 } 847 848 class FrequencyModal { 849 constructor() { 850 this.element = document.querySelector('place-frequencymodal'); 851 852 this.element.addEventListener('on_close_press', (e) => { 853 this.hide() 854 }) 855 856 this.element.addEventListener('on_save_press', (e) => { 857 Pubsub.publish('frequency_modal_save_clicked', e.detail) 858 }) 859 } 860 861 show(reportData) { 862 863 let frequency = reportData.frequency; 864 865 //daily, twice_daily, weekly, bi_weekly, monthly 866 867 switch(reportData.frequency){ 868 869 case 'daily': 870 frequency = 'Daily'; 871 break; 872 case 'bi_weekly': 873 frequency = 'Every 2 Weeks'; 874 break; 875 case 'twice_daily': 876 frequency = 'Twice Daily'; 877 break; 878 case 'four_times_daily': 879 frequency = 'Multiple Times Per Day'; 880 break; 881 case 'weekly': 882 frequency = 'Weekly'; 883 break; 884 case 'monthly': 885 frequency = 'Monthly'; 886 break; 887 } 888 889 let description = `Listing alerts keep you up to date on the latest market activity so you can stay one step ahead of the game.\n\nHow often would you like email updates?`; 890 this.element.setAttribute('description', description); 891 this.element.setAttribute('selected_menu_item', frequency); 892 this.element.setAttribute('style', 'display:flex') 893 } 894 895 hide() { 896 this.element.setAttribute('style', 'display:none'); 897 } 898 } 899 900 class PillSelector { 901 constructor() { 902 this.element = document.createElement('div'); 903 this.element.setAttribute('style', 'display:flex;flex-direction:column;width:100%;margin-bottom:24px;') 904 905 906 907 this.savedSearchFilter = document.createElement('place-text') 908 909 this.weeksUpdates = document.createElement('place-text') 910 this.weeksUpdates.setAttribute('style', 'margin-bottom:8px; margin-top: 40px;') 911 912 913 914 this.pillSelector = document.createElement('place-pillselector') 915 916 917 this.pillSelector.addEventListener('on_press', (e) => { 918 Pubsub.publish('pill_selector_item_selected', e.detail); 919 }) 920 921 this.element.append(this.savedSearchFilter) 922 this.element.append(this.weeksUpdates) 923 this.element.append(this.pillSelector) 924 } 925 926 setCurrentSavedSearch(savedSearch){ 927 928 this.savedSearch = savedSearch
929 this.stats = savedSearch.statistics 930 931 const items = [ 932 { 933 "text": `All (${this.stats.total})`, 934 "value": "all" 935 }, 936 { 937 "text": `New (${this.stats.new})`, 938 "value": "new" 939 }, 940 { 941 "text": `Price Change (${this.stats.priceChange})`, 942 "value": "price_change" 943 }, 944 { 945 "text": `Open House (${this.stats.openHouse})`, 946 "value": "open_house" 947 }, 948 { 949 "text": `Status Change (${this.stats.statusChange})`, 950 "value": "status_change" 951 } 952 ] 953 954 this.pillSelector.setAttribute('items', JSON.stringify(items)) 955 this.pillSelector.setAttribute('active_pill', 'all') 956 957 let city = this.savedSearch?.cityStates?.length > 0 && this.savedSearch?.cityStates[0].city || ""; 958 let baths = this.savedSearch?.bathsMin || 0; 959 let beds = this.savedSearch?.bedsMin || 0; 960 let minPrice = this.savedSearch?.priceMin || 0; 961 let maxPrice = this.savedSearch?.priceMax || 0; 962 963 let searchFilter = `${city} ${baths}+ baths ${beds}+ beds` 964 965 if(minPrice > 0 || maxPrice > 0){ 966 searchFilter += ` $${this.formatNumberToSymbol(minPrice)} - $${this.formatNumberToSymbol(maxPrice)}` 967 } 968 969 970 this.savedSearchFilter.innerText = searchFilter 971 972 this.weeksUpdates.innerText = "This Week's Updates"; 973 } 974 975 formatNumberToSymbol = (num) => { 976 if (num > 999 && num < 1000000) { 977 return (num / 1000).toFixed() + "K"; // convert to K for number from > 1000 < 1 million 978 } else if (num >= 1000000) { 979 return (num / 1000000).toFixed() + "M"; // convert to M for number from > 1 million 980 } else if (num < 900) { 981 return num; // if value < 1000, nothing to do 982 } 983 }; 984 985 986 } 987 988 class BlueroofMiddlewareApi { 989 constructor() { 990 this.baseUrl = "https://brivity-home-middleware.production.brivity.com"; 991 this.apiKey = localStorage.getItem('authorization'); 992 } 993 994 getStats = async () => { 995 const response = await fetch(`${this.baseUrl}/listingAlerts/all/forPerson/withStatistics`, { 996 method: 'GET', 997 headers: { 998 'Content-Type': 'application/json', 999 'Authorization': `${this.apiKey}` 1000 } 1001 }); 1002 1003 const data = await response.json(); 1004 return data; 1005 } 1006 1007 getSavedListings = async () => { 1008 const response = await fetch(`${this.baseUrl}/listingalerts/all/forperson/withStatistics`, { 1009 method: 'GET', 1010 headers: { 1011 'Content-Type': 'application/json', 1012 'Authorization': `${this.apiKey}` 1013 } 1014 }); 1015 1016 const data = await response.json(); 1017 return data; 1018 } 1019 1020 getUpdatedListings = async (id) => { 1021 const response = await fetch(`${this.baseUrl}/listingalerts//recentlyUpdatedListings/${id}`, { 1022 method: 'GET', 1023 headers: { 1024 'Content-Type': 'application/json', 1025 'Authorization': `${this.apiKey}` 1026 } 1027 }); 1028 1029 const data = await response.json(); 1030 return data; 1031 } 1032 1033 deleteSavedListing = async (alertId) => { 1034 const response = await fetch(`${this.baseUrl}/listingalerts/${alertId}`, { 1035 method: 'DELETE', 1036 headers: { 1037 'Content-Type': 'application/json', 1038 'Authorization': `${this.apiKey}` 1039 } 1040 }); 1041 1042 if(!response.ok){ 1043 throw new Error(); 1044 } 1045 1046 const data = await response; 1047 if(response.status == 200){ 1048 Pubsub.publish('saved_search_deleted', alertId); 1049 } 1050 return data; 1051 } 1052 1053 updateSavedListings = async (updatedListingData) => { 1054 const response = await fetch(`${this.baseUrl}/listingalerts/${updatedListingData.alertId}`, { 1055 method: 'PUT', 1056 headers: { 1057 'Content-Type': 'application/json', 1058 'Authorization': `${this.apiKey}` 1059 }, 1060 body: JSON.stringify(updatedListingData) 1061 }); 1062 1063 if(!response.ok){ 1064 throw new Error(); 1065 } 1066 1067 const data = await response 1068 return data; 1069 } 1070 1071 getBrivityHomeAppInvite = async (number) => { 1072 const response = await fetch(`${this.baseUrl}/brivityLeads/sendHomeAppInvite`, { 1073 method: 'POST', 1074 headers: { 1075 'Content-Type': 'application/json', 1076 'Authorization': `${this.apiKey}` 1077 }, 1078 body: JSON.stringify({ 1079 "phoneNumber": number 1080 }) 1081 }); 1082 1083 const data = await response.json(); 1084 return data; 1085 } 1086 1087 getMyFeed = async () => { 1088 const response = await fetch(`${this.baseUrl}/listings/voltron`, { 1089 method: 'POST', 1090 headers: { 1091 'Content-Type': 'application/json', 1092 'Authorization': `${this.apiKey}` 1093 }, 1094 body: JSON.stringify([]) 1095 1096 }); 1097 1098 const data = await response.json(); 1099 return data; 1100 } 1101 1102 getLeadBasicInfo = async () => { 1103 const response = await fetch(`${this.baseUrl}/blueroofleads/basicinfo`, { 1104 method: 'GET', 1105 headers: { 1106 'Content-Type': 'application/json', 1107 'Authorization': `${this.apiKey}` 1108 }, 1109 1110 }); 1111 1112 const data = await response.json(); 1113 return data; 1114 } 1115 1116 getAgentProfile = async (brivityUserId) => { 1117 const response = await fetch(`${this.baseUrl}/blueroofagents/profile`, { 1118 method: 'POST', 1119 headers: { 1120 'Content-Type': 'application/json', 1121 'Authorization': `${this.apiKey}` 1122 }, 1123 body: `{"brivityUserId": ${brivityUserId}}` 1124 1125 }); 1126 1127 const data = await response.json(); 1128 return data; 1129 } 1130 } 1131 1132 class ShareSavedPropertyModal { 1133 constructor() { 1134 let _this = this; 1135 this.savedProperty = {} 1136 this.element = document.getElementById('share-saved-property-modal'); 1137 1138 this.element.addEventListener("on_primary_press", (e) => { 1139 1140 navigator.clipboard.writeText(this.link) 1141 _this.hide(); 1142 toast.show('Link Copied!') 1143 1144 }); 1145 1146 this.element.addEventListener("on_close_press", (e) => { 1147 _this.hide(); 1148 }); 1149 } 1150 1151 show = (savedProperty) => { 1152 1153 1154 this.savedProperty = savedProperty; 1155 1156 this.link = document.location.origin + "/" + savedProperty.searchUrl 1157 this.element.setAttribute('share_link_text', this.link) 1158 this.element.setAttribute('style', 'display:flex') 1159 } 1160 1161 hide = () => { 1162 this.element.setAttribute('style', 'display:none'); 1163 } 1164 } 1165 1166 class CollectionModal { 1167 1168 constructor() { 1169 1170 let _this = this; 1171 this.element = document.querySelector('place-collectionpopup'); 1172 this.collectionUUID = 0; 1173 1174 this.element.addEventListener("on_close_press", (e) => { 1175 _this.hide(); 1176 }); 1177 1178 this.element.addEventListener("on_save_press", (e) => { 1179 this.showError(false); 1180 e.detail.collectionUUID = this.collectionUUID 1181 e.detail.type = this.isEditingCollection ? 'edit' : 'save' 1182 Pubsub.publish('on_new_collection_saved', e.detail); 1183 }); 1184 1185 } 1186 1187 setName(name) { 1188 this.element.setAttribute('name_value', name) 1189 } 1190 1191 setDescription(description) { 1192 this.element.setAttribute('description_value', description) 1193 } 1194 1195 showError(error) { 1196 this.element.setAttribute('show_error', error) 1197 } 1198 1199 show(collectionUUID, isEditingCollection) { 1200 this.isEditingCollection = isEditingCollection; 1201 if(collectionUUID){ 1202 this.collectionUUID = collectionUUID; 1203 } 1204 this.element.setAttribute('style', 'display:flex') 1205 } 1206 1207 hide() { 1208 this.element.setAttribute('style', 'display:none'); 1209 1210 this.showError(false) 1211 1212 // terrible hack.. only way i could get it to respond to prop changes 1213 // to clear the input fields after closing the modal 1214 this.setName('none') 1215 this.setDescription('none') 1216 setTimeout(() => { 1217 this.setName('') 1218 this.setDescription('') 1219 }, 100); 1220 } 1221 } 1222 1223 class CopyPropertyToCollectionModal { 1224 constructor(){ 1225 1226 this.element = document.querySelector('place-copycollectionmodal'); 1227 this.property = {} 1228 1229 this.element.addEventListener('close_button', (e) => { 1230 this.hide(); 1231 }); 1232 1233 this.element.addEventListener('cancel_button', (e) => { 1234 this.hide(); 1235 }); 1236 1237 this.element.addEventListener('on_save', (e) => { 1238 Pubsub.publish('copy_property_to_collection_modal_save_pressed', {'collectionUUID':e.detail, 'property':this.property}); 1239 }); 1240 1241 this.element.addEventListener('set_selected_collection', (e) => { 1242 console.log('set_selected_collection', e) 1243 }); 1244 1245 this.element.addEventListener('on_link_press', (e) => { 1246 Pubsub.publish('show_new_collection_modal'); 1247 }); 1248 1249 } 1250 getCollectionData(){ 1251 return JSON.parse(this.element.getAttribute("collections")); 1252 } 1253 1254 setCollectionData(collections){ 1255 this.element.setAttribute('collections', JSON.stringify(collections)) 1256 } 1257 1258 setIsAddingToCollection(isAddingToCollection){ 1259 this.element.setAttribute('is_add_to_collection', isAddingToCollection); 1260 } 1261 1262 show(property) { 1263 1264 if(property){ 1265 this.property = property; 1266 } 1267 1268 1269 1270 let mls = { 1271 status: property?.status || property?.standardStatus || "", 1272 image: this.getPropertyImageUrl(property), 1273 price: property?.price || "0", 1274 address: property?.address || property?.streetAddress || "", 1275 state: property?.state || "", 1276 city: property?.city || "", 1277 postal_code: property?.postal_code || "", 1278 beds: property?.beds || property?.bedrooms || 0, 1279 baths: property?.baths || property?.bathsTotalDecimal || 0, 1280 sqft: property?.sqft || property?.squareFeet || 0, 1281 creator: property?.creator || "", 1282 } 1283 1284 this.element.setAttribute('mls', JSON.stringify(mls)) 1285 this.element.setAttribute('image_url',mls?.image || "") 1286 this.element.setAttribute('style', 'display:flex') 1287 } 1288 1289 getPropertyImageUrl(property){ 1290 // property?.image[0]?.uri || property?.photos[0]?.url || "", 1291 1292 if(property.image && property.image.length > 0){ 1293 return property.image[0].uri 1294 }
1294 else if (property.photos && property.photos.length > 0){ 1295 return property.photos[0].url 1296 } else { 1297 return "" 1298 } 1299 } 1300 1301 hide() { 1302 this.element.setAttribute('style', 'display:none'); 1303 } 1304 } 1305 1306 class MyFeed { 1307 constructor(blueroofMiddlewareApi, collectionsService) { 1308 this.blueroofMiddlewareApi = blueroofMiddlewareApi; 1309 this.collectionsService = collectionsService; 1310 this.element = document.querySelector('place-myfeedblock'); 1311 1312 this.element.addEventListener('on_menu_open', (e) => { 1313 this.element.setAttribute('show_menu', e.detail.e); 1314 this.element.setAttribute('show_menu_index', e.detail.index); 1315 }); 1316 1317 this.element.addEventListener('on_view_all_pressed', (e) => { 1318 window.open('../../search.php', '_blank'); 1319 }); 1320 1321 this.element.addEventListener('on_add_collection', (e) => { 1322 1323 let property = e.detail; 1324 Pubsub.publish('add_property_to_collection', {property}); 1325 1326 }); 1327 1328 this.element.addEventListener('on_share_pressed', (e) => { 1329 1330 let property = e.detail 1331 1332 let url = this.getPropertyUrl(property); 1333 property.searchUrl = url; 1334 1335 Pubsub.publish('share_property', {property}); 1336 }); 1337 1338 this.element.addEventListener('on_favorite_pressed', (e) => { 1339 1340 let property = e.detail.property; 1341 let isAddingFavorite = e.detail.isAddingFavorite; 1342 1343 if(isAddingFavorite){ 1344 1345 1346 Pubsub.publish('add_property_to_collection', {property}); 1347 } 1348 else{ 1349 Pubsub.publish('remove_property_from_collections', {property}); 1350 } 1351 1352 1353 1354 }); 1355 1356 this.element.addEventListener('on_property_pressed', (e) => { 1357 let property = e.detail 1358 1359 let url = this.getPropertyUrl(property); 1360 property.searchUrl = url; 1361 window.open('../../' + url, '_blank'); 1362 }); 1363 1364 1365 this.blueroofMiddlewareApi.getMyFeed().then((data) => { 1366 1367 let myFeedBlossorIds = data.map(property => property.blossorId); 1368 1369 1370 this.collectionsService.checkIfInCollection(myFeedBlossorIds).then((propertiesInCollections) => { 1371 1372 let feed = [] 1373 data.forEach((item) => { 1374 feed.push({ 1375 image: [ 1376 { 1377 title: "", 1378 id: 0, 1379 uri: item?.photos[0].url, 1380 }, 1381 ], 1382 price: item?.price, 1383 favorite: propertiesInCollections?.data[item?.blossorId] != null || false, 1384 address: item?.streetAddress, 1385 city: item?.city, 1386 state: item?.state, 1387 postal_code: item?.postalCode, 1388 beds: item?.bedrooms, 1389 status: item?.standardStatus, 1390 baths: item?.bathsTotalDecimal, 1391 sqft: item?.squareFeet, 1392 creator: "", 1393 mls_price_history: item?.history[item.history.length-1]?.price, 1394 blossorId: item?.blossorId, 1395 open_house : item?.openhouses.length > 0 ? true : false, 1396 open_house_date : item?.openhouses[0]?.startDate, 1397 open_house_end_time : item?.openhouses[0]?.endDate, 1398 property_created_at : item?.listDate, 1399 lastStatusChangeDate : item?.lastStatusChangeDate, 1400 }) 1401 }) 1402 1403 if(feed && feed?.length > 0){ 1404 this.show(); 1405 this.element.setAttribute('mls_data', JSON.stringify(feed)); 1406 } 1407 }); 1408 }); 1409 1410 } 1411 1412 getPropertyUrl = (property) => { 1413 let state = property.state; 1414 let city = this.slugify(property.city); 1415 let zip = property.postal_code 1416 let address = this.slugify(property.address); 1417 let blossorId = property.blossorId; 1418 return `homes-for-sale/${state}/${city}/${zip}/${address}/bid-${blossorId}`; 1419 } 1420 1421 slugify(text) { 1422 // replace non letter or digits by - 1423 text = text.replace(/[^\pL\d]+~u/g, '_'); 1424 // transliterate 1425 text = text.normalize('NFKD').replace(/[\u0300-\u036F]/g,'') 1426 // remove unwanted characters 1427 text = text.replace(/[^_\w]+/g, '_'); 1428 // trim 1429 text = text.trim(); 1430 // remove duplicate - 1431 text = text.replace(/_+/g, '-'); 1432 // lowercase 1433 text = text.toLowerCase(); 1434 if (!text) { 1435 return 'n-a'; 1436 } 1437 return text 1438 } 1439 1440 getMlsData = () => { 1441 return JSON.parse(this.element.getAttribute('mls_data')); 1442 } 1443 1444 setMlsData = (data) => { 1445 this.element.setAttribute('mls_data', JSON.stringify(data)); 1446 } 1447 1448 1449 show() { 1450 this.element.setAttribute('style', 'display:flex') 1451 } 1452 1453 hide() { 1454 this.element.setAttribute('style', 'display:none') 1455 } 1456 } 1457 1458 class Page { 1459 constructor() { 1460 this.selectedSearch = null; 1461 this.lead = {} 1462 this.agent = {} 1463 1464 this.authorizationData = JSON.parse(atob(blueroofMiddlewareApi.apiKey.split('.')[1])); 1465 this.is_blueroof_person = this.authorizationData?.is_blueroof_person; 1466 this.viewingUpdatedListings = false;
1467 1468 } 1469 1470 setSelectedSearch(search){ 1471 this.selectedSearch = search; 1472 } 1473 1474 scrollToTop(){ 1475 document.getElementById('site-registration-bar').scrollIntoView({ behavior: 'smooth', block: 'start'}); 1476 } 1477 } 1478 1479 class messagingEmitter extends Messaging.BaseEmitter { 1480 1481 newMessage(message) { 1482 Pubsub.publish('messaging_emitter_new_message', message); 1483 } 1484 } 1485 1486 const blueroofMiddlewareApi = new BlueroofMiddlewareApi(); 1487 const page = new Page(blueroofMiddlewareApi); 1488 1489 let url = 'https://messaging.brivity.com' 1490 const messaging = new Messaging.Service(url, blueroofMiddlewareApi.apiKey, new messagingEmitter()); 1491 1492 1493 (async () => { 1494 let lead = await blueroofMiddlewareApi.getLeadBasicInfo(); 1495 let agent = await blueroofMiddlewareApi.getAgentProfile(lead.data?.brivity_agent_id); 1496 1497 page.lead = lead.data; 1498 page.agent = agent.data; 1499 1500 const menu = new Menu(page?.is_blueroof_person || false, page?.agent, blueroofMiddlewareApi.baseUrl, blueroofMiddlewareApi.apiKey); 1501 1502 1503 const collectionsService = new Collections.Service(window?.globalSiteVariables?.options?.apis?.collections?.url ?? '',blueroofMiddlewareApi.apiKey, "sitebuilder", new logger()); 1504 collectionsService.getCollections(0, 30).then((e) => { 1505 collections = e.data.Items; 1506 1507 let collectionList = []; 1508 1509 collections.forEach(collection => { 1510 collectionList.push({ 1511 collection_title: collection.collectionName, 1512 id: collection.collectionUUID, 1513 propertiesImages: collection?.propertiesImages?.length > 0 ? collection?.propertiesImages : [], 1514 1515 }) 1516 }); 1517 1518 copyPropertyToCollectionModal.setCollectionData(collectionList); 1519 1520 1521 1522 }); 1523 1524 const saveSearchBlock = new SaveSearchBlock(); 1525 const subHeader = new SubHeader(); 1526 const brivityHomeApp = new BrivityHomeApp(blueroofMiddlewareApi); 1527 const savedSearchSection = new SavedSearchesSection(); 1528 const deleteSavedSearchModal = new DeleteSavedSearchModal(blueroofMiddlewareApi); 1529 const shareSavedSearchModal = new ShareSavedSearchModal(); 1530 const updatedListingsSection = new UpdatedListingsSection(collectionsService); 1531 const pillSelector = new PillSelector(); 1532 const myFeed = new MyFeed(blueroofMiddlewareApi, collectionsService); 1533 const shareSavedPropertyModal = new ShareSavedPropertyModal(); 1534 const copyPropertyToCollectionModal = new CopyPropertyToCollectionModal(); 1535 const collectionModal = new CollectionModal(); 1536 const frequencyModal = new FrequencyModal(); 1537 1538 if(page?.is_blueroof_person) brivityHomeApp.hide(); 1539 1540 blueroofMiddlewareApi.getSavedListings().then((savedSearches) => { 1541 if(savedSearches.length > 0 ){ 1542 savedSearchSection.addSavedSearchCards(savedSearches); 1543 } 1544 else { 1545 saveSearchBlock.show(); 1546 } 1547 }) 1548 1549 document.addEventListener("click", (e) => { 1550 1551 const elements = document.querySelectorAll("[show_menu]"); 1552 elements.forEach((el) => { 1553 el.setAttribute("show_menu", "false"); 1554 }); 1555 1556 document.getElementById("c2dfac72-6233-4e8d-b0d2-f44e4240ebb4")?.setAttribute("show_menu", "false"); 1557 }); 1558 1559 1560 async function showUpdatedListings(savedSearch) { 1561 let updatedListings = await blueroofMiddlewareApi.getUpdatedListings(savedSearch.alertId) 1562 page.setSelectedSearch(savedSearch); 1563 1564 savedSearchSection.hide() 1565 1566 await updatedListingsSection.show(updatedListings); 1567 subHeader.showTopHeader(); 1568 subHeader.setTopHeaderTitle("Saved Searches"); 1569 subHeader.setTitle(savedSearch.searchName); 1570 1571 subHeader.hidePrimaryButton(); 1572 subHeader.showMenuButton(); 1573 1574 let currentSearch = savedSearchSection.savedSearches.find((search) => search.alertId == savedSearch.alertId) 1575 1576 1577 pillSelector.setCurrentSavedSearch(currentSearch);
1578 updatedListingsSection.element.prepend(pillSelector.element) 1579 1580 page.viewingUpdatedListings = true; 1581 page.scrollToTop() 1582 1583 } 1584 1585 Pubsub.subscription('messaging_emitter_new_message', (message) => { 1586 toast.show('New message from ' + message.createdByAlias) 1587 }).subscribe(); 1588 1589 Pubsub.subscription("delete_saved_search_pressed",deleteSavedSearchModal.show).subscribe() 1590 Pubsub.subscription("share_saved_search_pressed", shareSavedSearchModal.show).subscribe() 1591 1592 Pubsub.subscription('manage_alerts_pressed', ( savedSearch) => { 1593 page.selectedSearch = savedSearch; 1594 frequencyModal.show(savedSearch); 1595 }).subscribe(); 1596 1597 Pubsub.subscription('frequency_modal_save_clicked', (reportFrequency) => { 1598 1599 let frequency = ''; 1600 switch(reportFrequency){ 1601 1602 case 'Daily': 1603 frequency = 'daily'; 1604 break; 1605 case 'Twice Daily': 1606 frequency = 'twice_daily'; 1607 break; 1608 case 'Multiple Times Per Day': 1609 frequency = 'four_times_daily'; 1610 break; 1611 case 'Weekly': 1612 frequency = 'weekly'; 1613 break; 1614 case 'Every 2 Weeks': 1615 frequency = 'bi_weekly'; 1616 break; 1617 case 'Monthly': 1618 frequency = 'monthly'; 1619 break; 1620 } 1621 1622 let updateListingAlert = { 1623 alertId: page?.selectedSearch?.alertId, 1624 frequency: frequency, 1625 mlsIds: page?.selectedSearch?.mlsIds, 1626 source: page?.selectedSearch?.source, 1627 activeForEmails: page?.selectedSearch?.activeForEmails, 1628 activeForAppNotifications: page?.selectedSearch?.activeForAppNotifications, 1629 searchName: page?.selectedSearch?.searchName, 1630 neighborhoodCityStates: page?.selectedSearch?.neighborhoodCityStates, 1631 cityStates: page?.selectedSearch?.cityStates, 1632 streetAddress: page?.selectedSearch?.streetAddress, 1633 countyStates: page?.selectedSearch?.countyStates, 1634 postalCodes: page?.selectedSearch?.postalCodes, 1635 mlsAreas: page?.selectedSearch?.mlsAreas, 1636 polygon: page?.selectedSearch?.polygon, 1637 mlsNums: page?.selectedSearch?.mlsNums, 1638 blossorIds: page?.selectedSearch?.blossorIds 1639 1640 } 1641 1642 blueroofMiddlewareApi.updateSavedListings(updateListingAlert).then((updatedSearch) => { 1643 1644 frequencyModal.hide(); 1645 toast.show('Frequency updated'); 1646 }).catch((e) => { 1647 toast.show('Error updating frequency', true); 1648 }) 1649 1650 1651 1652 }).subscribe(); 1653 1654 Pubsub.subscription("saved_search_deleted", (alertId) => { 1655 savedSearchSection.removeSavedSearchCard(alertId) 1656 if(page.viewingUpdatedListings) { 1657 Pubsub.publish("top_header_back_pressed"); 1658 } 1659 1660 }).subscribe() 1661 Pubsub.subscription("save_search_block_updates_pressed", showUpdatedListings).subscribe() 1662 1663 Pubsub.subscription("saved_search_block_icon_pressed", (e) => { 1664 let icon = e.icon 1665 let savedSearch = e.savedSearch; 1666 let filter; 1667 1668 1669 switch(icon){ 1670 case 'new': 1671 filter = 'new'; 1672 break;
1673 case 'openHouse': 1674 filter = 'open_house'; 1675 break; 1676 case 'sold': 1677 filter = 'status_change'; 1678 break; 1679 case 'priceChange': 1680 filter = 'price_change'; 1681 break; 1682 } 1683 1684 showUpdatedListings(savedSearch).then(() => { 1685 pillSelector.pillSelector.setAttribute('active_pill', filter) 1686 updatedListingsSection.filterProperties(filter) 1687 }) 1688 1689 }).subscribe(); 1690 1691 1692 Pubsub.subscription("top_header_back_pressed", () => { 1693 window.location.hash = ''; 1694 subHeader.hideTopHeader(); 1695 subHeader.showPrimaryButton(); 1696 subHeader.hideMenuButton(); 1697 subHeader.setTitle("Saved Searches"); 1698 updatedListingsSection.hide(); 1699 savedSearchSection.show(); 1700 page.setSelectedSearch(''); 1701 page.scrollToTop(); 1702 page.viewingUpdatedListings = false; 1703 }).subscribe() 1704 Pubsub.subscription("pill_selector_item_selected",(e) => {updatedListingsSection.filterProperties(e)}).subscribe(); 1705 1706 Pubsub.subscription("top_header_menu_item_pressed", (menuItemPressed) => { 1707 1708 if(menuItemPressed == 'Delete Saved Search'){ 1709 Pubsub.publish('delete_saved_search_pressed', page.selectedSearch.alertId); 1710 } 1711 else if(menuItemPressed == 'Share Saved Search'){ 1712 Pubsub.publish('share_saved_search_pressed', page.selectedSearch); 1713 } 1714 else if(menuItemPressed == 'Manage Alerts'){ 1715 Pubsub.publish('manage_alerts_pressed', page.selectedSearch); 1716 } 1717 }).subscribe(); 1718 1719 Pubsub.subscription('share_property', (e) => { 1720 shareSavedPropertyModal.show(e.property); 1721 }).subscribe(); 1722 1723 Pubsub.subscription('add_property_to_collection', (e) => { 1724 copyPropertyToCollectionModal.setIsAddingToCollection(true); 1725 copyPropertyToCollectionModal.show(e.property); 1726 }).subscribe(); 1727 1728 Pubsub.subscription('remove_property_from_collections', (e) => { 1729 let blossorId = e.property.blossorId; 1730 let myFeedData = myFeed.getMlsData(); 1731 collectionsService.checkIfInCollection([blossorId]).then((propertiesInCollections) => { 1732 if(propertiesInCollections.data[blossorId]){ 1733 propertiesInCollections.data[blossorId].forEac
1733h((collection) => { 1734 collectionsService.removePropertyFromCollection(collection.collectionUUID, collection.propertyUUID).then(() => { 1735 1736 let data = copyPropertyToCollectionModal.getCollectionData(); 1737 let collectionUUID = collection.collectionUUID; 1738 collectionsService.getCollectionProperties(collectionUUID,1,1).then((e) => { 1739 1740 let collectionIndex = data.findIndex((x) => x.id == collectionUUID); 1741 let collection = data[collectionIndex]; 1742 1743 collection.propertiesImages = []; 1744 if(e?.data?.properties?.length > 0){ 1745 collection.propertiesImages.push({mainPhoto: e?.data?.properties[0]?.photos[0]?.url}); 1746 } 1747 1748 data[collectionIndex] = collection; 1749 1750 copyPropertyToCollectionModal.setCollectionData(data); 1751 }) 1752 1753 //update my feed to set property heart as not favorited 1754 let myFeedPropertyIndex = myFeedData.findIndex((x) => x.blossorId == blossorId); 1755 if(myFeedPropertyIndex > -1){ 1756 myFeedData[myFeedPropertyIndex].favorite = false; 1757 myFeed.setMlsData(myFeedData); 1758 } 1759 1760 //update property in update search 1761 let propertyCard = document.getElementById(blossorId); 1762 let propertyCardMLS = JSON.parse(propertyCard.getAttribute('mls')); 1763 propertyCardMLS.favorite = false; 1764 propertyCard.setAttribute('mls', JSON.stringify(propertyCardMLS)); 1765 1766 1767 }).catch((e) => { 1768 toast.show('Error removing from collection'); 1769 }); 1770 }); 1771 } 1772 }); 1773 }).subscribe(); 1774 1775 Pubsub.subscription('copy_property_to_collection_modal_save_pressed', (e) => { 1776 let collectionUUID = e.collectionUUID; 1777 let blossorId = e.property.blossorId; 1778 collectionsService.addPropertyToCollection(collectionUUID, [blossorId]).then(() => { 1779 1780 1781 let data = copyPropertyToCollectionModal.getCollectionData(); 1782 let myFeedData = myFeed.getMlsData(); 1783 1784 collectionsService.getCollectionProperties(collectionUUID,1,1).then((e) => { 1785 1786 let collectionIndex = data.findIndex((x) => x.id == collectionUUID); 1787 let collection = data[collectionIndex]; 1788 1789 collection.propertiesImages = []; 1790 if(e?.data?.properties?.length > 0){ 1791 collection.propertiesImages.push({mainPhoto: e?.data?.properties[0]?.photos[0]?.url}); 1792 } 1793 1794 data[collectionIndex] = collection; 1795 1796 copyPropertyToCollectionModal.setCollectionData(data); 1797 1798 //update my feed to set property heart as favorited 1799 let myFeedPropertyIndex = myFeedData.findIndex((x) => x.blossorId == blossorId); 1800 if(myFeedPropertyIndex > -1){ 1801 myFeedData[myFeedPropertyIndex].favorite = true; 1802 myFeed.setMlsData(myFeedData); 1803 } 1804 1805 //update property in update search 1806 let propertyCard = document.getElementById(blossorId); 1807 let propertyCardMLS = JSON.parse(propertyCard.getAttribute('mls')); 1808 propertyCardMLS.favorite = true; 1809 propertyCard.setAttribute('mls', JSON.stringify(propertyCardMLS)); 1810 }) 1811 1812 copyPropertyToCollectionModal.hide(); 1813 }); 1814 }).subscribe(); 1815 1816 Pubsub.subscription('on_new_collection_saved', (e) => { 1817 if(e.type == 'save'){ 1818 1819 let people = [{ personUUID: page.lead.brivity_uuid, role: "lead" }]; 1820 let properties = [""]; 1821 collectionsService.createCollection(e.name, e.description, page.lead.brivity_uuid, people, properties).then((e) => { 1822 1823 let collections = copyPropertyToCollectionModal.getCollectionData(); 1824 let newCollection = { 1825 collection_title: e.data.collectionName, 1826 id: e.data.collectionUUID, 1827 propertiesImages: [], 1828 } 1829 collections.unshift(newCollection); 1830 copyPropertyToCollectionModal.setCollectionData(collections); 1831 1832 collectionModal.hide(); 1833 1834 }).catch((e) => { 1835 collectionModal.showError(true) 1836 }); 1837 } 1838 1839 }).subscribe(); 1840 1841 Pubsub.subscription('show_new_collection_modal', (e) => { 1842 collectionModal.show(); 1843 }).subscribe(); 1844
1845 window.addEventListener( "hashchange", function( event ) { 1846 if(window.location.hash == ''){ 1847 Pubsub.publish("top_header_back_pressed"); 1848 } 1849 }); 1850 1851 let modalBackdrop = document.getElementsByClassName('center-modal'); 1852 for(let i = 0; i < modalBackdrop.length; i++){ 1853 modalBackdrop[i].addEventListener('click', (e) => { 1854 if(e.target == modalBackdrop[i]){ 1855 modalBackdrop[i].style.display = 'none'; 1856 } 1857 }); 1858 } 1859 1860 document.addEventListener("click", (e) => { 1861 1862 const elements = document.querySelectorAll("[show_menu]"); 1863 elements.forEach((el) => { 1864 el.setAttribute("show_menu", "false"); 1865 }); 1866 1867 // document.getElementById("c2dfac72-6233-4e8d-b0d2-f44e4240ebb4")?.setAttribute("show_menu", "false"); 1868 }); 1869 })(); 1870 } 1871 }) 1872 1873</script>
1873 <div id="myportal-page" style="display:none"> <div style="position:relative; width:100%;"> <div style="position:absolute;z-index:10; top:0; bottom:0; "> <place-menu></place-menu> </div> <div class="collection-page" style="flex:1;"> <div class="page-width-parent"> <place-pagesubheader title="SAVED SEARCHES" show_top_header="false" button_title="Create New" button_icon="plus" show_menu="false" menu_items='[{"icon":"bell", "text": "Manage Alerts"},{ "icon": "share-2", "text": "Share Saved Search" },{ "icon": "trash", "text": "Delete Saved Search" }]' ></place-pagesubheader> <div style="margin: 24px 0"> <place-actioncard style="display:none;" id="save-search-block" title="Save Search" sub_title="Save your customized searches and be the first to know about new properties" button_text="Search" button_icon="search" button_icon_fill="#fff" card_width="315" > </place-actioncard> </div> <div id="saved-searches" style="display:flex; flex-wrap:wrap; margin: 24px 0;"> </div> <div id="updated-listings-section" style="display:none; flex-wrap:wrap;"> <div id="updated-listings" style="display:flex;flex-wrap:wrap;gap:24px;margin-bottom:24px;"> </div> </div> <div style="margin-bottom:32px"> <place-gethomeapp></place-gethomeapp> </div> <div class="my-feed-parent"> <place-myfeedblock style="display:none" display_menu="false"></place-myfeedblock> </div> </div> </div> </div> <place-basicmodal id="delete-saved-search-modal" class="center-modal" style="display:none" title="Delete Saved Search" sub_title="Deleting a saved search will permanently remove it from your account and you will be unsubscribed to any connected listing alerts. Are you sure you would like to delete this search?" title_icon="trash" primary_button_text="Delete" tertiary_button_text="Cancel" ></place-basicmodal> <place-basicmodal id="share-saved-search-modal" class="center-modal" style="display:none" title="Share Saved Search" sub_title="Copy link to share search." title_icon="share-2" primary_button_text="Copy Link" ></place-basicmodal> <place-basicmodal id="share-saved-property-modal" class="center-modal" style="display:none" title="Share Property" sub_title="Copy link to share property." title_icon="share" primary_button_text="Copy Link" ></place-basicmodal> <place-copycollectionmodal class="center-modal" style="display:none" collections='[]' ></place-copycollectionmodal> <place-collectionpopup class="center-modal" style="display:none" ></place-collectionpopup> <place-frequencymodal class="center-modal" style="display:none" title="Manage Listing Alerts" title_icon="bell" menu_items='[{ "text": "Daily" },{ "text": "Twice Daily" }, { "text": "Multiple Times Per Day" },{ "text": "Weekly" },{ "text": "Every 2 Weeks" },{ "text": "Monthly" }]' selected_menu_item="Never" > </place-frequencymodal> </div> </div> <footer data-selector="footer" class="" style="outline: none; cursor: inherit;" id="footer-9n"> <div class="container"> <div class="row"> <div class="col-md-2"> <div class="render-menu hot-nav"> <ul class=""> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/index">Home</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/search">Listings</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/buying">Buying</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a class="white" href="/selling">Selling</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/financing">Financing</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/home_value">Home Value</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/realestateagent/search">Who We Are</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/connect">Connect</a> </li> </ul> </div> </div> <div class="col-md-7 col-md-offset-1"> <form id="form-contact1" action="" class="form-contact"> <div class="row margin-bottom-0"> <div class="col-sm-6" style="margin-bottom: 20px;"> <div class="form-group"> <input name="contact1_fname" id="contact1_fname" placeholder="First Name" class="form-control contact_fname" type="text" required="" style='background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVQ4EaVTO26DQBD1ohQWaS2lg9JybZ+AK7hNwx2oIoVf4UPQ0Lj1FdKktevIpel8AKNUkDcWMxpgSaIEaTVv3sx7uztiTdu2s/98DywOw3Dued4Who/M2aIx5lZV1aEsy0+qiwHELyi+Ytl0PQ69SxAxkWIA4RMRTdNsKE59juMcuZd6xIAFeZ6fGCdJ8kY4y7KAuTRNGd7jyEBXsdOPE3a0QGPsniOnnYMO67LgSQN9T41F2QGrQRRFCwyzoIF2qyBuKKbcOgPXdVeY9rMWgNsjf9ccYesJhk3f5dYT1HX9gR0LLQR30TnjkUEcx2uIuS4RnI+aj6sJR0AM8AaumPaM/rRehyWhXqbFAA9kh3/8/NvHxAYGAsZ/il8IalkCLBfNVAAAAABJRU5ErkJggg=="); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%; cursor: auto;'> </div> </div> <div class="col-sm-6" style="margin-bottom: 20px;"> <div class="form-group"> <input name="contact1_lname" id="contact1_lname" placeholder="Last Name" class="form-control contact_lname" type="text" required=""> </div> </div> </div> <div class="row margin-bottom-0"> <div class="col-sm-6" style="margin-bottom: 20px;"> <div class="form-group"> <input name="contact1_email" id="contact1_email" placeholder="Email Address" class="form-control contact_email" type="email" required=""> </div> </div> <div class="col-sm-6" style="margin-bottom: 20px;"> <div class="form-group"> <input name="contact1_phone" id="contact1_phone" placeholder="Phone Number" class="form-control contact_phone" type="tel" required=""> </div> </div> </div> <div class="row margin-bottom-0"> <div class="col-sm-12" style="margin-bottom: 20px;"> <i class="fa fa-caret-down" style="position: absolute; top: 13px; right: 30px; font-size: 14px; outline: none; cursor: inherit;" data-selector=".fa"></i> <select name="lead_type" style="width: 100%; height: 40px; padding-left: 12px; font-size: 14px; border-radius: 0; -webkit-appearance: none; -webkit-border-radius: 0px;"> <option value="buyer">I'm interested in buying a home</option> <option value="seller">I'm interested in selling a home</option> <option value="seller/buyer">I'm interested in buying and selling</option> <option value="tenant">I'm interested in finding a home to rent</option> <option value="recruit">I'm interested in a real estate career</option> <option value="n/a">Other reason to contact an agent</option> </select> </div> </div> <div class="row margin-bottom-0"> <div class="col-sm-12" style="margin-bottom: 20px;"> <textarea name="contact1_message" id="contact1_message" class="form-control contact_message" rows="3" placeholder="Your Message"></textarea> </div> </div> <div class="text-right"> <input type="text" id="contact1_robot_field" name="contact1_robot_field" style="display: none;"><button type="submit" class="btn btn-primary squared" data-selector="a.btn, button.btn, button">Send Us A Message</button> </div> <div id="honeypot-div"> <input name="age_required" id="age_required" value="" type="text" style="display: none;"> </div> </form> </div> <div class="col-md-2 col-md-offset-1"> <img class="ftr-logo" src="https://images.brivityidx.com/assets/images/uploads/106466/Mike_Mendoza_footer_LOGO.png" alt="Buy and Sell Homes Real Estate" data-selector="img" style="border-style: none; outline: none; cursor: inherit;"> <h3 class="text-left margin-top-40" data-selector="h1, h2, h3, h4, h5, h6">Reach Out</h3> <div class="text-left" style="outline: medium none; cursor: inherit;"> <ul style="list-style-type: none;"> <li data-selector="li" style="outline: none; cursor: inherit;"> <span class="agent_address_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading"></span> <br><span class="agent_city_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading"></span>, <span class="agent_state_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading"></span> <span class="agent_zip_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading"></span> </li> <li data-selector="li" style="outline: none; cursor: inherit;"> <a class="agent_phone_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="tel:8662953322" src="tel:"></a> </li> </ul> </div> </div> </div> <div class="row ftr-anchor"> <div class="col-sm-6 anchor-col no-padding editContent" data-selector=".editContent"> <p class="no-margin" data-selector="p"><span class="get_this_year">2021</span> © <strong>The Mendoza Team | eXp Realty</strong></p> <p style="margin: 10px 0px;" data-selector="p"> <img src="https://images.brivityidx.com/assets/images/uploads/1428/Equal-Housing-Realtor_gray50.png" alt="Equal Housing | Realtor" style="width: 50px; outline: none; cursor: inherit;" data-selector="img">  </p> </div> <div class="col-sm-6 anchor-col no-padding"> <ul class="social"> <li data-selector="li" style="outline: none; cursor: inherit;" class="agent_facebook_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.facebook.com/Brivity"><a class="btn btn-block agent_facebook_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.facebook.com/Brivity" target="blank" data-selector="a.btn, button.btn, button"><i class="fa fa-2x fa-facebook fa-adjust prmry-color" data-selector=".fa" style="outline: none; cursor: inherit;"></i></a></li> <li data-selector="li" style="outline: none; cursor: inherit;" class="agent_twitter_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://twitter.com/Brivity"><a class="btn btn-block agent_twitter_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://twitter.com/Brivity" target="blank" data-selector="a.btn, button.btn, button"><i class="fa fa-2x fa-twitter fa-adjust prmry-color" data-selector=".fa" style="outline: none; cursor: inherit;"></i></a></li> <li data-selector="li" style="outline: none; cursor: inherit;" class="agent_instagram_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.instagram.com/Brivityplatform/"><a class="btn btn-block agent_instagram_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.instagram.com/Brivityplatform/" target="blank" data-selector="a.btn, button.btn, button"><i class="fa fa-2x fa-instagram fa-adjust prmry-color" data-selector=".fa" style="outline: none; cursor: inherit;"></i></a></li> <li data-selector="li" style="outline: none; cursor: inherit;" class="agent_pinterest_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.pinterest.com/"><a class="btn btn-block agent_pinterest_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.pinterest.com/" target="blank" data-selector="a.btn, button.btn, button"><i class="fa fa-2x fa-pinterest fa-adjust prmry-color" data-selector=".fa" style="outline: none; cursor: inherit;"></i></a></li> <li data-selector="li" style="outline: none; cursor: inherit;" class="agent_youtube_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.youtube.com/channel/UCWdVYI1u9hnol74ibn62qFw"><a class="btn btn-block agent_youtube_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.youtube.com/channel/UCWdVYI1u9hnol74ibn62qFw" target="blank" data-selector="a.btn, button.btn, button"><i class="fa fa-2x fa-youtube fa-adjust prmry-color" data-selector=".fa" style="outline: none; cursor: inherit;"></i></a></li> <li data-selector="li" style="outline: none; cursor: inherit;" class="agent_linkedin_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.linkedin.com/company/brivity"><a class="btn btn-block agent_linkedin_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.linkedin.com/company/brivity" target="blank" data-selector="a.btn, button.btn, button"><i class="fa fa-2x fa-linkedin fa-adjust prmry-color" data-selector=".fa" style="outline: none; cursor: inherit;"></i></a></li> </ul> </div> </div> </div> </footer> </div> <section id="seo-anchor"> <div class="container"> <ul class="powered-by"> <li>Powered by <a class="pb-vendor" href="https://www.brivity.com/"> Brivity</a></li> <li class="pb-admin-login"><a href="https://login.brivityidx.com/login"><span class='pb-admin-login-text'>Admin Log In</span></a></li> </ul> <ul class="seo-anchor-links"> <li><a href="/privacy_policy">Privacy Policy</a></li> <li><a href="/tos">DMCA & Terms of Service</a></li> <li><a id='sitemapUrl' href='/sitemap' style='display: inline;'>Sitemap</a></li> </ul> </div> </section> <input type="hidden" id="hchatbot_settings" data-chatbot-version="1" value="{"chat_position":"right","call_to_action_text":"Hi there! Please let us know if you have any questions and an agent will reach out to you as soon as possible.","initial_message":"Enter your question below and an agent will be in touch with you.","tags":"IDX Chat","version":"1"}"> 1874<!-- chatbot v1 --> 1875<!-- Chatbot drawer container --> 1876<div class="chatbot-drawer-container loading"> 1877 <div class="chatbot-content-wrapper"> 1878 <div class="chatbot-outside-content"> 1879 <div class="chatbot-bubble-message-container cb-hide"> 1880 <img src="https://cdn.brivity.com/images/people/62711461/b5dc09ba2ffb5bdaa11ff9c20d0ccd9b9181a608-original.jpg?1778614623" class="chatbot-agent-img" alt="Agent profile image in chat bubble"/> 1881 <div id="call-to-action" class="bubble-message"></div> 1882 <button type="button" class="chatbox-bubble-close" data-dismiss="modal" aria-label="Close">
1883 <span aria-hidden="true">×</span> 1884 </button> 1885 </div> 1886 <button id="chatbot-open-btn" class="chatbot-open-btn bg-prmry" aria-label="Chatbot Open Button"> 1887 <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> 1888 <path d="M20.8 6.35501V16C20.8 17.765 19.365 19.195 17.6 19.195L11.2 19.2L5.755 22.28C5.645 22.365 5.52 22.4 5.4 22.4C5.09 22.4 4.8 22.155 4.8 21.8V19.2H3.2C1.4375 19.2 0 17.765 0 16V6.35501C0 4.63751 1.4375 3.20001 3.2 3.20001H17.6C19.365 3.20001 20.8 4.63751 20.8 6.35501ZM7.2 18.705L10.57 16.8H17.6C18.035 16.8 18.4 16.44 18.4 16V6.40001C18.4 5.96251 18.035 5.60001 17.6 5.60001H3.2C2.7625 5.60001 2.4 5.96251 2.4 6.40001V16C2.4 16.44 2.7625 16.8 3.2 16.8H7.2V18.705ZM12.8 22.4V20.8H15.2V22.4C15.2 22.835 15.56 23.2 16 23.2H21.43L24.8 25.105V23.2H28.8C29.235 23.2 29.6 22.835 29.6 22.4V12.8C29.6 12.365 29.235 12 28.8 12H22.4V9.60001H28.8C30.565 9.60001 32 11.035 32 12.755V22.4C32 24.165 30.565 25.6 28.8 25.6H27.2V28.2C27.2 28.555 26.91 28.8 26.6 28.8C26.48 28.8 26.355 28.765 26.245 28.68L20.8 25.6L16 25.595C14.24 25.595 12.8 24.165 12.8 22.4Z" fill="white"/> 1889 </svg> 1890 </button> 1891 </div> 1892 <div class="chatbot-drawer"> 1893 <div class="chatbot-header bg-prmry"> 1894 <div class="chatbot-agent-info"> 1895 <img src="https://cdn.brivity.com/images/people/62711461/b5dc09ba2ffb5bdaa11ff9c20d0ccd9b9181a608-original.jpg?1778614623" class="chatbot-agent-img" alt="Agent profile image in chat header"/> 1896 <div class="chatbot-agent"> 1897 <h3 class="chatbot-agent-name">Josh Mendoza</h3> 1898 <h4><span class="chatbot-agent-title"></span> | <span class="chatbot-agent-company">The Mendoza Team | eXp Realty</span></h4> 1899 </div> 1900 <a id="chatbot-agent-phone" style="display: none;">(480) 706-7234</a> 1901 </div> 1902 <button id="close-chatbot-drawer" type="button" class="chatbox-modal-close" data-dismiss="modal" aria-label="Close"> 1903 <span aria-hidden="true">×</span> 1904 </button> 1905 </div> 1906 <div class="chatbot-body"> 1907 <div class="chatbot-message-container"> 1908 <img src="https://cdn.brivity.com/images/people/62711461/b5dc09ba2ffb5bdaa11ff9c20d0ccd9b9181a608-original.jpg?1778614623" class="chatbot-agent-img" alt="Agent profile image in message"/> 1909 <h4 id="initial_message" class="chatbot-chat-messages not-loaded"></h4> 1910 <div class="chatbot-chat-messages loading"> 1911 <span class="typing-indicator"> 1912 <span></span> 1913 <span></span> 1914 <span></span> 1915 </span> 1916 </div> 1917 </div> 1918 <form id="chatbotForm" class="chatbot-form"> 1919 <input type="name" id="chatbot_fullname" class="chatbox-form-control no-native-focus" placeholder="Full Name" 1920 pattern="^[A-Za-z'\- ]+ [A-Za-z'\- ]+$" 1921 required /> 1922 <input type="tel" id="chatbot_phone" class="chatbox-form-control no-native-focus" placeholder="Phone" required /> 1923 <input type="email" id="chatbot_email" class="chatbox-form-control no-native-focus" placeholder="Email" 1924 pattern="^[^@\s]+@[^@\s]+\.[^@\s]+$" 1925 required /> 1926 <textarea id="chatbot_message" class="chatbox-form-control chatbot-message" rows="5" name="notes" placeholder="Any Comments or Questions"></textarea> 1927 <div class="chatbot-consent-container"> 1928 <div class="chatbot-toggle"> 1929 By proceeding and clicking the sign up button, you consent to receive calls and texts (SMS/MMS) including marketing and promotional communications, from <span class="agent_name_dynamic"></span>, its affiliates, and agents or vendors acting on their behalf. These
1929communications may be delivered using an automatic telephone dialing system or by using an artificial or prerecorded voice. Message and data rates may apply. To opt out of text messages, reply STOP. Your consent is not required as a condition of any purchase. By continuing, you also agree to our <a class="opt-out-href" href="/tos">Terms of Use</a> and <a class="opt-out-href" href="/privacy_policy">Privacy Policy</a>. 1930 </div> 1931 </div> 1932 <input type="hidden" id="chatbot_tags"> 1933 </form> 1934 </div> 1935 <div class="chatbot-footer"> 1936 <button type="submit" form="chatbotForm" class="chatbot-send bg-prmry chatbot-btn-disabled" data-dismiss="modal" aria-label="Close" disabled> 1937 Send 1938 <span aria-hidden="true"> 1939 <svg class="chatbot-btn-icon" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> 1940 <g clip-path="url(#clip0_2435_997)"> 1941 <path d="M14.6667 1.33331L7.33337 8.66665" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 1942 <path d="M14.6667 1.33331L10 14.6666L7.33337 8.66665L1.33337 5.99998L14.6667 1.33331Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 1943 </g> 1944 <defs> 1945 <clipPath id="clip0_2435_997"> 1946 <rect width="16" height="16" fill="white"/> 1947 </clipPath> 1948 </defs> 1949 </svg> 1950 </span> 1951 </button> 1952 </div> 1953 </div> 1954 </div> 1955</div> <style> 1956 .signup-consent-checkbox-section { 1957 display: none; 1958 flex-direction:column; 1959 align-items:flex-start; 1960 padding: 6px 0; 1961 } 1962 1963 .signup-consent-checkbox-section .checkbox { 1964 display:flex; 1965 align-items:flex-start; 1966 justify-content:center; 1967 gap:8px; 1968 padding:0 !important; 1969 } 1970 1971 .signup-consent-checkbox-section .checkbox input { 1972 position:unset; 1973 margin:2px 0 0 0 !important; 1974 } 1975 1976 .signup-consent-checkbox-section .checkbox span { 1977 color: #666666; 1978 font-size: 14px; 1979 font-weight: 400; 1980 line-height:16px; 1981 } 1982 1983 .signup-verbage { 1984 text-align:center; 1985 font-size:10px; 1986 line-height:16px; 1987 } 1988 1989 .signup-verbage span { 1990 color: #8C8C8C; 1991 font-weight:600; 1992 } 1993 1994 .signup-verbage a { 1995 color:#5386E4 !important; 1996 font-weight:400; 1997 } 1998 1999 .signup-verbage .twilio-enabled-verbage { 2000 display:none; 2001 } 2002 2003 2004 2005 </style> <div id="modal-mount" data-modal-bundle="https://cdn1.brivityidx.com/assets/modals/v1/all.html?ck=1790798866"></div>
2005 <div id="credential_picker_container_centered"> <div id="credential_picker_header_bar"> <p><button class="signOrLogBtn" onclick="showSignupModal();">Sign up</button> or <button class="signOrLogBtn" onclick="showLoginModal();">Login</button> another way</p> </div> <div id="credential_picker_header_bar_separator"></div> </div> <place-getyourhomecta id="contact_modal" style="display:none; justify-content: center; align-items: center; position:fixed; background-color:rgba(0,0,0,0.4); left:0; top:0; right:0; bottom:0; z-index: 100;" interest_items='[{"text":"Looking to sell ASAP"},{"text":"Looking to sell (1-3 months)"},{"text":"Looking to sell (3-6 months)"}, {"text":"Looking to sell (6-12 months)"},{"text":"Looking to sell (12+ months)"}, {"text":"Just curious"}]' > </place-getyourhomecta> <place-generictoast appear_from_both="true" container_style="right-1/2 z-200"></place-generictoast>
2005<script> 2006 document.addEventListener("DOMContentLoaded", () => { 2007 class Toast { 2008 constructor() { 2009 this.element = document.querySelector('place-generictoast'); 2010 } 2011 2012 show(message, error = false, link) { 2013 var dispatch = function () { 2014 window.dispatchEvent( 2015 new CustomEvent("ShowToast", { 2016 detail: { 2017 text: message, 2018 error: error, 2019 link: link, 2020 }, 2021 }) 2022 ); 2023 }; 2024 if (window.sitebuilderPlaceComponents && window.sitebuilderPlaceComponents.ensureLoaded) { 2025 window.sitebuilderPlaceComponents 2026 .ensureLoaded('place-generictoast') 2027 .then(dispatch) 2028 .catch(function (err) { 2029 console.warn('toast.show fallback (web-components unavailable):', message, err); 2030 }); 2031 } else { 2032 dispatch(); 2033 } 2034 } 2035 } 2036 2037 window.toast = new Toast(); 2038 }); 2039 </script>
2039
2039<script src="https://cdn.jsdelivr.net/npm/@turf/[email protected]/turf.min.js"></script>
2039
2039<script src="https://maps.googleapis.com/maps/api/js?libraries=geocoding,places,marker,drawing&key=AIzaSyAjpuNg6WGCMV5rzoJcIP2QmMTVto6hYmc&map_ids=85c127b7bf0255d9"></script>
2039
2039<script src="https://cdn1.brivityidx.com/assets/js/build.min.js?ck="></script>
2039
2039<script src="https://cdn1.brivityidx.com/assets/js/top_bar_v2.min.js?ck="></script>
2039
2039<script src="https://cdn1.brivityidx.com/assets/js/global_js.min.js?ck=1790798865"></script>
2039
2039<script>deferScript("https://cdn1.brivityidx.com/assets/js/global_js_defer.min.js?ck=1790798865", 5000);</script>
2039
2039<script> 2040 function shouldLoadChatbotImmediately() { 2041 const settingsEl = document.getElementById('hchatbot_settings'); 2042 if (!settingsEl) return false; 2043 2044 const version = Number(settingsEl.dataset.chatbotVersion); 2045 let isInitialized = false; 2046 2047 try { 2048 const session = JSON.parse(sessionStorage.getItem('cbSession') || '{}'); 2049 isInitialized = session.chatbotInitialized === true; 2050 } catch (e) {} 2051 2052 return version > 1 && isInitialized; 2053 } 2054 </script>
2054
2054<script>document.getElementById('hchatbot_settings') && Number(document.getElementById('hchatbot_settings').dataset.chatbotVersion) > 1 && deferScript("https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/9.0.6/signalr.min.js", 0);</script>
2054
2054<script>document.getElementById('hchatbot_settings') && deferScript(Number(document.getElementById('hchatbot_settings').dataset.chatbotVersion) > 1 ? "https://cdn1.brivityidx.com/assets/js/chatbot_v2.min.js?ck=1790798864" : "https://cdn1.brivityidx.com/assets/js/chatbot.min.js?ck=1790798864", shouldLoadChatbotImmediately() ? 50 : 5000);</script>
2054
2054<script type="text/javascript" src="https://cdn1.brivityidx.com/assets/js/jquery.geocomplete.min.js"></script>
2054<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.bootstrapvalidator/0.5.3/js/bootstrapValidator.min.js"></script>
2054<script type="text/javascript" src="https://cdn1.brivityidx.com/assets/js/member_area_components.js"></script>
2054<script type="text/javascript" src="https://cdn1.brivityidx.com/assets/js/update_agent_info.js"></script>
2054
2054<script src="https://mobile-component-services-library.s3.amazonaws.com/collections_service.min.js?ck=1"></script>
2054
2054<script src="https://mobile-component-services-library.s3.amazonaws.com/messaging_service.min.js?ck=1"></script>
2054
2054<script>$(document).ready(function(){function changePlaceholder(){if($(window).width()<=556){$("#home_value_my_portal_search_address").attr("placeholder","Address")}else if($(window).width()>556){$("#home_value_my_portal_search_address").attr("placeholder","Enter Property Address")}} 2055$(window).resize(changePlaceholder).trigger('resize')})</script>
2055
2055<script>$(document).ready(function(){$("#sitemap-listings > div.container > div > div.col-xs-12.col-md-12.col-lg-4.col-lg-push-8.seo-intro > a").attr("href","/search")})</script>
2055
2055<script>$(document).ready(function(){$("#sitemap-listings > div.container > div > div.col-xs-12.col-md-12.col-lg-4.col-lg-push-8.seo-intro > a").attr("href","/search")})</script>
2055
2055<script>$(document).ready(function(){$("ul.seo-anchor-links li:nth-of-type(4) a").attr("href","/search")})</script>
2055
2055<script>(function($){$.fn.countTo=function(options){options=options||{};return $(this).each(function(){var settings=$.extend({},$.fn.countTo.defaults,{from:$(this).data('from'),to:$(this).data('to'),speed:$(this).data('speed'),refreshInterval:$(this).data('refresh-interval'),decimals:$(this).data('decimals')},options);var loops=Math.ceil(settings.speed/settings.refreshInterval),increment=(settings.to-settings.from)/loops;var self=this,$self=$(this),loopCount=0,value=settings.from,data=$self.data('countTo')||{};$self.data('countTo',data);if(data.interval){clearInterval(data.interval)} 2056data.interval=setInterval(updateTimer,settings.refreshInterval);render(value);function updateTimer(){value+=increment;loopCount++;render(value);if(typeof(settings.onUpdate)=='function'){settings.onUpdate.call(self,value)} 2057if(loopCount>=loops){$self.removeData('countTo');clearInterval(data.interval);value=settings.to;if(typeof(settings.onComplete)=='function'){settings.onComplete.call(self,value)}}} 2058function render(value){var formattedValue=settings.formatter.call(self,value,settings);$self.html(formattedValue)}})};$.fn.countTo.defaults={from:0,to:0,speed:1000,refreshInterval:100,decimals:0,formatter:formatter,onUpdate:null,onComplete:null};function formatter(value,settings){return value.toFixed(settings.decimals)}}(jQuery));jQuery(function($){$('.count-number').data('countToOptions',{formatter:function(value,options){return value.toFixed(options.decimals).replace(/\B(?=(?:\d{3})+(?!\d))/g,',')}});$('.timer').each(count);function count(options){var $this=$(this);options=$.extend({},options||{},$this.data('countToOptions')||{});$this.countTo(options)}})</script>
2058
2058<script>$(document).ready(function(){$('#sign-up-modal.modal #signupForm').append('<input type="hidden" name="tags" value="registration_signup">')})</script>
2058
2058<script>$('.menu-toggle').click(function(){$('#slide-out-nav, .slide-out-nav-overlay').addClass('open')});$('.close-nav, .slide-out-nav-overlay').click(function(){$('#slide-out-nav, .slide-out-nav-overlay').removeClass('open')})</script>
2058
2058<script>$("#slide-out-nav > div.render-menu > ul").append('<li class="nav-item"><a style="color:#fff!important; max-width:250px; margin:0 auto;" id="top-nav-marketing-plan" class="nav-link-color btn-primary" data-toggle="modal" data-target="#getmarketingplan">Get Marketing Plan</a></li>')</script>
2058</body> </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.