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 | Collections</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/7090/mabryfavicon.ico" 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.legacy234.com/myportal/collections">
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.css" rel="stylesheet"><link href="https://cdn1.brivityidx.com/assets/css/style-premium.css" rel="stylesheet"><link href="https://cdn1.brivityidx.com/assets/css/style-footers.min.css" rel="stylesheet"><link href="https://cdn1.brivityidx.com/idx-sites/9/0/4/9049/site_custom.css?v=1791520554" rel="stylesheet">
204<script type="text/javascript" src="https://cdn1.brivityidx.com/idx-sites/9/0/4/9049/global_js_variables.js?v=1791520554"></script>
204<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" /> <link rel="stylesheet" href="https://use.typekit.net/mao5ffc.css"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=0"/> <meta name="facebook-domain-verification" content="25gzs18qwk62co2yoife58d1e4kdby" /> <div data-chat-widget data-widget-id="68c2d22ad62e98dad146ae9c" data-location-id="1NTeoUaHuw6CwfQOaKCD" > </div>
204<script 205 src="https://widgets.leadconnectorhq.com/loader.js" 206 data-resources-url="https://widgets.leadconnectorhq.com/chat-widget/loader.js" 207 data-widget-id="68c2d22ad62e98dad146ae9c" > 208 </script>
208
208<script src="https://cdn.polygraph.net/pg.js"></script>
208
208<script> 209var propDetailsPixelOnReady = function(){ 210 let propDetFpst = new FbRealEstatePixelTracker({"eventType": "ViewContent", "content_ids": [""]}); 211 propDetFpst.fireEvent(); 212}; 213if (document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll)) { 214 propDetailsPixelOnReady(); 215} else { 216 document.addEventListener("DOMContentLoaded", propDetailsPixelOnReady); 217} 218 219</script>
219
219<script>
vendor: 327 bytes, lines 219-223
219(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 220new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 221j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 222'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 223})(window,document,'script','dataLayer','
223GTM-MQZ3C7T
vendor: 3 bytes, line 223
223');
223</script>
223
223<script>
vendor: 327 bytes, lines 223-227
223(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 224new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 225j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 226'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 227})(window,document,'script','dataLayer','
227GTM-TVDJWZW7
vendor: 3 bytes, line 227
227');
227</script>
227 <meta property="og:url" content="https://www.legacy234.com/myportal/collections"> <meta property="og:image" content="http://images.brivityidx.com/assets/images/uploads/7090/OG_Image.jpg"> <meta property="og:image:secure_url" content="https://images.brivityidx.com/assets/images/uploads/7090/OG_Image.jpg"> <meta property="og:description" content=""> <meta property="og:title" content="MyPortal | Collections"> </head> <body>
vendor: 68 bytes, line 227
227 <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
227GTM-MQZ3C7T
vendor: 150 bytes, line 227
227" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
227GTM-TVDJWZW7
vendor: 83 bytes, line 227
227" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
227<meta name="google-signin-client_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>
227<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"> <div class="place-hiring-modal modal fade magic-modal" id="sell-modal" tabindex="-1" role="dialog" aria-labelledby="sell-modal" style="display: none;"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-body" style="text-align: center;"> <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;">We're Hiring!</h4> <p class="" data-selector="p" style="outline: none; cursor: inherit;">Join one of the fastest growing real estate teams in the US and Canada. Fill out the form below and we will contact you with more info.</p> <form class="form-contact" id="form-contact4" _lpchecked="1"> <input type="hidden" name="lead_type" value="recruit"><input type="hidden" name="tags" value="Hiring Submission"><div class="row"> <div class="col-sm-6"> <div class="form-group"> <input name="contact4_fullname" id="contact4_fullname" placeholder="Full Name" class="form-control" required="" type="text" autocomplete="off" style='background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAkCAYAAADo6zjiAAAAAXNSR0IArs4c6QAAAbNJREFUWAntV8FqwkAQnaymUkpChB7tKSfxWCie/Yb+gbdeCqGf0YsQ+hU95QNyDoWCF/HkqdeiIaEUqyZ1ArvodrOHxanQOiCzO28y781skKwFW3scPV1/febP69XqarNeNTB2KGs07U3Ttt/Ozp3bh/u7V7muheQf6ftLUWyYDB5yz1ijuPAub2QRDDunJsdGkAO55KYYjl0OUu1VXOzQZ64Tr+IiPXedGI79bQHdbheCIAD0dUY6gV6vB67rAvo6IxVgWVbFy71KBKkAFaEc2xPQarXA931ot9tyHphiPwpJgSbfe54Hw+EQHMfZ/msVEEURjMfjCjbFeG2dFxPo9/sVOSYzxmAwGIjnTDFRQLMQAjQ5pJAQkCQJ5HlekeERxHEsiE0xUUCzEO9AmqYQhiF0Oh2Yz+ewWCzEY6aYKKBZCAGYs1wuYTabKdNNMWWxnaA4gp3Yry5JBZRlWTXDvaozUgGTyQSyLAP0dbb3DtQlmcan0yngT2ekE9ARc+z4AvC7nauh9iouhpcGamJeX8XF8MaClwaeROWRA7nk+tUnyzGvZrKg0/40gdME/t8EvgG0/NOS6v9NHQAAAABJRU5ErkJggg=="); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%;'> </div> <div id="honeypot-div"> <input name="age_required" id="age_required" value="" type="text" style="display: none;"> </div> </div> <div class="col-sm-6"> <div class="form-group"> <input name="contact4_email" id="contact4_email" placeholder="Email Address" class="form-control" required="" type="email"> </div> </div> <div class="col-sm-6"> <div class="form-group"> <input name="contact4_phone" id="contact4_phone" placeholder="Phone Number" class="form-control phone_mask" type="tel"> </div> </div> <div class="col-sm-6"> <div class="form-group"> <input name="contact4_position" id="contact4_position" placeholder="Job Position" class="form-control contact_position" required="" type="text"> </div> </div> <div class="col-sm-6"> <div class="form-group dropdown-wrapper"> <select id="contact4_license" name="contact4_license" required="" class="form-control dropdown" type="text"><option value="I donât have a real estate license">I donât have a real estate license</option> <option value="I have started real estate license coursework">I have started real estate license coursework</option> <option value="I am currently licensed to practice real estate">I am currently licensed to practice real estate</option></select> </div> </div> <div class="col-sm-6"> <div class="form-group"> <input name="contact4_availability_date" id="contact4_availability_date" placeholder="Availability Date" class="form-control contact_date" type="text"> </div> </div> <div class="col-sm-6"> <div class="form-group"> <textarea name="contact4_resume" id="contact4_resume" class="form-control" rows="3" placeholder="Resumé Link (Dropbox/Google Drive)"></textarea> </div> </div> <div class="col-sm-6"> <div class="form-group"> <textarea name="contact4_message" id="contact4_message" class="form-control" rows="3" placeholder="Your Message" required=""></textarea> </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> <header id="premium-navigation" data-selector="#premium-navigation" style=""><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: none; 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: none; cursor: inherit;"> <img class="img-responsive site_custom_logo" src="https://cdn1.brivityidx.com/assets/images/agent-photos/1/3/8/13864243/6c8571cb-fd74-466a-9b77-0295089e921f-designrequestfiles-with-PLACELight.png" alt="Realvolution" style="border-radius: 0px !important; border-color: rgb(52, 52, 52) !important; border-style: none !important; border-width: 0px !important; outline: none; cursor: inherit;" data-selector="img"></a> </div> <div class="collapse navbar-collapse"> <ul class="nav navbar-nav navbar-right" style="outline: none; cursor: inherit;"><li class="nav-item" data-selector="li" style=""> <a class="nav-link-color" href="/search" style="outline: none; cursor: inherit;">SEARCH LISTINGS</a> </li> <li class="nav-item" data-selector="li" style=""> <a class="nav-link-color" href="/homevalue" style="outline: none; cursor: inherit;">Home Value</a> </li> <li class="nav-item dropdown" style="" data-selector="li"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false" href="/top_areas" aria-expanded="false">Top Areas<i class="fa fa-angle-down" style="outline: none; cursor: inherit;" data-selector=".fa"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color" style="outline: none; cursor: inherit;" data-selector="li">
227<a class="sec-nav-drop-link-color" href="/search?&multi_search=Chattanooga,%20TN&multi_cat=CityState&status=1#?q_limit=36&mlsId=287&multi_search=Chattanooga,%20TN&multi_cat=CityState&status=1%7C3&q_sort=createdAt-&q_offset=0">CHATTANOOGA</a></li><li class="sec-nav-drop-color" style="outline: none; cursor: inherit;" data-selector="li"><a class="sec-nav-drop-link-color" href="/search?&multi_search=Red%20Bank,%20TN&multi_cat=CityState&status=1#?q_limit=36&mlsId=287&multi_search=Red%20Bank,%20TN&multi_cat=CityState&status=1%7C3&q_sort=createdAt-&q_offset=0">RED BANK</a></li><li class="sec-nav-drop-color" style="outline: none; cursor: inherit;" data-selector="li"><a class="sec-nav-drop-link-color" href="/search?&multi_search=Signal%20Mountain,%20TN&multi_cat=CityState&status=1#?q_limit=36&mlsId=287&multi_search=Signal%20Mountain,%20TN&multi_cat=CityState&status=1%7C3&q_sort=createdAt-&q_offset=0">SIGNAL MOUNTAIN</a></li><li class="sec-nav-drop-color" style="outline: none; cursor: inherit;" data-selector="li"><a class="sec-nav-drop-link-color" href="/search?&multi_search=East%20Brainerd%20Elementary&multi_cat=Elementary%20School&status=1#?q_limit=36&mlsId=287&multi_search=East%20Brainerd%20Elementary&multi_cat=Elementary%20School&status=1%7C3&q_sort=createdAt-&q_offset=0">EAST BRAINERD</a></li><li class="sec-nav-drop-color" style="outline: none; cursor: inherit;" data-selector="li"><a class="sec-nav-drop-link-color" href="/search?&multi_search=Ooltewah,%20TN&multi_cat=CityState&status=1#?q_limit=36&mlsId=287&multi_search=Ooltewah,%20TN&multi_cat=CityState&status=1%7C3&q_sort=createdAt-&q_offset=0">OOLTEWAH</a></li><li class="sec-nav-drop-color" style="outline: none; cursor: inherit;" data-selector="li"><a class="sec-nav-drop-link-color" href="/search?&multi_search=Hixson,%20TN&multi_cat=CityState&status=1#?q_limit=36&mlsId=287&multi_search=Hixson,%20TN&multi_cat=CityState&status=1%7C3&q_sort=createdAt-&q_offset=0">HIXSON</a></li><li class="sec-nav-drop-color" style="outline: none; cursor: inherit;" data-selector="li"><a class="sec-nav-drop-link-color" href="/search?&multi_search=Ringgold,%20GA&multi_cat=CityState&status=1#?q_limit=36&mlsId=287&multi_search=Ringgold,%20GA&multi_cat=CityState&status=1%7C3&q_sort=createdAt-&q_offset=0">RINGGOLD</a></li><li class="sec-nav-drop-color" style="outline: none; cursor: inherit;" data-selector="li"><a class="sec-nav-drop-link-color" href="/search?&multi_search=East%20Ridge%20High&multi_cat=High%20School&status=1#?q_limit=36&mlsId=287&multi_search=East%20Ridge%20High&multi_cat=High%20School&status=1%7C3&q_sort=createdAt-&q_offset=0">EAST RIDGE</a></li></ul></li> <li class="nav-item" data-selector="li" style=""> <a class="nav-link-color" href="/buying" style="outline: none; cursor: inherit;">BUY</a> </li> <li class="nav-item" data-selector="li" style=""> <a class="nav-link-color" href="/selling" style="outline: none; cursor: inherit;">SELL</a> </li> <li class="nav-item" data-selector="li" style=""> <a class="nav-link-color" href="/financing" style="outline: none; cursor: inherit;">FINANCE</a> </li> <li data-selector="li" style=""> <a class="menu-toggle nav-link-color" style="outline: none; cursor: inherit;"> <span>MENU</span> <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></a> </li> <li class="nav-item" data-selector="li" style=""> <a id="top-nav-marketing-plan" data-toggle="modal" data-target="#sell-modal" class="nav-link-color" style="outline: none; cursor: inherit;">WE'RE HIRING</a> </li> </ul></div> </div> </div> </header> <div class="modal fade magic-modal" id="getmarketingplan" tabindex="-1" role="dialog" aria-labelledby="getmarketingplan" style="display: none;"> <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"
227class="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> <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"><a class="sec-nav-link-color" href="/buying">BUYING</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/selling">SELLING</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/financing">FINANCING</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/homevalue">Home Value</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">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=Chattanooga,%20TN&multi_cat=CityState&status=1|3&mlsId=287&q_sort=createdAt-&q_offset=0">CHATTANOOGA</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Red%20Bank,%20TN&multi_cat=CityState&status=1|3&mlsId=287&q_sort=createdAt-&q_offset=0">RED BANK</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Signal%20Mountain,%20TN&multi_cat=CityState&status=1|3&mlsId=287&q_sort=createdAt-&q_offset=0">SIGNAL MOUNTAIN</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=East%20Brainerd%20Elementary&multi_cat=Elementary%20School&status=1|3&mlsId=287&q_sort=createdAt-&q_offset=0">EAST BRAINERD</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Ooltewah,%20TN&multi_cat=CityState&status=1|3&mlsId=287&q_sort=createdAt-&q_offset=0">OOLTEWAH</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Hixson,%20TN&multi_cat=CityState&status=1|3&mlsId=287&q_sort=createdAt-&q_offset=0">HIXSON</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Ringgold,%20GA&multi_cat=CityState&status=1|3&mlsId=287&q_sort=createdAt-&q_offset=0">RINGGOLD</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=East%20Ridge%20High&multi_cat=High%20School&status=1|3&mlsId=287&q_sort=createdAt-&q_offset=0">EAST RIDGE</a></li></ul><li class="nav-item"><a class="sec-nav-link-color" href="/realestateagent/search">MEET THE TEAM</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/team-forms-resources">TEAM FORMS & RESOURCES</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/client-events">Client Events</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="/careers">CAREERS</a></li><li class="nav-item"><a class="sec-nav-link-color" href="https://www.place.com/">ABOUT PLACE</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/connect">CONNECT</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/blog">blog</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/featured-listings">Featured Listings</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/8/13864243/6c8571cb-fd74-466a-9b77-0295089e921f-designrequestfiles-with-PLACELight.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> 228 229 .center-modal { 230 display:flex; 231 justify-content: center; 232 align-items:center; 233 position:fixed; 234 background-color:rgba(0,0,0,0.4); 235 left:0; 236 top:0; 237 right:0; 238 bottom:0; 239 z-index: 300; 240 } 241 242 .page-width-parent{ 243 max-width: 1280px; 244 margin: 0 auto; 245 } 246 247 248 .property-list-map-view { 249 display:flex; 250 flex-wrap:wrap; 251 gap:16px; 252 } 253 .property-list-map-view-parent { 254 background-color: #F9F9F9; 255 padding:16px; 256 height:710px; 257 overflow:scroll; 258 } 259 260 .property-list-list-view { 261 display:flex; 262 flex-wrap:wrap; 263 gap:24px 264 } 265 266 .property-container { 267 268 gap:24px; 269 } 270 271 .property-map-container { 272 flex:1; 273 height:710px; 274 } 275 276 .property-pagination { 277 margin-top: 26px; 278 } 279 280 .collection-saved-listings { 281 margin-bottom: 26px; 282 font-size:16px; 283 color:black; 284 } 285 286 .collection-description { 287 padding: 20px 0 18px 8px; 288 } 289 290 .my-feed-parent { 291 margin-top:32px; 292 padding-top:32px; 293 border-top: solid 1px #C4C4C4; 294 } 295 296 .collection-description-text { 297 font-size:16px; 298 margin:0; 299 color:black; 300 } 301 302 #collections { 303 display:flex; 304 flex-wrap:wrap; 305 gap:40px 24px; 306 } 307
308 #collection-pagination{ 309 margin-top: 55px 310 } 311 312 #add-listing-btn{ 313 margin-bottom: 20px 314 } 315 316 @media only screen and (min-width: 1280px) { 317 .collection-page { 318 padding:48px 48px 48px 120px; 319 } 320 .my-feed-parent { 321 width:90vw; 322 max-width: 100%; 323 overflow: hidden; 324 } 325 .property-list-map-view-parent { 326 width:500px; 327 } 328 .property-container { 329 display:flex; 330 } 331 } 332 333 @media only screen and (max-width:1280px) { 334 .collection-page { 335 padding:60px 16px 16px 16px; 336 } 337 .my-feed-parent { 338 width: unset; 339 } 340 .property-container { 341 display:flex; 342 flex-direction: column-reverse; 343 } 344 .property-list-map-view { 345 flex-wrap:nowrap; 346 overflow:scroll; 347 height:280px; 348 } 349 .property-list-map-view-parent { 350 height:unset; 351 padding:0px; 352 background-color: #FFFFFF 353 } 354 .property-map-container { 355 flex:none; 356 height:446px; 357 } 358 } 359 360 @media only screen and (max-width:768px) { 361 #collections { 362 justify-content: center; 363 } 364 .property-map-container { 365 width: calc(100% + 32px); 366 margin-left: -16px; 367 } 368 .property-list-map-view { 369 height:250px; 370 } 371 } 372 373</style>
373<script> 374 window.addEventListener("load", () => { 375 const key = localStorage.getItem('authorization'); 376 377 if( !key) { 378 $("#sign-up-modal").modal('show'); 379 380 $("#sign-up-modal").on("hidden.bs.modal", function () { 381 location.reload(); 382 }); 383 } 384 else{ 385 386 let myPortalPage = document.getElementById('myportal-page'); 387 myPortalPage.style.display = "block"; 388 389 window.location.hash = "" 390 391 function isGuid(value) { 392 var regex = /[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}/i; 393 var match = regex.exec(value); 394 return match != null; 395 } 396 397 let lastUrlItem = window.location.href.substring(window.location.href.lastIndexOf('/') + 1) 398 let showCollectionByUUID = false 399 400 if (isGuid(lastUrlItem)) { 401 showCollectionByUUID = true 402 } 403 404 405 class logger extends Collections.BaseLogger { 406 log(e) { 407 console.log(e); 408 } 409 } 410 411 412 class Pubsub { 413 static events = {}; 414 constructor() { 415 //this.events = {}; 416 } 417 418 static subscription (eventName, func) { 419 return { 420 subscribe: () => { 421 if (this.events[eventName]) { 422 this.events[eventName].push(func); 423 } else { 424 this.events[eventName] = [func]; 425 } 426 }, 427 unsubscribe: () => { 428 if(this.events[eventName]){ 429 this.events[eventName] = this.events[eventName].filter((subscriber) => subscriber !== func); 430 } 431 } 432 } 433 } 434 435 static publish(eventName, ...args) { 436 const funcs = this.events[eventName]; 437 if (Array.isArray(funcs)) { 438 funcs.forEach((func) => { 439 func.apply(null, args); 440 }); 441 } 442 } 443 } 444 445 class CollectionCard { 446 constructor(collection, count){ 447 448 this.element = document.createElement(`place-collectioncard`); 449 this.collection = collection 450 let _this = this; 451 let menuOpen = false; 452 var images = []; 453 454 for (let i = 0; i < collection?.propertiesImages?.length; i++) { 455 images.push(collection.propertiesImages[i].mainPhoto); 456 } 457 458 this.element.setAttribute("appearance", "regular"); 459 this.element.setAttribute("image", images); 460 this.element.setAttribute("num_properties", collection?.totalListings ?? 0) 461 this.element.setAttribute("title", collection.collectionName); 462 this.element.setAttribute("description", collection.collectionDescription ? collection.collectionDescription : collection.description ? collection.description : ""); 463 this.element.setAttribute("creator", ""); 464 this.element.setAttribute("disable_dropdown", "false"); 465 this.element.setAttribute("style", "height: 254px"); 466 this.element.setAttribute('z_index', count); 467 this.element.setAttribute("show_menu", "false"); 468 this.element.setAttribute("id", collection.collectionUUID); 469 this.element.setAttribute("container_styles", "w-[300px]"); 470 471 const collectionUUID = collection.collectionUUID; 472 473 this.element.addEventListener(`on_menu_item_pressed`, (e) => { 474 let menuItem = e.detail 475 Pubsub.publish('collection_card_menu_item_pressed', {collection,menuItem}); 476 }); 477 478 this.element.addEventListener('on_search_pressed', (e) => { 479 if (e.target.tagName != "svg" && e.target.tagName != "path") { 480 window.open('../../search.php', '_blank'); 481 e.stopPropagation(); 482 } 483 }); 484 485 this.element.addEventListener(`click`, (e) => { 486 if (e.target.tagName != "svg" && e.target.tagName != "path" && !menuOpen) { 487 Pubsub.publish('collection_card_pressed', {collection:_this.collection,e}); 488 e.stopPropagation(); 489 } 490 }); 491 492 this.element.addEventListener(`on_menu_open`, (e) => { 493 if (this.element.getAttribute("title") === "Favorites") { 494 this.element.setAttribute("disable_menu", "true"); 495 } 496 497 menuOpen = e.detail; 498 this.element.setAttribute("show_menu", menuOpen); 499 }); 500 } 501 } 502 503 class CollectionSection { 504 505 506 collectionSection = document.getElementById('collection-section') 507 collections = document.getElementById('collections') 508 509 addCollectionCard = (collection, count) => { 510 const collectionCard = new CollectionCard(collection, count); 511 512 513 514 515 this.collections.append(collectionCard.element); 516 517 } 518 519 show = () => { 520 this.collectionSection.style.display = 'block' 521 } 522 523 hide = () => { 524 this.collectionSection.style.display = 'none' 525 } 526 } 527 528 class PropertyCard { 529 constructor(collectionUUID,property){ 530 531 let _this = this; 532 this.element = document.createElement(`place-propertycard`); 533 let menuOpen = false;
534 this.property = property; 535 536 this.element.setAttribute("id", property.blossorId) 537 this.element.setAttribute("display_menu", "true"); 538 this.element.setAttribute("show_menu", "false"); 539 this.element.setAttribute("items", '[{"icon":"share-2","text":"Share Property"},{"icon":"layers","text":"Copy to Collection"},{"icon":"trash","text":"Remove from Collection"}]'); 540 541 this.element.setAttribute('appearance','small') 542 this.element.setAttribute('layout_width', '300') 543 this.element.setAttribute('display_tag', 'true') 544 this.element.setAttribute('display_favorite', 'true') 545 this.element.setAttribute('mls',`{ 546 "status":"${property.statusText}", 547 "favorite":"true", 548 "image":[{"uri":"${property?.photos[0]?.url}"}], 549 "price":"${property?.price}", 550 "address":"${property?.address?.street}", 551 "state":"${property?.address?.state}", 552 "city":"${property?.address?.city}", 553 "postalCode":"${property?.address?.zip}", 554 "beds":"${property?.bedrooms}", 555 "baths":"${property?.totalBaths}", 556 "sqft":"${property?.sqFeet}" 557 }`) 558 this.element.setAttribute('on_hover', 'true') 559 560 this.element.addEventListener('mouseenter', (e) => { 561 Pubsub.publish('property_card_mouseenter', property); 562 }) 563 564 this.element.addEventListener('mouseleave', (e) => { 565 Pubsub.publish('property_card_mouseleave', property); 566 }) 567 568 this.element.addEventListener(`on_menu_item_pressed`, (e) => { 569 let menuItem = e.detail 570 let propertyCollectionUUID = property.propertyCollectionUUID 571 let url = this.getPropertyUrl(this.property); 572 property.searchUrl = url; 573 Pubsub.publish('property_card_menu_item_pressed', {property,collectionUUID,propertyCollectionUUID,menuItem, url}); 574 }); 575 576 this.element.addEventListener(`on_menu_open`, (e) => { 577 menuOpen = e.detail; 578 this.element.setAttribute("show_menu", menuOpen); 579 }); 580 581 this.element.addEventListener('click', (e) => { 582 if (e.target.tagName != "svg" && e.target.tagName != "path" && !menuOpen) { 583 let state = _this.property.address.state; 584 let city = _this.slugify(_this.property.address.city); 585 let zip = _this.property.address.zip 586 let address = _this.slugify(_this.property.address.street); 587 let blossorId = _this.property.blossorId; 588 let url = this.getPropertyUrl(property); 589 window.open(`../../${url}`, '_blank'); 590 } 591 }); 592 593 this.element.addEventListener('on_favorite_press', (e) => { 594 let propertyCollectionUUID = property.propertyCollectionUUID; 595 Pubsub.publish('delete_property_modal_pressed', {collectionUUID, propertyCollectionUUID}); 596 }); 597 598 } 599 600 getPropertyUrl = (property) => { 601 let state = property.address.state; 602 let city = this.slugify(property.address.city); 603 let zip = property.address.zip 604 let address = this.slugify(property.address.street); 605 let blossorId = property.blossorId; 606 return `homes-for-sale/${state}/${city}/${zip}/${address}/bid-${blossorId}`; 607 } 608 609 slugify(text) { 610 // replace non letter or digits by - 611 text = text.replace(/[^\pL\d]+~u/g, '_'); 612 // transliterate 613 text = text.normalize('NFKD').replace(/[\u0300-\u036F]/g,'') 614 // remove unwanted characters 615 text = text.replace(/[^_\w]+/g, '_'); 616 // trim 617 text = text.trim(); 618 // remove duplicate - 619 text = text.replace(/_+/g, '-'); 620 // lowercase 621 text = text.toLowerCase(); 622 if (!text) { 623 return 'n-a'; 624 } 625 return text 626 } 627 } 628 629 let dateNow = new Date(); 630 dateNow.setDate(dateNow.getDate()-7); 631 dateNow.setHours(dateNow.getHours()); 632 dateNow.setMinutes(dateNow.getMinutes()); 633 dateNow.setSeconds(dateNow.getSeconds()); 634 const sevenDaysAgo = dateNow.getTime(); 635 636 class PropertySection { 637 propertySection = document.getElementById('property-section') 638 listIcon = document.getElementById('property-list-icon') 639 mapIcon = document.getElementById('property-map-icon') 640 propertyHeader = document.getElementById('property-header') 641 propertyList = document.getElementById("property-list") 642 propertyListParent = document.getElementById("property-list-parent") 643 propertyMap = document.getElementById('property-map') 644 selectedView = 'map' 645 646 collectionProperties = [] 647 648 properties = [] 649 650 651 constructor() { 652 this.listIcon.addEventListener('click', () => { 653 this.setView('list') 654 }) 655 656 this.mapIcon.addEventListener('click', () => { 657 this.setView('map') 658 }) 659 } 660 661 show = (collectionUUID, collectionProperties) => { 662 this.propertySection.style.display = 'block' 663 this.collectionProperties = collectionProperties 664 this.collectionUUID = collectionUUID 665 666 this.propertyList.innerHTML = '' 667 count = 100; 668 669 this.collectionProperties?.data?.properties?.forEach((property) => { 670 count-- 671 this.addPropertyCard(property,collectionUUID, count) 672 }); 673 } 674 675 hide = () => { 676 this.propertySection.style.display = 'none' 677 } 678 679 setPropertyCardWidth = () => { 680 let width; 681 let imageHeight; 682 let windowWidth = window.innerWidth 683 if(this.selectedView == 'map') { 684 if(windowWidth > 1279) { 685 width = `220`; 686 imageHeight = `154`; 687 } else if(windowWidth > 768) { 688 width = `325`; 689 imageHeight = `184`; 690 } else{ 691 width = `244`; 692 imageHeight = `154`; 693 } 694 } 695 else { 696 if(windowWidth > 1440 ){ 697 width = `300`; 698 imageHeight = `184`; 699 } 700 else if(windowWidth > 1279) { 701 width = `260`; 702 imageHeight = `152`; 703 } else if(windowWidth > 768) { 704 width = `218`; 705 imageHeight = `152`; 706 } else{ 707 width = `288`; 708 imageHeight = `184`; 709 } 710 } 711 712 let propertyCards = document.querySelectorAll('place-propertycard') 713 propertyCards.forEach((propertyCard) => { 714 propertyCard.setAttribute('layout_width', width) 715 propertyCard.setAttribute('image_height', imageHeight) 716 }) 717 } 718
719 setView = (view) => { 720 this.selectedView = view 721 if (view == 'list') { 722 this.listIcon.setAttribute('stroke', 'black') 723 this.mapIcon.setAttribute('stroke', 'gray') 724 725 this.propertyMap.style.display = 'none' 726 this.propertyList.classList.add('property-list-list-view') 727 this.propertyList.classList.remove('property-list-map-view') 728 this.propertyListParent.classList.remove('property-list-map-view-parent') 729 730 Pubsub.publish('property_section_show_list_view', this.collectionProperties?.data?.properties); 731 } else { 732 this.listIcon.setAttribute('stroke', 'gray') 733 this.mapIcon.setAttribute('stroke', 'black') 734 735 this.propertyMap.style.display = 'block' 736 this.propertyList.classList.remove('property-list-list-view') 737 this.propertyList.classList.add('property-list-map-view') 738 this.propertyListParent.classList.add('property-list-map-view-parent') 739 740 Pubsub.publish('property_section_show_map_view', this.collectionProperties?.data?.properties); 741 } 742 743 this.setPropertyCardWidth(); 744 } 745 746 scrollIntoView = (id) => { 747 let propertyCard = document.getElementById(id); 748 propertyCard.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' }) 749 } 750 751 addPropertyCard = (property, collectionUUID, count) => { 752 753 var propertyCardWrapperElement = document.createElement(`div`) 754 propertyCardWrapperElement.setAttribute('style', `z-index:${count}`) 755 propertyCardWrapperElement.setAttribute('class', 'property-card-wrapper') 756 propertyCardWrapperElement.setAttribute("id", property.propertyCollectionUUID); 757 758 const propertyCard = new PropertyCard(collectionUUID,property); 759 var propertyCardElement = propertyCard.element; 760 761 propertyCardWrapperElement.append(propertyCardElement) 762 763 this.propertyList.append(propertyCardWrapperElement) 764 765 } 766 767 } 768 769 770 class PageSubHeader{ 771 constructor() { 772 773 this.element = document.querySelector('place-pagesubheader') 774 775 this.element.addEventListener('button_on_press', (e) => { 776 Pubsub.publish('create_new_collection_pressed', e) 777 }) 778 779 this.element.addEventListener('top_header_on_press', (e) => { 780 Pubsub.publish('top_header_back_pressed', e) 781 }) 782 783 this.element.addEventListener('on_menu_item_pressed', (e) => { 784 Pubsub.publish('top_header_menu_item_pressed', e.detail) 785 }) 786 787 this.element.addEventListener('secondary_button_on_press', (e) => { 788 window.open('../../search.php', '_blank') 789 }) 790 } 791 792 setTitle(title) { 793 this.element.setAttribute('title', title) 794 } 795 796 setTopHeaderTitle(title){ 797 this.element.setAttribute('top_header_title', title) 798 } 799 800 showTopHeader(){ 801 this.element.setAttribute('show_top_header', true) 802 } 803 804 hideTopHeader(){ 805 this.element.setAttribute('show_top_header', false) 806 } 807 808 showPrimaryButton() { 809 this.element.setAttribute('show_button', true) 810 } 811 812 hidePrimaryButton() { 813 this.element.setAttribute('show_button', false) 814 } 815 816 showSecondaryButton(){ 817 this.element.setAttribute('show_secondary_button', true) 818 } 819 820 hideSecondaryButton(){ 821 this.element.setAttribute('show_secondary_button', false) 822 } 823 824 showMenuButton() { 825 this.element.setAttribute('show_menu_button', true) 826 } 827 828 hideMenuButton() { 829 this.element.setAttribute('show_menu_button', false) 830 } 831 } 832 833 class CollectionModal { 834 835 constructor() { 836 837 let _this = this; 838 this.element = document.querySelector('place-collectionpopup'); 839 this.collectionUUID = 0; 840 841 this.element.addEventListener("on_close_press", (e) => { 842 _this.hide(); 843 }); 844 845 this.element.addEventListener("on_save_press", (e) => { 846 this.showError(false); 847 e.detail.collectionUUID = this.collectionUUID 848 e.detail.type = this.isEditingCollection ? 'edit' : 'save' 849 Pubsub.publish('on_new_collection_saved', e.detail); 850 }); 851 852 } 853 854 setName(name) { 855 this.element.setAttribute('name_value', name) 856 } 857 858 setDescription(description) { 859 this.element.setAttribute('description_value', description ? description : "") 860 } 861 862 showError(error) { 863 this.element.setAttribute('show_error', error) 864 } 865 866 show(collectionUUID, isEditingCollection) { 867 this.isEditingCollection = isEditingCollection; 868 if(collectionUUID){ 869 this.collectionUUID = collectionUUID; 870 } 871 this.element.setAttribute('style', 'display:flex') 872 } 873 874 hide() { 875 this.element.setAttribute('style', 'display:none'); 876 877 this.showError(false) 878 879 // terrible hack.. only way i could get it to respond to prop changes 880 // to clear the input fields after closing the modal 881 this.setName('none') 882 this.setDescription('none') 883 setTimeout(() => { 884 this.setName('') 885 this.setDescription('') 886 }, 100); 887 } 888 } 889 890 class CollectionCreatedModal { 891 constructor() { 892 893 894 this.collection = "" 895 this.element = document.getElementById('collection-created-modal'); 896 let _this = this; 897 898 this.element.addEventListener("on_primary_press", (e) => { 899 this.hide(); 900 window.location.href = '../../search.php' 901 }); 902 903 this.element.addEventListener("on_tertiary_press", (e) => { 904 _this.hide(); 905 Pubsub.publish('collection_created_modal_view_collection_pressed', _this.collection); 906 }); 907 908 this.element.addEventListener("on_close_press", (e) => { 909 _this.hide(); 910 }); 911 912 this.element.setAttribute("stacked_buttons", true) 913 this.element.setAttribute("primary_button_text", "Search Listings") 914 this.element.setAttribute("tertiary_button_text", "View Collection") 915 } 916 917 show(collection) { 918 if(collection){ 919 this.collection = collection; 920 } 921 this.element.setAttribute('style', 'display:flex') 922 } 923 924 hide() { 925 this.element.setAttribute('style', 'display:none'); 926 } 927 } 928 929 class EditCollectionModal { 930 constructor() { 931 932 933 this.collection = "" 934 this.element = document.getElementById('edit-collection-modal'); 935 let _this = this; 936 937 this.element.addEventListener("on_primary_press", (e) => { 938 _this.hide(); 939 940 }); 941 942 943 944 this.element.addEventListener("on_close_press", (e) => { 945 _this.hide(); 946 }); 947 } 948 949 show() { 950 951 this.element.setAttribute('style', 'display:flex') 952 } 953 954 hide() { 955 this.element.setAttribute('style', 'display:none'); 956 } 957 } 958 959 class DeleteCollectionModal { 960 constructor() { 961 962 963 this.collection = "" 964 this.element = document.getElementById('delete-collection-modal'); 965 let _this = this; 966 967 this.element.addEventListener("on_primary_press", (e) => { 968 _this.hide(); 969 Pubsub.publish('delete_collection_modal_delete_pressed', _this.collection); 970 }); 971 972 this.element.addEventListener("on_tertiary_press", (e) => { 973 this.hide(); 974 }); 975 976 this.element.addEventListener("on_close_press", (e) => { 977 _this.hide(); 978 }); 979 } 980 981 show(collection) { 982 if(collection){ 983 this.collection = collection; 984 } 985 this.element.setAttribute('style', 'display:flex') 986 } 987 988 hide() { 989 this.element.setAttribute('style', 'display:none'); 990 } 991 } 992 993 class ShareSavedPropertyModal { 994 constructor() { 995 let _this = this; 996 this.savedProperty = {} 997 this.element = document.getElementById('share-saved-property-modal'); 998 999 this.element.addEventListener("on_primary_press", (e) => { 1000 1001 1002 1003 navigator.clipboard.writeText(this.link) 1004 _this.hide(); 1005 Pubsub.publish('share_saved_property_modal_share_pressed'); 1006 1007 }); 1008 1009 this.element.addEventListener("on_close_press", (e) => { 1010 _this.hide(); 1011 }); 1012 } 1013 1014 show = (savedProperty) => { 1015 1016 1017 this.savedProperty = savedProperty; 1018 1019 this.link = document.location.origin + "/" + this.savedProperty.searchUrl 1020 this.element.setAttribute('share_link_text', this.link) 1021 this.element.setAttribute('style', 'display:flex') 1022 } 1023 1024 hide = () => { 1025 this.element.setAttribute('style', 'display:none'); 1026 } 1027 } 1028 1029 class DeletePropertyModal { 1030 constructor() { 1031 1032 1033 this.collectionUUID = "" 1034 this.propertyCollectionUUID = "" 1035 this.element = document.getElementById('delete-property-modal'); 1036 let _this = this; 1037 1038 this.element.addEventListener("on_primary_press", (e) => { 1039 _this.hide(); 1040 Pubsub.publish('delete_property_modal_delete_pressed', {"collectionUUID":_this.collectionUUID, "propertyCollectionUUID":_this.propertyCollectionUUID}); 1041 }); 1042 1043 this.element.addEventListener("on_tertiary_press", (e) => { 1044 this.hide(); 1045 }); 1046 1047 this.element.addEventListener("on_close_press", (e) => { 1048 _this.hide(); 1049 }); 1050 } 1051 1052 show(collectionUUID, propertyCollectionUUID) { 1053 if(collectionUUID){ 1054 this.collectionUUID = collectionUUID; 1055 } 1056 if(propertyCollectionUUID){ 1057 this.propertyCollectionUUID = propertyCollectionUUID; 1058 } 1059 this.element.setAttribute('style', 'display:flex') 1060 } 1061 1062 hide() { 1063 this.element.setAttribute('style', 'display:none'); 1064 } 1065 } 1066 1067 class CopyPropertyToCollectionModal { 1068 constructor(){ 1069 1070 this.element = document.querySelector('place-copycollectionmodal'); 1071 this.collections = []; 1072 this.property = {} 1073 this.isVisible = false;
1074 1075 1076 1077 this.element.addEventListener('close_button', (e) => { 1078 this.hide(); 1079 }); 1080 1081 this.element.addEventListener('cancel_button', (e) => { 1082 this.hide(); 1083 }); 1084 1085 this.element.addEventListener('on_save', (e) => { 1086 Pubsub.publish('copy_property_to_collection_modal_save_pressed', {'collectionUUID':e.detail, 'property':this.property}); 1087 }); 1088 1089 this.element.addEventListener('set_selected_collection', (e) => { 1090 console.log('set_selected_collection', e) 1091 }); 1092 1093 this.element.addEventListener('on_link_press', (e) => { 1094 Pubsub.publish('show_new_collection_modal'); 1095 }); 1096 1097 } 1098 1099 getCollectionData(){ 1100 return JSON.parse(this.element.getAttribute("collections")); 1101 } 1102 1103 setCollectionData(collections){ 1104 this.element.setAttribute('collections', JSON.stringify(collections)) 1105 } 1106 1107 getCollectionList(collections, currentCollectionName) { 1108 let collectionList = []; 1109 collections.forEach(collection => { 1110 if (currentCollectionName && (collection.collectionName == currentCollectionName)) return; 1111 collectionList.push({ 1112 collection_title: collection.collectionName, 1113 id: collection.collectionUUID, 1114 propertiesImages: collection?.propertiesImages?.length > 0 ? collection?.propertiesImages : [], 1115 }) 1116 }); 1117 this.setCollectionData(collectionList); 1118 1119 } 1120 1121 setIsAddingToCollection(isAddingToCollection){ 1122 this.element.setAttribute('is_add_to_collection', isAddingToCollection); 1123 } 1124 1125 show(property) { 1126 1127 if(property){ 1128 this.property = property; 1129 } 1130 1131 this.isVisible = true; 1132 1133 let mls = { 1134 status: property?.status || property?.standardStatus || "", 1135 image: this.getPropertyImageUrl(property), 1136 price: property?.price || "0", 1137 address: ( typeof property?.address === "string") ? property?.address : (property?.address?.street || property?.streetAddress || ""), 1138 state: property?.state || property?.address?.state || "", 1139 city: property?.city || property?.address?.city || "", 1140 postal_code: property?.postal_code || property?.address?.zip || "", 1141 beds: property?.beds || property?.bedrooms || 0, 1142 baths: property?.baths || property?.fullBaths || property?.bathsTotalDecimal || 0, 1143 sqft: property?.sqft || property?.squareFeet || property?.sqFeet || 0, 1144 creator: property?.creator || "", 1145 } 1146 1147 this.element.setAttribute('mls', JSON.stringify(mls)) 1148 this.element.setAttribute('image_url',mls?.image || "") 1149 this.element.setAttribute('style', 'display:flex') 1150 } 1151 1152 getPropertyImageUrl(property){ 1153 // property?.image[0]?.uri || property?.photos[0]?.url || "", 1154 1155 if(property.image && property.image.length > 0){ 1156 return property.image[0].uri 1157 } else if (property.photos && property.photos.length > 0){ 1158 return property.photos[0].url 1159 } else { 1160 return "" 1161 } 1162 } 1163 1164 hide() { 1165 this.isVisible = false;
1166 this.element.setAttribute('style', 'display:none'); 1167 } 1168 } 1169 1170 class CollectionPaging { 1171 constructor(collectionsPerPage){ 1172 1173 1174 this.element = document.getElementById('collection-pagination'); 1175 this.collectionsPerPage = collectionsPerPage; 1176 1177 this.element.addEventListener('page_changed', (e) => { 1178 Pubsub.publish('collection_page_changed', e.detail); 1179 }); 1180 } 1181 1182 setPageCount(pageCount){ 1183 this.element.setAttribute('page_count', pageCount); 1184 } 1185 1186 show() { 1187 this.element.setAttribute('style', 'display:flex') 1188 } 1189 1190 hide() { 1191 this.element.setAttribute('style', 'display:none') 1192 } 1193 } 1194 1195 class PropertyPaging { 1196 constructor(propertiesPerPage){ 1197 1198 1199 this.element = document.getElementById('property-pagination'); 1200 this.propertiesPerPage = propertiesPerPage; 1201 1202 this.element.addEventListener('page_changed', (e) => { 1203 Pubsub.publish('property_page_changed', e.detail); 1204 }); 1205 } 1206 1207 setPageCount(pageCount){ 1208 this.element.setAttribute('page_count', pageCount); 1209 } 1210 1211 setCurrentPage(currentPage){ 1212 this.element.setAttribute('current_page', currentPage); 1213 } 1214 1215 show() { 1216 this.element.setAttribute('style', 'display:flex') 1217 } 1218 1219 hide() { 1220 this.element.setAttribute('style', 'display:none') 1221 } 1222 } 1223 1224 class NewCollectionBlock { 1225 constructor(){ 1226 1227 this.element = document.getElementById('new-collection-block'); 1228 1229 this.element.addEventListener('on_main_press', (e) => { 1230 Pubsub.publish('new_collection_block_create_collection_pressed', e.detail); 1231 }); 1232 } 1233 show(collectionUUID, propertyCollectionUUID) { 1234 this.element.setAttribute('style', 'display:flex') 1235 } 1236 1237 hide() { 1238 this.element.setAttribute('style', 'display:none'); 1239 } 1240 } 1241 1242 class AddListingsBlock { 1243 constructor() { 1244 1245 this.element = document.getElementById('add-listings-block'); 1246 1247 this.element.addEventListener('on_main_press', (e) => { 1248 window.open('../../search.php', '_blank') 1249 }); 1250 1251 this.element.addEventListener("on_tertiary_press", (e) => { 1252 1253 }); 1254 } 1255 1256 show() { 1257 this.element.setAttribute('style', 'display:flex') 1258 } 1259 1260 hide() { 1261 this.element.setAttribute('style', 'display:none'); 1262 } 1263 } 1264 1265 class MyFeed { 1266 constructor(blueroofMiddlewareApi, collectionsService) { 1267 this.blueroofMiddlewareApi = blueroofMiddlewareApi; 1268 this.collectionsService = collectionsService; 1269 this.element = document.querySelector('place-myfeedblock'); 1270 1271 this.element.addEventListener('on_menu_open', (e) => { 1272 this.element.setAttribute('show_menu', e.detail.e); 1273 this.element.setAttribute('show_menu_index', e.detail.index); 1274 }); 1275 1276 this.element.addEventListener('on_view_all_pressed', (e) => { 1277 window.open('../../search.php', '_blank'); 1278 }); 1279 1280 this.element.addEventListener('on_add_collection', (e) => { 1281 1282 let property = e.detail; 1283 Pubsub.publish('my_feed_add_collection_pressed', {property}); 1284 1285 }); 1286 1287 this.element.addEventListener('on_share_pressed', (e) => { 1288 1289 let property = e.detail 1290 1291 let url = this.getPropertyUrl(property); 1292 property.searchUrl = url; 1293 1294 Pubsub.publish('my_feed_share_pressed', {property}); 1295 }); 1296 1297 this.element.addEventListener('on_favorite_pressed', (e) => { 1298 let property = e.detail.property; 1299 let isAddingFavorite = e.detail.isAddingFavorite; 1300 1301 if(isAddingFavorite){ 1302 Pubsub.publish('my_feed_on_favorite_pressed', {property}); 1303 } 1304 else{ 1305 Pubsub.publish('my_feed_on_unfavorite_pressed', {property}); 1306 } 1307 }); 1308 1309 this.element.addEventListener('on_property_pressed', (e) => { 1310 let property = e.detail 1311 1312 let url = this.getPropertyUrl(property); 1313 property.searchUrl = url; 1314 window.open('../../' + url, '_blank'); 1315 }); 1316 1317 1318 this.blueroofMiddlewareApi.getMyFeed().then((data) => { 1319 1320 let myFeedBlossorIds = data.map(property => property.blossorId); 1321 1322 1323 this.collectionsService.checkIfInCollection(myFeedBlossorIds).then((propertiesInCollections) => { 1324 1325 let feed = [] 1326 data.forEach((item) => { 1327 feed.push({ 1328 image: [ 1329 { 1330 title: "", 1331 id: 0, 1332 uri: item?.photos[0].url, 1333 }, 1334 ], 1335 price: item?.price, 1336 favorite: propertiesInCollections?.data[item?.blossorId] != null || false, 1337 address: item?.streetAddress, 1338 city: item?.city, 1339 state: item?.state, 1340 postal_code: item?.postalCode, 1341 beds: item?.bedrooms, 1342 status: item?.standardStatus, 1343 baths: item?.bathsTotalDecimal, 1344 sqft: item?.squareFeet, 1345 creator: "", 1346 mls_price_history: item?.history[item.history.length-1]?.price, 1347 blossorId: item?.blossorId, 1348 open_house : item?.openhouses?.length > 0 ? true : false, 1349 open_house_date : item?.openhouses[0]?.startDate, 1350 open_house_end_time : item?.openhouses[0]?.endDate, 1351 property_created_at : item?.listDate, 1352 lastStatusChangeDate : item?.lastStatusChangeDate, 1353 }) 1354 }) 1355 1356 if(feed && feed?.length > 0){ 1357 this.show(); 1358 this.element.setAttribute('mls_data', JSON.stringify(feed)); 1359 } 1360 }); 1361 }); 1362 1363 } 1364 1365 getPropertyUrl = (property) => { 1366 let state = property.state; 1367 let city = this.slugify(property.city); 1368 let zip = property.postal_code 1369 let address = this.slugify(property.address); 1370 let blossorId = property.blossorId; 1371 return `homes-for-sale/${state}/${city}/${zip}/${address}/bid-${blossorId}`; 1372 } 1373 1374 slugify(text) { 1375 // replace non letter or digits by - 1376 text = text.replace(/[^\pL\d]+~u/g, '_'); 1377 // transliterate 1378 text = text.normalize('NFKD').replace(/[\u0300-\u036F]/g,'') 1379 // remove unwanted characters 1380 text = text.replace(/[^_\w]+/g, '_'); 1381 // trim 1382 text = text.trim(); 1383 // remove duplicate - 1384 text = text.replace(/_+/g, '-'); 1385 // lowercase 1386 text = text.toLowerCase(); 1387 if (!text) { 1388 return 'n-a'; 1389 } 1390 return text 1391 } 1392 1393 getMlsData = () => { 1394 return JSON.parse(this.element.getAttribute('mls_data')); 1395 } 1396 1397 setMlsData = (data) => { 1398 this.element.setAttribute('mls_data', JSON.stringify(data)); 1399 } 1400 1401 show() { 1402 this.element.setAttribute('style', 'display:flex') 1403 } 1404 1405 hide() { 1406 this.element.setAttribute('style', 'display:none') 1407 } 1408 } 1409 1410 class BlueroofMiddlewareApi { 1411 constructor() { 1412 this.baseUrl = "https://brivity-home-middleware.production.brivity.com"; 1413 this.apiKey = localStorage.getItem('authorization'); 1414 } 1415 1416 getMyFeed = async () => { 1417 const response = await fetch(`${this.baseUrl}/listings/voltron`, { 1418 method: 'POST', 1419 headers: { 1420 'Content-Type': 'application/json', 1421 'Authorization': `${this.apiKey}` 1422 }, 1423 body: JSON.stringify([]) 1424 }); 1425 1426 const data = await response.json(); 1427 return data; 1428 } 1429 1430 getLeadBasicInfo = async () => { 1431 const response = await fetch(`${this.baseUrl}/blueroofleads/basicinfo`, { 1432 method: 'GET', 1433 headers: { 1434 'Content-Type': 'application/json', 1435 'Authorization': `${this.apiKey}` 1436 }, 1437 1438 }); 1439 1440 const data = await response.json(); 1441 return data; 1442 } 1443 1444 getAgentProfile = async (brivityUserId) => { 1445 const response = await fetch(`${this.baseUrl}/blueroofagents/profile`, { 1446 method: 'POST', 1447 headers: { 1448 'Content-Type': 'application/json', 1449 'Authorization': `${this.apiKey}` 1450 }, 1451 body: `{"brivityUserId": ${brivityUserId}}` 1452 1453 }); 1454 1455 const data = await response.json(); 1456 return data; 1457 } 1458 1459 } 1460 1461 class Map { 1462 constructor(){ 1463 this.element = document.querySelector('place-map'); 1464 this.properties = []; 1465 1466 this.element.addEventListener('on_marker_clicked', (e) => { 1467 Pubsub.publish('map_marker_clicked', e.detail.id) 1468 }); 1469 } 1470 1471 setMarkers = (properties) => { 1472 let markers = []; 1473 let color = 'black' 1474 1475 let dateNow = new Date(); 1476 dateNow.setDate(dateNow.getDate()-7); 1477 dateNow.setHours(dateNow.getHours()); 1478 dateNow.setMinutes(dateNow.getMinutes()); 1479 dateNow.setSeconds(dateNow.getSeconds()); 1480 const sevenDaysAgo = dateNow.getTime(); 1481 1482 this.properties = properties; 1483 properties?.forEach(property => { 1484 1485 if(property.statusText == 'Active'){ 1486 color = '#1FA6E8' 1487 }else if(property.statusText == 'Pending'){ 1488 color = '#FFC82C' 1489 }else if(property.statusText == 'Sold'){ 1490 color = '#FF7343' 1491 } 1492 1493 let listDate = new Date(property.listDate); 1494 1495 1496 if(listDate.getTime() > sevenDaysAgo){ 1497 color = '#24D0BC' 1498 } 1499 1500 markers.push({ 1501 id: `${property.blossorId}`, 1502 location: property.location, 1503 price: property.price, 1504 color : color 1505 }) 1506 }); 1507 1508 this.element.setAttribute('markers', JSON.stringify(markers)); 1509 } 1510 1511 setSelectedMarker = (property) => { 1512 let markerIndex = this.properties.findIndex((p) => p.blossorId == property.blossorId) 1513 if(markerIndex > -1){ 1514 this.element.setAttribute('selected_property_index', markerIndex); 1515 } 1516 } 1517 1518 clearSelectedMarker = () => { 1519 this.element.setAttribute('selected_property_index', -1); 1520 } 1521 1522 } 1523 1524 class SavedListings { 1525 constructor(){ 1526 this.element = document.getElementById('collection-saved-listings'); 1527 } 1528 1529 setCount(count) { 1530 this.element.innerText = `Saved Listings (${count})`; 1531 } 1532 1533 hide() { 1534 this.element.style.display = `none`; 1535 } 1536 show() { 1537 this.element.style.display = `block`; 1538 } 1539 } 1540 1541 class AddListingBtn { 1542 constructor(){ 1543 this.element = document.getElementById('add-listing-btn'); 1544 this.element.setAttribute('button_style', JSON.stringify({paddingLeft: '0px'})); 1545 this.element.addEventListener('on_press', (e) => { 1546 window.open('../../search.php', '_blank') 1547 }) 1548 } 1549 1550 hide() { 1551 this.element.style.display = `none`; 1552 } 1553 show() { 1554 this.element.style.display = `block`; 1555 } 1556 } 1557 1558 class Page { 1559 constructor(blueroofMiddlewareApi) { 1560 this.selectedCollection = {}; 1561 this.inPropertyView = false;
1562 this.lead = {} 1563 this.agent = {} 1564 this.isInMapView = false; 1565 this.isInListView = true; 1566 1567 this.authorizationData = JSON.parse(atob(blueroofMiddlewareApi.apiKey.split('.')[1])); 1568 this.is_blueroof_person = this.authorizationData?.is_blueroof_person; 1569 1570 1571 } 1572 1573 setSelectedCollection(collection) { 1574 this.selectedCollection = collection; 1575 } 1576 1577 setInPropertyView(inPropertyView) { 1578 this.inPropertyView = inPropertyView; 1579 } 1580 } 1581 1582 1583 class messagingEmitter extends Messaging.BaseEmitter { 1584 1585 newMessage(message) { 1586 Pubsub.publish('messaging_emitter_new_message', message); 1587 } 1588 } 1589 1590 1591 1592 (async () => { 1593 1594 const blueroofMiddlewareApi = new BlueroofMiddlewareApi(); 1595 const page = new Page(blueroofMiddlewareApi); 1596 1597 let url = 'https://messaging.brivity.com' 1598 const messaging = new Messaging.Service(url, blueroofMiddlewareApi.apiKey, new messagingEmitter()); 1599 1600 let lead = await blueroofMiddlewareApi.getLeadBasicInfo(); 1601 let agent = await blueroofMiddlewareApi.getAgentProfile(lead.data?.brivity_agent_id); 1602 1603 page.lead = lead.data; 1604 page.agent = agent.data; 1605 1606 const collectionsService = new Collections.Service(window?.globalSiteVariables?.options?.apis?.collections?.url ?? '',blueroofMiddlewareApi.apiKey, "sitebuilder", new logger()); 1607 1608 1609 const menu = new Menu(page?.is_blueroof_person || false, page?.agent, blueroofMiddlewareApi.baseUrl, blueroofMiddlewareApi.apiKey); 1610 const collectionSection = new CollectionSection() 1611 const propertySection = new PropertySection() 1612 const collectionModal = new CollectionModal(); 1613 const collectionCreatedModal = new CollectionCreatedModal(); 1614 const deleteCollectionModal = new DeleteCollectionModal();
1615 const editCollectionModal = new EditCollectionModal(); 1616 const shareSavedPropertyModal = new ShareSavedPropertyModal(); 1617 const deletePropertyModal = new DeletePropertyModal(); 1618 const copyPropertyToCollectionModal = new CopyPropertyToCollectionModal(); 1619 const pageSubHeader = new PageSubHeader(); 1620 const collectionPaging = new CollectionPaging(8) 1621 const propertyPaging = new PropertyPaging(8) 1622 const newCollectionBlock = new NewCollectionBlock(); 1623 const addListingsBlock = new AddListingsBlock(); 1624 const myFeed = new MyFeed(blueroofMiddlewareApi, collectionsService); 1625 const map = new Map(); 1626 const savedListings = new SavedListings(); 1627 const addListingBtn = new AddListingBtn(); 1628 1629 collectionPaging.hide(); 1630 propertySection.hide(); 1631 1632 let collections = []; 1633 let extraCollections = 0; 1634 let createCopyCollection = false; 1635 1636 if(!showCollectionByUUID){ 1637 const collectionDescription = document.getElementById("collectionDescription"); 1638 1639 collectionsService.getCollections(0, collectionPaging.collectionsPerPage).then((e) => { 1640 1641 extraCollections = e?.data?.totalCollections 1642 1643 if(e.data.TotalPages > 1) { 1644 collectionPaging.show() 1645 collectionPaging.setPageCount(e.data.TotalPages); 1646 } else { 1647 collectionPaging.setPageCount(1); 1648 } 1649 1650 1651 if(e?.data?.Items){ 1652 collections = e.data.Items; 1653 count = 100; 1654 e.data.Items.forEach((collection) => { 1655 count-- 1656 1657 collectionSection.addCollectionCard(collection, count) 1658 }); 1659 } 1660 1661 copyPropertyToCollectionModal.getCollectionList(collections) 1662 1663 if(collections.length == 0){ 1664 newCollectionBlock.show(); 1665 } 1666 1667 }).catch((e) => { 1668 if(collections.length == 0){ 1669 newCollectionBlock.show(); 1670 } 1671 }); 1672 } 1673 else{ 1674 collectionsService.getCollections(0, collectionPaging.collectionsPerPage).then((e) => { 1675 1676 if(e?.data?.Items){ 1677 collections = e.data.Items; 1678 } 1679 1680 }); 1681 } 1682 1683 Pubsub.subscription('property_card_mouseenter', (property) => { 1684 1685 document.querySelectorAll('place-propertycard').forEach((propertyCard) => { 1686 propertyCard.setAttribute('show_border', false); 1687 }) 1688 1689 if(page.isInMapView){ 1690 map.setSelectedMarker(property) 1691 } 1692 }).subscribe(); 1693 1694 Pubsub.subscription('property_card_mouseleave', () => { 1695 if(page.isInMapView){ 1696 map.clearSelectedMarker() 1697 } 1698 }).subscribe(); 1699 1700 Pubsub.subscription('messaging_emitter_new_message', (message) => { 1701 toast.show('New message from ' + message.createdByAlias) 1702 }).subscribe(); 1703 1704 Pubsub.subscription('property_section_show_map_view', (properties) => { 1705 map.setMarkers(properties); 1706 page.isInMapView = true; 1707 page.isInListView = false; 1708 1709 document.querySelectorAll('place-propertycard').forEach((propertyCard) => { 1710 propertyCard.setAttribute('show_border_on_hover', true); 1711 }) 1712 }).subscribe(); 1713 1714 Pubsub.subscription('property_section_show_list_view', (properties) => { 1715 page.isInMapView = false;
1716 page.isInListView = true; 1717 1718 document.querySelectorAll('place-propertycard').forEach((propertyCard) => { 1719 propertyCard.setAttribute('show_border_on_hover', false); 1720 }) 1721 1722 }).subscribe(); 1723 1724 Pubsub.subscription('property_page_changed', (page) => { 1725 collectionsService.getCollectionProperties(propertySection.collectionUUID, page, propertyPaging.propertiesPerPage).then((collectionProperties) => { 1726 map.setMarkers(collectionProperties?.data?.properties); 1727 savedListings.setCount(collectionProperties?.data?.totalListings || 0); 1728 propertySection.show(propertySection.collectionUUID,collectionProperties) 1729 propertySection.setPropertyCardWidth(); 1730 propertyPaging.setCurrentPage(page); 1731 }); 1732 }).subscribe(); 1733 1734 Pubsub.subscription("top_header_menu_item_pressed", (menuItemPressed) => { 1735 1736 if(menuItemPressed == 'Edit Collection'){ 1737 collectionModal.setName(page.selectedCollection.collectionName); 1738 collectionModal.setDescription(page.selectedCollection.collectionDescription); 1739 collectionModal.show(page.selectedCollection.collectionUUID, true); 1740 } 1741 else if(menuItemPressed == 'Delete Collection'){ 1742 deleteCollectionModal.show(page.selectedCollection); 1743 } 1744 }).subscribe(); 1745 1746 Pubsub.subscription('new_collection_block_create_collection_pressed', (e) => { 1747 collectionModal.show(0, false); 1748 }).subscribe(); 1749 1750 Pubsub.subscription('collection_card_pressed', (e) => { 1751 1752 window.location.hash = e.collection.collectionUUID; 1753 1754 page.setSelectedCollection(e.collection); 1755 1756 collectionsService.getCollectionProperties(e.collection.collectionUUID,1, propertyPaging.propertiesPerPage).then((collectionProperties) => { 1757 1758 1759 savedListings.setCount(collectionProperties?.data?.totalListings || 0); 1760 propertyPaging.setPageCount(collectionProperties.data.totalPages); 1761 1762 1763 if(collectionProperties?.data?.properties == null){ 1764 addListingsBlock.show(); 1765 } 1766 propertySection.show(e.collection.collectionUUID,collectionProperties) 1767 propertySection.setPropertyCardWidth(); 1768 1769 if(collectionProperties.data.totalPages > 1){ 1770 propertyPaging.show(); 1771 } 1772 1773 }); 1774 1775 1776 collectionSection.hide(); 1777 1778 let collectionList = []; 1779 1780 collections.forEach(collection => { 1781 if (collection.collectionName == e.collection.collectionName) return; 1782 1783 collectionList.push({ 1784 collection_title: collection.collectionName, 1785 id: collection.collectionUUID, 1786 propertiesImages: collection?.propertiesImages?.length > 0 ? collection?.propertiesImages : [], 1787 }) 1788 }); 1789 1790 copyPropertyToCollectionModal.getCollectionList(collections, e.collection.collectionName); 1791 1792 pageSubHeader.showTopHeader(); 1793 pageSubHeader.setTopHeaderTitle("Collections"); 1794 pageSubHeader.setTitle(e.collection.collectionName); 1795 pageSubHeader.hidePrimaryButton(); 1796 pageSubHeader.showMenuButton(); 1797 1798 if(window.innerWidth > 768 ){ 1799 pageSubHeader.showSecondaryButton(); 1800 } 1801 1802 page.setInPropertyView(true) 1803 1804 propertyPaging.setCurrentPage(1); 1805 propertySection.setView('list') 1806 1807 1808 const collectionDescription = document.getElementById('collection-description') 1809 collectionDescription.style.display="flex" 1810 collectionDescription.children[0].innerText = e?.collection.collectionDescription || "" 1811 }).subscribe(); 1812 1813 Pubsub.subscription('collection_card_menu_item_pressed', (e) => { 1814 if (e.menuItem == "Delete Collection") { 1815 1816 deleteCollectionModal.show(e.collection); 1817 1818 } else { 1819 1820 1821 collectionModal.setName(e.collection.collectionName); 1822 collectionModal.setDescription(e.collection.collectionDescription); 1823 collectionModal.show(e.collection.collectionUUID, true); 1824 } 1825 }).subscribe(); 1826 1827 Pubsub.subscription('property_card_menu_item_pressed', (e) => { 1828 if(e.menuItem == 'Remove from Collection') { 1829 deletePropertyModal.show(e.collectionUUID, e.propertyCollectionUUID); 1830 } 1831 else if(e.menuItem == 'Copy to Collection') { 1832 copyPropertyToCollectionModal.show(e.property); 1833 } 1834 else if(e.menuItem == 'Share Property') { 1835 1836 shareSavedPropertyModal.show(e.property); 1837 } 1838 }).subscribe(); 1839 1840 Pubsub.subscription('delete_property_modal_pressed', (e) => { 1841 deletePropertyModal.show(e.collectionUUID, e.propertyCollectionUUID); 1842 }).subscribe(); 1843 1844 Pubsub.subscription('show_new_collection_modal', (e) => { 1845 collectionModal.show(); 1846 copyPropertyToCollectionModal.hide(); 1847 createCopyCollection = true; 1848 }).subscribe(); 1849 1850 Pubsub.subscription('top_header_back_pressed', () => { 1851 window.location.hash = ''; 1852 pageSubHeader.hideTopHeader(); 1853 page.selectedCollection = {}; 1854 pageSubHeader.setTitle("COLLECTIONS"); 1855 pageSubHeader.showPrimaryButton(); 1856 pageSubHeader.hideSecondaryButton(); 1857 pageSubHeader.hideMenuButton(); 1858 1859 page.setInPropertyView(false) 1860 1861 collectionSection.show(); 1862 propertySection.hide() 1863 1864 propertyPaging.setCurrentPage(1); 1865 1866 copyPropertyToCollectionModal.getCollectionList(collections) 1867 1868 const collectionDescription = document.getElementById('collection-description') 1869 collectionDescription.style.display="none" 1870 collectionDescription.children[0].innerText = ""; 1871 addListingsBlock.hide(); 1872 }).subscribe() 1873 1874 Pubsub.subscription('create_new_collection_pressed', (e) => { 1875 collectionModal.show(0, false); 1876 }).subscribe(); 1877 1878 Pubsub.subscription('on_new_collection_saved', (e) => { 1879 if(e.type == 'save'){ 1880 1881 let people = [{ personUUID: page.lead.brivity_uuid, role: "lead" }]; 1882 let properties = [""]; 1883 collectionsService.createCollection(e.name, e.description, page.lead.brivity_uuid, people, properties).then((e) => { 1884 1885 collections.unshift(e.data); 1886 1887 extraCollections++ 1888 if(collections.length > 8) { 1889 collections.pop(); 1890 collectionPaging.show() 1891 collectionPaging.setPageCount(Math.ceil(extraCollections / 8)); 1892 } 1893 1894 count = 100; 1895 collectionSection.collections.innerHTML = ""; 1896 collections.forEach((collection) => { 1897 count-- 1898 collectionSection.addCollectionCard(collection, count) 1899 }); 1900 1901 let collectionsList = copyPropertyToCollectionModal.getCollectionData(); 1902 let newCollection = { 1903 collection_title: e.data.collectionName, 1904 id: e.data.collectionUUID, 1905 propertiesImages: [], 1906 } 1907 collectionsList.unshift(newCollection); 1908 copyPropertyToCollectionModal.setCollectionData(collectionsList); 1909 1910 if(!copyPropertyToCollectionModal.isVisible){ 1911 if (createCopyCollection) { 1912 copyPropertyToCollectionModal.isVisible = true; 1913 copyPropertyToCollectionModal.element.setAttribute('style', 'display:flex'); 1914 createCopyCollection = false;
1915 } else { 1916 collectionCreatedModal.show(e.data); 1917 } 1918 } 1919 1920 collectionModal.hide(); 1921 1922 newCollectionBlock.hide(); 1923 }).catch((e) => { 1924 collectionModal.showError(true) 1925 }); 1926 } 1927 else{ 1928 collectionsService.updateCollection(e.collectionUUID, e.name, e.description).then((collection) => { 1929 let element = document.getElementById(e.collectionUUID); 1930 element.setAttribute('title', e.name); 1931 element.setAttribute('description', e.description); 1932 if(Object.keys(page.selectedCollection).length !== 0){ 1933 pageSubHeader.setTitle(e.name); 1934 } 1935 const collectionDescription = document.getElementById('collection-description') 1936 collectionDescription.children[0].innerText = e.description; 1937 let updatedCollection = collections.findIndex((c) => c.collectionUUID == e.collectionUUID) 1938 if(updatedCollection != -1){ 1939 collections[updatedCollection].collectionName = e.name; 1940 collections[updatedCollection].collectionDescription = e.description; 1941 } 1942 collectionModal.hide(); 1943 editCollectionModal.show(); 1944 }); 1945 } 1946 }).subscribe(); 1947 1948 Pubsub.subscription('collection_created_modal_view_collection_pressed', (collection) => { 1949 Pubsub.publish('collection_card_pressed', {"collection": collection}) 1950 }).subscribe(); 1951 1952 Pubsub.subscription('delete_collection_modal_delete_pressed', (collection) => { 1953 collectionsService.deleteCollection(collection.collectionUUID).then((e) => { 1954 document.getElementById(collection.collectionUUID).remove(); 1955 toast.show('Collection was Deleted') 1956 1957 extraCollections-- 1958 1959 if(extraCollections.length < 9) { 1960 collectionPaging.hide() 1961 }else{ 1962 collectionPaging.setPageCount(Math.ceil(extraCollections / 8)); 1963 } 1964 1965 if(page.inPropertyView){ 1966 Pubsub.publish('top_header_back_pressed'); 1967 } 1968 }); 1969 }).subscribe(); 1970 1971 Pubsub.subscription('delete_property_modal_delete_pressed', (e) => { 1972 const currentPage = $("#property-pagination").find("#info-parent").filter( 1973 function() { 1974 return $(this).css("color") === "rgb(196, 196, 196)" 1975 } 1976 ).text(); 1977 1978 const propertiesPerPage = 8; 1979 const numOfProperties = $("#property-list .property-card-wrapper").length; 1980 const setPage = numOfProperties === 1 ? currentPage - 1 : currentPage; 1981 1982 collectionsService.removePropertyFromCollection(e.collectionUUID, e.propertyCollectionUUID) 1983 .then(() => { 1984 toast.show('Property removed from collection'); 1985 1986 return collectionsService.getCollectionProperties(e.collectionUUID, setPage, propertiesPerPage); 1987 }) 1988 .then((collectionProperties) => { 1989 const totalListingsCount = collectionProperties?.data?.totalListings; 1990 const properties = collectionProperties?.data?.properties; 1991 const totalPages = collectionProperties?.data?.totalPages; 1992 const currentCollection = $(`#${e.collectionUUID}`); 1993 1994 currentCollection.attr("num_properties", totalListingsCount); 1995 1996 map.setMarkers(properties); 1997 savedListings.setCount(totalListingsCount || 0); 1998 propertySection.show(propertySection.collectionUUID, collectionProperties); 1999 propertySection.setPropertyCardWidth(); 2000 2001 propertyPaging.setCurrentPage(setPage); 2002 propertyPaging.setPageCount(totalPages); 2003 2004 if (totalListingsCount <= 8) { 2005 propertyPaging.hide(); 2006 } 2007 }) 2008 .catch(error => { 2009 console.error("Error in collection operations:", error); 2010 }); 2011 }).subscribe(); 2012 2013 Pubsub.subscription('copy_property_to_collection_modal_save_pressed', (e) => { 2014 2015 let collectionUUID = e.collectionUUID; 2016 let blossorId = e.property.blossorId; 2017 collectionsService.addPropertyToCollection(collectionUUID, [blossorId]).then(() => { 2018 2019 2020 let data = copyPropertyToCollectionModal.getCollectionData(); 2021 let myFeedData = myFeed.getMlsData(); 2022 2023 collectionsService.getCollectionProperties(collectionUUID,1,1).then((e) => { 2024 2025 // update photos in add property to collection modal 2026 let collectionIndex = data.findIndex((x) => x.id == collectionUUID); 2027 let collection = data[collectionIndex]; 2028 let photo = e?.data?.properties[0]?.photos[0]?.url; 2029 2030 collection.propertiesImages = []; 2031 if(e?.data?.properties?.length > 0){ 2032 collection.propertiesImages.push({mainPhoto: photo}); 2033 } 2034 2035 data[collectionIndex] = collection; 2036 2037 copyPropertyToCollectionModal.setCollectionData(data); 2038 2039 2040 // update collection card if in collection view 2041 pageCollectionIndex = collections.findIndex((x) => x.collectionUUID == collectionUUID) 2042 2043 if(pageCollectionIndex > -1){ 2044 2045 let collectionCard = document.getElementById(collectionUUID); 2046 let numProperties = parseInt(collectionCard.getAttribute('num_properties')); 2047 numProperties++; 2048 collectionCard.setAttribute('num_properties', numProperties); 2049 2050 let images = collectionCard.getAttribute('image'); 2051 if(images){ 2052 images += "," + photo; 2053 } 2054 else{ 2055 images = photo; 2056 } 2057 2058 collectionCard.setAttribute('image', images); 2059 } 2060 2061 //update my feed to set property heart as favorited 2062 let myFeedPropertyIndex = myFeedData.findIndex((x) => x.blossorId == blossorId); 2063 if(myFeedPropertyIndex > -1){ 2064 myFeedData[myFeedPropertyIndex].favorite = true; 2065 myFeed.setMlsData(myFeedData); 2066 } 2067 2068 }) 2069 2070 copyPropertyToCollectionModal.hide(); 2071 toast.show('Property added to collection') 2072 2073 }).catch((e) => { 2074 toast.show('Error adding property to collection', true) 2075 }); 2076 }).subscribe(); 2077 2078 Pubsub.subscription('collection_page_changed', (e) => { 2079 collectionsService.getCollections(e, collectionPaging.collectionsPerPage).then((e) => { 2080 if(e?.data?.Items){ 2081 collections = e.data.Items; 2082 2083 collectionSection.collections.innerHTML = ""; 2084 count = 100;
2085 e.data.Items.forEach((collection) => { 2086 count-- 2087 2088 collectionSection.addCollectionCard(collection, count) 2089 }); 2090 } 2091 }); 2092 }).subscribe(); 2093 2094 Pubsub.subscription('share_saved_property_modal_share_pressed', (e) => { 2095 toast.show('Link Copied!') 2096 }).subscribe(); 2097 2098 Pubsub.subscription('my_feed_share_pressed', (e) => { 2099 shareSavedPropertyModal.show(e.property); 2100 }).subscribe(); 2101 2102 Pubsub.subscription('my_feed_add_collection_pressed', (e) => { 2103 copyPropertyToCollectionModal.setIsAddingToCollection(true); 2104 copyPropertyToCollectionModal.show(e.property); 2105 }).subscribe(); 2106 2107 Pubsub.subscription('map_marker_clicked', (id) => { 2108 propertySection.scrollIntoView(id); 2109 2110 document.querySelectorAll('place-propertycard').forEach((propertyCard) => { 2111 if(propertyCard.id == id) { 2112 propertyCard.setAttribute('show_border', true) 2113 } 2114 else { 2115 propertyCard.setAttribute('show_border', false) 2116 } 2117 }) 2118 }).subscribe(); 2119 2120 Pubsub.subscription('my_feed_on_favorite_pressed', (e) => { 2121 copyPropertyToCollectionModal.setIsAddingToCollection(true); 2122 copyPropertyToCollectionModal.show(e.property); 2123 }).subscribe(); 2124 2125 Pubsub.subscription('my_feed_on_unfavorite_pressed', (e) => { 2126 let blossorId = e.property.blossorId; 2127 let myFeedData = myFeed.getMlsData(); 2128 collectionsService.checkIfInCollection([blossorId]).then((propertiesInCollections) => { 2129 if(propertiesInCollections.data[blossorId]){ 2130 propertiesInCollections.data[blossorId].forEac
2130h((collection) => { 2131 collectionsService.removePropertyFromCollection(collection.collectionUUID, collection.propertyUUID).then(() => { 2132 2133 let data = copyPropertyToCollectionModal.getCollectionData(); 2134 let collectionUUID = collection.collectionUUID; 2135 collectionsService.getCollectionProperties(collectionUUID,1,1).then((e) => { 2136 2137 // update photos in add property to collection modal 2138 let collectionIndex = data.findIndex((x) => x.id == collectionUUID); 2139 let collection = data[collectionIndex]; 2140 let photo = e?.data?.properties?.length > 0 ? e?.data?.properties[0]?.photos[0]?.url : ''; 2141 2142 collection.propertiesImages = []; 2143 if(e?.data?.properties?.length > 0){ 2144 collection.propertiesImages.push({mainPhoto: photo}); 2145 } 2146 2147 data[collectionIndex] = collection; 2148 2149 copyPropertyToCollectionModal.setCollectionData(data); 2150 2151 2152 // update collection card if in collection view 2153 pageCollectionIndex = collections.findIndex((x) => x.collectionUUID == collectionUUID) 2154 2155 if(pageCollectionIndex > -1){ 2156 2157 let collectionCard = document.getElementById(collectionUUID); 2158 let numProperties = parseInt(collectionCard.getAttribute('num_properties')); 2159 numProperties--; 2160 collectionCard.setAttribute('num_properties', numProperties); 2161 2162 let images = collectionCard.getAttribute('image'); 2163 let newImages = images.split(',').filter((x) => x == photo).join(','); 2164 collectionCard.setAttribute('image', newImages); 2165 } 2166 2167 //update my feed to set property heart as not favorited 2168 let myFeedPropertyIndex = myFeedData.findIndex((x) => x.blossorId == blossorId); 2169 if(myFeedPropertyIndex > -1){ 2170 myFeedData[myFeedPropertyIndex].favorite = false; 2171 myFeed.setMlsData(myFeedData); 2172 } 2173 }) 2174 toast.show('Property removed from collection'); 2175 }).catch((e) => { 2176 toast.show('Error removing from collection', true); 2177 }); 2178 }); 2179 } 2180 }); 2181 }).subscribe(); 2182 2183 let modalBackdrop = document.getElementsByClassName('center-modal'); 2184 for(let i = 0; i < modalBackdrop.length; i++){ 2185 modalBackdrop[i].addEventListener('click', (e) => { 2186 if(e.target == modalBackdrop[i]){ 2187 modalBackdrop[i].style.display = 'none'; 2188 } 2189 }); 2190 } 2191 2192 window.addEventListener( "hashchange", function( event ) { 2193 if(window.location.hash == ''){ 2194 Pubsub.publish("top_header_back_pressed"); 2195 } 2196 }); 2197 2198 2199 document.addEventListener("click", (e) => { 2200 2201 const elements = document.querySelectorAll("[show_menu]");
2202 elements.forEach((el) => { 2203 el.setAttribute("show_menu", "false"); 2204 }); 2205 2206 document.getElementById("c2dfac72-6233-4e8d-b0d2-f44e4240ebb4")?.setAttribute("show_menu", "false"); 2207 }); 2208 if(window.innerWidth < 768 ){ 2209 savedListings.hide(); 2210 pageSubHeader.hideSecondaryButton(); 2211 } else{ 2212 addListingBtn.hide(); 2213 } 2214 })(); 2215 } 2216 }) 2217 2218</script>
2218 <div id="myportal-page" style="display:none"> <div style="position:relative; width:100%;"> <div style="position:absolute;z-index:110; top:0; bottom:0; "> <place-menu></place-menu> </div> <div class="collection-page" style="flex:1;"> <div class="page-width-parent"> <place-pagesubheader title="COLLECTIONS" show_top_header="false" button_title="Create New" button_icon="plus" secondary_button_icon="plus" secondary_button_title="Add Listings" show_secondary_button="false" show_menu="false" menu_items='[{ "icon": "edit-2", "text": "Edit Collection" },{ "icon": "trash", "text": "Delete Collection" }]' ></place-pagesubheader> <div id="collection-description" class="collection-description" style="display:none;"> <p class="collection-description-text" style="" ></p> </div> <div id="collection-section" style="margin-top:24px;"> <div id="collections" style="display:flex; flex-wrap:wrap"> <place-actioncard id="new-collection-block" style="display:none;" title="Create A Collection" sub_title="You can create a collection to save and keep track of your favorite properties." button_text="Create New" button_icon="plus" button_icon_fill="white" card_width="300" /> </div> <place-pagination id="collection-pagination" style="display:none"></place-pagination> <div class="my-feed-parent"> <place-myfeedblock style="display:none" display_menu="false"></place-myfeedblock> </div> </div> <div id="property-section"> <div id="property-header" style="display:flex; justify-content: space-between"> <p id="collection-saved-listings" class="collection-saved-listings"></p> <place-button icon="plus" ghost="true" btn_text_styles="text-[#5386E4]" icon_stroke="#5386E4" id="add-listing-btn" title="Add Listing"></place-button> <div style="padding: 0 5px; display:flex"> <place-icon id="property-list-icon" style="margin-right:10px" name="list" size="24" fill="none" stroke="black"></place-icon> <place-icon id="property-map-icon" name="map" size="24" fill="none" stroke="gray"></place-icon> </div> </div> <div class="property-container" style=""> <div id="property-list-parent"> <div id="property-list" class="property-list-list-view"> </div> <div> <place-actioncard id="add-listings-block" style="display:none;" title="Add Listings" sub_title="You can search and add properties to a collection to keep track of your favorite homes using the heart icon." button_text="Search Listings" button_icon="search" button_icon_fill="white" card_width="300" /> </div> </div> <div id="property-map" class="property-map-container" style="display:none" > <place-map map_type_control="true" zoom_control="true"> </place-map> </div> </div> <place-pagination id="property-pagination" class="property-pagination" style="display:none"></place-pagination> </div> </div> </div> </div> <place-basicmodal id="collection-created-modal" class="center-modal" style="display:none" title="Collection Created" sub_title="Would you like to add listings to your new collection? You can search for new listings or copy them from an existing collection." title_icon="heart" primary_button_text="View Collection" tertiary_button_text="Search" stacked_buttons="true" ></place-basicmodal> <place-basicmodal id="delete-collection-modal" class="center-modal" style="display:none" title="Delete Collection" sub_title="Deleting a collection will permanently remove it from your account. Your saved properties will only be visible in your Favorites collection." description="Are you sure you would like to delete this collection?" title_icon="trash" primary_button_text="Delete" tertiary_button_text="Cancel" no_stack_buttons="true" ></place-basicmodal> <place-basicmodal id="edit-collection-modal" class="center-modal" style="display:none" title="Changes Saved" sub_title="The changes to your collection have been saved." title_icon="check" primary_button_text="Close" ></place-basicmodal> <place-basicmodal id="delete-property-modal" class="center-modal" style="display:none" title="Remove Property" sub_title="Deleting this property will remove it from the current collection. Are you sure you would like to delete this property from your collection?" title_icon="trash" primary_button_text="Delete" tertiary_button_text="Cancel" no_stack_buttons="true" ></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> </div> <footer id="footer-9n" data-selector="footer" style="outline: none; cursor: inherit;"><div class="container"> <div class="row"> <div class="col-md-2"> <div class="render-menu hot-nav"> <ul class="" style=""><li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/index" style="outline: none; cursor: inherit;">Home</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/search" style="outline: none; cursor: inherit;">Listings</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/buying" style="outline: none; cursor: inherit;">Buying</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a class="white" href="/selling" style="outline: none; cursor: inherit;">Selling</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/financing" style="outline: none; cursor: inherit;">Financing</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/homevalue" style="outline: none; cursor: inherit;">Home Value</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/realestateagent/search" style="outline: none; cursor: inherit;">Who We Are</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/connect" style="outline: none; cursor: inherit;">Connect</a> </li> </ul></div> </div>
2218 <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,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAfBJREFUWAntVk1OwkAUZkoDKza4Utm61iP0AqyIDXahN2BjwiHYGU+gizap4QDuegWN7lyCbMSlCQjU7yO0TOlAi6GwgJc0fT/fzPfmzet0crmD7HsFBAvQbrcrw+Gw5fu+AfOYvgylJ4TwCoVCs1ardYTruqfj8fgV5OUMSVVT93VdP9dAzpVvm5wJHZFbg2LQ2pEYOlZ/oiDvwNcsFoseY4PBwMCrhaeCJyKWZU37KOJcYdi27QdhcuuBIb073BvTNL8ln4NeeR6NRi/wxZKQcGurQs5oNhqLshzVTMBewW/LMU3TTNlO0ieTiStjYhUIyi6DAp0xbEdgTt+LE0aCKQw24U4llsCs4ZRJrYopB6RwqnpA1YQ5NGFZ1YQ41Z5S8IQQdP5laEBRJcD4Vj5DEsW2gE6s6g3d/YP/g+BDnT7GNi2qCjTwGd6riBzHaaCEd3Js01vwCPIbmWBRx1nwAN/1ov+/drgFWIlfKpVukyYihtgkXNp4mABK+1GtVr+SBhJDbBIubVw+Cd/TDgKO2DPiN3YUo6y/nDCNEIsqTKH1en2tcwA9FKEItyDi3aIh8Gl1sRrVnSDzNFDJT1bAy5xpOYGn5fP5JuL95ZjMIn1ya7j5dPGfv0A5eAnpZUY3n5jXcoec5J67D9q+VuAPM47D3XaSeL4AAAAASUVORK5CYII="); 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 btn-footer" data-selector="a.btn, button.btn, button" style="">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/7090/mabrybrokeragelogo.png" alt="Buy and Sell Homes Real Estate" data-selector="img" style="border-style: none; outline: none; cursor: inherit;"> <div class="text-left" style="outline: medium none; cursor: inherit;"> <ul style="list-style-type: none; outline: none; cursor: inherit;"><li data-selector="li" style="outline: none; cursor: inherit;">4122 N Access Road</li><li data-selector="li" style="outline: none; cursor: inherit;">Chattanooga,TN 37415</li> <li data-selector="li" style="outline: none; cursor: inherit;"> <a class="agent_phone_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="tel:4236054393" src="tel:" style="outline: none; cursor: inherit;"></a> </li> </ul></div> </div> </div> <div class="row ftr-anchor"> <div class="col-sm-6 anchor-col no-padding editContent" style="" data-selector=".editContent"> <p class="no-margin" style="outline: none; cursor: inherit;" data-selector="p"><span class="get_this_year">2018</span> © <b>Legacy234 | Keller Williams Realty Greater Downtown Realty | </b><a href="https://www.place.com/" traget="_blank" style="font-weight: bold; outline: none; cursor: inherit;">PLACE</a></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">  Each office is independently owned and operated. </p> </div> <div class="col-sm-6 anchor-col no-padding"> <ul class="list-inline social" style="outline: none; cursor: inherit;"><li data-selector="li" style="outline: none; cursor: inherit;"> <a class="agent_facebook_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.facebook.com/CharlotteMabryTeamChattanoogaRealEstateDoctor/" target="_blank" style="outline: none; cursor: inherit;"> <svg viewbox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"></path></svg></a> </li> <li data-selector="li" style="outline: none; cursor: inherit;"> <a class="agent_twitter_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://twitter.com/charlottemabry" target="_blank" style="outline: none; cursor: inherit;"> <svg viewbox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><path d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z"></path></svg></a> </li> <li data-selector="li" style="outline: none; cursor: inherit;"> <a class="agent_linkedin_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.linkedin.com/in/charlotte-mabry-b2b99110/" target="_blank" style="outline: none; cursor: inherit;"> <svg viewbox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"></path><rect x="2" y="9" width="4" height="12"></rect><circle cx="4" cy="4" r="2"></circle></svg></a> </li> <li data-selector="li" style="outline: none; cursor: inherit;"> <a class="agent_instagram_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.instagram.com/charlottemabryteam/" target="_blank" style="outline: none; cursor: inherit;"> <svg viewbox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><rect x="2" y="2" width="20" height="20" rx="5" ry="5"></rect><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"></path><line x1="17.5" y1="6.5" x2="17.5" y2="6.5"></line></svg></a> </li> <li data-selector="li" style="outline: none; cursor: inherit;"> <a class="agent_youtube_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="https://www.youtube.com/user/CharlotteMabryTeam/vi
2218deos" target="_blank" style="outline: none; cursor: inherit;"> <svg viewbox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><path d="M22.54 6.42a2.78 2.78 0 0 0-1.94-2C18.88 4 12 4 12 4s-6.88 0-8.6.46a2.78 2.78 0 0 0-1.94 2A29 29 0 0 0 1 11.75a29 29 0 0 0 .46 5.33A2.78 2.78 0 0 0 3.4 19c1.72.46 8.6.46 8.6.46s6.88 0 8.6-.46a2.78 2.78 0 0 0 1.94-2 29 29 0 0 0 .46-5.25 29 29 0 0 0-.46-5.33z"></path><polygon points="9.75 15.02 15.5 11.75 9.75 8.48 9.75 15.02"></polygon></svg></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"}"> 2219<!-- chatbot v1 --> 2220<!-- Chatbot drawer container --> 2221<div class="chatbot-drawer-container loading"> 2222 <div class="chatbot-content-wrapper"> 2223 <div class="chatbot-outside-content"> 2224 <div class="chatbot-bubble-message-container cb-hide"> 2225 <img src="https://cdn.brivity.com/images/people/14950217/2a9997fe9f34b76c0c400f5c778fe017fc0ba6f5-original.jpg?1773844592" class="chatbot-agent-img" alt="Agent profile image in chat bubble"/> 2226 <div id="call-to-action" class="bubble-message"></div> 2227 <button type="button" class="chatbox-bubble-close" data-dismiss="modal" aria-label="Close"> 2228 <span aria-hidden="true">×</span> 2229 </button> 2230 </div> 2231 <button id="chatbot-open-btn" class="chatbot-open-btn bg-prmry" aria-label="Chatbot Open Button"> 2232 <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> 2233 <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"/> 2234 </svg> 2235 </button> 2236 </div> 2237 <div class="chatbot-drawer"> 2238 <div class="chatbot-header bg-prmry"> 2239 <div class="chatbot-agent-info"> 2240 <img src="https://cdn.brivity.com/images/people/14950217/2a9997fe9f34b76c0c400f5c778fe017fc0ba6f5-original.jpg?1773844592" class="chatbot-agent-img" alt="Agent profile image in chat header"/> 2241 <div class="chatbot-agent"> 2242 <h3 class="chatbot-agent-name">Charlotte Mabry</h3> 2243 <h4><span class="chatbot-agent-title">Team Leader / CEO</span> | <span class="chatbot-agent-company">Legacy234 | Keller Williams Realty Greater Downtown Realty</span></h4> 2244 </div> 2245 <a id="chatbot-agent-phone" style="display: none;">(423) 605-4393</a> 2246 </div>
2247 <button id="close-chatbot-drawer" type="button" class="chatbox-modal-close" data-dismiss="modal" aria-label="Close"> 2248 <span aria-hidden="true">×</span> 2249 </button> 2250 </div> 2251 <div class="chatbot-body"> 2252 <div class="chatbot-message-container"> 2253 <img src="https://cdn.brivity.com/images/people/14950217/2a9997fe9f34b76c0c400f5c778fe017fc0ba6f5-original.jpg?1773844592" class="chatbot-agent-img" alt="Agent profile image in message"/> 2254 <h4 id="initial_message" class="chatbot-chat-messages not-loaded"></h4> 2255 <div class="chatbot-chat-messages loading"> 2256 <span class="typing-indicator"> 2257 <span></span> 2258 <span></span> 2259 <span></span> 2260 </span> 2261 </div> 2262 </div> 2263 <form id="chatbotForm" class="chatbot-form"> 2264 <input type="name" id="chatbot_fullname" class="chatbox-form-control no-native-focus" placeholder="Full Name" 2265 pattern="^[A-Za-z'\- ]+ [A-Za-z'\- ]+$" 2266 required /> 2267 <input type="tel" id="chatbot_phone" class="chatbox-form-control no-native-focus" placeholder="Phone" required /> 2268 <input type="email" id="chatbot_email" class="chatbox-form-control no-native-focus" placeholder="Email" 2269 pattern="^[^@\s]+@[^@\s]+\.[^@\s]+$" 2270 required /> 2271 <textarea id="chatbot_message" class="chatbox-form-control chatbot-message" rows="5" name="notes" placeholder="Any Comments or Questions"></textarea> 2272 <div class="chatbot-consent-container"> 2273 <div class="chatbot-toggle"> 2274 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 communications 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>. 2275 </div> 2276 </div> 2277 <input type="hidden" id="chatbot_tags"> 2278 </form> 2279 </div> 2280 <div class="chatbot-footer"> 2281 <button type="submit" form="chatbotForm" class="chatbot-send bg-prmry chatbot-btn-disabled" data-dismiss="modal" aria-label="Close" disabled> 2282 Send 2283 <span aria-hidden="true"> 2284 <svg class="chatbot-btn-icon" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> 2285 <g clip-path="url(#clip0_2435_997)"> 2286 <path d="M14.6667 1.33331L7.33337 8.66665" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 2287 <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"/> 2288 </g> 2289 <defs> 2290 <clipPath id="clip0_2435_997"> 2291 <rect width="16" height="16" fill="white"/> 2292 </clipPath> 2293 </defs> 2294 </svg> 2295 </span> 2296 </button> 2297 </div> 2298 </div> 2299 </div> 2300</div> <style> 2301 .signup-consent-checkbox-section { 2302 display: none; 2303 flex-direction:column; 2304 align-items:flex-start; 2305 padding: 6px 0; 2306 } 2307 2308 .signup-consent-checkbox-section .checkbox { 2309 display:flex; 2310 align-items:flex-start; 2311 justify-content:center; 2312 gap:8px; 2313 padding:0 !important; 2314 } 2315 2316 .signup-consent-checkbox-section .checkbox input { 2317 position:unset; 2318 margin:2px 0 0 0 !important; 2319 } 2320 2321 .signup-consent-checkbox-section .checkbox span { 2322 color: #666666; 2323 font-size: 14px; 2324 font-weight: 400; 2325 line-height:16px; 2326 } 2327 2328 .signup-verbage { 2329 text-align:center; 2330 font-size:10px; 2331 line-height:16px; 2332 } 2333 2334 .signup-verbage span { 2335 color: #8C8C8C; 2336 font-weight:600; 2337 } 2338 2339 .signup-verbage a { 2340 color:#5386E4 !important; 2341 font-weight:400; 2342 } 2343 2344 .signup-verbage .twilio-enabled-verbage { 2345 display:none; 2346 } 2347 2348 2349 2350 </style> <div id="modal-mount" data-modal-bundle="https://cdn1.brivityidx.com/assets/modals/v1/all.html?ck=1791485733"></div>
2350 <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>
2350<script> 2351 document.addEventListener("DOMContentLoaded", () => { 2352 class Toast { 2353 constructor() { 2354 this.element = document.querySelector('place-generictoast'); 2355 } 2356 2357 show(message, error = false, link) { 2358 var dispatch = function () { 2359 window.dispatchEvent( 2360 new CustomEvent("ShowToast", { 2361 detail: { 2362 text: message, 2363 error: error, 2364 link: link, 2365 }, 2366 }) 2367 ); 2368 }; 2369 if (window.sitebuilderPlaceComponents && window.sitebuilderPlaceComponents.ensureLoaded) { 2370 window.sitebuilderPlaceComponents 2371 .ensureLoaded('place-generictoast') 2372 .then(dispatch) 2373 .catch(function (err) { 2374 console.warn('toast.show fallback (web-components unavailable):', message, err); 2375 }); 2376 } else { 2377 dispatch(); 2378 } 2379 } 2380 } 2381 2382 window.toast = new Toast(); 2383 }); 2384 </script>
2384
2384<script src="https://cdn.jsdelivr.net/npm/@turf/[email protected]/turf.min.js"></script>
2384
2384<script src="https://maps.googleapis.com/maps/api/js?libraries=geocoding,places,marker,drawing&key=AIzaSyAjpuNg6WGCMV5rzoJcIP2QmMTVto6hYmc&map_ids=85c127b7bf0255d9"></script>
2384
2384<script src="https://cdn1.brivityidx.com/assets/js/build.min.js?ck="></script>
2384
2384<script src="https://cdn1.brivityidx.com/assets/js/top_bar_v2.min.js?ck="></script>
2384
2384<script src="https://cdn1.brivityidx.com/assets/js/global_js.min.js?ck=1791485733"></script>
2384
2384<script>deferScript("https://cdn1.brivityidx.com/assets/js/global_js_defer.min.js?ck=1791485733", 5000);</script>
2384
2384<script> 2385 function shouldLoadChatbotImmediately() { 2386 const settingsEl = document.getElementById('hchatbot_settings'); 2387 if (!settingsEl) return false; 2388 2389 const version = Number(settingsEl.dataset.chatbotVersion); 2390 let isInitialized = false; 2391 2392 try { 2393 const session = JSON.parse(sessionStorage.getItem('cbSession') || '{}'); 2394 isInitialized = session.chatbotInitialized === true; 2395 } catch (e) {} 2396 2397 return version > 1 && isInitialized; 2398 } 2399 </script>
2399
2399<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>
2399
2399<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=1791485731" : "https://cdn1.brivityidx.com/assets/js/chatbot.min.js?ck=1791485731", shouldLoadChatbotImmediately() ? 50 : 5000);</script>
2399
2399<script type="text/javascript" src="https://cdn1.brivityidx.com/assets/js/jquery.geocomplete.min.js"></script>
2399<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.bootstrapvalidator/0.5.3/js/bootstrapValidator.min.js"></script>
2399<script type="text/javascript" src="https://cdn1.brivityidx.com/assets/js/menu2.js"></script>
2399<script type="text/javascript" src="https://cdn1.brivityidx.com/assets/js/member_area_components.js"></script>
2399<script type="text/javascript" src="https://cdn1.brivityidx.com/assets/js/update_agent_info.min.js"></script>
2399
2399<script src="https://mobile-component-services-library.s3.amazonaws.com/collections_service.min.js?ck=1"></script>
2399
2399<script src="https://mobile-component-services-library.s3.amazonaws.com/messaging_service.min.js?ck=1"></script>
2399
2399<script>$(document).ready(function(){$("ul.seo-anchor-links li:nth-of-type(4) a").attr("href","/search")})</script>
2399
2399<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>
2399
2399<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>
2399
2399<script>$("#slide-out-nav > div.render-menu > ul").append('<li class="nav-item"><a style="color:#fff!important; border-radius:5px; max-width:250px; margin:0 auto;" id="top-nav-marketing-plan" class="nav-link-color" data-toggle="modal" data-target="#getmarketingplan">Get Marketing Plan</a></li>')</script>
2399
2399<script>$("#contact1_availability_date").click(function(){$(this).prop('type','date')})</script>
2399
2399<script>$(document).ready(function(){if($('#slide-out-nav .render-menu ul li a:contains("ABOUT PLACE")')){$('#slide-out-nav .render-menu ul li a:contains("ABOUT PLACE")').attr('target','_blank')}})</script>
2399</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.