1<!DOCTYPE html> 2<html lang="en" data-header-tone="dark" data-brand-tone="dark" data-header-brand="merged"> 3<head> 4<meta charset="UTF-8"> 5<meta name="viewport" content="width=device-width,initial-scale=1"> 6<meta name="theme-color" content="#ed1b24"> 7 8<!-- SEO --> 9<title>Your Cart - Good To Go</title> 10<meta name="description" content="Review items in your cart before checkout."><link rel="canonical" href="https://goodtogostore.com/cart"> 11<meta name="robots" content="index, follow"> 12<!-- Single-language (en) storefronts: self-referential hreflang + x-default. --> 13<link rel="alternate" hreflang="en" href="https://goodtogostore.com/cart"> 14<link rel="alternate" hreflang="x-default" href="https://goodtogostore.com/cart"> 15 16<!-- Open Graph --> 17<meta property="og:type" content="website"> 18<meta property="og:site_name" content="Good To Go"> 19<meta property="og:title" content="Your Cart - Good To Go"> 20<meta property="og:description" content="Review items in your cart before checkout."> 21<meta property="og:image" content="https://cdn.uengage.io/brand_logo/logo-68249-1781851626.png"> 22<meta property="og:image:alt" content="Your Cart - Good To Go"> 23<meta property="og:url" content="https://goodtogostore.com/cart"> 24 25<!-- Twitter --> 26<meta name="twitter:card" content="summary"> 27<meta name="twitter:title" content="Your Cart - Good To Go"> 28<meta name="twitter:description" content="Review items in your cart before checkout."> 29<meta name="twitter:image" content="https://cdn.uengage.io/brand_logo/logo-68249-1781851626.png"> 30<meta name="twitter:image:alt" content="Your Cart - Good To Go"> 31 32 33<!-- JSON-LD: one @graph per page â global Organization + WebSite, plus any 34 page-specific nodes a controller passes in $pageSchema (Product, ItemList, 35 BreadcrumbList, LocalBusiness, â¦). Built via app/Helpers/schema_helper.php. -->
36<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://goodtogostore.com/#organization","name":"Good To Go","url":"https://goodtogostore.com","logo":"https://cdn.uengage.io/brand_logo/logo-68249-1782395208.jpeg","email":"[email protected]","contactPoint":{"@type":"ContactPoint","telephone":"9911277733","contactType":"customer service"},"sameAs":["https://www.facebook.com/goodtogostore/","https://www.instagram.com/goodtogo.meats/?hl=en"]},{"@type":"WebSite","@id":"https://goodtogostore.com/#website","name":"Good To Go","url":"https://goodtogostore.com","potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://goodtogostore.com/products?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}</script>
36 37<!-- Favicons --> 38<link rel="icon" href="https://cdn.uengage.io/brand_logo/logo-68249-1781851626.png" type="image/png"><link rel="icon" sizes="16x16" href="https://cdn.uengage.io/brand_logo/logo-68249-1781851626_16.png" type="image/png"><link rel="icon" sizes="32x32" href="https://cdn.uengage.io/brand_logo/logo-68249-1781851626_32.png" type="image/png"><link rel="icon" sizes="96x96" href="https://cdn.uengage.io/brand_logo/logo-68249-1781851626_96.png" type="image/png"><link rel="icon" sizes="192x192" href="https://cdn.uengage.io/brand_logo/logo-68249-1781851626_192.png" type="image/png"><link rel="apple-touch-icon" href="https://cdn.uengage.io/brand_logo/logo-68249-1781851626_192.png"><link rel="manifest" href="/manifest.json"> 39 40<!-- Preconnect (PageSpeed) â only the image CDN now; all libs/fonts are self-hosted. --> 41<link rel="preconnect" href="https://cdn.uengage.io" crossorigin> 42 43<!-- Critical: jQuery in head (prod JS depends on it). Self-hosted under assets/. -->
44<script src="https://goodtogostore.com/assets/jquery/jquery.min.js"></script>
44 45 46<!-- Slick carousel â CI3 parity. Any [data-slick] auto-inits via slick_init.js. 47 Self-hosted ([email protected]) under assets/slick/ â NOT assets/wla_new/ 48 (that dir is in our staging excludes, so files under it never reach 49 UAT/prod). Without slick.min.css, `.slick-list` loses `overflow: hidden` 50 and carousels spill sideways. slick.min.css's relative url()s resolve to 51 assets/slick/fonts/ and assets/slick/ajax-loader.gif. --> 52<link rel="stylesheet" href="https://goodtogostore.com/assets/slick/slick.min.css"> 53<!-- slick-theme provides the native `.slick-dots` styling. Without it, `dots: true` 54 carousels render invisible dots (slick.min.css is structural only). --> 55<link rel="stylesheet" href="https://goodtogostore.com/assets/slick/slick-theme.min.css"> 56<!-- defer: not needed for first paint. Runs before the deferred slick_init.js 57 (defer scripts execute in document order), so carousels still auto-init. 58 jQuery above stays eager since slick depends on it. -->
59<script defer src="https://goodtogostore.com/assets/slick/slick.min.js"></script>
59 60 61<!-- AppConfig bridge â must run before any page-script reads window.AppConfig. 62 Endpoint values come from .env only (no in-code defaults); missing keys 63 surface as empty strings so the failure is loud. -->
64<script> 65window.AppConfig={businessId:68249,domain:"goodtogostore.com",theme:"ue_silver",brandColor:"#ed1b24",logo:"https:\/\/cdn.uengage.io\/brand_logo\/logo-68249-1782395208.jpeg",logoSquare:"https:\/\/cdn.uengage.io\/brand_logo\/logo-68249-1781851626.png",brandName:"Good To Go",mapsKey:"null",mapsFlow:0,ecomm:0,localityMapping:0,locationPopupConfig:2,storesCount:9,autoOpenLocationModal:0,apiBase:"https:\/\/api.uengage.in",menuFeedBase:"https:\/\/menu-feed.uengage.in",searchBase:"https:\/\/menu-search.uengage.in",searchSalt:"i(8EkR^xO$1M7[6w",crmBase:"https:\/\/crm.uengage.in",cdnBase:"https:\/\/cdn.uengage.io",webBase:"https:\/\/www.uengage.in",paytmProcessUrl:"",staticApiKey:"a7f3e9c1b8d4k2m6n9p5q7r3s8t1u4v",razorpayPlatformAccount:"acc_6pLAEaTkp0IwO7",crmAuthToken:"GF6fNR283siI4qm2YQ4y8Ba602kgbHYT",loyaltyBase:"https:\/\/crm.uengage.in",loyaltyAuthToken:"U1CXDZ5S2HQLIE6F",geocodeHashKey:"601a50c701a7018ec7ca7315e4be286d2cd62abda3e571b12d6f569e83448e53",homeOutletId:0,cBID:68396,truecallerKey:"1CcwSd888aa952f454e24abdd009fe38a1c62",whatsappLogin:0,waJwt:"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXJlbnRfaWQiOiI2ODI0OSJ9.4yLWZp4TiD2Mhcx1pjyvYyarc77g5jRNJxxI2oQYNmU", 66 // Set by WhatsappOrderAuthFilter on a successful `wo` nonce redeem (the 67 // entry_channel cookie â see wa_entry_channel() in wla_helper.php for why 68 // it's a cookie, not session data). Exposed here so page scripts can read 69 // it without re-parsing document.cookie themselves â e.g. menu.js's debug 70 // trail, gated on this being 'whatsapp'. 71 entryChannel:null, 72 catalogSlug:"products",catalogDetailSlug:"product-detail", 73 flags:{},realtime:{"enabled":true,"env":"prod","pollIntervalMs":5000}}; 74</script>
74 75 76<!-- Bootstrap/Icons retained during migration â scheduled for removal in cleanup phase. 77 Self-hosted under assets/ ([email protected], [email protected]). The icon 78 CSS's relative url()s resolve to assets/bootstrap-icons/fonts/. --> 79<link rel="stylesheet" href="https://goodtogostore.com/assets/bootstrap/bootstrap.min.css"> 80<link rel="stylesheet" href="https://goodtogostore.com/assets/bootstrap-icons/bootstrap-icons.min.css"> 81<!-- uEngage Design System --> 82<link rel="stylesheet" href="https://goodtogostore.com/assets/css/colors_and_type.min.css?v=1791374064"> 83<link rel="stylesheet" href="https://goodtogostore.com/assets/css/brand_themes.min.css?v=1791374064"> 84<link rel="stylesheet" href="https://goodtogostore.com/assets/css/storefront.min.css?v=1791374064"> 85<link rel="stylesheet" href="https://goodtogostore.com/assets/css/home_widgets.min.css?v=1791374064"> 86<link rel="stylesheet" href="https://goodtogostore.com/assets/css/cloud-brand-pill.min.css?v=1791374064"> 87<!-- Active Orders â renders inside the profile sidebar (partials/active_orders.php, 88 included from partials/profile_sidebar.php). Generic, loaded site-wide, 89 same as the sidebar itself â no route exclusions. --> 90<link rel="stylesheet" href="https://goodtogostore.com/assets/css/home_active_orders.min.css?v=1791374064"> 91<!-- Legacy theme.css â remove once home widgets are re-migrated --> 92<link rel="stylesheet" href="https://goodtogostore.com/assets/css/theme.min.css?v=1791374064"> 93<!-- Footer styles (extracted from theme.css; loaded after to preserve cascade) --> 94<link rel="stylesheet" href="https://goodtogostore.com/assets/css/footer.min.css?v=1791374064"> 95<!-- Shared modal styles (location picker + menu item/variant/combo popups). 96 Loaded when the location popup is configured OR on menu pages, which render 97 the item-detail / variant / combo popups whose CSS lives in this file. 98 NB: the Manage Addresses form + delete-confirm/toast styles live in theme.css 99 (global), so they no longer depend on this file being loaded. --> 100<link rel="stylesheet" href="https://goodtogostore.com/assets/css/location_modal.min.css?v=1791374064"> 101 102 103<!-- Runtime brand tokens â DB-driven, applies to every brand (Theobroma, CBTL, new ones). 104 Darker/tinted shades are computed via color-mix() so only primary + secondary are stored. --> 105<style> 106body{ 107 --brand-primary: #ed1b24; 108 --brand-primary-rgb: 237,27,36; 109 --brand-primary-600: color-mix(in srgb, var(--brand-primary) 85%, #000); 110 --brand-primary-100: color-mix(in srgb, var(--brand-primary) 12%, #fff); 111 --brand-secondary: #ffffff; 112 --brand-secondary-rgb: 255,255,255; 113 --brand-gradient: #ffffff; 114 --brand-on-primary: #fff; 115 --page-bg: var(--bg-canvas); 116 /* Legacy aliases â old theme.css + older JS modules still reference these. */ 117 --brand: var(--brand-primary); 118 --brand-rgb: var(--brand-primary-rgb); 119 --brand-soft: var(--brand-primary-100); 120 --brand-hover: var(--brand-primary-600); 121 /* Extracted from the legacy header_theme fragment at the top of this file, 122 alongside the light/dark tone that <html data-header-tone> publishes. */ 123 --header-bg: #ed1b24; 124 --header-text: #ffffff; 125 /* Footer defaults to the brand primary so every brand gets a branded 126 footer without a DB column set. `footer_color` overrides per-brand. */ 127 --footer-bg: #ed1b24; 128 --footer-text: #ffffff; 129} 130</style> 131 132 133<!-- Analytics â per-brand IDs (web_config) handed to the self-contained analytics.js module. 134 The module loads each vendor SDK itself and fires the funnel events. Adding a new provider 135 later = add an id key here + one provider object in analytics.js (no other file changes). -->
136<script> 137window.AnalyticsConfig = { 138 ga4: "", 139 gtm: "", 140 metaPixels: [], 141 webengage: ""}; 142</script>
vendor: 1 bytes, line 142
142
143<script src="/src/js/modules/analytics.js?v=1791374065" type="module"></script>
143 144<!-- UTM capture â writes the first-party utm_data cookie on landing (read server-side at order confirmation) -->
145<script src="/src/js/modules/utm.js?v=1791374065" defer></script>
145 146<!-- Banner click tracking â one delegated listener for every banner widget (banners.php 147 emits data-banner-id on linked slides). Plain script, not a module: it only reads the 148 window.Analytics bridge, so it needs no imports. -->
149<script src="/src/js/modules/banner_click.js?v=1791374065" defer></script>
149 150</head> 151<body class="ds-page" data-theme="ue_silver"> 152 153<header class="site-header hdr2" role="banner"> 154 155 156 <div class="hdr2-main"> 157 <div class="container hdr2-main__inner"> 158 159 <button class="hdr2-burger d-lg-none" type="button" data-bs-toggle="offcanvas" 160 data-bs-target="#mobileDrawer" aria-label="Open menu"> 161 <i class="bi bi-list" aria-hidden="true"></i> 162 </button> 163 164 <a class="hdr2-logo" href="/" aria-label="Good To Go home"> 165 <img src="https://cdn.uengage.io/brand_logo/logo-68249-1782395208.jpeg" alt="Good To Go" class="brand-logo"> 166 </a> 167 168 169 <div class="hdr2-actions"> 170 171 <a class="hdr2-icon hdr2-addmore d-none d-lg-inline-flex" 172 href="/order/cart" 173 data-hdr2-addmore 174 aria-label="Add more items to your order"> 175 <span class="hdr2-icon__ic"> 176 <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg> 177 </span> 178 <span class="hdr2-icon__label">Add more items</span> 179</a> 180 181 182 183 184 <a class="hdr2-icon hdr2-track" href="/past-order" aria-label="Track your order" data-hdr2-track> 185 <span class="hdr2-icon__ic"> 186 <svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3.6H7.8a4.2 4.2 0 0 0 0 8.4h9.6a4.2 4.2 0 0 1 0 8.4H12"/><circle cx="19.2" cy="3.6" r="2.4"/><circle cx="4.8" cy="20.4" r="2.4"/></svg> 187 <span class="js-profile-order-badge profile-order-badge" hidden>0</span> 188 </span> 189 <span class="hdr2-icon__label d-none d-lg-inline">Track</span> 190 </a> 191 192 <button type="button" class="hdr2-icon hdr2-profile" aria-label="My account" 193 data-hdr2-profile data-hdr2-login-source="header"> 194 <svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="8" r="4"/><path d="M4 21v-1a6 6 0 0 1 6-6h4a6 6 0 0 1 6 6v1"/></svg> 195 <span class="hdr2-icon__label user-name-display d-none d-lg-inline">Login</span> 196 </button> 197 198 <a class="hdr2-icon hdr2-cart" href="/cart" aria-label="View your cart" data-hdr2-cart> 199 <span class="hdr2-icon__ic"> 200 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"/></svg> 201 <span class="hdr2-cart__count" data-hdr2-cart-count hidden>0</span> 202 </span> 203 <span class="hdr2-icon__label d-none d-lg-inline">Cart</span> 204 </a> 205 206 </div> 207 </div> 208 </div> 209 210 <nav class="hdr2-nav d-none d-lg-block" aria-label="Main navigation"> 211 <div class="container hdr2-nav__inner"> 212 <ul class="hdr2-nav__list"> 213 <li class="hdr2-nav__item"> 214 <a class="hdr2-nav__link" href="/" 215 >Home</a> 216 </li> 217 <li class="hdr2-nav__item"> 218 <a class="hdr2-nav__link" href="/online-order" 219 >Order Now</a> 220 </li> 221 <li class="hdr2-nav__item"> 222 <a class="hdr2-nav__link" href="/products" 223 >Products</a> 224 </li> 225 <li class="hdr2-nav__item"> 226 <a class="hdr2-nav__link" href="/articles" 227 >Blogs</a> 228 </li> 229 <li class="hdr2-nav__item"> 230 <a class="hdr2-nav__link" href="/store-locator" 231 >Store Locator</a> 232 </li> 233 234 </ul> 235 </div> 236 </nav> 237 238 </header> 239 240<div class="offcanvas offcanvas-start mobile-drawer" tabindex="-1" id="mobileDrawer" aria-label="Mobile menu"> 241 <div class="offcanvas-header mobile-drawer-bar mobile-nav-bar"> 242 <button type="button" class="btn-icon" data-bs-dismiss="offcanvas" aria-label="Close menu"> 243 <i class="bi bi-x fs-5"></i> 244 </button> 245 <div class="mobile-logo-center"> 246 <a href="/" aria-label="Good To Go home"> 247 <img src="https://cdn.uengage.io/brand_logo/logo-68249-1782395208.jpeg" alt="Good To Go" class="brand-logo"> 248 </a> 249 </div> 250 <button type="button" class="btn-icon" data-bs-dismiss="offcanvas" aria-label="My account" 251 data-hdr2-profile data-hdr2-login-source="drawer">
252 <i class="bi bi-person"></i> 253 <span class="js-profile-order-badge profile-order-badge" hidden>0</span> 254 </button> 255 </div> 256 <div class="offcanvas-body mobile-drawer-body"> 257 <div class="mobile-drawer-card"> 258 <nav class="mobile-drawer-nav"> 259 <a class="mobile-drawer-item" href="/">Home</a> 260 <a class="mobile-drawer-item" href="/online-order">Order Now</a> 261 <a class="mobile-drawer-item" href="/products">Products</a> 262 <a class="mobile-drawer-item" href="/articles">Blogs</a> 263 <a class="mobile-drawer-item" href="/store-locator">Store Locator</a> 264 265 </nav> 266 <div class="mobile-drawer-actions"> 267 <a href="/online-order" class="mobile-drawer-btn mobile-drawer-btn--outline">Order Online</a> 268 <a href="https://uen.io/goodtogo" target="_blank" rel="noopener" class="mobile-drawer-btn mobile-drawer-btn--fill">Download The App</a> 269 <span class="mobile-drawer-actions__cap">Get App Exclusive Discounts</span> 270 </div> 271 272 <div class="mobile-drawer-meta"> 273 <a class="mobile-drawer-metalink" href="/store-locator"> 274 <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0z"/><circle cx="12" cy="10" r="2.6"/></svg> 275 <span>Our stores</span> 276 </a> 277 <a class="mobile-drawer-metalink" href="tel:9911277733"> 278 <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.79 19.79 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z"/></svg> 279 <span>9911277733</span> 280 </a> 281 </div> 282 </div> 283 </div> 284</div>
285<script src="/src/js/modules/headerV2.js?v=1791374065" defer></script>
285 286 287<main id="main-content"> 288<section class="cart-page" id="cartPage"> 289 <div class="menu-wrap"> 290 <header class="cart-page__head"> 291 <a href="javascript:history.back()" class="icon-btn-back" aria-label="Back"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6"/></svg> 292</a> 293 <h1 class="cart-page__title">Your cart</h1> 294 </header> 295 296 <div class="cart-page__layout"> 297 <div class="cart-page__items" id="cartItemsContainer"> 298 <div class="cart-empty" id="cartEmptyState" hidden> 299 <p class="body">Your cart is empty.</p> 300 <a href="/" class="btn btn--primary">Browse menu</a> 301 </div> 302 <div id="cartRows"></div> 303 </div> 304 305 <aside class="cart-page__summary card card--elevated" aria-label="Bill summary"> 306 <div class="card__body"> 307 <h2 class="cart-page__summary-title">Bill summary</h2> 308 <dl class="bill"> 309 <div class="bill__row"> 310 <dt>Subtotal</dt> 311 <dd id="billSubtotal">â¹0</dd> 312 </div> 313 <div class="bill__row bill__row--muted" id="billDiscountRow" hidden> 314 <dt>Discount</dt> 315 <dd id="billDiscount">ââ¹0</dd> 316 </div> 317 <div class="bill__row bill__row--muted"> 318 <dt>Taxes & charges</dt> 319 <dd class="muted">Calculated at payment</dd> 320 </div> 321 <div class="bill__row bill__row--muted"> 322 <dt>Delivery</dt> 323 <dd class="muted">Calculated at payment</dd> 324 </div> 325 <div class="bill__row bill__row--total"> 326 <dt>Total</dt> 327 <dd id="billTotal">â¹0</dd> 328 </div> 329 </dl> 330 </div> 331 <div class="card__footer"> 332 <button type="button" class="btn btn--primary btn--lg btn--block" 333 id="proceedCheckoutBtn" disabled > 334 Proceed to Checkout</button> 335 </div> 336 </aside> 337 </div> 338 </div> 339</section> 340</main> 341 342 343<footer class="site-footer" role="contentinfo"> 344 <div class="container"> 345 <div class="footer-top"> 346 <div class="footer-col"> 347 <h6>Useful Links</h6> 348 <ul class="footer-links"> 349 <li><a href="/terms-and-conditions">Terms & Conditions</a></li> 350 <li><a href="/privacy-policy">Privacy Policy</a></li> 351 <li><a href="/refund-policy">Refund Policy</a></li> 352 <li><a href="/promo-codes">Promo Codes</a></li> 353 <li><a href="/shipping-policy">Shipping Policy</a></li> 354 </ul> 355 </div> 356 357 <div class="footer-col"> 358 <h6>Payment Methods</h6> 359 <div class="footer-payments"> 360 <img src="/assets/img/footer/cash-svg.svg" width="44" height="26" alt="Cash" loading="lazy"> <img src="/assets/img/footer/mastercard-svg.svg" width="44" height="26" alt="Mastercard" loading="lazy"> 361 <img src="/assets/img/footer/gpay-svg.svg" width="44" height="26" alt="Google Pay" loading="lazy"> 362 <img src="/assets/img/footer/paytm-svg.svg" width="44" height="26" alt="Paytm" loading="lazy"> 363 <img src="/assets/img/footer/visa-svg.svg" width="44" height="26" alt="Visa" loading="lazy"> 364 <img src="/assets/img/footer/upi-icon.svg" width="44" height="26" alt="UPI" loading="lazy"> 365 </div> 366 </div> 367 368 <div class="footer-col footer-col--wide"> 369 <h6>Address</h6> 370 <div class="footer-address"> 371 <i class="bi bi-geo-alt-fill"></i> 372 <p class="footer-text mb-0">30/28, East Patel Nagar, New Delhi</p> 373 </div> 374 </div> 375 376 <div class="footer-col footer-col--wide"> 377 <h6>Contact & Connect</h6> 378 <p class="footer-text footer-contact-line mb-2"><i class="bi bi-envelope"></i><a href="mailto:[email protected]">[email protected]</a></p> 379 <p class="footer-text footer-contact-line mb-2"><i class="bi bi-telephone"></i><a href="tel:9911277733">9911277733</a></p> 380 <div class="footer-social"> 381 <a href="https://www.facebook.com/goodtogostore/" target="_blank" rel="noopener" aria-label="Facebook"><i class="bi bi-facebook"></i></a> 382 <a href="https://www.instagram.com/goodtogo.meats/?hl=en" target="_blank" rel="noopener" aria-label="Instagram"><i class="bi bi-instagram"></i></a> 383 </div> 384 </div> 385 </div> 386 387 388 <div class="tho-footer-extras"> 389 <p class="tho-footer-stores"> 390 <strong>OUR STORES - </strong> 391 <a href="https://goodtogostore.com/store-locator/delhi">Delhi</a>
391 | <a href="https://goodtogostore.com/store-locator/faridabad">Faridabad</a> | <a href="https://goodtogostore.com/store-locator/gurgaon">Gurgaon</a> | <a href="https://goodtogostore.com/store-locator/gurugram">Gurugram</a> | <a href="https://goodtogostore.com/store-locator/noida">Noida</a> | <a href="https://goodtogostore.com/store-locator/pinjore">Pinjore</a> </p> 392 393 </div> 394 395 </div> 396</footer> 397<div class="footer-copy"> 398 <div class="container"> 399 <span class="footer-powered">Powered By <a href="https://www.uengage.io" target="_blank" rel="noopener"><img src="/assets/img/footer/uengage-logo.svg" alt="uEngage" loading="lazy"></a></span> 400 <span class="footer-copyright"><i class="bi bi-c-circle-fill"></i> Copyright. All Rights Reserved</span> 401 </div> 402</div> 403 404<button type="button" class="scroll-top-btn" id="scrollTopBtn" aria-label="Scroll to top" hidden> 405 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="18 15 12 9 6 15"/></svg> 406</button> 407 408<!-- JS: Bootstrap bundle (must load before login modal script). Self-hosted under assets/. -->
409<script src="https://goodtogostore.com/assets/bootstrap/bootstrap.bundle.min.js"></script>
vendor: 1 bytes, line 409
409
410<script> 411// Bootstrap 4 jQuery modal-API shim: lets ported CI3 code keep using `$('#x').modal('show'|'hide'|'toggle')`. 412(function () { 413 if (!window.jQuery || !window.bootstrap) return; 414 window.jQuery.fn.modal = function (action) { 415 return this.each(function () { 416 var inst = bootstrap.Modal.getOrCreateInstance(this); 417 if (action === 'show' || action === undefined) inst.show(); 418 else if (action === 'hide') inst.hide(); 419 else if (action === 'toggle') inst.toggle(); 420 else if (action === 'dispose') inst.dispose(); 421 }); 422 }; 423})(); 424</script>
424 425 426<!-- Global Login Modal (available on all pages) â bottom-sheet on mobile, top-aligned on desktop --> 427<div class="popup-overlay popup-overlay--top" id="loginModal" role="dialog" aria-modal="true" aria-labelledby="loginModalTitle" hidden> 428 <div class="popup-sheet popup-sheet--sm"> 429 <div class="popup-sheet__header login-header"> 430 <span class="login-brand"><img src="https://cdn.uengage.io/brand_logo/logo-68249-1782395208.jpeg" alt="Good To Go" class="login-brand__img"></span> 431 <div class="popup-sheet__head-text"> 432 <h5 class="popup-sheet__title fw-bold mb-1" id="loginModalTitle">Sign in to your account</h5> 433 <p class="popup-sheet__subtitle mb-0" id="loginModalSubtitle">We'll text you a one-time code â no password needed.</p> 434 </div> 435 <button type="button" class="icon-btn-close js-modal-close" aria-label="Close"> 436 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg> 437 </button> 438 </div> 439 <div class="popup-sheet__body"> 440 441 <!-- Step 1: Phone --> 442 <div id="loginStep1"> 443 <!-- Social login â mobile only; social_login.js reveals each per UA + brand flags. 444 Styling mirrors CI3 (.mail-btn/.mail-btns): full-width, rounded, bold. --> 445 <div id="socialLoginBlock"> 446 <button type="button" class="social-login-btn d-none" id="truecallerBtn"> 447 Continue with <span class="social-login-btn__tc">truecaller</span> 448 </button> 449 <button type="button" class="social-login-btn social-login-btn--whatsapp d-none" id="whatsappLoginBtn"> 450 <span id="whatsappBtnLabel" style="display:inline-flex;align-items:center;gap:6px">Continue with <svg style="height:20px;width:20px;flex-shrink:0" viewBox="0 0 24 24" fill="#fff" aria-hidden="true"><path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/></svg> WhatsApp</span> 451 </button> 452 <div class="d-none login-or" id="socialLoginOr">OR</div> 453 </div> 454 455 <!-- Phone Number â mobile only; reveals the OTP form (CI3 loginWithOtpBtn) --> 456 <button type="button" class="social-login-btn d-none" id="loginWithOtpBtn"> 457 <i class="bi bi-telephone"></i> Phone Number 458 </button> 459 460 <!-- T&C for the social view (mobile-initial). Hidden on desktop / once OTP form is shown. 461 Mirrors #loginConsent state via JS so either can satisfy the consent gate. --> 462 <label class="login-consent d-none" id="loginConsentSocialWrap" for="loginConsentSocial"> 463 <input type="checkbox" class="form-check-input" id="loginConsentSocial" checked>
464 <span>I agree to the <a href="/tnc" target="_blank" class="login-consent__link">Terms of Use</a> and <a href="/privacy-policy" target="_blank" class="login-consent__link">Privacy Policy</a></span> 465 </label> 466 467 <!-- OTP form â shown directly on desktop; revealed by "Phone Number" on mobile --> 468 <div id="otpFormSection"> 469 <div class="login-field"> 470 <label class="login-label" for="loginPhone">Mobile Number <span class="login-label__req">*</span></label> 471 <div class="input-group login-field-group"> 472 <span class="input-group-text fw-semibold login-field-group__prefix">+91</span> 473 <input type="tel" class="form-control login-field-group__input" id="loginPhone" maxlength="10" placeholder="10-digit phone number" inputmode="numeric"> 474 </div> 475 </div> 476 477 <!-- Captcha --> 478 <div class="login-field" id="captchaSection"> 479 <label class="login-label" for="captchaInput">Security Check <span class="login-label__hint" id="captchaHint">Enter your mobile number first</span></label> 480 <div class="login-captcha is-disabled" id="captchaRow"> 481 <input type="text" inputmode="numeric" pattern="[0-9]*" class="form-control login-captcha__input" id="captchaInput" maxlength="4" placeholder="Type code shown here" disabled> 482 <div class="login-captcha__img" id="captchaImg"> 483 <img alt="Security code image" id="captchaImgTag"> 484 </div> 485 <button type="button" class="login-captcha__refresh" id="refreshCaptcha" title="Refresh code" aria-label="Refresh security code"><i class="bi bi-arrow-clockwise"></i></button> 486 </div> 487 </div> 488 489 <!-- T&C â consent applies to every login method, sits above Send OTP on the OTP form view --> 490 <label class="login-consent" for="loginConsent"> 491 <input type="checkbox" class="form-check-input" id="loginConsent" checked> 492 <span>I agree to the <a href="/tnc" target="_blank" class="login-consent__link">Terms of Use</a> and <a href="/privacy-policy" target="_blank" class="login-consent__link">Privacy Policy</a></span> 493 </label> 494 495 <button class="btn-brand w-100 btn-lg login-cta" id="sendOtpBtn" disabled>Send OTP</button> 496 <button type="button" class="btn btn-link btn-sm text-muted w-100 mt-2 d-none" id="backToMethodsLink">‹ Change login method</button> 497 </div> 498 </div> 499 500 <!-- Step 2: OTP --> 501 <div id="loginStep2" hidden> 502 <div class="login-otp__head"> 503 <h6 class="login-otp__heading">Enter the 6-digit code</h6> 504 <button type="button" id="changePhone" class="login-otp__edit">Edit</button> 505 </div> 506 <p class="login-otp__sentto">Sent to <strong id="loginPhoneDisplay"></strong></p> 507 <input type="text" class="form-control form-control-lg text-center mb-3" id="loginOtp" maxlength="6" placeholder="â â â â â â" inputmode="numeric" style="letter-spacing:.5rem;font-weight:600"> 508 <div class="login-otp__resend"> 509 <span class="login-otp__timer" id="resendTimerWrap">Resend code in <span id="resendTimer">0:30</span></span> 510 <button class="login-otp__resend-btn" id="resendBtn" disabled>Resend</button> 511 </div> 512 <button class="btn-brand w-100 btn-lg login-cta" id="verifyOtpBtn">Verify & Sign In</button> 513 </div> 514 515 <!-- Error msg --> 516 <div class="alert alert-danger mt-3 small" id="loginError" hidden></div> 517 518 <!-- Reassurance footer â shown on both steps --> 519 <p class="login-reassure">
520 <svg class="login-reassure__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg> 521 We never share your number. Used only for order updates. 522 </p> 523 </div> 524 </div> 525</div> 526 527<!-- Truecaller polling modal â shown by social_login.js while waiting for the SDK callback --> 528<div class="modal fade" id="truecallerModal" tabindex="-1" data-bs-backdrop="static"> 529 <div class="modal-dialog modal-dialog-centered" style="max-width:340px"> 530 <div class="modal-content" style="border-radius:var(--r-lg);border:none"> 531 <div class="modal-body p-4 text-center"> 532 <div class="spinner-border mb-3" role="status" aria-hidden="true"></div> 533 <h6 class="fw-bold mb-1">Verifying with Truecaller</h6> 534 <p class="text-muted small mb-3" id="truecallerStatusText">Complete the prompt in the Truecaller appâ¦</p> 535 <button type="button" class="btn btn-link btn-sm text-muted" data-bs-dismiss="modal" id="truecallerCancel">Cancel</button> 536 </div> 537 </div> 538 </div> 539</div> 540 541<div class="modal fade locationFlowModal" id="locationFlowModal" tabindex="-1" role="dialog" 542 aria-labelledby="locationFlowModal" data-bs-backdrop="static"> 543 <div class="modal-dialog modal-lg" role="document"> 544 <div class="modal-content"> 545 546 <!-- STEP: location --> 547 <div class="location-flow-step active" data-step="location"> 548 <div class="location-flow-step--inner"> 549 <div class="lp-brandhead"> 550 <img class="lp-brandhead__logo" src="https://cdn.uengage.io/brand_logo/logo-68249-1782395208.jpeg" alt="Good To Go"> 551 <button type="button" class="lp-brandhead__close" onclick="closeLocationFlow()" aria-label="Close"> 552 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg> 553 </button> 554 </div> 555 <div class="modal-body locationfetch-body"> 556 <div class="lp-entry-head"> 557 <h4 class="locationfetch-heading">Let's Find a Store Near You</h4> 558 <p class="locationfetch-subtext">Share your location and we'll handle the rest.</p> 559 </div> 560 <div id="locationModalContent"> 561 <button type="button" onclick="CurrentAddress();" class="locationfetch-btn-current"> 562 <svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 21 21" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.718 10.311c0 0.331 0.268 0.6 0.6 0.6h1.626a6.394 6.394 0 0 0 5.767 5.767v1.626a0.6 0.6 0 0 0 1.199 0V16.677a6.394 6.394 0 0 0 5.767 -5.767h1.626a0.6 0.6 0 1 0 0 -1.199H16.677a6.394 6.394 0 0 0 -5.767 -5.767V2.317a0.6 0.6 0 1 0 -1.199 0v1.626a6.394 6.394 0 0 0 -5.767 5.767H2.317a0.601 0.601 0 0 0 -0.6 0.6m5.595 0a2.998 2.998 0 1 1 5.994 0 2.998 2.998 0 0 1 -5.994 0" fill="currentColor"></path><path d="M8.512 10.311a1.799 1.799 0 1 1 3.598 0 1.799 1.799 0 0 1 -3.598 0" fill="currentColor"></path></svg> 563 <span>Use Your Current Location</span> 564 </button> 565 <div class="locationfetch-or" aria-hidden="true">OR</div> 566 <button type="button" onclick="showLocationStep('enterAddress'); return false;" class="lp-searchbar" aria-label="Enter pincode, locality, area etc."> 567 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"> 568 <circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/> 569 </svg>
570 <span class="lp-searchbar__ph">Enter pincode, locality, area etc.</span> 571 </button> 572 <div class="locationfetch-or" aria-hidden="true">OR</div> 573 <div class="alreadyhaveanaccount__cta lp-login-card" onclick="openLoginOrSavedAddresses()"> 574 <span class="lp-login-card__icon"> 575 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"> 576 <path d="M21 10c0 7-9 13-9 13S3 17 3 10a9 9 0 0118 0z"/><circle cx="12" cy="10" r="3"/> 577 </svg> 578 </span> 579 <span class="lp-login-card__text"> 580 <span class="lp-login-card__title">Log In to Use a Saved Address</span> 581 <span class="lp-login-card__sub">Use an address saved on your account</span> 582 </span> 583 <span class="lp-login-card__chev"> 584 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg> 585 </span> 586 </div> 587 </div> 588 <p class="error d-none" id="error-msg-show"></p> 589 </div> 590 </div> 591 </div> 592 593 <!-- STEP: savedAddresses --> 594 <div class="location-flow-step" data-step="savedAddresses"> 595 <div class="lp-brandhead"> 596 <img class="lp-brandhead__logo" src="https://cdn.uengage.io/brand_logo/logo-68249-1782395208.jpeg" alt="Good To Go"> 597 <button type="button" class="lp-brandhead__close" onclick="closeLocationFlow()" aria-label="Close"> 598 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg> 599 </button> 600 </div> 601 <div class="modal-body px-3 pt-3 pb-3"> 602 <div class="lp-entry-head"> 603 <h4 class="locationfetch-heading">Welcome Back<span id="lpWelcomeName"></span></h4> 604 <p class="locationfetch-subtext">Choose an address, or share a new location.</p> 605 </div> 606 <div class="savedaddress_card"> 607 <div class="savedaddress_box"> 608 <p>Saved Addresses</p> 609 </div> 610 <div id="savedaddress_list"></div> 611 </div> 612 <button onclick="CurrentAddress();" class="btn saved-addr-btn-current" type="button"> 613 <svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 21 21" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.718 10.311c0 0.331 0.268 0.6 0.6 0.6h1.626a6.394 6.394 0 0 0 5.767 5.767v1.626a0.6 0.6 0 0 0 1.199 0V16.677a6.394 6.394 0 0 0 5.767 -5.767h1.626a0.6 0.6 0 1 0 0 -1.199H16.677a6.394 6.394 0 0 0 -5.767 -5.767V2.317a0.6 0.6 0 1 0 -1.199 0v1.626a6.394 6.394 0 0 0 -5.767 5.767H2.317a0.601 0.601 0 0 0 -0.6 0.6m5.595 0a2.998 2.998 0 1 1 5.994 0 2.998 2.998 0 0 1 -5.994 0" fill="currentColor"></path><path d="M8.512 10.311a1.799 1.799 0 1 1 3.598 0 1.799 1.799 0 0 1 -3.598 0" fill="currentColor"></path></svg> 614 Use Your Current Location 615 </button> 616 <div class="locationfetch-or" aria-hidden="true">OR</div> 617 <button type="button" onclick="showLocationStep('enterAddress')" class="lp-searchbar" aria-label="Enter pincode, locality, area etc."> 618 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"> 619 <circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/> 620 </svg>
621 <span class="lp-searchbar__ph">Enter pincode, locality, area etc.</span> 622 </button> 623 </div> 624 </div> 625 626 <!-- STEP: enterAddress --> 627 <div class="location-flow-step" data-step="enterAddress"> 628 <div class="lp-brandhead"> 629 <img class="lp-brandhead__logo" src="https://cdn.uengage.io/brand_logo/logo-68249-1782395208.jpeg" alt="Good To Go"> 630 <button type="button" class="lp-brandhead__close" onclick="showLocationStep((window._lpPrevStep||'location'))" aria-label="Close"> 631 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg> 632 </button> 633 </div> 634 <div class="modal-body lp-enter-body"> 635 <div class="lp-entry-head lp-entry-head--tight"> 636 <h4 class="locationfetch-heading">Where Should We Deliver?</h4> 637 </div>
638 <ul class="lp-enter-checklist"> 639 <li> 640 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg> 641 <span>Order for yourself or someone else</span> 642 </li> 643 <li> 644 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg> 645 <span>Nearby — delivered in jiffy</span> 646 </li> 647 </ul> 648 <div class="form-subscribe lp-enter-search"> 649 <div class="lp-searchfield"> 650 <span class="lp-searchfield__icon" aria-hidden="true"> 651 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"> 652 <circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/> 653 </svg> 654 </span> 655 <!-- The lookup itself already accepts a pincode for every brand (it's a 656 generic locality/pincode search, not gated) â only the "ships pan-India" 657 promise above is brand-specific, so this placeholder isn't $isPincodeJourney-gated. --> 658 <input type="text" class="pincodeArea lp-searchfield__input" id="search_locality_new" 659 placeholder="Enter pincode, locality, area etc." autocomplete="off" 660 onkeyup="enterAddressSearchLocality(this.value)"> 661 </div> 662 <p class="lp-enter-hint">One search covers everything — we'll show what's possible for that address.</p> 663 <ul id="enterAddressLocalityResults" class="lp-result-list" style="display:none;"></ul> 664 <div class="mt-4 text-center" id="location_emptyImage"></div> 665 </div> 666 <button type="button" class="lp-current-link" onclick="CurrentAddress()"> 667 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 21 21" fill="none" aria-hidden="true"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.718 10.311c0 0.331 0.268 0.6 0.6 0.6h1.626a6.394 6.394 0 0 0 5.767 5.767v1.626a0.6 0.6 0 0 0 1.199 0V16.677a6.394 6.394 0 0 0 5.767 -5.767h1.626a0.6 0.6 0 1 0 0 -1.199H16.677a6.394 6.394 0 0 0 -5.767 -5.767V2.317a0.6 0.6 0 1 0 -1.199 0v1.626a6.394 6.394 0 0 0 -5.767 5.767H2.317a0.601 0.601 0 0 0 -0.6 0.6m5.595 0a2.998 2.998 0 1 1 5.994 0 2.998 2.998 0 0 1 -5.994 0" fill="currentColor"></path><path d="M8.512 10.311a1.799 1.799 0 1 1 3.598 0 1.799 1.799 0 0 1 -3.598 0" fill="currentColor"></path></svg> 668 <span>Or Use Your Current Location</span> 669 </button> 670 </div> 671 </div> 672 673 <!-- STEP: addressForm --> 674 <div class="location-flow-step homeAddressFormModal" data-step="addressForm"> 675 <!-- Full-width header (desktop) â mirrors the shared #addAddModal header. --> 676 <div class="addr-fullhead d-none d-md-flex"> 677 <div class="addr-fullhead__title"> 678 <h4 class="modal-title">Add New Address</h4> 679 <p class="addr-fullhead__sub">Pin your location on the map, then fill in the door details.</p> 680 </div> 681 <button type="button" class="modal-crossIcon modal-crossIcon--circle" onclick="closeAddressForm()" aria-label="Close"> 682 <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26" fill="none"> 683 <rect x="0.5" y="0.5" width="25" height="25" rx="12.5" fill="#F8F8F8"></rect> 684 <rect x="0.5" y="0.5" width="25" height="25" rx="12.5" stroke="#ECEAE6"></rect> 685 <path fill-rule="evenodd" clip-rule="evenodd" d="M18.3361 18.3342C18.061 18.5676 17.6332 18.5507 17.3806 18.2964L7.62578 8.47281C7.37324 8.2185 7.3916 7.82313 7.66678 7.58974C7.94195 7.35635 8.36975 7.37331 8.62229 7.62763L18.3771 17.4512C18.6297 17.7055 18.6113 18.1009 18.3361 18.3342Z" fill="#111111"></path> 686 <path fill-rule="evenodd" clip-rule="evenodd" d="M7.66581 18.3342C7.94099 18.5676 8.36878 18.5507 8.62132 18.2964L18.3762 8.47281C18.6287 8.2185 18.6104 7.82313 18.3352 7.58974C18.06 7.35635 17.6322 7.37331 17.3797 7.62763L7.62482 17.4512C7.37228 17.7055 7.39063 18.1009 7.66581 18.3342Z" fill="#111111"></path> 687 </svg> 688 </button> 689 </div> 690 <div class="addadress-starting"> 691 <div class="address-left address-nez"> 692 <div class="modal-header d-flex d-md-none"> 693 <div class="addr-mhead__titles">
694 <span class="modal-title">Pin location</span> 695 <span class="addr-mhead__step">Step 1 of 2</span> 696 </div> 697 <button type="button" class="p-0 modal-crossIcon" onclick="closeAddressForm()" aria-label="Close" style="background:none !important;border:none;"> 698 <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26" fill="none"> 699 <rect x="0.5" y="0.5" width="25" height="25" rx="12.5" fill="#F8F8F8"></rect> 700 <rect x="0.5" y="0.5" width="25" height="25" rx="12.5" stroke="#ECEAE6"></rect> 701 <path fill-rule="evenodd" clip-rule="evenodd" d="M18.3361 18.3342C18.061 18.5676 17.6332 18.5507 17.3806 18.2964L7.62578 8.47281C7.37324 8.2185 7.3916 7.82313 7.66678 7.58974C7.94195 7.35635 8.36975 7.37331 8.62229 7.62763L18.3771 17.4512C18.6297 17.7055 18.6113 18.1009 18.3361 18.3342Z" fill="#111111"></path> 702 <path fill-rule="evenodd" clip-rule="evenodd" d="M7.66581 18.3342C7.94099 18.5676 8.36878 18.5507 8.62132 18.2964L18.3762 8.47281C18.6287 8.2185 18.6104 7.82313 18.3352 7.58974C18.06 7.35635 17.6322 7.37331 17.3797 7.62763L7.62482 17.4512C7.37228 17.7055 7.39063 18.1009 7.66581 18.3342Z" fill="#111111"></path> 703 </svg> 704 </button> 705 </div> 706 <div class="map-outer"> 707 <div class="map-search"> 708 <span class="map-button" aria-hidden="true"> 709 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" style="width:100%;max-width:22px;" stroke="#000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"> 710 <circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/> 711 </svg> 712 </span> 713 <input type="text" id="homeLocalitySearchInput" class="form-control" placeholder="Search apartment, street or areaâ¦" autocomplete="off" onkeyup="homeSearchLocality(this.value)"> 714 <button type="button" class="addr-map__useloc" onclick="homeAddrGoToCurrentLocation(true)" aria-label="Use my location"> 715 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="3" fill="currentColor" stroke="none"/><line x1="12" y1="2" x2="12" y2="5"/><line x1="12" y1="19" x2="12" y2="22"/><line x1="2" y1="12" x2="5" y2="12"/><line x1="19" y1="12" x2="22" y2="12"/></svg> 716 <span>Use my location</span> 717 </button> 718 <ul id="homeLocalityResults" 719 style="display:none;position:absolute;top:100%;left:0;right:0;z-index:1050;background:#fff;max-height:250px;overflow-y:auto;list-style:none;padding:0;margin:0;border:1px solid #ddd;border-top:none;border-radius:0 0 8px 8px;box-shadow:0 4px 12px rgba(0,0,0,0.1);"></ul> 720 </div> 721 <div class="row m-0"> 722 <div class="col-12 m-0 p-0"> 723 <div id="homeLeafletMap" style="height:388px;background:#e8e8e8;display:flex;align-items:center;justify-content:center;"> 724 <p style="color:#888;font-size:14px;">Search a locality to view map</p> 725 </div> 726 </div> 727 </div> 728 <!-- Decorative pin coach-mark (centered above the map pin). --> 729 <div class="addr-map__tip" aria-hidden="true"> 730 <strong>Your order will be delivered here</strong>
731 <span>Move the map to place the pin</span> 732 </div> 733 </div> 734 <!-- Geolocation ("Use my location") failure â shown on the MAP step so it's 735 visible on mobile where the button lives, not hidden on the form step. --> 736 <div class="addr-map__error" id="homeLocateError" hidden></div> 737 <div id="homeAddrMapInfo" style="display:none;"> 738 <div class="addr-map__info"> 739 <span class="addr-map__info-pin" aria-hidden="true"> 740 <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg> 741 </span> 742 <div class="addr-map__info-text"> 743 <p class="addr-map__info-loc"> 744 <span id="homeAddrMapLocality"></span> 745 <span class="addr-map__badge">Delivering here</span> 746 </p> 747 <p class="addr-map__info-full" id="homeAddrMapFullAddress"></p> 748 </div> 749 </div> 750 </div> 751 <div id="confirmLocationBtn" class="confirmLocationBtn"> 752 <button type="button" class="btn btn-primary animatebtn w-100" 753 style="background-color:var(--brand);color:#fff;padding:12px;font-size:16px;font-weight:600;border-radius:10px;" 754 onclick="confirmLocationAndShowForm()" disabled> 755 Confirm pin 756 </button> 757 </div> 758 </div> 759 <div class="address-right" id="addressFormRight"> 760 <div class="modal-header d-flex d-md-none" style="gap:8px;align-items:center;"> 761 <button type="button" class="icon-btn-back" onclick="backToLocationMap()" aria-label="Back to map"> 762 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6"/></svg> 763 </button> 764 <div class="addr-mhead__titles"> 765 <span class="modal-title">Address details</span> 766 <span class="addr-mhead__step">Step 2 of 2</span> 767 </div> 768 </div> 769 <div class="modal-body"> 770 <!-- Confirmed-location green card (mirror of the shared #addAddModal card). --> 771 <div id="homeAddrFormInfo" style="display:none;"> 772 <div class="addr-form-info"> 773 <span class="addr-form-info__check" aria-hidden="true"> 774 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg> 775 </span> 776 <div class="addr-form-info__text"> 777 <p class="addr-form-info__loc" id="homeAddrFormLocality"></p> 778 <p class="addr-form-info__sub">Locality & city set from the map pin â no need to type them.</p> 779 <p class="addr-form-info__full" id="homeAddrFormFullAddress" hidden></p> 780 </div> 781 <button type="button" class="addr-form-info__change" onclick="homeChangeOnMap()">Change on map</button> 782 </div> 783 </div> 784 <form class="contact-bx" onsubmit="return false;"> 785 <div class="row"> 786 <div class="col-lg-12"> 787 <div class="form-group"><div class="input-group"> 788 <label for="homeAddrLine1" class="mb-0">House / Flat / Office No. <span class="addr-req">*</span></label> 789 <input type="text" id="homeAddrLine1" class="form-control" placeholder="e.g. B-204, 2nd floor" maxlength="100"> 790 <p class="addr-field-hint">This is the only detail the rider can't see on the map â be specific.</p> 791 </div></div> 792 </div> 793 <div class="col-lg-12"> 794 <div class="form-group"><div class="input-group"> 795 <label for="homeAddrLine2" class="mb-0">Landmark <span class="addr-opt">(optional)</span></label> 796 <input type="text" id="homeAddrLine2" class="form-control" placeholder="e.g. opposite Committee centre" maxlength="50"> 797 </div></div> 798 </div> 799 </div> 800 <div class="addr-row-2"> 801 <div class="form-group"><div class="input-group"> 802 <label for="homeAddrPhone" class="mb-0">Phone Number <span class="addr-req">*</span></label> 803 <div class="addr-phone">
804 <span class="addr-phone__cc">+91</span> 805 <input type="text" id="homeAddrPhone" class="form-control" placeholder="9915550701" maxlength="10"> 806 </div> 807 </div></div> 808 <div class="form-group"><div class="input-group"> 809 <label for="homeAddrEmail" class="mb-0">Email <span class="addr-opt">(optional)</span></label> 810 <input type="text" id="homeAddrEmail" class="form-control" placeholder="[email protected]" maxlength="50"> 811 </div></div> 812 </div> 813 <!-- Locality & City are resolved from the map pin and shown in the green 814 confirmed-location card above, so the visible fields are hidden from the 815 form. The save payload still posts them via the hidden #homeAddrLocality / 816 #homeAddrCity inputs below (location_picker.js reads state + those). --> 817 <div class="addr-save-as"> 818 <h4 class="location-hd">Save as</h4> 819 <div class="custom-radios"> 820 <div onclick="document.querySelector('input[name=homeAddrType][value=Home]').checked=true;"> 821 <input value="Home" id="homeRadio1" name="homeAddrType" type="radio" checked> 822 <label for="homeRadio1" class="animatebtn"><span>Home</span></label> 823 </div> 824 <div onclick="document.querySelector('input[name=homeAddrType][value=Office]').checked=true;"> 825 <input value="Office" id="homeRadio2" name="homeAddrType" type="radio"> 826 <label for="homeRadio2" class="animatebtn"><span>Office</span></label> 827 </div> 828 <div onclick="document.querySelector('input[name=homeAddrType][value=Hotel]').checked=true;"> 829 <input value="Hotel" id="homeRadio3" name="homeAddrType" type="radio"> 830 <label for="homeRadio3" class="animatebtn"><span>Hotel</span></label> 831 </div> 832 <div onclick="document.querySelector('input[name=homeAddrType][value=Other]').checked=true;"> 833 <input value="Other" id="homeRadio4" name="homeAddrType" type="radio"> 834 <label for="homeRadio4" class="animatebtn"><span>Other</span></label> 835 </div> 836 </div> 837 </div> 838 <input type="hidden" id="homeAddrLat"> 839 <input type="hidden" id="homeAddrLng"> 840 <input type="hidden" id="homeAddrCity"> 841 <input type="hidden" id="homeAddrState"> 842 <input type="hidden" id="homeAddrPincode"> 843 <input type="hidden" id="homeAddrLocality"> 844 </form> 845 </div> 846 <div class="modal-footer" style="flex-direction:column;align-items:stretch;"> 847 <p id="homeAddrError" class="homeAddrError text-center d-none mb-1"></p> 848 <button type="button" class="btn btn-primary animatebtn" id="homeAddrSaveBtn" onclick="saveHomeAddress()" style="background-color:var(--brand);border-color:var(--brand);color:#fff;opacity:0.5;" disabled>Save Address & Deliver Here</button> 849 </div> 850 </div> 851 </div> 852 </div> 853 854 <!-- STEP: orderType --> 855 <div class="location-flow-step modal--grid--delivery" data-step="orderType"> 856 <div class="lp-brandhead"> 857 <img class="lp-brandhead__logo" src="https://cdn.uengage.io/brand_logo/logo-68249-1782395208.jpeg" alt="Good To Go"> 858 <button type="button" class="lp-brandhead__close" onclick="closeLocationFlow()" aria-label="Close"> 859 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg> 860 </button> 861 </div> 862 <div class="modal-header"> 863 <div class="modal-header-content w-100"> 864 <div class="ordertype-modal-location-info w-100"> 865 <div class="ordertype-modal-location-row"> 866 <div class="ordertype-modal-location-title modal-title"> 867 <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="#22c55e"> 868 <path d="M12 0a12 12 0 100 24 12 12 0 000-24zm5.3 9.05l-6.86 6.86a1 1 0 01-1.42 0L5.7 12.6a1 1 0 011.42-1.42l2.6 2.6 6.16-6.16a1 1 0 011.42 1.43z"/> 869 </svg>
870 <span>Your Location</span> 871 </div> 872 <div class="ordertype-modal-actions"> 873 <button type="button" onclick="changeUserLocation()" class="ordertype-modal-location-change">Change</button> 874 </div> 875 </div> 876 <p class="ordertype-modal-address" id="orderTypeModal_address"></p> 877 </div> 878 </div> 879 </div> 880 <div class="modal-body px-3 pt-3"> 881 <p class="ordertype-modal-heading pb-0 mb-0" id="orderTypeHeading">Great, you're covered! How would you like your order?</p> 882 <div class="grid order-type-grid" id="orderTypeButtonsContainer"> 883 <div class="location_header--card order-type-card" id="orderTypeBtn_2" style="display:none;" onclick="selectOrderTypeAndRedirect(2)" data-order-type="2"> 884 <span class="order-type-card__icon"> 885 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 886 <path d="M5 7h14l-1 13a1 1 0 0 1-1 .9H7a1 1 0 0 1-1-.9z"/> 887 <path d="M8.5 7V5.5a3.5 3.5 0 0 1 7 0V7"/> 888 </svg> 889 </span> 890 <span class="order-type-card__text"> 891 <span class="order-type-card__label">Pick Up</span> 892 <span class="order-type-card__sub">Skip the queue</span> 893 </span> 894 <span class="order-type-card__chev" aria-hidden="true"> 895 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M9 18l6-6-6-6"/></svg> 896 </span> 897 </div> 898 <div class="location_header--card order-type-card" id="orderTypeBtn_1" style="display:none;" onclick="selectOrderTypeAndRedirect(1)" data-order-type="1"> 899 <span class="order-type-card__icon"> 900 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 901 <rect x="1.5" y="6" width="12" height="9" rx="1"/> 902 <path d="M13.5 9h3.6a2 2 0 0 1 1.7 1l1.9 3a2 2 0 0 1 .3 1v1.5a.5.5 0 0 1-.5.5H13.5z"/> 903 <circle cx="6" cy="17.5" r="1.9"/><circle cx="17.5" cy="17.5" r="1.9"/> 904 </svg> 905 </span> 906 <span class="order-type-card__text"> 907 <span class="order-type-card__label">Delivery</span> 908 <span class="order-type-card__sub">To your doorstep</span> 909 </span> 910 <span class="order-type-card__chev" aria-hidden="true"> 911 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M9 18l6-6-6-6"/></svg> 912 </span> 913 </div> 914 <div class="location_header--card order-type-card" id="orderTypeBtn_3" style="display:none;" onclick="selectOrderTypeAndRedirect(3)" data-order-type="3"> 915 <span class="order-type-card__icon"> 916 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 917 <path d="M4 3v6a2.2 2.2 0 0 0 4.4 0V3"/> 918 <path d="M6.2 9v12"/> 919 <path d="M19 14V3a4 4 0 0 0-4 4v5a2 2 0 0 0 2 2h2Zm0 0v7"/> 920 </svg> 921 </span>
922 <span class="order-type-card__text"> 923 <span class="order-type-card__label">Dine In</span> 924 <span class="order-type-card__sub">Order from your table</span> 925 </span> 926 <span class="order-type-card__chev" aria-hidden="true"> 927 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M9 18l6-6-6-6"/></svg> 928 </span> 929 </div> 930 <div class="location_header--card order-type-card" id="orderTypeBtn_4" style="display:none;" onclick="selectOrderTypeAndRedirect(4)" data-order-type="4"> 931 <span class="order-type-card__icon"> 932 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 933 <path d="M4 11l1.6-4.2A2 2 0 0 1 7.5 5.5h6.9a2 2 0 0 1 1.7.9L18.5 10"/> 934 <path d="M2.5 11h18a1.5 1.5 0 0 1 1.5 1.5V16a1 1 0 0 1-1 1h-1"/> 935 <path d="M4 17H3a1 1 0 0 1-1-1v-3.5A1.5 1.5 0 0 1 3.5 11"/> 936 <circle cx="7" cy="17" r="2"/><circle cx="17" cy="17" r="2"/> 937 <path d="M9 17h6"/> 938 </svg> 939 </span> 940 <span class="order-type-card__text"> 941 <span class="order-type-card__label">In-Car</span> 942 <span class="order-type-card__sub">Served at your car</span> 943 </span> 944 <span class="order-type-card__chev" aria-hidden="true"> 945 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M9 18l6-6-6-6"/></svg> 946 </span> 947 </div> 948 <div class="location_header--card order-type-card" id="orderTypeBtn_5" style="display:none;" onclick="selectOrderTypeAndRedirect(5)" data-order-type="5"> 949 <span class="order-type-card__icon"> 950 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 951 <rect x="3" y="4.5" width="18" height="16.5" rx="2"/> 952 <path d="M3 9.5h18"/> 953 <path d="M8 2.5v4"/><path d="M16 2.5v4"/> 954 <path d="M8.5 15l2.2 2.2 4.3-4.3"/> 955 </svg> 956 </span> 957 <span class="order-type-card__text"> 958 <span class="order-type-card__label">Reservation</span> 959 <span class="order-type-card__sub">Reserve in advance</span> 960 </span> 961 <span class="order-type-card__chev" aria-hidden="true"> 962 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M9 18l6-6-6-6"/></svg> 963 </span> 964 </div> 965 <div class="location_header--card order-type-card" id="orderTypeBtn_6" style="display:none;" onclick="selectOrderTypeAndRedirect(6)" data-order-type="6"> 966 <span class="order-type-card__icon"> 967 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 968 <rect x="2" y="5" width="20" height="14" rx="2"/> 969 <path d="M2 10h20"/> 970 <path d="M6 15h4"/> 971 </svg> 972 </span>
973 <span class="order-type-card__text"> 974 <span class="order-type-card__label">Direct Pay</span> 975 <span class="order-type-card__sub">Pay your bill here</span> 976 </span> 977 <span class="order-type-card__chev" aria-hidden="true"> 978 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M9 18l6-6-6-6"/></svg> 979 </span> 980 </div> 981 </div> 982 <!-- Shown by renderOrderTypes() when the resolved outlet has no order 983 type enabled: every card above is hidden, so without this the step 984 renders as an empty panel under the heading. Two ways forward â 985 "Change" (above) to re-pick a location, or the full outlet list. --> 986 <div class="ordertype-modal-empty" id="orderTypeEmpty" hidden> 987 <p class="ordertype-modal-empty__msg">This outlet isn't accepting online orders right now.</p> 988 <a href="/store-locator" class="ordertype-modal-empty__link">Browse all outlets</a> 989 </div> 990 </div> 991 </div> 992 993 <!-- STEP: redirect --> 994 <div class="location-flow-step" data-step="redirect"> 995 <div class="lp-brandhead"> 996 <img class="lp-brandhead__logo" src="https://cdn.uengage.io/brand_logo/logo-68249-1782395208.jpeg" alt="Good To Go"> 997 <button type="button" class="lp-brandhead__close" onclick="closeLocationFlow()" aria-label="Close"> 998 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg> 999 </button> 1000 </div> 1001 <div class="modal-body redirect-step"> 1002 <div class="redirect-row"> 1003 <span class="redirect-row__check" aria-hidden="true"> 1004 <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="#22c55e"> 1005 <path d="M12 0a12 12 0 100 24 12 12 0 000-24zm5.3 9.05l-6.86 6.86a1 1 0 01-1.42 0L5.7 12.6a1 1 0 011.42-1.42l2.6 2.6 6.16-6.16a1 1 0 011.42 1.43z"/> 1006 </svg> 1007 </span> 1008 <span class="redirect-row__label">Your Location</span> 1009 <span class="redirect-row__value" id="redirectModal_address"></span> 1010 <span class="redirect-row__ot" id="redirectModal_orderType"></span> 1011 </div> 1012 <div class="redirect-row"> 1013 <span class="redirect-row__check" aria-hidden="true"> 1014 <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="#22c55e"> 1015 <path d="M12 0a12 12 0 100 24 12 12 0 000-24zm5.3 9.05l-6.86 6.86a1 1 0 01-1.42 0L5.7 12.6a1 1 0 011.42-1.42l2.6 2.6 6.16-6.16a1 1 0 011.42 1.43z"/> 1016 </svg> 1017 </span> 1018 <span class="redirect-row__label">Selected Outlet</span> 1019 <span class="redirect-row__value" id="redirectModal_outlet"></span> 1020 <button type="button" onclick="changeUserLocation()" class="redirect-row__change">Change</button> 1021 </div> 1022 <div class="redirect-banner">All set! Your nearest outlet is ready to serve you</div> 1023 <div class="redirect-loader" id="redirectLoader"> 1024 <div class="redirect-loader__progress"> 1025 <span class="redirect-loader__fill" id="redirectProgressBar"></span>
1026 <span class="redirect-loader__text"> 1027 <svg class="redirect-loader__spinner" width="14" height="14" viewBox="0 0 24 24" 1028 fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true"> 1029 <path d="M21 12a9 9 0 1 1-6.22-8.56"/> 1030 </svg> 1031 <span id="redirectProgressText">Taking you to the menu in 3...</span> 1032 </span> 1033 </div> 1034 <button type="button" class="redirect-loader__cancel" id="redirectCancelBtn" 1035 onclick="cancelRedirect(); return false;" aria-label="Stop redirect"> 1036 <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" 1037 stroke-width="2.5" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg> 1038 </button> 1039 </div> 1040 </div> 1041 </div> 1042 1043 <!-- STEP: notServiceable --> 1044 <div class="location-flow-step" data-step="notServiceable"> 1045 <div class="modal-body text-center pt-4 pb-4"> 1046 <div class="mb-3"> 1047 <svg xmlns="http://www.w3.org/2000/svg" width="120" height="120" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="1.2"> 1048 <path d="M21 10c0 7-9 13-9 13S3 17 3 10a9 9 0 0118 0z"/><circle cx="12" cy="10" r="3"/> 1049 <line x1="3" y1="3" x2="21" y2="21" stroke="#e63946" stroke-width="2"/> 1050 </svg> 1051 </div> 1052 <p class="font-weight-500 mb-0">No nearest serviceable outlet found, please explore some other menu.</p> 1053 <div class="btn btn-primary animatebtn errorCta--primary mt-3" onclick="exploreNearestOutlet();" style="background-color:var(--brand);border-color:var(--brand);color:#fff;cursor:pointer;">Explore Menu</div> 1054 </div> 1055 </div> 1056 1057 </div> 1058 </div> 1059</div> 1060 1061<div class="profile-overlay" id="profileOverlay" hidden></div> 1062<aside class="profile-sidebar" id="profileSidebar" aria-label="Profile menu" aria-hidden="true"> 1063 1064 <div class="profile-sidebar__body"> 1065 1066 <div class="ao-sidebar" data-ao-root hidden> 1067 <div class="ao-list" data-ao-list role="list"></div> 1068 <button type="button" class="ao-sidebar__toggle" data-ao-toggle hidden> 1069 <span data-ao-toggle-label>See more orders</span> 1070 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" 1071 stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg> 1072 </button> 1073</div> 1074 1075 <div class="profile-sidebar__card"> 1076 1077 <div class="profile-sidebar__header"> 1078 <div class="profile-sidebar__avatar"> 1079 <svg width="32" height="32" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"> 1080 <path d="M12 12a5 5 0 1 0 0-10 5 5 0 0 0 0 10Zm0 2c-4.42 0-8 2.69-8 6v1h16v-1c0-3.31-3.58-6-8-6Z"/> 1081 </svg> 1082 </div> 1083 <div class="profile-sidebar__user"> 1084 <p class="profile-sidebar__name" id="psName">Loadingâ¦</p> 1085 <p class="profile-sidebar__email" id="psEmail"></p> 1086 </div> 1087 <button type="button" class="profile-sidebar__close" id="profileSidebarClose" aria-label="Close"> 1088 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg> 1089 </button> 1090 </div> 1091 1092 <nav class="profile-sidebar__menu"> 1093 1094 <a href="/profile" class="profile-sidebar__item"> 1095 <span class="profile-sidebar__icon"><img src="https://goodtogostore.com/assets/wla_new/img/personal_info_ic.png" alt="Personal Information icon" width="18" height="20" loading="lazy"></span>
1096 <span class="profile-sidebar__label">Personal Information</span> 1097 </a> 1098 1099 <a href="/past-order" class="profile-sidebar__item"> 1100 <span class="profile-sidebar__icon"><img src="https://goodtogostore.com/assets/wla_new/img/my_orders_ic.png" alt="My Orders icon" width="18" height="20" loading="lazy"></span> 1101 <span class="profile-sidebar__label">My Orders</span> 1102 </a> 1103 1104 <a href="/memberships" class="profile-sidebar__item"> 1105 <span class="profile-sidebar__icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M7 9h6M7 13h4M16 13l1.5 1.5L21 11"/></svg></span> 1106 <span class="profile-sidebar__label">Memberships</span> 1107 </a> 1108 1109 1110 1111 <a href="/profile/manage-addresses" class="profile-sidebar__item"> 1112 <span class="profile-sidebar__icon"><img src="https://goodtogostore.com/assets/wla_new/img/manage_address_ic.png" alt="Manage Addresses icon" width="18" height="20" loading="lazy"></span> 1113 <span class="profile-sidebar__label">Manage Addresses</span> 1114 </a> 1115 1116 1117 <a href="/faqs" class="profile-sidebar__item"> 1118 <span class="profile-sidebar__icon"><img src="https://goodtogostore.com/assets/wla_new/img/faq_ic.png" alt="FAQs icon" width="18" height="20" loading="lazy"></span> 1119 <span class="profile-sidebar__label">FAQs</span> 1120 </a> 1121 1122 <a href="/refund-policy" class="profile-sidebar__item"> 1123 <span class="profile-sidebar__icon"><img src="https://goodtogostore.com/assets/wla_new/img/track_refund_ic.png" alt="Track my Refund icon" width="18" height="20" loading="lazy"></span> 1124 <span class="profile-sidebar__label">How to track my Refund?</span> 1125 </a> 1126 1127 <a href="#" class="profile-sidebar__item" data-raise-concern> 1128 <span class="profile-sidebar__icon"><img src="https://goodtogostore.com/assets/wla_new/img/concern_ic.png" alt="Raise a Concern icon" width="18" height="20" loading="lazy"></span> 1129 <span class="profile-sidebar__label">Raise a Concern</span> 1130 </a> 1131 1132 </nav> 1133 1134 <button type="button" class="profile-sidebar__logout" id="psLogout"> 1135 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg> 1136 <span>Logout</span> 1137 </button> 1138 1139 </div> 1140 1141 <p class="profile-sidebar__powered"> 1142 <span>Powered By</span> 1143 <a href="https://www.uengage.in/" target="_blank" rel="noopener" aria-label="uEngage"> 1144 <img src="https://goodtogostore.com/assets/img/footer/uengage-logo.svg" alt="uEngage" width="90" height="22" loading="lazy"> 1145 </a> 1146 </p> 1147 1148 </div> 1149</aside> 1150 1151<!-- Raise a Concern (Help & Support) â global modal, wired by raiseConcern.js. 1152 CI3 parity: #raseaconcern â /support/getConcernType + /support/raiseConcern. 1153 The accordion is populated at runtime from the concern-type API. --> 1154<div class="modal fade" id="raiseConcernModal" tabindex="-1" aria-labelledby="raiseConcernLabel" aria-hidden="true"> 1155 <div class="modal-dialog modal-dialog-centered"> 1156 <div class="modal-content help-modal-content"> 1157 <div class="modal-header"> 1158 <h5 class="modal-title" id="raiseConcernLabel">Help & Support</h5> 1159 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 1160 </div> 1161 <div class="modal-body"> 1162 <p class="help-modal-intro">We're sorry for any inconvenience. Pick a topic below â we'll get back to you shortly.</p> 1163 <form id="raiseConcernForm" autocomplete="off">
1164 <input type="hidden" id="rcConcernType" value=""> 1165 <div class="accordion help-accordion" id="rcAccordion"> 1166 <p class="rc-state" data-rc-state>Loadingâ¦</p> 1167 </div> 1168 </form> 1169 <p class="rc-status" id="rcStatus" role="status" aria-live="polite" hidden></p> 1170 </div> 1171 </div> 1172 </div> 1173</div> 1174 1175<!-- Secondary picker for order / outlet selection â CI3 #other-inputs parity. --> 1176<div class="modal fade" id="rcPickerModal" tabindex="-1" aria-labelledby="rcPickerTitle" aria-hidden="true"> 1177 <div class="modal-dialog modal-dialog-centered"> 1178 <div class="modal-content help-modal-content"> 1179 <div class="modal-header"> 1180 <h5 class="modal-title" id="rcPickerTitle">Select</h5> 1181 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 1182 </div> 1183 <div class="modal-body"> 1184 <div class="rc-list" id="rcPickerList"></div> 1185 </div> 1186 </div> 1187 </div> 1188</div> 1189 1190<!-- Global cart FAB â site-wide quick access to the cart. floating_cart.js reveals 1191 it only when the user is logged in and the selected outlet's cart (v4_cart) 1192 has items. Hidden on the menu/cart/checkout pages, which carry their own 1193 cart UI. CI3 #cart_icon parity. --> 1194<button type="button" class="cart-fab" id="cartFab" aria-label="View your cart" hidden> 1195 <svg class="cart-fab__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 1196 <circle cx="9" cy="21" r="1"></circle> 1197 <circle cx="20" cy="21" r="1"></circle> 1198 <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path> 1199 </svg> 1200 <span class="cart-fab__count" id="cartFabCount">0</span> 1201</button> 1202 1203<!-- Login logic -->
1204<script> 1205(function(){ 1206 const captchaEnabled = 1; 1207 const consentCb = document.getElementById('loginConsent'); 1208 const consentCbSocial = document.getElementById('loginConsentSocial'); 1209 const sendBtn = document.getElementById('sendOtpBtn'); 1210 const phoneInp = document.getElementById('loginPhone'); 1211 const captchaInp = document.getElementById('captchaInput'); 1212 const captchaSection = document.getElementById('captchaSection'); 1213 const captchaRow = document.getElementById('captchaRow'); 1214 const captchaHint = document.getElementById('captchaHint'); 1215 1216 // Hide captcha section if not enabled 1217 if(!captchaEnabled && captchaSection) captchaSection.hidden = true; 1218 1219 // Security code stays disabled until a valid 10-digit number is entered. 1220 // Its label reflects the state; the code clears when the field disables. 1221 function phoneValid(){ return !!(phoneInp && phoneInp.value.length === 10); } 1222 function updateCaptchaState(){ 1223 if(!captchaEnabled || !captchaInp) return; 1224 const ok = phoneValid(); 1225 captchaInp.disabled = !ok; 1226 if(!ok) captchaInp.value = ''; 1227 if(captchaRow) captchaRow.classList.toggle('is-disabled', !ok); 1228 if(captchaHint) captchaHint.textContent = ok ? 'Type the code shown below' : 'Enter your mobile number first'; 1229 } 1230 1231 // Enable send button when consent + phone + captcha (if required) are valid. 1232 // Either consent checkbox (social-view or OTP-view) satisfies the gate since they're synced. 1233 function checkReady(){ 1234 let ok = consentCb && consentCb.checked && phoneValid(); 1235 if(captchaEnabled && captchaInp) ok = ok && captchaInp.value.length >= 4; 1236 if(sendBtn){ sendBtn.disabled = !ok; } 1237 } 1238 1239 // Keep the two consent checkboxes (social-view + OTP-view) in lockstep. When the 1240 // social-view checkbox changes, dispatch a 'change' on the OTP-view one so 1241 // social_login.js's updateConsentGating() (which gates WhatsApp) fires from one place. 1242 let syncingConsent = false; 1243 function syncConsent(source){ 1244 if(syncingConsent || !source) return; 1245 syncingConsent = true; 1246 const target = source === consentCb ? consentCbSocial : consentCb; 1247 if(target) target.checked = source.checked; 1248 if(source !== consentCb && consentCb){ 1249 consentCb.dispatchEvent(new Event('change')); 1250 } 1251 checkReady(); 1252 syncingConsent = false; 1253 } 1254 if(consentCb) consentCb.addEventListener('change', () => syncConsent(consentCb)); 1255 if(consentCbSocial) consentCbSocial.addEventListener('change', () => syncConsent(consentCbSocial)); 1256 // Auth-funnel one-shots. Both fire on the FIRST time the field becomes valid within a 1257 // given modal session â an 'input' listener would otherwise emit on every keystroke 1258 // (and again on every edit). showLogin() resets them so a second login attempt in the 1259 // same page view is counted as its own pass through the funnel. 1260 let _firedMobile = false, _firedCaptcha = false; 1261 window._resetAuthFunnelFlags = function(){ _firedMobile = false; _firedCaptcha = false; }; 1262 1263 // Digits-only guard â inputmode="numeric" only hints the mobile keyboard; desktop 1264 // typing (and paste) still lets letters through, so strip non-digits on every input. 1265 if(phoneInp) phoneInp.addEventListener('input', () => { 1266 const digits = phoneInp.value.replace(/\D/g, '').slice(0, 10); 1267 if(phoneInp.value !== digits) phoneInp.value = digits; 1268 if(!_firedMobile && phoneValid()){ 1269 _firedMobile = true; 1270 window.Analytics?.trackMobileEntered?.(); 1271 } 1272 updateCaptchaState(); checkReady(); 1273 }); 1274 if(captchaInp) captchaInp.addEventListener('input', () => { 1275 const digits = captchaInp.value.replace(/\D/g, '').slice(0, 4); 1276 if(captchaInp.value !== digits) captchaInp.value = digits; 1277 if(!_firedCaptcha && captchaInp.value.length >= 4){ 1278 _firedCaptcha = true; 1279 window.Analytics?.trackCaptchaCompleted?.(); 1280 } 1281 checkReady(); 1282 }); 1283 // Initial state on load (captcha disabled, label prompt, Send OTP gated). 1284 updateCaptchaState(); 1285 checkReady(); 1286 1287 // Load captcha image 1288 function loadCaptcha(){ 1289 if(!captchaEnabled) return; 1290 const img = document.getElementById('captchaImgTag'); 1291 if(img) img.src = '/auth/captcha?' + Date.now(); 1292 } 1293 document.getElementById('refreshCaptcha')?.addEventListener('click', loadCaptcha); 1294 1295 // Send OTP (POST to /auth/send-otp) â businessId required (CI2 client/login contract) 1296 if(sendBtn) sendBtn.addEventListener('click', async function(){ 1297 const phone = phoneInp.value.trim(); 1298 if(phone.length !== 10) return; 1299 sendBtn.disabled = true; sendBtn.textContent = 'Sending...'; 1300 // Fired BEFORE the request: the gap between otp_initiated and send_otp is 1301 // OTP-delivery failure, not user drop-off. Those are different problems. 1302 window.Analytics?.trackOtpInitiated?.(); 1303 try{ 1304 const body = { mobile: phone, businessId: (window.AppConfig && window.AppConfig.businessId) || 0 }; 1305 if(captchaEnabled && captchaInp) body.captcha = captchaInp.value.trim(); 1306 const r = await fetch('/auth/send-otp', { 1307 method: 'POST', 1308 headers: { 'Content-Type': 'application/json' }, 1309 body: JSON.stringify(body) 1310 }); 1311 const d = await r.json(); 1312 if(d.status == 1){ 1313 window.Analytics?.trackOtpSent?.(); 1314 document.getElementById('loginStep1').hidden = true; 1315 document.getElementById('loginStep2').hidden = false;
1316 document.getElementById('loginPhoneDisplay').textContent = '+91 ' + phone; 1317 document.getElementById('loginError').hidden = true; 1318 startResendTimer(); 1319 1320 } else { 1321 showLoginError(d.msg || 'Failed to send OTP'); 1322 if(captchaEnabled) loadCaptcha(); // Refresh captcha on error 1323 } 1324 }catch(e){ showLoginError('Network error. Please try again.'); } 1325 sendBtn.disabled = false; sendBtn.textContent = 'Send OTP'; 1326 checkReady(); 1327 }); 1328 1329 // Verify OTP (POST to /auth/verify-otp) 1330 const verifyBtn = document.getElementById('verifyOtpBtn'); 1331 if(verifyBtn) verifyBtn.addEventListener('click', async function(){ 1332 const phone = phoneInp.value.trim(); 1333 const otp = document.getElementById('loginOtp').value.trim(); 1334 if(otp.length < 4) return; 1335 verifyBtn.disabled = true; verifyBtn.textContent = 'Verifying...'; 1336 try{ 1337 // Consent: the terms checkbox gates Send OTP, so it's accepted by now. 1338 // No separate age/marketing UI â mirror terms into age, marketing stays 0. 1339 const consented = (consentCb && consentCb.checked) ? '1' : '0'; 1340 const r = await fetch('/auth/verify-otp', { 1341 method: 'POST', 1342 headers: { 'Content-Type': 'application/json' }, 1343 body: JSON.stringify({ 1344 mobile: phone, otp: otp, 1345 businessId: (window.AppConfig && window.AppConfig.businessId) || 0, 1346 data_consent: consented, 1347 age_consent: consented 1348 }) 1349 }); 1350 const d = await r.json(); 1351 if(d.status == 1 && d.rows){ 1352 // verify-otp upstream doesn't echo the number back â carry the 1353 // typed phone into userdata so downstream API calls (getOrderInfo, 1354 // getAllStores, wallet) can send the required `mobile` param. 1355 // CI3 parity: wla_20260505.js stored `mobile: mobileNo` explicitly. 1356 if(!d.rows.mobile) d.rows.mobile = phone; 1357 window.Analytics?.trackOtpValidated?.(); 1358 window._completeLogin(d.rows, 'otp'); 1359 } else { 1360 showLoginError(d.msg || 'Invalid OTP'); 1361 } 1362 }catch(e){ showLoginError('Network error. Please try again.'); } 1363 verifyBtn.disabled = false; verifyBtn.textContent = 'Verify & Login'; 1364 }); 1365 1366 // Auto-submit once the full 6-digit OTP is entered (CI3 parity: no manual tap needed) 1367 const otpInp = document.getElementById('loginOtp'); 1368 if(otpInp && verifyBtn) otpInp.addEventListener('input', function(){ 1369 // Keep digits only, then auto-verify when the code is complete 1370 this.value = this.value.replace(/\D/g, ''); 1371 if(this.value.length === 6 && !verifyBtn.disabled) verifyBtn.click(); 1372 }); 1373 1374 // Resend OTP 1375 document.getElementById('resendBtn')?.addEventListener('click', function(){ 1376 if(this.disabled) return; 1377 sendBtn.click(); // Reuse send OTP logic (captcha already validated) 1378 }); 1379 1380 // Change phone number 1381 document.getElementById('changePhone')?.addEventListener('click', function(e){ 1382 e.preventDefault(); 1383 document.getElementById('loginStep1').hidden = false; 1384 document.getElementById('loginStep2').hidden = true; 1385 document.getElementById('loginError').hidden = true; 1386 if(captchaEnabled) loadCaptcha(); 1387 }); 1388 1389 function startResendTimer(){ 1390 const btn = document.getElementById('resendBtn'); 1391 const span = document.getElementById('resendTimer'); 1392 const wrap = document.getElementById('resendTimerWrap'); 1393 const fmt = s => '0:' + String(Math.max(0, s)).padStart(2, '0'); 1394 let sec = 30; btn.disabled = true; 1395 if(wrap) wrap.style.visibility = 'visible'; 1396 if(span) span.textContent = fmt(sec); 1397 const iv = setInterval(()=>{ 1398 sec--; if(span) span.textContent = fmt(sec); 1399 if(sec <= 0){ clearInterval(iv); btn.disabled = false; if(wrap) wrap.style.visibility = 'hidden'; } 1400 }, 1000); 1401 } 1402 1403 function showLoginError(msg){ 1404 const el = document.getElementById('loginError'); 1405 if(el){ el.textContent = msg; el.hidden = false; setTimeout(()=>el.hidden=true, 5000); } 1406 } 1407 1408 // Login analytics, shared by every method. Extracted so the WhatsApp path â which
1409 // completes on a DIFFERENT page (/wb_login) and so cannot call _completeLogin â fires 1410 // exactly the same three events instead of a drifting copy. See the deferred block below. 1411 function _loginAnalytics(rows, method){ 1412 if(!rows || !window.Analytics) return; 1413 window.Analytics.trackLogin({ method: method || 'otp' }); 1414 // Registration fires ONLY for genuinely new users. This was previously 1415 // unconditional, so Meta CompleteRegistration / WebEngage "Customer Registered" 1416 // counted every returning login as a signup â inflating the conversion Meta 1417 // optimises against. CI3 parity: wla_20260505.js:2324 gates on the same 1418 // upstream flag (`if (rows.newUser == 1)`); the CI4 port dropped the condition. 1419 if(Number(rows.newUser) === 1){ 1420 window.Analytics.trackRegistration({ mobile: rows.mobileNo || rows.mobile || '' }); 1421 } 1422 window.Analytics.identifyUser({ 1423 mobile: rows.mobileNo || rows.mobile || '', email: rows.email || '', 1424 name: rows.name || '', dob: rows.dob || '', gender: rows.gender || '', 1425 anniversary: rows.anniversary || '', 1426 }); 1427 } 1428 1429 // Shared login completion â used by OTP verify and by social_login.js (Truecaller). 1430 // NOT used by WhatsApp: that flow finishes on /wb_login (a different document) and 1431 // hands off via the pending-login marker read below. 1432 // Persists session, closes the login overlay + any open truecaller bootstrap modal, then refreshes UI. 1433 window._completeLogin = function(rows, method){ 1434 if(!rows) return; 1435 localStorage.setItem('userdata', JSON.stringify(rows)); 1436 localStorage.setItem('token', rows.token || ''); 1437 _loginAnalytics(rows, method); 1438 window.hideLogin && window.hideLogin(); 1439 const tc = document.getElementById('truecallerModal'); 1440 const tcInst = tc && window.bootstrap ? bootstrap.Modal.getInstance(tc) : null; 1441 if(tcInst) tcInst.hide(); 1442 document.querySelectorAll('.login-required').forEach(el => el.hidden = false); 1443 // Swap the header "Login" label to "Profile" immediately â pages that define 1444 // _onLoginSuccess skip the reload below, so the page-load swap never fires for them. 1445 document.querySelectorAll('.user-name-display').forEach(el => { el.textContent = 'Profile'; }); 1446 // Welcome form (feedback #239): prompt for the name right after login when it's 1447 // still missing â mandatory, non-cancellable (firstLoginProfile.js). All login 1448 // methods (OTP / WhatsApp / Truecaller / social) funnel through here. Pages that 1449 // reload pick it up via the justLoggedIn flag below; pages with an inline 1450 // _onLoginSuccess (no reload) open it directly. 1451 if(window._onLoginSuccess){ 1452 // A handler that reloads (menu) sets justLoggedIn synchronously and the welcome 1453 // form opens AFTER the reload (firstLoginProfile.js). Only consider it inline for 1454 // in-place handlers (location picker / reservation) that don't reload â 1455 // otherwise it would flash briefly and get wiped by the reload. 1456 var _willReload = false; 1457 try{ _willReload = localStorage.getItem('justLoggedIn') === '1'; }catch(e){} 1458 var _needsProfile = false; 1459 try{ 1460 var _nm = String((rows && rows.name) || '').trim().toLowerCase(); 1461 _needsProfile = (_nm === '' || _nm === 'user') && typeof window.openProfilePrompt === 'function'; 1462 }catch(e){} 1463 if(_needsProfile && !_willReload){ 1464 // Welcome form takes priority: an in-place _onLoginSuccess (location picker's 1465 // "saved addresses" reopen, reservation's confirmation popup) would otherwise 1466 // fire in the same tick as the welcome form, stacking a Bootstrap modal behind 1467 // it â its focus-trap then steals keystrokes from the (non-cancellable) welcome 1468 // form, making it look open but un-typeable. Defer the reopen until the name 1469 // is actually captured (profile:completed, dispatched by firstLoginProfile.js). 1470 window.addEventListener('profile:completed', function _onProfileDone(){ 1471 window.removeEventListener('profile:completed', _onProfileDone); 1472 if(window._onLoginSuccess) window._onLoginSuccess(rows); 1473 }, { once: true }); 1474 window.openProfilePrompt(); 1475 } else { 1476 window._onLoginSuccess(rows); 1477 } 1478 } else { 1479 try{ localStorage.setItem('justLoggedIn','1'); }catch(e){} 1480 location.reload(); 1481 } 1482 }; 1483 1484 // Open/close the login overlay. Mirrors the .popup-overlay pattern used elsewhere. 1485 function hideLogin(){ 1486 const m = document.getElementById('loginModal'); 1487 if(!m) return; 1488 m.setAttribute('hidden', ''); 1489 m.setAttribute('aria-hidden', 'true'); 1490 document.body.style.overflow = ''; 1491 } 1492 window.hideLogin = hideLogin; 1493 1494 // Global: any page can call window.showLogin() 1495 // `source` separates a DELIBERATE login (header button) from a FORCED prompt â ~20 1496 // call-sites gate add-to-cart, checkout, reservations, loyalty, membership and wallet 1497 // behind this. Without the split, login_initiated is mostly "we blocked the user", 1498 // not "the user chose to log in", and is useless as a funnel denominator. 1499 window.showLogin = function(source){ 1500 const m = document.getElementById('loginModal'); 1501 if(!m) return; 1502 // Reset state 1503 document.getElementById('loginStep1').hidden = false;
1504 document.getElementById('loginStep2').hidden = true; 1505 document.getElementById('loginError').hidden = true; 1506 if(phoneInp) phoneInp.value = ''; 1507 if(captchaInp) captchaInp.value = ''; 1508 document.getElementById('loginOtp').value = ''; 1509 // Consent is accepted by default; keep both checkboxes in sync. 1510 if(consentCb) consentCb.checked = true; 1511 if(consentCbSocial) consentCbSocial.checked = true; 1512 updateCaptchaState(); 1513 checkReady(); 1514 m.removeAttribute('hidden'); 1515 m.setAttribute('aria-hidden', 'false'); 1516 document.body.style.overflow = 'clip'; 1517 loadCaptcha(); 1518 // Top of the auth funnel â the first high-intent signal, and the denominator every 1519 // later login event is measured against. Reset the one-shots so a second attempt in 1520 // the same page view counts as its own pass. 1521 window._resetAuthFunnelFlags && window._resetAuthFunnelFlags(); 1522 // analytics.js is a deferred module â it may not have set window.Analytics yet when 1523 // showLogin() is called early in the page lifecycle (e.g. from a pageshow handler or 1524 // an inline script before the module executes). Fire immediately if ready; otherwise 1525 // queue on the analytics:ready event that analytics.js dispatches after its init. 1526 const _loginSrc = source || 'forced'; 1527 if (window.Analytics) { 1528 window.Analytics.trackLoginInitiated?.({ source: _loginSrc }); 1529 } else { 1530 window.addEventListener('analytics:ready', function() { 1531 window.Analytics?.trackLoginInitiated?.({ source: _loginSrc }); 1532 }, { once: true }); 1533 } 1534 // Signal listeners (social_login.js) that the modal just opened. 1535 m.dispatchEvent(new CustomEvent('loginmodal:shown')); 1536 }; 1537 1538 // Close interactions: close button, backdrop click, Escape key. 1539 const loginOverlay = document.getElementById('loginModal'); 1540 if(loginOverlay){ 1541 loginOverlay.addEventListener('click', function(e){ 1542 if(e.target === loginOverlay) hideLogin(); 1543 else if(e.target.closest('.js-modal-close')) hideLogin(); 1544 }); 1545 document.addEventListener('keydown', function(e){ 1546 if(e.key === 'Escape' && !loginOverlay.hasAttribute('hidden')) hideLogin(); 1547 }); 1548 } 1549 1550 // Check if user already logged in â swap "Login" label to "Profile" 1551 const ud = localStorage.getItem('userdata'); 1552 if(ud && ud !== 'null'){ 1553 try{ 1554 JSON.parse(ud); // validate it's parseable; ignore the payload 1555 document.querySelectorAll('.user-name-display').forEach(el => { el.textContent = 'Profile'; }); 1556 }catch{} 1557 } 1558 1559 // Deferred login analytics â the WhatsApp arm only. 1560 // 1561 // WhatsApp completes on /wb_login/{JWT}, which renders through base_minimal.php: no 1562 // AnalyticsConfig, no analytics.js, no GTM, no pixel. So nothing could fire there, and 1563 // WhatsApp logins were invisible to every provider. wa_login_return.js leaves this 1564 // marker instead and we fire here, one hop later, on the page it bounces back to â 1565 // where the full stack is loaded. Same origin and same GA4 client id, so the funnel 1566 // still joins up. (Loading analytics onto the bounce page would have been simpler but 1567 // injects a junk PageView/page_view into every WhatsApp login.) 1568 try{ 1569 const pendingMethod = localStorage.getItem('pending_login_method'); 1570 if(pendingMethod){ 1571 localStorage.removeItem('pending_login_method'); 1572 if(ud && ud !== 'null') _loginAnalytics(JSON.parse(ud), pendingMethod); 1573 } 1574 // Same hand-off for a FAILED WhatsApp return. That page doesn't redirect on 1575 // failure, so this lands whenever the user next navigates â later than the 1576 // success case, but it is the only way to see this dropout at all. 1577 const pendingFailure = localStorage.getItem('pending_login_failure'); 1578 if(pendingFailure){ 1579 localStorage.removeItem('pending_login_failure'); 1580 window.Analytics?.trackLoginMethodFailed?.({ method: 'whatsapp', reason: pen
1580dingFailure }); 1581 } 1582 }catch(e){} 1583})(); 1584</script>
1584 1585 1586<!-- AppConfig bridge â moved up to <head> earlier in the document. --> 1587 1588<!-- Scroll + animation -->
1589<script> 1590(function(){ 1591 // Header shadow on scroll 1592 var h=document.querySelector('.site-header'); 1593 if(h) window.addEventListener('scroll',function(){ 1594 // Skip while a modal is open â the page is locked and the scrolled 1595 // class would otherwise stay on the header from the pre-open scroll 1596 // position (e.g. the offer-details popup). 1597 if(document.documentElement.classList.contains('modal-open'))return; 1598 h.classList.toggle('scrolled',scrollY>10); 1599 },{passive:true}); 1600 1601 // Reveal animations 1602 var els=document.querySelectorAll('.animate'); 1603 if(!els.length) return; 1604 if('IntersectionObserver' in window){ 1605 var ob=new IntersectionObserver(function(entries){ 1606 entries.forEach(function(e){ 1607 if(e.isIntersecting){e.target.classList.add('in');ob.unobserve(e.target);} 1608 }); 1609 },{threshold:0.05,rootMargin:'0px 0px 50px 0px'}); 1610 els.forEach(function(el){ob.observe(el);}); 1611 } else { 1612 // Fallback: show all immediately 1613 els.forEach(function(el){el.classList.add('in');}); 1614 } 1615})(); 1616</script>
1616 1617 1618<!-- First-time-login profile prompt â CI3 parity (#updateProfileModal_new), OTP-only. 1619 Static dialog: only the close (skip) button dismisses it; no backdrop-click / Escape 1620 handler is bound, mirroring CI3's backdrop:'static', keyboard:false. modal-lock.js 1621 locks scroll automatically via [aria-modal]. firstLoginProfile.js drives it. --> 1622<div class="popup-overlay popup-overlay--top" id="profilePromptModal" role="dialog" aria-modal="true" aria-labelledby="fpTitle" hidden> 1623 <div class="popup-sheet popup-sheet--profile"> 1624 <div class="popup-sheet__header"> 1625 <span class="fp-badge" aria-hidden="true"> 1626 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg> 1627 </span> 1628 <div class="popup-sheet__head-text"> 1629 <div class="fp-title-row"> 1630 <h5 class="popup-sheet__title fw-bold mb-0" id="fpTitle">Welcome</h5> 1631 <span class="fp-pill" id="fpPill" hidden>Last step</span> 1632 </div> 1633 <p class="text-muted small mb-0" id="fpSubtitle">Help us know you better!</p> 1634 </div> 1635 <button type="button" class="icon-btn-close js-fp-close" aria-label="Skip"> 1636 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg> 1637 </button> 1638 </div> 1639 <div class="popup-sheet__body"> 1640 <form class="pf-pi-form" id="fpForm" novalidate> 1641 1642 <div class="pf-pi-field"> 1643 <label class="pf-pi-label" for="fpName">Full Name <span class="pf-pi-required" aria-hidden="true">*</span></label> 1644 <input class="pf-pi-input" type="text" id="fpName" name="name" placeholder="Your full name" maxlength="50" autocomplete="name" required aria-required="true"> 1645 </div> 1646 1647 <div class="pf-pi-field"> 1648 <label class="pf-pi-label" for="fpEmail">Email Address <span class="pf-pi-optional">(Optional)</span></label> 1649 <input class="pf-pi-input" type="email" id="fpEmail" name="email" placeholder="[email protected]" maxlength="50" autocomplete="email"> 1650 </div> 1651 1652 <div class="pf-pi-field"> 1653 <label class="pf-pi-label">Gender <span class="pf-pi-optional">(Optional)</span></label> 1654 <div class="pf-pi-radio-row fp-gender"> 1655 <label class="pf-pi-radio"> 1656 <input type="radio" name="fpGender" value="M"> 1657 <span class="pf-pi-radio-box"></span> 1658 Male 1659 </label> 1660 <label class="pf-pi-radio"> 1661 <input type="radio" name="fpGender" value="F"> 1662 <span class="pf-pi-radio-box"></span> 1663 Female 1664 </label> 1665 </div> 1666 </div> 1667 1668 <!-- DOB + Anniversary side-by-side (CI3 col-md-6 parity) to keep the modal short. --> 1669 <div class="fp-date-row"> 1670 <div class="pf-pi-field"> 1671 <label class="pf-pi-label" for="fpDob">Date of Birth <span class="pf-pi-optional">(Optional)</span></label> 1672 <div class="pf-pi-date-wrap"> 1673 <input class="pf-pi-input" type="date" id="fpDob" name="dob"> 1674 <svg class="pf-pi-date-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg> 1675 </div> 1676 </div> 1677 1678 <div class="pf-pi-field"> 1679 <label class="pf-pi-label" for="fpAnniversary">Anniversary <span class="pf-pi-optional">(Optional)</span></label> 1680 <div class="pf-pi-date-wrap"> 1681 <input class="pf-pi-input" type="date" id="fpAnniversary" name="anniversary"> 1682 <svg class="pf-pi-date-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg> 1683 </div> 1684 </div> 1685 </div> 1686 1687 <!-- Soft nudge: birthday/anniversary unlock loyalty treats (no emoji â inline SVG). --> 1688 <div class="fp-hint" aria-hidden="true"> 1689 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 12 20 22 4 22 4 12"/><rect x="2" y="7" width="20" height="5"/><line x1="12" y1="22" x2="12" y2="7"/><path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z"/><path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z"/></svg>
1690 <span>Add these to unlock birthday & anniversary treats.</span> 1691 </div> 1692 1693 <!-- Referral code â ue_silver parity (.referCodeInput). Hidden by default; 1694 firstLoginProfile.js reveals it only for new users and prefills it from ?refer=. --> 1695 <div class="pf-pi-field" id="fpReferralWrap" hidden> 1696 <label class="pf-pi-label" for="fpReferral">Referral Code <span class="pf-pi-optional">(Optional)</span></label> 1697 <input class="pf-pi-input" type="text" id="fpReferral" name="referralcode" placeholder="Referral code" maxlength="50" autocomplete="off"> 1698 </div> 1699 1700 <p class="pf-pi-error" id="fpError" hidden></p> 1701 1702 <button type="submit" class="pf-pi-submit" id="fpSubmit"> 1703 <span id="fpSubmitLabel">Save & Continue</span> 1704 <svg class="fp-submit-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg> 1705 </button> 1706 1707 </form> 1708 </div> 1709 </div> 1710</div> 1711
1712<script src="/src/js/modules/modal-lock.js" type="module"></script>
1712 1713 1714<!-- Social login (WhatsApp + Truecaller) â reveals buttons per UA + brand flags, drives both flows -->
1715<script src="/src/js/modules/social_login.js?v=1791374065" type="module"></script>
1715 1716 1717<!-- Welcome form: prompts for name after login (any method) and is enforced at payment (feedback #239) -->
1718<script src="/src/js/modules/firstLoginProfile.js?v=1791374065" type="module"></script>
vendor: 1 bytes, line 1718
1718
1719<script src="/src/js/modules/cart_page.js?v=1791374065" type="module"></script>
1719 1720 1721<!-- Location picker â always loaded; handles both flow-enabled (modal) and flow-disabled (direct nav) cases -->
1722<script src="/src/js/modules/location_picker.js?v=1791374065" defer></script>
1722 1723 1724<!-- Pickup tooltip â toggles the .pickup-tip popover from any [data-pickup-trigger] (menu + checkout) -->
1725<script src="/src/js/modules/pickup_tooltip.js?v=1791374065" defer></script>
1725 1726 1727<!-- Slick init â initializes every [data-slick] element with its data-option config -->
1728<script src="/src/js/modules/slick_init.js?v=1791374065" defer></script>
1728 1729 1730<!-- Testimonial "Read more" â clamps long quotes so the carousel can't fluctuate the page -->
1731<script src="/src/js/modules/testimonial_readmore.js?v=1791374065" defer></script>
1731 1732 1733 1734<!-- Profile sidebar â header-triggered drawer, available on every page -->
1735<script src="/src/js/modules/profile_sidebar.js?v=1791374065" defer></script>
1735 1736 1737<!-- Global search â header search icon â dropdown (desktop) / strip (mobile). 1738 Per-brand: addo_business.globalSearch. -->
1739<script src="/src/js/modules/global_search.js?v=1791374065" type="module"></script>
1739 1740 1741<!-- Raise a Concern (Help & Support) â global modal opened from the profile sidebar -->
1742<script src="/src/js/modules/raiseConcern.js?v=1791374065" type="module"></script>
1742 1743 1744<!-- Global cart FAB â reveals #cartFab when logged in & the outlet cart has items -->
1745<script src="/src/js/modules/floating_cart.js?v=1791374065" defer></script>
1745 1746 1747<!-- Scroll-to-top floating button â no-op where #scrollTopBtn isn't rendered (checkout/payment) -->
1748<script src="/src/js/modules/scrollTop.js?v=1791374065" defer></script>
1748 1749 1750<!-- Active Orders â renders the section inside the profile sidebar. Generic, 1751 wired on every page (no route exclusions, see the module's own header 1752 comment). ES module for the activeOrderCard.js import, so type="module" 1753 rather than defer. --> 1754
1755<script src="/src/js/modules/activeOrders.js?v=1791374065" type="module"></script>
1755 1756 1757<!-- Match card thumbnails to their rendered size (upgrades /crops/160/ â /crops/256/ on wider cards) -->
1758<script src="/src/js/modules/cardImage.js?v=1791374065" type="module"></script>
1758 1759 1760 1761</body> 1762</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.