1 2 3<!DOCTYPE html> 4<html lang="en" class="wide wow-animation desktop landscape rd-navbar-static-linked"> 5<head> 6 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 8 <title>Burger, Fried Chicken & Wrap Collection in London | Order Online | Crays Fish Bar </title> 9 <meta name="format-detection" content="telephone=no" /> 10<meta name="description" content="Order burger, fried chicken &amp; wrap in London from Crays Fish Bar. Easy online ordering for collection.">
11<script type="application/ld+json"> 12{"@context":"https://schema.org","@type":"FastFoodRestaurant","name":"Crays Fish Bar","url":"https://craysfishbar.co.uk","hasMenu":"https://craysfishbar.co.uk/menu","image":"https://craysfishbar.co.uk/sitelogo/sitelogo.png","telephone":"02031 616743","servesCuisine":"Burger, Fried Chicken & Wrap","address":{"@type":"PostalAddress","streetAddress":"360 Footscray Rd","addressLocality":"London","postalCode":"SE9 2AA","addressCountry":"GB"},"geo":{"@type":"GeoCoordinates","latitude":"51.438631","longitude":"0.070715"},"openingHoursSpecification":[{"@type":"OpeningHoursSpecification","dayOfWeek":"https://schema.org/Sunday","opens":"12:00","closes":"21:00"},{"@type":"OpeningHoursSpecification","dayOfWeek":"https://schema.org/Monday","opens":"12:00","closes":"21:45"},{"@type":"OpeningHoursSpecification","dayOfWeek":"https://schema.org/Tuesday","opens":"12:00","closes":"21:45"},{"@type":"OpeningHoursSpecification","dayOfWeek":"https://schema.org/Wednesday","opens":"12:00","closes":"21:45"},{"@type":"OpeningHoursSpecification","dayOfWeek":"https://schema.org/Thursday","opens":"12:00","closes":"21:45"},{"@type":"OpeningHoursSpecification","dayOfWeek":"https://schema.org/Friday","opens":"12:00","closes":"21:45"},{"@type":"OpeningHoursSpecification","dayOfWeek":"https://schema.org/Saturday","opens":"12:00","closes":"21:45"}]} 13</script>
13 14 15 16 <meta name="viewport" content="width=device-width, initial-scale=1"> 17 <meta http-equiv="X-UA-Compatible" content="IE=edge" /> 18 <meta name="theme-color"> 19 <link rel="icon" href="data:;base64,="> 20 <meta charset="utf-8" /> 21 <link rel="stylesheet" type="text/css" href="css/style.css" /> 22 <link href="css/theme.css?v=5" rel="stylesheet"> 23 <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:400,300,100"> 24 25 <meta name="appleid-signin-client-id" content="com.boostit.appleSignIn3"> 26 <meta name="appleid-signin-scope" content="name email"> 27 <meta name="appleid-signin-redirect-uri" content="https://craysfishbar.co.uk/auth/apple/callback"> 28 <meta name="appleid-signin-state" content="origin:web"> 29 <meta name="appleid-signin-use-popup" content="true"> 30 31 <style> 32 33 34.rowff .col-xs-6{ 35width: 50% !important; 36} 37 38.rowff .col-xs-12{ 39text-align:center; 40} 41 42 #appleid-signin{ 43 width: 235px; 44 height: 50px; 45 text-align: center; 46 display: inline-block; 47 48 width: 235px; 49 height: 51px; 50 text-align: center; 51 display: inline-block; 52 background: black; 53 line-height: 50px; 54 display: -webkit-inline-box; 55 /* margin-top: -10px; */ 56 padding: 5px 0px; 57 border-radius: 8px; 58 59 } 60 61 62 63 64 .appleid-signin{ 65 width: 235px; 66 height: 50px; 67 text-align: center; 68 display: inline-block; 69 70 width: 235px; 71 height: 51px; 72 text-align: center; 73 display: inline-block; 74 background: black; 75 line-height: 50px; 76 display: -webkit-inline-box; 77 /* margin-top: -10px; */ 78 padding: 5px 0px; 79 border-radius: 8px; 80 81 } 82 83 .appleButton { 84 width: 245px; 85 height: 56px; 86 background: black; 87 border: none; 88 border-radius: 8px; 89 padding: 5px 0; 90 cursor: pointer; 91 display: inline-flex; 92 justify-content: center; 93 align-items: center; 94} 95 96.appleButton img { 97 width: auto; 98 /* height: 58px; */ 99 display: block; 100 transform: scale(1.35); 101} 102.s2x1y1{ 103 overflow-x: hidden; 104} 105 106.s2x1y1ios{ 107 overflow-x: hidden; 108} 109 110 111 112 113 114 .social-btn .btn { 115 border: none; 116 margin: 10px 3px 0; 117 opacity: 1; 118 width: 45%; 119 height: 47px; 120 padding: 12px 27px; 121 font-size: 14px; 122 border-radius: 9px; 123 } 124 125 </style> 126 127</head> 128 129<body> 130 131 <div id="modalArea"></div> 132 <div id="modalArea3"></div> 133 134
135 <div class="page"> 136 <div class="page-loader" style="background:black;"> 137 <div class="page-loader-body"> 138 <div class="cssload-container"> 139 <img src="/sitelogo/sitelogo.png" style="margin-top:-150px; "> 140 </div> 141 </div> 142 </div> 143 </div> 144 <header class="page-head"> 145 <div class="rd-navbar-wrap rd-navbar-minimal"> 146 <nav data-layout="rd-navbar-fixed" data-sm-layout="rd-navbar-fixed" data-md-device-layout="rd-navbar-fixed" 147 data-lg-layout="rd-navbar-static" data-lg-device-layout="rd-navbar-static" data-stick-up-clone="false" 148 data-md-stick-up-offset="100px" data-lg-stick-up-offset="100px" class="rd-navbar"> 149 <div class="shell shell-fluid"> 150 <div class="rd-navbar-inner"> 151 <!-- RD Navbar Panel--> 152 <div class="rd-navbar-panel"> 153 <!-- RD Navbar Toggle--> 154 <button data-rd-navbar-toggle=".rd-navbar-nav-wrap" class="rd-navbar-toggle"> 155 <span></span> 156 </button> 157 <a href="/menu" class="rd-navbar-brand brand" id="menuhxy"> 158 <div class="brand-logo" > 159 <img src="/sitelogo/sitelogo.png" height="90" style="height: 40px; margin-top: -1px;" class="mainlclass" alt=""> 160 </div> 161 </a> 162 <div class=" rd-navbar-brand brand" id="cartdivision" onclick="enableCart();"> 163 <div class="shop-cardt"> 164 <!-- <i class="thin-icon-cartShop icon-basket-general"></i> --> 165 166 <svg width="30" height="30" viewBox="0 0 24 24" fill="" stroke="green" stroke-width="2.0" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="margin-right:4px;"> 167 <circle cx="9" cy="21" r="1"></circle> 168 <circle cx="20" cy="21" r="1"></circle> 169 <path d="M1 1h4l2.7 13.4a2 2 0 0 0 2 1.6h8.9a2 2 0 0 0 1.9-1.4L23 6H6"></path> 170</svg> 171 172 173 <!-- <svg class="nav-iconx" viewBox="0 0 24 24" aria-hidden="true"> 174 <path d="M3 6h18M3 12h18M3 18h18" 175 stroke="currentColor" 176 stroke-width="2.5" 177 stroke-linecap="round"/> 178</svg> --> 179 180 181 <a id="basketShow" class="basketClass basketxyz" style="display:inline;">0 Items </a> 182 </div> 183 </div> 184 </div> 185 <div class="rd-navbar-nav-wrap"> 186 <ul class="rd-navbar-nav"> 187 <li id="menlink"> 188 <a href="/menu" class="navbar-iconx"> 189 190<svg class="nav-iconx" viewBox="0 0 24 24" aria-hidden="true"> 191 <path d="M6 2v8M9 2v8M6 6h3M7.5 10v12" 192 stroke="currentColor" 193 stroke-width="1.8" 194 stroke-linecap="round"/> 195 196 <path d="M14 2c0 4 4 4 4 8v12" 197 stroke="currentColor" 198 stroke-width="1.8" 199 stroke-linecap="round"/> 200</svg> 201 <span>MENU</span> 202 203 </a> 204</li> 205 <li> 206 207 208 209 210<a href="/checkout" class="navbar-iconx"> 211 <span class="checkout-svg-wrap"> 212 <svg class="nav-iconx" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"> 213 <circle cx="9" cy="21" r="1"></circle> 214 <circle cx="20" cy="21" r="1"></circle> 215 <path d="M1 1h4l2.7 13.4a2 2 0 0 0 2 1.6h8.9a2 2 0 0 0 1.9-1.4L23 6H6"></path> 216 </svg> 217 </span> 218 <span class="checkout-text">CHECKOUT</span> 219</a> 220 221 222</li> 223 224 <li> 225 <a class="navbar-icon thin-icon-key" data-toggle="modal" data-target="#loginModal">Login </a> 226 </li> 227 <li> 228 <a class="navbar-icon thin-icon-layers" data-toggle="modal" data-target="#registerModal">Register </a> 229 </li> 230 231 232 233 <li> 234 <a href="/contact" class="navbar-iconx"> 235 <span class="checkout-svg-wrap"> 236 <svg class="nav-iconx" viewBox="0 0 24 24"> 237 <rect x="3" y="5" width="18" height="14" stroke="currentColor" stroke-width="1.8" fill="none"/> 238 <path d="M3 7l9 6 9-6" stroke="currentColor" stroke-width="1.8" fill="none"/> 239 </svg> 240 </span> 241 <span class="checkout-text">Contact</span> 242 </a> 243</li> 244 245 246 247 <li> 248 <a class="navbar-iconx" href="tel:02031 616743"> 249 <span class="checkout-svg-wrap"> 250 <svg class="nav-iconx" viewBox="0 0 24 24"> 251 <path d="M22 16.9v3a2 2 0 0 1-2.2 2 252 19.8 19.8 0 0 1-8.6-3.1 253 19.5 19.5 0 0 1-6-6 254 19.8 19.8 0 0 1-3.1-8.7A2 2 0 0 1 4.1 2h3 255 a2 2 0 0 1 2 1.7c.1.8.3 1.5.6 2.2 256 a2 2 0 0 1-.5 2.1L8 9 257 a16 16 0 0 0 6 6l1-1.2
258 a2 2 0 0 1 2.1-.5c.7.3 1.4.5 2.2.6 259 a2 2 0 0 1 1.7 2z" 260 stroke="currentColor" stroke-width="1.8" fill="none"/> 261 </svg> 262 </span> 263 <span class="checkout-text">02031 616743</span> 264 </a> 265</li> 266 267 268 269 </ul> 270 </div> 271 </div> 272 </div> 273 </nav> 274 </div> 275 </header> 276 277 278<main class="bo-legal-page"> 279 280 <style> 281 body { background:#f4f4f5; } 282 .bo-legal-page { width:min(calc(100% - 24px),900px); margin:28px auto; padding:28px; border:1px solid #ddd; border-radius:14px; background:#fff; color:#292733; font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; line-height:1.55; box-shadow:0 3px 14px rgba(0,0,0,.1); } 283 .bo-legal-copy h1 { margin:26px 0 8px; color:#dc4c46; font-size:1.55rem; } 284 .bo-legal-copy h1:first-child { margin-top:0; } 285 .bo-legal-copy h2 { margin:22px 0 7px; font-size:1.22rem; } 286 .bo-legal-copy h3 { margin:18px 0 6px; font-size:1.08rem; } 287 .bo-legal-copy p,.bo-legal-copy li { height:auto; margin:8px 0; font-size:15px; text-align:left; } 288 .bo-legal-copy ul,.bo-legal-copy ol { padding-left:22px; } 289 .bo-legal-copy a { color:#08799b; overflow-wrap:anywhere; } 290 .bo-legal-back { display:inline-flex; margin-top:18px; color:#08799b; font-weight:700; } 291 @media(max-width:560px){.bo-legal-page{width:calc(100% - 12px);margin:8px auto;padding:20px 16px;border-radius:11px}.bo-legal-copy p,.bo-legal-copy li{font-size:14px}} 292 </style> 293 294 <article class="bo-legal-copy"> 295 <h1>Privacy Policy</h1> 296 <p>Last updated: September 07, 2022</p> 297 <p>This Privacy Policy describes Our policies and procedures on the collection, use and disclosure of Your information when You use the Service and tells You about Your privacy rights and how the law protects You.</p> 298 <p>We use Your Personal data to provide and improve the Service. By using the Service, You agree to the collection and use of information in accordance with this Privacy Policy.</p> 299 <h1>Interpretation and Definitions</h1> 300 <h2>Interpretation</h2> 301 <p>The words of which the initial letter is capitalized have meanings defined under the following conditions. The following definitions shall have the same meaning regardless of whether they appear in singular or in plural.</p> 302 <h2>Definitions</h2> 303 <p>For the purposes of this Privacy Policy:</p> 304 <ul> 305 <li> 306 <p><strong>Account</strong> means a unique account created for You to access our Service or parts of our Service.</p> 307 </li> 308 <li> 309 <p><strong>Affiliate</strong> means an entity that controls, is controlled by or is under common control with a party, where "control" means ownership of 50% or more of the shares, equity interest or other securities entitled to vote for election of directors or other managing authority.</p> 310 </li> 311 <li> 312 <p><strong>Application</strong> means the software program provided by the Business and downloaded by You on an electronic device.</p> 313 </li> 314 <li> 315 <p><strong>Business</strong> (referred to as either "Crays Fish Bar ", "We", "Us" or "Our" in this Agreement) refers to Crays Fish Bar , 360 Footscray Rd.</p> 316 <p>For the purpose of the GDPR, the Business is the Data Controller.</p> 317 </li> 318 <li> 319 320 321 <p><strong>Cookies</strong> are small files that are placed on Your computer, mobile device or any other device by a website, containing the details of Your browsing history on that website among its many uses.</p> 322 </li> 323 <li> 324 <p><strong>Country</strong> refers to: United Kingdom</p> 325 </li> 326 <li> 327 <p><strong>Data Controller</strong>, for the purposes of the GDPR (General Data Protection Regulation), refers to the Business as the legal person which alone or jointly with others determines the purposes and means of the processing of Personal Data.</p> 328 </li> 329 <li> 330 <p><strong>Device</strong> means any device that can access the Service such as a computer, a cellphone or a digital tablet.</p> 331 </li> 332 <li> 333 <p><strong>Personal Data</strong> is any information that relates to an identified or identifiable individual.</p> 334 <p>For the purposes of GDPR, Personal Data means any information relating to You such as a name, an identification number, location data, online identifier or to one or more factors specific to the physical, physiological, genetic, mental, economic, cultural or social identity.</p> 335 </li> 336 <li> 337 <p><strong>Service</strong> refers to the Application or the Website or both.</p> 338 </li> 339 <li> 340 <p><strong>Service Provider</strong> means any natural or legal person who processes the data on behalf of Crays Fish Bar . It refers to third-party companies or individuals employed by Crays Fish Bar to facilitate the Service, to provide the Service on behalf of Crays Fish Bar , to perform services related to the Service or to assist the Business in analyzing how the Service is used. 341 For the purpose of the GDPR, Service Providers are considered Data Processors.</p> 342 </li> 343 <li> 344 <p><strong>Third-party Social Media Service</strong> refers to any website or any social network website through which a User can log in or create an account to use the Service.</p> 345 </li> 346 <li> 347 <p><strong>Usage Data</strong> refers to data collected automatically, either generated by the use of the Service or from the Service infrastru
347cture itself (for example, the duration of a page visit).</p> 348 </li> 349 <li> 350 <p><strong>Website</strong> refers to the online ordering website accessible from <a href="https://craysfishbar.co.uk" rel="external nofollow noopener" target="_blank">https://craysfishbar.co.uk</a>.</p> 351 </li> 352 <li> 353 <p><strong>You</strong> means the individual accessing or using the Service, or the company, or other legal entity on behalf of which such individual is accessing or using the Service, as applicable.</p> 354 <p>Under GDPR (General Data Protection Regulation), You can be referred to as the Data Subject or as the User as you are the individual using the Service.</p> 355 </li> 356 </ul> 357 <h1 class="h1up">Collecting and Using Your Personal Data</h1> 358 <h2>Types of Data Collected</h2> 359 <h3>Personal Data</h3> 360 <p>While using Our Service, We may ask You to provide Us with certain personally identifiable information that can be used to contact or identify You. Personally identifiable information may include, but is not limited to:</p> 361 <ul> 362 <li> 363 <p>Email address</p> 364 </li> 365 <li> 366 <p>First name and last name</p> 367 </li> 368 <li> 369 <p>Phone number</p> 370 </li> 371 <li> 372 <p>Address, State, Province, ZIP/Postal code, City</p> 373 </li> 374 <li> 375 <p>Usage Data</p> 376 </li> 377 </ul> 378 <h3 class="h3up">Usage Data</h3> 379 <p>Usage Data is collected automatically when using the Service.</p> 380 <p>Usage Data may include information such as Your Device's Internet Protocol address (e.g. IP address), browser type, browser version, the pages of our Service that You visit, the time and date of Your visit, the time spent on those pages, unique device identifiers and other diagnostic data.</p> 381 <p>When You access the Service by or through a mobile device, We may collect certain information automatically, including, but not limited to, the type of mobile device You use, Your mobile device unique ID, the IP address of Your mobile device, Your mobile operating system, the type of mobile Internet browser You use, unique device identifiers and other diagnostic data.</p> 382 <p>We may also collect information that Your browser sends whenever You visit our Service or when You access the Service by or through a mobile device.</p> 383 <h3 class="h3up">Information from Third-Party Social Media Services</h3> 384 <p>The Company allows You to create an account and log in to use the Service through the following Third-party Social Media Services:</p> 385 <ul> 386 <li>Google</li> 387 <li>Facebook</li> 388 <li>Apple Id Sign In</li> 389 390 </ul> 391 <p>If You decide to register through or otherwise grant us access to a Third-Party Social Media Service, We may collect Personal data that is already associated with Your Third-Party Social Media Service's account, such as Your name & Your email address, Your activities or Your contact list associated with that account.</p> 392 <p>You may also have the option of sharing additional information with the Business through Your Third-Party Social Media Service's account. If You choose to provide such information and Personal Data, during registration or otherwise, You are giving the Business permission to use, share, and store it in a manner consistent with this Privacy Policy.</p> 393 <h3 class="h3up">Tracking Technologies and Cookies</h3> 394 <p>We use Cookies and similar tracking technologies to track the activity on Our Service and store certain information. Tracking technologies used are beacons, tags, and scripts to collect and track information and to improve and analyze Our Service. The technologies We use may include:</p> 395 <ul> 396 <li><strong>Cookies or Browser Cookies.</strong> A cookie is a small file placed on Your Device. You can instruct Your browser to refuse all Cookies or to indicate when a Cookie is being sent. However, if You do not accept Cookies, You may not be able to use some parts of our Service. Unless you have adjusted Your browser setting so that it will refuse Cookies, our Service may use Cookies.</li> 397 <li><strong>Flash Cookies.</strong> Certain features of our Service may use local stored objects (or Flash Cookies) to collect and store information about Your preferences or Your activity on our Service. Flash Cookies are not managed by the same browser settings as those used for Browser Cookies. For more information on how You can delete Flash Cookies, please read "Where can I change the settings for disabling, or deleting local shared objects?" available at <a href="https://helpx.adobe.com/flash-player/kb/disable-local-shared-objects-flash.html#main_Where_can_I_change_the_settings_for_disabling__or_deleting_local_shared_objects_" rel="external nofollow noopener" target="_blank">https://helpx.adobe.com/flash-player/kb/disable-local-shared-objects-flash.html#main_Where_can_I_change_the_settings_for_disabling__or_deleting_local_shared_objects_</a></li> 398 <li><strong>
398Web Beacons.</strong> Certain sections of our Service and our emails may contain small electronic files known as web beacons (also referred to as clear gifs, pixel tags, and single-pixel gifs) that permit the Business, for example, to count users who have visited those pages or opened an email and for other related website statistics (for example, recording the popularity of a certain section and verifying system and server integrity).</li> 399 </ul> 400 <p>Cookies can be "Persistent" or "Session" Cookies. Persistent Cookies remain on Your personal computer or mobile device when You go offline, while Session Cookies are deleted as soon as You close Your web browser. You can learn more about cookies on <a href="https://www.termsfeed.com/blog/cookies/#What_Are_Cookies" target="_blank">TermsFeed website</a> article.</p> 401 <p>We use both Session and Persistent Cookies for the purposes set out below:</p> 402 <ul> 403 <li> 404 <p><strong>Necessary / Essential Cookies</strong></p> 405 <p>Type: Session Cookies</p> 406 <p>Administered by: Us</p> 407 <p>Purpose: These Cookies are essential to provide You with services available through the Website and to enable You to use some of its features. They help to authenticate users and prevent fraudulent use of user accounts. Without these Cookies, the services that You have asked for cannot be provided, and We only use these Cookies to provide You with those services.</p> 408 </li> 409 <li> 410 <p><strong>Cookies Policy / Notice Acceptance Cookies</strong></p> 411 <p>Type: Persistent Cookies</p> 412 <p>Administered by: Us</p> 413 <p>Purpose: These Cookies identify if users have accepted the use of cookies on the Website.</p> 414 </li> 415 <li> 416 <p><strong>Functionality Cookies</strong></p> 417 <p>Type: Persistent Cookies</p> 418 <p>Administered by: Us</p> 419 <p>Purpose: These Cookies allow us to remember choices You make when You use the Website, such as remembering your login details or language preference. The purpose of these Cookies is to provide You with a more personal experience and to avoid You having to re-enter your preferences every time You use the Website.</p> 420 </li> 421 </ul> 422 <p>For more information about the cookies we use and your choices regarding cookies, please visit our Cookies Policy or the Cookies section of our Privacy Policy.</p> 423 <h2 class="h2up">Use of Your Personal Data</h2> 424 <p>The Company may use Personal Data for the following purposes:</p> 425 <ul> 426 <li> 427 <p><strong>To provide and maintain our Service</strong>, including to monitor the usage of our Service.</p> 428 </li> 429 <li> 430 <p><strong>To manage Your Account:</strong> to manage Your registration as a user of the Service. The Personal Data You provide can give You access to different functionalities of the Service that are available to You as a registered user.</p> 431 </li> 432 <li> 433 <p><strong>For the performance of a contract:</strong> the development, compliance and undertaking of the purchase contract for the products, items or services You have purchased or of any other contract with Us through the Service.</p> 434 </li> 435 <li> 436 <p><strong>To contact You:</strong> To contact You by email, telephone calls, SMS, or other equivalent forms of electronic communication, such as a mobile application's push notifications regarding updates or informative communications related to the functionalities, products or contracted services, including the security updates, when necessary or reasonable for their implementation.</p> 437 </li> 438 <li> 439 <p><strong>To provide You</strong> with news, special offers and general information about other goods, services and events which we offer that are similar to those that you have already purchased or enquired about unless You have opted not to receive such information.</p> 440 </li> 441 <li> 442 <p><strong>To manage Your requests:</strong> To attend and manage Your requests to Us.</p> 443 </li> 444 <li> 445 <p><strong>For business transfers:</strong> We may use Your information to evaluate or conduct a merger, divestiture, restructuring, reorganization, dissolution, or other sale or transfer of some or all of Our assets, whether as a going concern or as part of bankruptcy, liquidation, or similar proceeding, in which Personal Data held by Us about our Service users is among the assets transferred.</p> 446 </li> 447 <li> 448 <p><strong>For other purposes</strong>: We may use Your information for other purposes, such as data analysis, identifying usage trends, determining the effectiveness of our promotional campaigns and to evaluate and improve our Service, products, services, marketing and your experience.</p> 449 </li> 450 </ul> 451 <p>We may share Your personal information in the following situations:</p> 452 <ul> 453 <li><strong>With Service Providers:</strong> We may share Your personal information with Service Providers to monitor and analyze the use of our Service, for payment processing, to contact You.</li> 454 <li><strong>For business transfers:</strong> We may share or transfer Your personal information in connection with, or during negotiations of, any merger, sale of Company assets, financing, or acquisition of all or a portion of Our business to another company.</li> 455 <li><strong>With Affiliates:</strong> We may share Your information with Our affiliates, in which case we will require those affiliates to honor this Privacy Policy. Affiliates include Our parent company and any other subsidiaries, joint venture partners or other companies that We control or that are under common control with Us.</li> 456 <li><strong>With business partners:</strong> We may share Your information with Our business partners to offer You certain products, services or promotions.</li> 457 <li><strong>With other users:</strong> when You share personal information or otherwise interact in the public areas with other users, such information may be viewed by all users and may be publicly distributed outside. If You interact with other users or register through a Third-Party Social Media Service, Your contacts on the Third-Party Social Media Service may see Your name, profile, pictures and description of Your activity. Similarly, other users will be able to view descriptions of Your activity, communicate with You and view Your profile.</li> 458 <li><strong>
458With Your consent</strong>: We may disclose Your personal information for any other purpose with Your consent.</li> 459 </ul> 460 <h2 class="h2up">Retention of Your Personal Data</h2> 461 <p>The Company will retain Your Personal Data only for as long as is necessary for the purposes set out in this Privacy Policy. We will retain and use Your Personal Data to the extent necessary to comply with our legal obligations (for example, if we are required to retain your data to comply with applicable laws), resolve disputes, and enforce our legal agreements and policies.</p> 462 <p>The Company will also retain Usage Data for internal analysis purposes. Usage Data is generally retained for a shorter period of time, except when this data is used to strengthen the security or to improve the functionality of Our Service, or We are legally obligated to retain this data for longer time periods.</p> 463 <h2 class="h2up">Transfer of Your Personal Data</h2> 464 <p>Your information, including Personal Data, is processed at the Business's operating offices and in any other places where the parties involved in the processing are located. It means that this information may be transferred to â and maintained on â computers located outside of Your state, province, country or other governmental jurisdiction where the data protection laws may differ than those from Your jurisdiction.</p> 465 <p>Your consent to this Privacy Policy followed by Your submission of such information represents Your agreement to that transfer.</p> 466 <p>The Company will take all steps reasonably necessary to ensure that Your data is treated securely and in accordance with this Privacy Policy and no transfer of Your Personal Data will take place to an organization or a country unless there are adequate controls in place including the security of Your data and other personal information.</p> 467 <h2 class="h2up">Disclosure of Your Personal Data</h2> 468 <h3 class="h3up">Business Transactions</h3> 469 <p>If the Business is involved in a merger, acquisition or asset sale, Your Personal Data may be transferred. We will provide notice before Your Personal Data is transferred and becomes subject to a different Privacy Policy.</p> 470 <h3 class="h3up">Law enforcement</h3> 471 <p>Under certain circumstances, the Business may be required to disclose Your Personal Data if required to do so by law or in response to valid requests by public authorities (e.g. a court or a government agency).</p> 472 <h3 class="h3up">Other legal requirements</h3> 473 <p>The Company may disclose Your Personal Data in the good faith belief that such action is necessary to:</p> 474 <ul> 475 <li>Comply with a legal obligation</li> 476 <li>Protect and defend the rights or property of the Business</li> 477 <li>Prevent or investigate possible wrongdoing in connection with the Service</li> 478 <li>Protect the personal safety of Users of the Service or the public</li> 479 <li>Protect against legal liability</li> 480 </ul> 481 <h2 class="h2up">Security of Your Personal Data</h2> 482 <p>The security of Your Personal Data is important to Us, but remember that no method of transmission over the Internet, or method of electronic storage is 100% secure. While We strive to use commercially acceptable means to protect Your Personal Data, We cannot guarantee its absolute security.</p> 483 <h1>Detailed Information on the Processing of Your Personal Data</h1> 484 <p>The Service Providers We use may have access to Your Personal Data. These third-party vendors collect, store, use, process and transfer information about Your activity on Our Service in accordance with their Privacy Policies.</p> 485 <h2 class="h2up">Email & SMS Marketing ( including informative communication)</h2> 486 <p>We may use Your Personal Data to contact You with newsletters, marketing or promotional materials and other information that may be of interest to You. You may opt-out of receiving any, or all, of these communications from Us by following the unsubscribe link or instructions provided in any email We send or by contacting Us.</p> 487 <p>We may use Email Marketing or SMS Marketing Service Providers to manage and send emails,sms messages to You.</p> 488 <ul> 489 <li> 490 <p><strong>SendInBlue</strong></p> 491 <p>Their Privacy Policy can be viewed at <a href="https://www.sendinblue.com/legal/privacypolicy/" rel="external nofollow noopener" target="_blank">https://www.sendinblue.com/legal/privacypolicy/</a></p> 492 </li> 493 <li> 494 <p><strong>TheSmsWorks</strong></p> 495 <p>Their Privacy Policy can be viewed at <a href="https://thesmsworks.co.uk/privacy" rel="external nofollow noopener" target="_blank">https://thesmsworks.co.uk/privacy</a></p> 496 </li> 497 </ul> 498 <h2 class="h2up">Payments</h2> 499 <p>We may provide paid products and/or services within the Service. In that case, we may use third-party services for payment processing (e.g. payment processors). We work with Stripe for payment processing. </p> 500 <p>We will not store or collect Your payment card details. That information is provided directly to Our third-party payment processors whose use of Your personal information is governed by their Privacy Policy. These payment processors adhere to the standards set by PCI-DSS as managed by the PCI Security Standards Council, which is a joint effort of brands like Visa, Mastercard, American Express and Discover. PC
500I-DSS requirements help ensure the secure handling of payment information.</p> 501 <ul> 502 <li> 503 <p><strong>Stripe</strong></p> 504 <p>Their Privacy Policy can be viewed at <a href="https://stripe.com/us/privacy" rel="external nofollow noopener" target="_blank">https://stripe.com/us/privacy</a></p> 505 </li> 506 </ul> 507 <h2 class="h2up">Usage, Performance and Miscellaneous</h2> 508 <p>We may use third-party Service Providers to provide better improvement of our Service.</p> 509 <ul> 510 <li> 511 <!-- <p><strong>Google Places</strong></p> 512 <p>Google Places is a service that returns information about places using HTTP requests. It is operated by Google</p> 513 <p>Google Places service may collect information from You and from Your Device for security purposes.</p> 514 <p>The information gathered by Google Places is held in accordance with the Privacy Policy of Google: <a href="https://www.google.com/intl/en/policies/privacy/" rel="external nofollow noopener" target="_blank">https://www.google.com/intl/en/policies/privacy/</a></p> --> 515 </li> 516 </ul> 517 <h1 class="h1up">GDPR Privacy</h1> 518 <h2 class="h2up">Legal Basis for Processing Personal Data under GDPR</h2> 519 <p>We may process Personal Data under the following conditions:</p> 520 <ul> 521 <li><strong>Consent:</strong> You have given Your consent for processing Personal Data for one or more specific purposes.</li> 522 <li><strong>Performance of a contract:</strong> Provision of Personal Data is necessary for the performance of an agreement with You and/or for any pre-contractual obligations thereof.</li> 523 <li><strong>Legal obligations:</strong> Processing Personal Data is necessary for compliance with a legal obligation to which the Business is subject.</li> 524 <li><strong>Vital interests:</strong> Processing Personal Data is necessary in order to protect Your vital interests or of another natural person.</li> 525 <li><strong>Public interests:</strong> Processing Personal Data is related to a task that is carried out in the public interest or in the exercise of official authority vested in the Business.</li> 526 <li><strong>Legitimate interests:</strong> Processing Personal Data is necessary for the purposes of the legitimate interests pursued by the Business.</li> 527 </ul> 528 <p>In any case, the Business will gladly help to clarify the specific legal basis that applies to the processing, and in particular whether the provision of Personal Data is a statutory or contractual requirement, or a requirement necessary to enter into a contract.</p> 529 <h2>Your Rights under the GDPR</h2> 530 <p>The Company undertakes to respect the confidentiality of Your Personal Data and to guarantee You can exercise Your rights.</p> 531 <p>You have the right under this Privacy Policy, and by law if You are within the EU, to:</p> 532 <ul> 533 <li><strong>Request access to Your Personal Data.</strong> The right to access, update or delete the information We have on You. Whenever made possible, you can access, update or request deletion of Your Personal Data directly within Your account settings section. If you are unable to perform these actions yourself, please contact Us to assist You. This also enables You to receive a copy of the Personal Data We hold about You.</li> 534 <li id="deletedata"><strong style="color:red;">Delete your personal data</strong> In order to delete your personal data login your account, select my profile from the dropdown menu, choose "My Profile" section again and select "DELETE MY ACCOUNT". This will delete the account data we hold about you, including social logins. Alternatively please <button class="btn-button" onclick="deleteAccountx();">click here </button> to request your data to be deleted. Upon following these links your personal data will be deleted and this action can not be reversed. If you still have problem deleting your data please email us : <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="71181f171e31131e1e02051805051412191f1e1d1e161814025f121e5f041a">[email protected]</a> and we will take care of it for you. </li> 535 <li><strong>Request correction of the Personal Data that We hold about You.</strong> You have the right to have any incomplete or inaccurate information We hold about You corrected.</li> 536<li> 537<p><strong>Requesting Deletion of Your Personal Data</strong></p> 538 539<p>
539You have the right to request deletion of your Personal Data that We have collected about You. The Business will process such requests in accordance with applicable data protection laws including the GDPR.</p> 540 541<p>You may request deletion of your Personal Data in the following ways:</p> 542 543<p><strong>1. Through Your account</strong></p> 544<p>If You have created an account with Crays Fish Bar, You may delete Your data by logging into Your account, navigating to the profile or account settings page, and selecting the option to delete Your account.</p> 545 546<p><strong>2. Without logging into an account</strong></p> 547<p>If You cannot access Your account, You may request deletion by contacting the Business and providing sufficient information to identify Your data (such as the email address or phone number used when placing an order).</p> 548 549<p><strong>3. Contacting the Business directly</strong></p> 550<p>You may request deletion of Your Personal Data by contacting the Business using the contact details below:</p> 551 552<p>Email: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bdd4d3dbd2fddfd2d2cec9d4c9c9d8ded5d3d2d1d2dad4d8ce93ded293c8d6">[email protected]</a></p> 553<p>Telephone: 02031 616743</p> 554 555<p>Upon receiving a verified request, the Business will delete Your Personal Data from its systems within a reasonable timeframe, unless the Business is required to retain certain information for legal, accounting, or fraud prevention purposes.</p> 556 557<p>You may also request access to, correction of, or export of Your Personal Data by contacting the Business using the same contact details.</p> 558 559</li> 560 561 <li><strong>Object to processing of Your Personal Data.</strong> This right exists where We are relying on a legitimate interest as the legal basis for Our processing and there is something about Your particular situation, which makes You want to object to our processing of Your Personal Data on this ground. You also have the right to object where We are processing Your Personal Data for direct marketing purposes.</li> 562 <li><strong>Request erasure of Your Personal Data.</strong> You have the right to ask Us to delete or remove Personal Data when there is no good reason for Us to continue processing it.</li> 563 <li><strong>Request the transfer of Your Personal Data.</strong> We will provide to You, or to a third-party You have chosen, Your Personal Data in a structured, commonly used, machine-readable format. Please note that this right only applies to automated information which You initially provided consent for Us to use or where We used the information to perform a contract with You.</li> 564 <li><strong>Withdraw Your consent.</strong> You have the right to withdraw Your consent on using your Personal Data. If You withdraw Your consent, We may not be able to provide You with access to certain specific functionalities of the Service.</li> 565 </ul> 566 <h2 class="h2up">Exercising of Your GDPR Data Protection Rights</h2> 567 <p>You may exercise Your rights of access, rectification, cancellation and opposition by contacting Us. Please note that we may ask You to verify Your identity before responding to such requests. If You make a request, We will try our best to respond to You as soon as possible.</p> 568 <p>You have the right to complain to a Data Protection Authority about Our collection and use of Your Personal Data. For more information, if You are in the European Economic Area (EEA), please contact Your local data protection authority in the EEA.</p> 569 <h1 class="h1up">Children's Privacy</h1> 570 <p>Our Service does not address anyone under the age of 18. We do not knowingly collect personally identifiable information from anyone under the age of 18. If You are a parent or guardian and You are aware that Your child has provided Us with Personal Data, please contact Us. If We become aware that We have collected Personal Data from anyone under the age of 18 without verification of parental consent, We take steps to remove that information from Our servers.</p> 571 <p>If We need to rely on consent as a legal basis for processing Your information and Your country requires consent from a parent, We may require Your parent's consent before We collect and use that information.</p> 572 <h1 class="h1up">Links to Other Websites</h1> 573 <p>Our Service may contain links to other websites that are not operated by Us. If You click on a third party link, You will be directed to that third party's site. We strongly advise You to review the Privacy Policy of every site You visit.</p> 574 <p>We have no control over and assume no responsibility for the content, privacy policies or practices of any third party sites or services.</p> 575 <h1 class="h1up">Changes to this Privacy Policy</h1> 576 <p>We may update Our Privacy Policy from time to time. We will notify You of any changes by posting the new Privacy Policy on this page.</p> 577 <p>We will let You know via email and/or a prominent notice on Our Service, prior to the change becoming effective and update the "Last updated" date at the top of this Privacy Policy.</p> 578 <p>You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.</p> 579 <h1>Contact Us</h1> 580 <p>If you have any questions about this Privacy Policy, You can contact us:</p> 581 <ul> 582 <li> 583 <p>
583By email: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="026b6c646d42606d6d71766b767667616a6c6d6e6d656b67712c616d2c7769">[email protected]</a></p> 584 </li> 585 <li> 586 <p>By phone number: 02031 616743</p> 587 588 <h2>Facebook / App Data Deletion Instructions</h2> 589 590<p>If you have used Facebook Login or another social login to access the services provided by Crays Fish Bar, you have the right to request deletion of your personal data.</p> 591 592<p>You may request deletion of your data in the following ways:</p> 593 594<p><strong>1. From within your account</strong></p> 595<p>Log into your account, navigate to the profile settings page and choose the option <strong>"Delete My Account"</strong>. This will permanently remove your account and associated personal data.</p> 596 597<p><strong>2. Request deletion without logging in</strong></p> 598<p>If you cannot access your account, you may request deletion by contacting the Business using the email address associated with your order or account.</p> 599 600<p>Email: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9ef7f0f8f1defcf1f1edeaf7eaeafbfdf6f0f1f2f1f9f7fbedb0fdf1b0ebf5">[email protected]</a></p> 601 602<p><strong>3. Facebook data deletion requests</strong></p> 603<p>You may also request deletion through Facebook by contacting us directly. Once we receive a verified request, we will delete your personal data from our systems within a reasonable timeframe, unless we are legally required to retain certain information for accounting or legal purposes.</p> 604 605 </li> 606 </ul> 607 608 609 <h1>Order cancellations, returns and refunds</h1> 610 <p>Meals and other food products are freshly prepared and perishable. They cannot normally be returned or cancelled simply because You have changed Your mind.</p> 611 <p>This does not affect Your legal rights where an order is faulty, incorrect or not as described. If there is a problem with an order, please contact the shop promptly by telephone, email or any other contact channel made available by the shop so the matter can be reviewed.</p> 612 </article> 613 <a class="bo-legal-back" href="/menu">Return to menu</a> 614</main> 615 616<footer id="footer"> 617 <div class="footer-part text-center" > 618 <span> 619 <a onclick="window.open('/allergy', '_blank', 'location=no,height=570,width=320,scrollbars=yes,status=yes')" style="color:#fff;">Allergen Information</a> 620 </span> 621 622 <h6 style="color:red">Open 7 Days a Week. </h6> 623 624 <h6 style="color:white; font-size:16px; font-weight: 400;">Download our applications or use our webpage to place order.</h6> 625<div class="rowff"> 626 <div class="col-xs-12"> <a class="btn btn-burnt-sienna btn-md btn-shape-circle offset-top-20 addButton website" href="/menu">Menu</a> </div><div class="col-xs-6" style="text-align: right;"> <a href="https://play.google.com/store/apps/details?id=com.boost_it.craysfishbar"><img src="https://rookcala.sirv.com/playStore.png" style="height:43px;"></a></div><div class="col-xs-6" style="text-align: left;"> <a href="https://apps.apple.com/us/app/crays-fish-bar-london/id6746380694"><img src="https://rookcala.sirv.com/appStore.png" style="height:43px;"></a></div> 627</div> 628 <div class="container"> 629 <div class="footer-inner"> 630 <div class="footer-info"> 631 <div class="brand-logo" style="margin-top:10px; margin-bottom:10px;"> 632 <img src="/sitelogo/sitelogo.png" height="60px" style="margin-bottom:6px;"> 633 </div> 634 <p>360 Footscray Rd,London,SE9 2AA</p> 635 <p> 636 <a href="tel:02031 616743" style="font-size:14px;" id="shopTel">02031 616743</a> 637 </p> 638 </div> 639 </div> 640 <div class="copy-right"> 641 <div class="row"> 642 <div class="col-md-12 col-sm-12 col-xs-12 text-center "> 643 <span> 644 <a onclick="window.open('/copyright', '_blank', 'location=no,height=570,width=320,scrollbars=yes,status=yes')">Copyright Crays Fish Bar All Rights Reserved.</a> 645 </span> 646 <br>
647 <span> 648 <a onclick="window.open('/terms', '_blank', 'location=no,height=570,width=320,scrollbars=yes,status=yes')" style="color:#fff;">Terms & Conditions</a> 649 </span><br> 650 <span> 651 <a onclick="window.open('/disclaimer', '_blank', 'location=no,height=570,width=320,scrollbars=yes,status=yes')" style="color:#fff;">Service Disclaimer</a> 652 </span> 653 </div> 654 </div> 655 </div> 656 </div> 657 </div> 658 <div id="cookieConsent" style="position: fixed; bottom: 45px; background-color: #272626; width: 100%; text-align: center; color:#fff; font-weight: 400; display:none;"> 659 This website is using cookies for better browsing experience.<button class="cookieConsentOK" style=" background: #822222; border: none; border-radius: 5px;">I agree.</button> 660 <h>Click here for our <a href="/terms">Cookie Policy</a></h> 661</div> 662</footer> 663 664 <div class="modal fade " id="popupModal" tabindex="-1" role="dialog" aria-labelledby="popupModal"> 665 <div class="modal-dialog modal-sm popupxx" role="dialog"> 666 <div class="modal-content" style="margin-top: 5%; overflow: hidden;"> 667 <div class="modal-body modal-bodyxx popupbodyxx" style="background:white;"> 668 <button type="button" class="close_new2x" data-dismiss="modal" aria-label="Close" style="top: 10px;"> Ã </button> 669 <div class="table-title" style="margin-bottom: 0px; margin-top:8px;"> 670 <h2 class="cartclass">Shopping Cart </h2> 671 672 <div class="cartwrap"> 673 <svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="green" stroke-width="2.0" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="margin-right:4px;"> 674 <circle cx="9" cy="21" r="1"></circle> 675 <circle cx="20" cy="21" r="1"></circle> 676 <path d="M1 1h4l2.7 13.4a2 2 0 0 0 2 1.6h8.9a2 2 0 0 0 1.9-1.4L23 6H6"></path> 677</svg> 678 <p id="basketShow2" class="basketxyz"> </p> 679 </div> 680 </div> 681 <div class="cart-wdrap" id="cart-blogs" style="margin-top:10px;"> 682 <div class="cart-blog row " id="cartPopUp" > 683 <div class="cart-btn col-xs-12" style=" margin-bottom: 20px; width:100%;"> 684 <!-- <a href="javascript:;" onclick="clearCarts();" class="btn-black cartMainButtons" >Clear Cart</a> --> 685 686 687 688 <a href="/checkout" class="btn-main cartMainButtons"> CHECK OUT <span class="arrow">â</span></a> 689 690 691 </div> 692 <div class="cartpopupitems popupxyz" id="cartPopUpx"></div> 693 </div> 694 </div> 695 </div> 696 </div> 697 </div> 698</div> 699 700 701 702<div class="modal fade " id="optionmodal" tabindex="-1" role="dialog" aria-labelledby="optionmodal" style="z-index: 99999999999 !important;"> 703 <div class="modal-dialog modal-sm" role="dialog"> 704 <div class="modal-content" style="margin-top: 5%; padding:46px; background:transparent; border:none;"> 705 <div class="modal-body" style="background:white; margin-top: 3px !important;"> 706 <div class="cart-wdrap" id="optionsmenu"> 707 </div> 708 </div> 709 </div> 710 </div> 711</div> 712 713<div class="modal fade " id="loginModal" tabindex="-1" role="dialog" aria-labelledby="loginModal"> 714 <div class="modal-dialog modal-sm loginModalx" role="dialog"> 715 <div class="modal-content modal-contentx" style="margin-top: 30%;"> 716 <div class="modal-body modal-bodyx modal-logx" style=" padding: 2px 3px 3px 3px;"> 717 <button type="button" class="close_new fa fa-close" data-dismiss="modal" aria-label="Close"> </button> 718 <div class="table-title"> 719 <h2 class="headersLog">Login</h2> 720 <h6 class="heade-xs btn lpassword" onclick="lostPassword();" style="color:red; margin-bottom: -15px;" id="lostPasswordOpen">Lost your password ? Click Here</h6> 721 </div> 722 <form class="form" id="loginForms"> 723 <div class="row" id="loginForm"> 724 725 726 <div class="col-md-12 col-sm-12 col-xs-12" style="position:relative;"> 727 728 <span class="icony"> 729 <svg viewBox="0 0 24 24"> 730 <rect x="3" y="5" width="18" height="14"></rect> 731 <path d="M3 7l9 6 9-6"></path> 732 </svg> 733 </span> 734 735 <input type="text" 736 name="username" 737 placeholder="Your E-Mail" 738 class="input-fields with-icon" 739 id="username2" 740 style="text-transform: lowercase;"> 741 742</div> 743 744 745 <div class="col-md-12 col-sm-12 col-xs-12" style="position:relative;"> 746 747 <!-- LOCK ICON --> 748 <span class="icony"> 749 <svg viewBox="0 0 24 24"> 750 <rect x="5" y="11" width="14" height="9"></rect> 751 <path d="M8 11V8a4 4 0 0 1 8 0v3"></path> 752 </svg> 753 </span> 754 755 <!-- INPUT --> 756 <input type="text" 757 name="search" 758 placeholder="Password" 759 class="input-fields with-icon passfield" 760 id="password2" 761 onfocus="this.type='password'" 762 autocorrect="off" 763 autocapitalize="none"> 764 765 <!-- EYE ICON --> 766 <span class="eye-toggle" onclick="togglePasswordField(this)"> 767 <svg viewBox="0 0 24 24"> 768 <path d="M1 12s4-6 11-6 11 6 11 6-4 6-11 6-11-6-11-6z"/> 769 <circle cx="12" cy="12" r="3"/> 770 </svg> 771 </span> 772 773</div> 774 775 776 777 778 <div class="or-left"></div><div class="or-right"></div> 779 <div class="col-md-12 col-sm-12 col-xs-12" style="margin-top:8px;"> 780 <input type="submit" name="submit" class="btn-main submitButtons" value="Login" style=" width:100%; margin-bottom:18px;" id="loginButton1"> 781 </div> 782 783 <div class="or-seperatorx1" style=" margin: 16px 20px 0 20px !important; font-size:14px;"><i>New Customer? </i></div> 784 785 786 <div class="col-xs-12 " > 787 <a class="btn registerB" href="#" style="font-size:16px; margin-bottom:4px;" onclick="regModal();"> Register</a> 788 </div> 789 790 791 <div class="col-md-12 col-sm-12 col-xs-12" id="socialLoginsx"> 792 <div class="or-seperator" style="margin-top:14px !important;"><i>or</i></div> 793 <p class="text-center xxc" style="height:27px !important;">Login with your social media account</p> 794 <div class="text-center social-btn"> 795 <div class="fb-login-button" data-width="" data-size="large" data-button-type="continue_with" data-layout="default" data-auto-logout-link="false" data-use-continue-as="false"></div> 796 797 798 <div id="appleid-signin" data-color="black" data-border="true" data-type="sign in"></div>
vendor: 123 bytes, lines 798-799
798 799 <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
799<script type="text/javascript" src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script>
799 800 801 802 <a href="/auth/facebook" class="btn btn-primary"><i class="fa fa-facebook"></i> Facebook</a> 803 <a href="/auth/google" class="btn btn-danger"><i class="fa fa-google-plus"></i> Google</a> 804 </div> 805 806 <h1 class="terms" style="margin-top:10px;"> By logging via social platforms you accept the <a onclick="termsconditions();">terms & conditions</a></h1> 807 808 </div> 809 810 <!-- --> 811 </div> 812 </form> 813 </div> 814 </div> 815 </div> 816</div> 817 818<div class="modal fade " id="fgModal" tabindex="-1" role="dialog" aria-labelledby="fgModal"> 819 <div class="modal-dialog modal-sm modal-dialogx" role="dialog"> 820 <div class="modal-content modal-contentx" style="margin-top: 30%;"> 821 <div class="modal-body modal-bodyx" style=" padding: 2px 3px 3px 3px;"> 822 <button type="button" class="close_new fa fa-close" data-dismiss="modal" aria-label="Close"> </button> 823 <form class="form" id="sendForgottenForm"> 824 <h2 class="heade-xs2">Please enter your email and follow the instructions</h2> 825 826 <div id="lostPassword"> 827 828 <div class="col-md-12 col-sm-12 col-xs-12"> 829 <span class="icony"> 830 <svg viewBox="0 0 24 24"> 831 <rect x="3" y="5" width="18" height="14"></rect> 832 <path d="M3 7l9 6 9-6"></path> 833 </svg> 834 </span> 835 836 837 <input type="text" name="email" placeholder="Your E-Mail" class="input-fields" id="forgetEmail"> 838 </div> 839 840 841 <div class="col-md-12 col-sm-12 col-xs-12"> 842 <input type="submit" name="submit" class="btn-main submitButtons" value="Send Reset Link" style="width:100%;" id="resetlinkbutton"> 843 </div> 844 </form> 845 <form class="form" id="changefpassword"> 846 <div class="col-md-12 col-sm-12 col-xs-12"> 847 <h2 class="headersLogx">Enter the code sent to you by email or follow the link in the email to change your password</h2> 848 </div> 849 <div class="col-md-12 col-sm-12 col-xs-12"> 850 <span class="icony"> 851 <svg viewBox="0 0 24 24"> 852 <rect x="3" y="5" width="18" height="14"></rect> 853 <path d="M3 7l9 6 9-6"></path> 854 </svg> 855 </span> <input type="text" name="email" placeholder="Your E-Mail" class="input-fields" id="forgetEmailxx" required> 856 </div> 857 <div class="col-md-12 col-sm-12 col-xs-12"> 858 859 <span class="icony"> 860 <svg viewBox="0 0 24 24"> 861 <path d="M10 3L8 21"></path> 862 <path d="M16 3L14 21"></path> 863 <path d="M4 9h17"></path> 864 <path d="M3 15h17"></path> 865 </svg> 866</span> 867 868 <input type="text" name="number" placeholder="Reset Code" class="input-fields" id="resetcode" required> 869 </div> 870 <div class="col-md-12 col-sm-12 col-xs-12"> 871 872 873 <span class="icony"> 874 <svg viewBox="0 0 24 24"> 875 <rect x="5" y="11" width="14" height="9"></rect> 876 <path d="M8 11V8a4 4 0 0 1 8 0v3"></path> 877 </svg> 878 </span> 879 880 <input type="text" name="search" placeholder="Password" class="input-fields passfield" id="password1xx" onfocus="this.type='password'" autocorrect="off" autocapitalize="none" required> 881 882 <span class="eye-toggle" onclick="togglePasswordField(this)"> 883 <svg viewBox="0 0 24 24"> 884 <path d="M1 12s4-6 11-6 11 6 11 6-4 6-11 6-11-6-11-6z"/> 885 <circle cx="12" cy="12" r="3"/> 886 </svg> 887 </span> 888 </div> 889 <div class="col-md-12 col-sm-12 col-xs-12"> 890 <span class="icony"> 891 <svg viewBox="0 0 24 24"> 892 <rect x="5" y="11" width="14" height="9"></rect> 893 <path d="M8 11V8a4 4 0 0 1 8 0v3"></path> 894 </svg> 895 </span> 896 897 898 <input type="text" name="search" placeholder="Confirm Password" class="input-fields passfield" id="verifypassword1xx" onfocus="this.type='password'" autocorrect="off" autocapitalize="none" required> 899 900 <span class="eye-toggle" onclick="togglePasswordField(this)"> 901 <svg viewBox="0 0 24 24"> 902 <path d="M1 12s4-6 11-6 11 6 11 6-4 6-11 6-11-6-11-6z"/> 903 <circle cx="12" cy="12" r="3"/> 904 </svg> 905 </span> 906 907 </div> 908 <div class="col-md-12 col-sm-12 col-xs-12" style="padding-bottom:20px;"> 909 <input type="submit" name="submit" class="btn-main submitButtons" value="Change Password" style="width:100%;" onclik="changefpassword();"> 910 </div> 911 </form> 912 </div> 913 </div> 914 </div> 915</div> 916</div> 917 918<div class="modal fade" id="appAlert" tabindex="-1" role="dialog" aria-labelledby="appAlert"> 919 <div class="modal-dialog modal-sm" role="dialog"> 920 <div class="modal-content" style="background: transparent; border: none;"> 921 <div class="modal-body" style="padding: 4px;"> 922 <div class="yes-no" style="min-height: 130px;"> 923 <h2 class="coolal-title" id="appAlertTitle"></h2> 924 <p class="coolal-text" id="appAlertText"></p> 925 926 <div id="appAlertFooter" class="coolal-btnWrapper"> 927 <a href="javascript:;" class="coolal-yes" data-dismiss="modal">OK</a> 928 </div> 929 </div> 930 </div> 931 </div> 932 </div> 933</div> 934 935 936<div class="modal fade " id="iosAlert" tabindex="-1" role="dialog" aria-labelledby="iosAlert"> 937 <div class="modal-dialog modal-sm" role="dialog"> 938 <div class="modal-content" style="background: transparent; border:none;"> 939 <div class="modal-body" style=" padding: 2px 3px 3px 3px; "> 940 <div id="coolal" class="yes-no" style="height: 154px; opacity: 1; top: 0px;"> 941 <h2 class="coolal-title"id="titlex1"></h2> 942 <p class="coolal-text" id="textx1"> 943 </p> 944 <div id="coolal-btnWrapper" data-dismiss="modal" aria-label="Close"><a id="coolal-btn" class="coolal-yes-no coolal-yes" href="#" class="close_new fa fa-close" data-dismiss="modal" aria-label="Close">OK</a> </div> 945 </div> 946 </div> 947 </div> 948 </div> 949</div> 950 951<div class="modal fade " id="iosAlertx" tabindex="-1" role="dialog" aria-labelledby="iosAlertx"> 952 <div class="modal-dialog modal-sm modal-dialogx" role="dialog"> 953 <div class="modal-content modal-contentx" style="background: transparent;">
954 <div class="modal-body modal-bodyx" style=" padding: 2px 3px 3px 3px;"> 955 <div id="coolal" class="yes-no" style="height: 135px; opacity: 1; top: 0px; height: max-content !important;"> 956 <h2 class="coolal-title" id="titlex"></h2> 957 <p class="coolal-text" id="textx"></p> 958 <div id="coolal-btnWrapperx"> 959 960 </div> 961 </div> 962 </div> 963 </div> 964 </div> 965</div> 966 967 968 969 970<div class="modal fade " id="telephoneModal" tabindex="-1" role="dialog" aria-labelledby="telephoneModal"> 971 <div class="modal-dialog modal-sm modal-dialogx profileModalxx" role="dialog"> 972 <div class="modal-content modal-contentx contentxx"> 973 <div class="modal-body modal-bodyx modal-telx" style=" padding: 2px 3px 3px 3px;"> 974 <button type="button" class="close_new fa fa-close" data-dismiss="modal" aria-label="Close"> </button> 975 <form id="telephoneForm"> 976 <div class="row"> 977 978 979 980 <div class="col-md-12 col-sm-12 table-titlex"> 981 <h6 class="heade-xs2" id="profilxtel">Please update your phone number and name in case we need to contact you regarding to your order</h6> 982 <h6 class="heade-xs2" id="telxtel" style="display:none;">Update your phone number</h6> 983 </div> 984 985 986 987 988 989 <div class="col-md-12 col-sm-12 col-xs-12" id="telephoneModalName"> 990 <label for="contactName3x" class="field-label">Name</label> 991 <i class="fa fa-icon-name1 icon-classes-general"></i> <input type="text" name="contactName3x" placeholder="Name" class="input-fields" id="contactName3x" required> 992 </div> 993 <div class="col-md-12 col-sm-12 col-xs-12" style="margin-bottom:30px;"> 994 <label for="telephone3x" class="field-label">Telephone</label> 995 <i class="fa fa-icon-telephone1 icon-classes-general"></i> 996 <input type="tel" name="number3x" placeholder="Telephone (e.g. 07761 111111)" class="input-fields" id="telephone3x" inputmode="tel" required > 997 </div> 998 <div class="col-md-12 col-sm-12 col-xs-12" style="margin-bottom:15px; margin-top:5px;"> 999 <input type="submit" name="submit" class="btn-main submitButtons" value="Save Changes" style="width:100%;" required> 1000 <span class="validity"></span> 1001 </div> 1002 </div> 1003 1004 </form> 1005 </div> 1006 </div> 1007 </div> 1008 </div> 1009 1010 1011 1012 1013 1014<div class="modal fade " id="passChangeModal" tabindex="-1" role="dialog" aria-labelledby="passChangeModal"> 1015 <div class="modal-dialog modal-sm modal-dialogx" role="dialog"> 1016 <div class="modal-content modal-contentx"> 1017 <div class="modal-body modal-bodyx" style=" padding: 2px 3px 3px 3px;"> 1018 <button type="button" class="close_new fa fa-close" data-dismiss="modal" aria-label="Close"> </button> 1019 <div class="table-title"> 1020 <h6 class="heade-xs2">Change your password</h6> 1021 </div> 1022 <form id="changePassForm"> 1023 <div class="row"> 1024 <div class="col-md-12 col-sm-12 col-xs-12"> 1025 <div class="col-md-12 col-sm-12 col-xs-12"> 1026 <label for="password3x" class="form-label form-label-outside chpassword">New Password </label> 1027 <input id="password3x" type="search" name="password" required pattern=".{5,30}" title="Min 5, Max 30 Characters" class="form-control" autocomplete="off" onfocus="this.type='password'" autocorrect="off" autocapitalize="none"> 1028 </div> 1029 <div class="col-md-12 col-sm-12 col-xs-12"> 1030 <label for="retypex" class="form-label form-label-outside chpassword">Re-Type New Password </label> 1031 <input id="retypex" type="search" name="password" required pattern=".{5,30}" title="Min 5, Max 30 Characters" class="form-control" onfocus="this.type='password'" autocorrect="off" autocapitalize="none"> 1032 </div> 1033 <div class="col-md-12 col-sm-12 col-xs-12" style="margin-bottom:25px; margin-top:20px;"> 1034 <input type="submit" name="submit" class="btn-main submitButtons" value="Change Password" style="width:100%;" id="changesPassword" required>
1035 <span class="validity"></span> 1036 </div> 1037 </div> 1038 </div> 1039 </form> 1040 </div> 1041 </div> 1042 </div> 1043</div> 1044 1045 1046<div class="modal fade " id="aboutUs" tabindex="-1" role="dialog" aria-labelledby="aboutUs"> 1047 <div class="modal-dialog modal-sm modal-dialogx" role="dialog"> 1048 <div class="modal-content modal-contentx"> 1049 <div class="modal-body modal-bodyx" style=" padding: 2px 3px 3px 3px;"> 1050 <button type="button" class="close_new fa fa-close" data-dismiss="modal" aria-label="Close"> </button> 1051 <div class="table-title"> 1052 <h6 class="heade-xs2"></h6> 1053 <h6 class="heade-xs2">If you have any questions or inqueries please contact us.</h6> 1054 </div> 1055 <div class="row"> 1056 <div class="col-md-12 col-sm-12 col-xs-12"> 1057 <h6 class="heade-xs23">Opening Days</h6> 1058 <h6 class="heade-xs24" id="openingDays"> </h6> 1059 </div> 1060 <div class="col-md-12 col-sm-12 col-xs-12"> 1061 <h6 class="heade-xs23">Phone</h6> 1062 <h6 class="heade-xs24" id="phoneShop"> 1063 <li class="navbar-icon thin-icon-phonenav"></li> <a class="telclaz" href="callto:02031 616743 "> 1064 02031 616743 1065 </a> 1066 </h6> 1067 </div> 1068 <div class="col-md-12 col-sm-12 col-xs-12"> 1069 <h6 class="heade-xs23">Address</h6> 1070 <h6 class="heade-xs24" id="shopAddressx"> </h6> 1071 </div> 1072 <div class="col-md-12 col-sm-12 col-xs-12" style="margin-bottom:20px;"> 1073 <h6 class="heade-xs23">Promotions</h6> 1074 <h6 class="heade-xs24" id="promotions"> </h6> 1075 </div> 1076 </div> 1077 </div> 1078 </div> 1079 </div> 1080</div> 1081 1082<div class="modal fade " id="addressModal" tabindex="-1" role="dialog" aria-labelledby="addressModal"> 1083 <div class="modal-dialog modal-sm modal-dialogx profileModalxx" role="dialog"> 1084 <div class="modal-content modal-contentx contentxx"> 1085 <div class="modal-body modal-bodyx modal-telx" style=" padding: 2px 3px 3px 3px;"> 1086 <button type="button" class="close_new fa fa-close" data-dismiss="modal" aria-label="Close"> </button> 1087 <form id="addressForm3x"> 1088 <div class="row"> 1089 <div class="col-md-12 col-sm-12 table-titlex"> 1090 <h6 class="heade-xs2">Please update your address and postcode for delivery</h6> 1091 </div> 1092 1093 <div class="col-md-12 col-sm-12 col-xs-12"> 1094 <i class="fa fa-icon-name1 icon-classes-general"></i> <input type="text" name="contactName2x" placeholder="Name" class="input-fields" id="contactName2x" required> 1095 </div> 1096 <div class="col-md-12 col-sm-12 col-xs-12"> 1097 <i class="fa fa-icon-telephone1 icon-classes-general"></i> 1098 1099<input 1100 type="tel" 1101 name="number2x" 1102 placeholder="Telephone (e.g. 07761 111111)" 1103 class="input-fields" 1104 id="telephone2x" 1105 inputmode="tel" 1106 required 1107> 1108 </div> 1109 <div class="row" style="margin:0;" id="postcodeUpdate"> 1110 <div class="col-md-12 col-sm-12 col-xs-12"> 1111 <i class="fa fa-icon-address1 icon-classes-general"></i> <input type="text" name="address2x" placeholder="Address" class="input-fields" id="address2x" title="Between 2 -55 charachters" pattern=".{2,75}" required oninvalid="this.setCustomValidity('Between 2-55 charachters')" 1112 onchange="try{setCustomValidity('')}catch(e){}"> 1113 </div> 1114 1115 <div class="col-md-12 col-sm-12 col-xs-12" > 1116 <i class="fa fa-icon-postcode1 icon-classes-general"></i> <input type="text" name="postcode2x" placeholder="Postcode" class="input-fields" id="postcode2x" required oninvalid="this.setCustomValidity('Use a valid postcode')" 1117 onchange="try{setCustomValidity('')}catch(e){}"> 1118 </div> 1119 </div> 1120 <div class="col-md-12 col-sm-12 col-xs-12" style="margin-bottom:15px; margin-top:5px;"> 1121 <input type="submit" name="submit" class="btn-main submitButtons" value="Save Changes" style="width:100%;" required>
1122 <span class="validity"></span> 1123 </div> 1124 1125 </div> 1126 </form> 1127 </div> 1128 </div> 1129 </div> 1130</div> 1131 1132 1133<div class="modal fade " id="profileModal" tabindex="-1" role="dialog" aria-labelledby="profileModal"> 1134 <div class="modal-dialog modal-sm modal-dialogx profileModalxx" role="dialog"> 1135 <div class="modal-content modal-contentx contentxx"> 1136 <div class="modal-body modal-bodyx" style=" padding: 2px 3px 3px 3px;"> 1137 <button type="button" class="close_new fa fa-close" data-dismiss="modal" aria-label="Close"> </button> 1138 <div class="table-title"> 1139 <h6 class="heade-xs2">View or change your details</h6> 1140 <h6 class="heade-xs2 " style="display:none;" id="addressWarning">Your delivery address seems incomplete. Please add your house/flat number or house name, then save your details. 1141</h6> 1142 <div class="col-md-12 col-sm-12 col-xs-12" style="margin-bottom:8px;" id="deleteAccountDiv"> 1143 <input type="submit" name="submit" class="btn-main submitButtons" value="Delete my Account" id="deleteAccount" onclick="deleteAccount();"> 1144 <span class="validity"></span> 1145 </div> 1146 <h6 class="heade-xs2" id="email-xs2">Please use a valid email address if you would like to get order notifications</h6> 1147 </div> 1148 <form id="myProfileForm"> 1149 <input type="hidden" id="profileAddressConfirmed" value="no"> 1150 <div class="row"> 1151 <div class="col-md-12 col-sm-12 col-xs-12"> 1152 1153 <!-- NAME --> 1154<div class="col-md-12 col-sm-12 col-xs-12" id="profileModalName"> 1155 <label for="name1x" class="field-label">Name</label> 1156 1157 <span class="iconx"> 1158 <svg viewBox="0 0 24 24"> 1159 <circle cx="12" cy="8" r="4"></circle> 1160 <path d="M4 20c0-4 4-6 8-6s8 2 8 6"></path> 1161 </svg> 1162 </span> 1163 1164 <input type="text" name="name" placeholder="Name" 1165 class="input-fields with-icon" id="name1x" required> 1166</div> 1167 1168<!-- EMAIL --> 1169<div class="col-md-12 col-sm-12 col-xs-12" id="profileModalEmail"> 1170 <label for="email1x" class="field-label">Email</label> 1171 1172 <span class="iconx"> 1173 <svg viewBox="0 0 24 24"> 1174 <rect x="3" y="5" width="18" height="14"></rect> 1175 <path d="M3 7l9 6 9-6"></path> 1176 </svg> 1177 </span> 1178 1179 <input type="email" name="emails" 1180 placeholder="Your E-Mail ( [email protected] )" 1181 class="input-fields with-icon" id="email1x" required> 1182</div> 1183 1184<!-- TELEPHONE --> 1185<div class="col-md-12 col-sm-12 col-xs-12" id="profileModalTelephone"> 1186 <label for="telephone1x" class="field-label">Telephone</label> 1187 1188 <span class="iconx"> 1189 <svg viewBox="0 0 24 24"> 1190 <path d="M22 16.9v3a2 2 0 0 1-2.2 2 1191 19.8 19.8 0 0 1-8.6-3.1 1192 19.5 19.5 0 0 1-6-6 1193 19.8 19.8 0 0 1-3.1-8.7A2 2 0 0 1 4.1 2h3 1194 a2 2 0 0 1 2 1.7c.1.8.3 1.5.6 2.2 1195 a2 2 0 0 1-.5 2.1L8 9 1196 a16 16 0 0 0 6 6l1-1.2 1197 a2 2 0 0 1 2.1-.5c.7.3 1.4.5 2.2.6 1198 a2 2 0 0 1 1.7 2z"></path> 1199 </svg> 1200 </span> 1201 1202<input 1203 type="tel" 1204 name="number" 1205 placeholder="Telephone (e.g. 07761 111111)" 1206 class="input-fields with-icon"
1207 id="telephone1x" 1208 inputmode="tel" 1209 required 1210> 1211</div> 1212 1213<!-- ADDRESS + POSTCODE --> 1214<div class="row" style="margin:0;" id="postcodeUpdate2"> 1215 1216 <!-- ADDRESS --> 1217 <div class="col-md-12 col-sm-12 col-xs-12"> 1218 <label for="address1x" class="field-label">Address</label> 1219 1220 <span class="iconx"> 1221 <svg viewBox="0 0 24 24"> 1222 <path d="M12 21s6-5.5 6-10a6 6 0 0 0-12 0c0 4.5 6 10 6 10z"></path> 1223 <circle cx="12" cy="11" r="2"></circle> 1224 </svg> 1225 </span> 1226 1227 <input type="text" name="address" 1228 placeholder="Address" 1229 class="input-fields with-icon" 1230 id="address1x" 1231 pattern=".{2,85}" required> 1232 </div> 1233 1234 <!-- POSTCODE --> 1235 <div class="col-md-12 col-sm-12 col-xs-12"> 1236 <label for="postcode1x" class="field-label">Postcode</label> 1237 1238 <span class="iconx"> 1239 <svg viewBox="0 0 24 24"> 1240 <path d="M10 3L8 21"></path> 1241 <path d="M16 3L14 21"></path> 1242 <path d="M4 9h17"></path> 1243 <path d="M3 15h17"></path> 1244 </svg> 1245 </span> 1246 1247 <input type="text" name="postcode" 1248 placeholder="Postcode" 1249 class="input-fields with-icon" 1250 id="postcode1x" required> 1251 </div> 1252 1253</div> 1254 1255 <!-- EMAIL NOTIFICATIONS SWITCH (unchanged) --> 1256 <div class="col-md-12 col-sm-12 col-xs-12" style=" margin-top:15px;" id="profileModalNotifications"> 1257 <label class="form-switch switchlabel"> 1258 <input type="checkbox" id="emailswitch"> 1259 <i></i> 1260 Email Notifications 1261 </label> 1262 </div> 1263 1264 <!-- SAVE BUTTON (unchanged) --> 1265 <div class="col-md-12 col-sm-12 col-xs-12" style="margin-bottom:15px;" id="saveChangesMyProfile"> 1266 <input type="submit" 1267 name="submit" 1268 class="btn-main submitButtons" 1269 value="Save Changes" 1270 style="width:100%;" 1271 id="saveChanges" 1272 required> 1273 <span class="validity"></span> 1274 </div> 1275 1276 </div> 1277 </div> 1278</form> 1279 1280 </div> 1281 </div> 1282 </div> 1283</div> 1284 1285<div class="modal fade " id="contactModalx" tabindex="-1" role="dialog" aria-labelledby="contactModalx"> 1286 <div class="modal-dialog modal-sm modal-dialogx" role="dialog"> 1287 <div class="modal-content modal-contentx"> 1288 <div class="modal-body modal-bodyx"> 1289 <button type="button" class="close_new fa fa-close" data-dismiss="modal" aria-label="Close"> </button> 1290 <div class="table-title" style="padding:35px;"> 1291 <h6 class="heade-xs2" style="font-size:18px;">If you have a problem or question about your order please call the shop</h6> 1292 <h6 class="heade-xs2" style="font-size:20px; color:red;"> 02031 616743 </h6> 1293 1294 </div> 1295 <!-- <form id="contactForms"> 1296 <div class="row"> 1297 <div class="col-md-12 col-sm-12 col-xs-12"> 1298 <h5 class="formInputsx">About*</h5> 1299 </div> 1300 <div class="col-md-12 col-sm-12 col-xs-12"> 1301 <i class="fa fa-icon-arrow-right icon-classes-general" style="top: 14px;"></i> 1302 <select class="timeSelectx input-fields" id="contactTitle" name="subject" required> 1303 </select> 1304 </div> 1305 <div class="col-md-12 col-sm-12 col-xs-12"> 1306 <i class="fa fa-icon-name1 icon-classes-general"></i> <input type="text" name="contactName" placeholder="Name" class="input-fields" id="contactName" required> 1307 </div> 1308 <div class="col-md-12 col-sm-12 col-xs-12"> 1309 <i class="fa fa-icon-mailLog icon-classes-general"></i> <input type="email" name="email" placeholder="Your E-Mail ( [email protected])" class="input-fields" id="contactEmail" required> 1310 </div> 1311 <div class="col-md-12 col-sm-12 col-xs-12"> 1312 <i class="fa fa-icon-telephone1 icon-classes-general"></i> <input type="tel" name="phone" placeholder="Telephone Ex(:0776 111 11 11)" class="input-fields" id="contactTelephone"> 1313 </div> 1314 <div class="col-md-12 col-sm-12 col-xs-12" style="margin-top:10px;"> 1315 <textarea placeholder="Your Message" id="messageCustomerx" name="message" required></textarea> 1316 </div> 1317 <div class="col-md-12 col-sm-12 col-xs-12" style="margin:16px 0;"> 1318 <input type="submit" name="submit" class="btn-main submitButtons" value="Submit Message" style="width:100%;" id="saveChanges" required>
1319 <span class="validity"></span> 1320 </div> 1321 <input type="text" placeholder="Phone" name="address" class="inputlabels" value="" id="csAddress" style="display:none;" readonly> 1322 <input type="text" placeholder="Phone" name="postcode" class="inputlabels" value="" id="csPostcode" style="display:none;" readonly> 1323 </div> 1324 </form> --> 1325 </div> 1326 </div> 1327 </div> 1328</div> 1329 1330<div class="modal fade " id="messageModal" tabindex="-1" role="dialog" aria-labelledby="messageModal"> 1331 <div class="modal-dialog modal-sm" role="dialog"> 1332 <div class="modal-content" style="margin-top: 5%; max-width: 470px; overflow: hidden;"> 1333 <div class="modal-body" style="background:white;"> 1334 <button type="button" class="close_new fa fa-close" data-dismiss="modal" aria-label="Close"> </button> 1335 <div class="table-title" style="margin-bottom: 0px;"> 1336 <div id="situation"></div> 1337 <div id="yourMessage"> </div> 1338 <div id="shopReply"></div> 1339 <div id="generic"></div> 1340 </div> 1341 </div> 1342 </div> 1343 </div> 1344</div> 1345 1346<div class="modal fade " id="termsModal" tabindex="-1" role="dialog" aria-labelledby="termsModal"> 1347 <div class="modal-dialog modal-sm registerModalx termModalx" role="dialog"> 1348 <div class="modal-content modal-contentx term-contentx"> 1349 <div class="modal-body modal-bodyx" style=" padding: 2px 3px 3px 3px;"> 1350 <button type="button" class="close_new fa fa-close" data-dismiss="modal" aria-label="Close"> </button> 1351 <div class="table-title"> 1352 <h2 class="termsHeader" id="termheader"> </h2> 1353 </div> 1354 <div class="row" id="termsModalBody"> 1355 </div> 1356 </div> 1357 </div> 1358 </div> 1359</div> 1360 1361 1362 1363 1364<div class="modal fade " id="registerModal" tabindex="-1" role="dialog" aria-labelledby="registerModal"> 1365 <div class="modal-dialog modal-sm registerModalx" role="dialog"> 1366 <div class="modal-content modal-contentx"> 1367 <div class="modal-body modal-bodyx" style=" padding: 2px 3px 3px 3px;"> 1368 <button type="button" class="close_new fa fa-close" data-dismiss="modal" aria-label="Close"> </button> 1369 <div class="table-title"> 1370 <h2 class="headersLog">Register</h2> 1371 <h6 class="heade-xs">Use a valid email and telephone number</h6> 1372 </div> 1373 <form id="registerForm"> 1374 <div class="row"> 1375 <div class="col-md-12 col-sm-12 col-xs-12"> 1376 <label for="name1" class="field-label">Name</label> 1377 <span class="iconr"> 1378 <svg viewBox="0 0 24 24"> 1379 <rect x="3" y="5" width="18" height="14"></rect> 1380 <path d="M3 7l9 6 9-6"></path> 1381 </svg> 1382 </span> <input type="text" name="name" placeholder="Name" class="input-fields" id="name1" required> 1383 </div> 1384 1385 <div class="col-md-12 col-sm-12 col-xs-12"> 1386 <label for="email1" class="field-label">Email</label> 1387 <span class="iconr"> 1388 <svg viewBox="0 0 24 24"> 1389 <rect x="3" y="5" width="18" height="14"></rect> 1390 <path d="M3 7l9 6 9-6"></path> 1391 </svg> 1392 </span><input type="email" name="emails" placeholder="Your E-Mail ( [email protected])" class="input-fields" id="email1" required> 1393 </div> 1394 <div class="col-md-12 col-sm-12 col-xs-12"> 1395 <label for="telephone1" class="field-label">Telephone</label> 1396 1397 <span class="iconr"> 1398 <svg viewBox="0 0 24 24"> 1399 <path d="M22 16.9v3a2 2 0 0 1-2.2 2 1400 19.8 19.8 0 0 1-8.6-3.1 1401 19.5 19.5 0 0 1-6-6 1402 19.8 19.8 0 0 1-3.1-8.7A2 2 0 0 1 4.1 2h3 1403 a2 2 0 0 1 2 1.7c.1.8.3 1.5.6 2.2 1404 a2 2 0 0 1-.5 2.1L8 9 1405 a16 16 0 0 0 6 6l1-1.2 1406 a2 2 0 0 1 2.1-.5c.7.3 1.4.5 2.2.6 1407 a2 2 0 0 1 1.7 2z" ></path> 1408 </svg> 1409</span> 1410 1411 1412 1413 <input type="tel" name="number" placeholder="Telephone Ex(:0776 111 11 11)" class="input-fields" id="telephone1" required> 1414 </div> 1415 <div class="col-md-12 col-sm-12 col-xs-12"> 1416 <label for="address1" class="field-label">Address</label> 1417 <i class="fa fa-icon-address1 icon-classes-general"></i> <input type="text" name="address" placeholder="Address" class="input-fields" id="address1" title="Between 2 -35 charachters" minlength="2" maxlength="35"> 1418 </div> 1419 <div class="col-md-12 col-sm-12 col-xs-12"> 1420 <label for="postcode1" class="field-label">Postcode</label> 1421 <i class="fa fa-icon-postcode1 icon-classes-general"></i> <input type="text" name="postcode" placeholder="Postcode" class="input-fields" id="postcode1"> 1422 </div> 1423 <div class="col-md-12 col-sm-12 col-xs-12"> 1424 <label for="password1" class="field-label">Password</label> 1425 1426
1427 <span class="iconr"> 1428 <svg viewBox="0 0 24 24"> 1429 <rect x="5" y="11" width="14" height="9"></rect> 1430 <path d="M8 11V8a4 4 0 0 1 8 0v3"></path> 1431 </svg> 1432 </span> 1433 1434 <input type="text" name="search" placeholder="password" class="input-fields passfield" id="password1" onfocus="this.type='password'" autocorrect="off" autocapitalize="none" required> <span class="eye-toggler" onclick="togglePasswordField(this)"> 1435 <svg viewBox="0 0 24 24"> 1436 <path d="M1 12s4-6 11-6 11 6 11 6-4 6-11 6-11-6-11-6z"></path> 1437 <circle cx="12" cy="12" r="3"></circle> 1438 </svg> 1439 </span> 1440 </div> 1441 <div class="col-md-12 col-sm-12 col-xs-12" style="margin-bottom:27px;"> 1442 <label for="verifypassword1" class="field-label">Re-type Password</label> 1443 1444 <span class="iconr"> 1445 <svg viewBox="0 0 24 24"> 1446 <rect x="5" y="11" width="14" height="9"></rect> 1447 <path d="M8 11V8a4 4 0 0 1 8 0v3"></path> 1448 </svg> 1449 </span> 1450 <input type="text" name="search" placeholder="confirm password" class="input-fields passfield" id="verifypassword1" onfocus="this.type='password'" autocorrect="off" autocapitalize="none" required> <span class="eye-toggler" onclick="togglePasswordField(this)"> 1451 <svg viewBox="0 0 24 24"> 1452 <path d="M1 12s4-6 11-6 11 6 11 6-4 6-11 6-11-6-11-6z"></path> 1453 <circle cx="12" cy="12" r="3"></circle> 1454 </svg> 1455 </span> 1456 </div> 1457 <div class="col-md-12 col-sm-12 col-xs-12" > 1458 <input type="submit" name="submit" class="btn-main submitButtons" value="Register Now" style="width:100%;" id="registerButton" required> 1459 <span class="validity"></span> 1460 </div> 1461 1462 <div class="col-md-12 col-sm-12 col-xs-12" id="privacy"> 1463 <!-- <h1 class="terms"> By registering you accept the <a onclick="window.open('/terms', '_blank', 'location=no,height=570,width=320,scrollbars=yes,status=yes')">terms & conditions</a></h1> --> 1464 <h1 class="terms"> By registering you accept the <a onclick="termsconditions();">terms & conditions</a></h1></h1> 1465 </div> 1466 </div> 1467 </form> 1468 </div> 1469 </div> 1470 </div> 1471</div> 1472 1473 1474 1475<!-- End Register --> 1476 1477 <div class="bottomAndroidFix" style=" background-color: black; 1478display: -webkit-flex; 1479display: flex; 1480position: fixed; 1481left: 0; 1482/* top: 0; */ 1483right: 0; 1484padding: 4px 0px; 1485height: 56px; 1486color: #2b2c2f; 1487z-index: 999; 1488bottom: 4%; display:none; " id="bottomAndroidFix"> 1489 1490 <div class="row" style="margin-left:-7px;"> 1491 <div class="col-xs-3 mycolxs3"><button class="btn btn-success btn-menu" onclick="location.href='/apphome?ios=android';">Home</button> </div> 1492 <div class="col-xs-3 mycolxs3"><button class="btn btn-success btn-menu" onclick="location.href='/menu?ios=android';">Menu</button> </div> 1493 <div class="col-xs-3 mycolxs3"><button class="btn btn-success btn-menu" onclick="location.href='/checkout?ios=android';">Checkout</button></div> 1494 <div class="col-xs-3 mycolxs3"> <button class="btn btn-success btn-menu" onclick="location.href='/myprofile?ios=android';">Orders</button></div> 1495 </div> 1496 </div> 1497 1498 1499 1500
1500<script src="https://cdn.trackjs.com/agent/v3/latest/t.js"></script>
1500 1501
1501<script> 1502 1503 var ete = 0; 1504 window.TrackJS && TrackJS.install({ 1505 token: "b611dee257d8438a80caa0c4dc74fa7d", 1506 application: "my-app-prod" 1507 }); 1508 </script>
1508 1509 1510
1510<script src="js/utils/core.min.js"></script>
1510 1511
1511<script src="js/utils/scripts.js"></script>
1511 1512 1513 1514 <a href="#" class="top-arrow"></a> 1515 1516
1516<script> 1517 1518 window.addEventListener('load', function () { 1519 try { 1520 1521 window.TrackJS && TrackJS.addMetadata("userx", "none"); 1522 1523 1524 } catch (e) { 1525 // swallow â never let this kill the page 1526 console.log('TrackJS/init error', e); 1527 } 1528 }); 1529 1530 function checkCookieConsent() { 1531 try { 1532 if (window.sessionStorage && sessionStorage.getItem('999') !== 'Cookies Ok') { 1533 $("#cookieConsent").show(); 1534 } 1535 } catch (e) { 1536 // Storage not available â safest is just show banner and move on 1537 $("#cookieConsent").show(); 1538 } 1539 } 1540 1541 function regModal() { 1542 $('#loginModal').modal('hide'); 1543 $('#registerModal').modal('show'); 1544 } 1545 1546 function ajaxHandler(typeA, urlA, sendData, callback) { 1547 $.ajax({ 1548 type: typeA, 1549 url: urlA, 1550 data: sendData, 1551 error: function (response) { endEvent(); callback(response); }, 1552 success: function (response) { }, 1553 complete: function (response) { callback(response); } 1554 }); 1555 } 1556 1557 $("#loginButton1x").click(function (e) { 1558 stopForm(e); 1559 var sendUrl = "/logMeIn2"; var sendData = {}; 1560 sendData.username = ($("#username2y").val()).toLowerCase().trim(); 1561 sendData.password = $("#passworda3y").val(); 1562 ajaxHandler("POST", sendUrl, sendData, function (response) { 1563 if (response.responseText == "ACCESS") { window.location.reload(); } 1564 else if (response.responseText == "Password or Username is Wrong") { endEvent(); alertUser("Your password or email is wrong. Please try again or use forget password link."); } 1565 else { endEvent(); alertUser("There has been a problem. Please try again later."); } 1566 }); 1567 }); 1568 1569 $("#loginForms").submit(function (e) { 1570 stopForm(e); 1571 var sendUrl = "/logMeIn2"; var sendData = {}; 1572 sendData.username = ($("#username2").val()).toLowerCase().trim(); 1573 sendData.password = $("#password2").val(); 1574 ajaxHandler("POST", sendUrl, sendData, function (response) { 1575 if (response.responseText == "ACCESS") { window.location.reload(); } 1576 else if (response.responseText == "Password or Username is Wrong") { endEvent(); alertUser("Your password or email is wrong. Please try again or use forget password link."); } 1577 else { endEvent(); alertUser("There has been a problem. Please try again later."); } 1578 }); 1579 }); 1580 1581 $(".icon-classes-generalx").click(function (e) { 1582 var pinput = $(this).parent().find('.passfield'); 1583 //var pinput= $(this).next().find('.passfield'); 1584 if ($(pinput).attr('type') == "password") { 1585 $(pinput).attr('type', 'text'); 1586 } 1587 else { 1588 $(pinput).attr('type', 'password'); 1589 } 1590 }); 1591 1592 function appAlert(options) { 1593 1594 1595 $('#appAlertTitle').text(options.title || ''); 1596 $('#appAlertText').text(options.text || ''); 1597 1598 var footerHtml = ''; 1599 1600 if (options.buttons && options.buttons.length) { 1601 options.buttons.forEach(function (btn, i) { 1602 footerHtml += ` 1603 <a href="javascript:;" 1604 class="${btn.class || 'coolal-yes'}" 1605 data-btn-index="${i}"> 1606 ${btn.text} 1607 </a> 1608 `; 1609 }); 1610 } else { 1611 footerHtml = `<a href="javascript:;" class="coolal-yes" data-dismiss="modal">OK</a>`; 1612 } 1613 1614 $('#appAlertFooter').html(footerHtml); 1615 1616 // Attach actions 1617 $('#appAlertFooter a').off('click').on('click', function () { 1618 var index = $(this).data('btn-index'); 1619 var btn = options.buttons && options.buttons[index]; 1620 1621 $('#appAlert').modal('hide'); 1622 1623 if (btn && typeof btn.action === 'function') { 1624 setTimeout(btn.action, 150); 1625 } 1626 }); 1627 1628 $('#appAlert').modal('show'); 1629} 1630 1631 1632 function deleteAccount() { 1633 appAlert({ 1634 title: 'Delete Account', 1635 text: 'Are you sure you would like to proceed?', 1636 buttons: [ 1637 { 1638 text: 'Cancel', 1639 class: 'coolal-nox' 1640 }, 1641 { 1642 text: 'Remove', 1643 class: 'coolal-yesx', 1644 action: function () { 1645 deleteAccountx(); 1646 } 1647 } 1648 ] 1649 }); 1650} 1651 1652 function deleteAccountx() { 1653 var sendUrl = "/deleteAccount"; var sendData = {}; 1654 //$('#iosAlertx').modal('hide'); 1655 1656 ajaxHandler("GET", sendUrl, "", function (response) { 1657 if (response.responseText == "error") { alertUser("An error occured. Please try again."); } 1658 1659 else if (response.responseText == "neworder") { 1660 alertUser("You have recently placed an order, you can not delete your account until you have a live order. Wait until it is completed by the shop. Thanks"); 1661 return; 1662 } 1663 else { 1664 alertUser("Your account has been deleted however we have to keep some data for legal requirements related to your account for a certain period time. We would like to remind you that we do not share, sell or use your data for any purposes with any 3rd party."); 1665 setTimeout(function () { 1666 window.location.reload(); 1667 }, 3000); 1668 } 1669 }); 1670 } 1671 $("#contactForms").submit(function (e) { 1672 stopForm(e); 1673 var fields = $(this).serializeArray(); 1674 var sendUrl = "/contact"; 1675 ajaxHandler("POST", sendUrl, fields, function (response) { 1676 if (response.responseText == "Sent") { $('#mainWrapper').html("<h1 style='font-size:16px; padding:80px; 35px; height:500px;'>Your message has been sent.We aim to reply you within 24 hours.If it is an urgent issue please call shop. </h1>"); alertIos("Sent", "Your message has been successfully sent. Check your email or here for replies."); $('#contactModalx').modal('hide'); endEvent(); } 1677 else if (response.responseText == "Too Early") { alertUser("You have sent a message recently. You can only send one message in every 5 minutes"); endEvent(); } 1678 else { endEvent(); alertUser("There has been a problem. Please try again later."); } 1679 }); 1680 }); 1681 1682 $("#formPasswordReset").submit(function (e) { 1683 stopForm(e); 1684 var sendData = {}; 1685 var sendUrl = '/resetPassword'; 1686 sendData.password = $("#password3").val(); 1687 sendData.verifypassword = $("#retype").val(); 1688 sendData.username = $("#userEmail").val(); 1689 sendData.token = $("#token").val(); 1690 if (sendData.password != sendData.verifypassword) { 1691 $("#ajaxMessage3").text("Passwords do not match").fadeIn("slow").delay(1500).fadeOut("slow"); 1692 document.getElementById("retype").style.background = "red"; 1693 endEvent(); 1694 return; 1695 } 1696 ajaxHandler("POST", sendUrl, sendData, function (response) { 1697 if (response.responseText == "success") { window.location.href = "/"; } 1698 else if (response.responseText == "Expired") { alertUser("Your Token Has Been Expired, Please demand a new one."); } 1699 else { alertUser("An error occured please try again;"); } 1700 endEvent(); 1701 }); 1702 }); 1703 1704 $("#sendForgottenForm").submit(function (e) { 1705 stopForm(e); 1706 var sendData = {}; sendData.email = $("#forgetEmail").val().toLowerCase(); 1707 var sendUrl = "/forgetPassword"; 1708 ajaxHandler("POST", sendUrl, sendData, function (response) { 1709 if (response.responseText == "successfull") { 1710 $("#forgotPass2").html("Please check your email for further instructions. Also check your spam folder.").show().css('color', 'green'); 1711 $('#resetlinkbutton').val("Email Sent").css('background', 'green'); 1712 alertUser("<h1 style='margin-bottom:-70px;'>Success</h1> <h2 style='color:green; font-size: 20px; padding: 0 25px;'>Password reset email is sent to the registered email address. Please check your email for instructions. Please also check your spam folder as well</h2>"); 1713 } 1714 else { 1715 alertUser("The email you entered does not exist or you need to wait 6 minutes between each email request"); 1716 $('#resetlinkbutton').val("Send Reset Link").css('background', '#DC4C46'); 1717 endEvent(e); 1718 } 1719 }); 1720 }); 1721 1722 function checkEmail(emailValue) { 1723 var sendUrl = "/checkEmail"; 1724 var sendData = {}; sendData.email = emailValue; 1725 ajaxHandler("POST", sendUrl, sendData, function (response) { 1726 if (response.responseText == 'exist') { alertUser("This email is used before,use a different one"); } 1727 }); 1728 } 1729 1730 function isSuspiciousAddress(address, postcode) { 1731 if (!address) return true; 1732 1733 var cleanAddr = address.trim().toUpperCase(); 1734 var cleanPc = (postcode || "") 1735 .trim() 1736 .toUpperCase() 1737 .replace(/\s+/g, ""); 1738 1739 var compactAddr = cleanAddr.replace(/\s+/g, ""); 1740 var hasDigit = /\d/.test(cleanAddr); 1741 var containsPostcode = 1742 cleanPc && compactAddr.indexOf(cleanPc) !== -1; 1743 1744 return !hasDigit || containsPostcode; 1745} 1746 1747 1748 1749 function sendRegisterAjax(data) { 1750 var sendUrl = "/register"; 1751 ajaxHandler("POST", sendUrl, data, function (response) { 1752 if (response.status == 429) { 1753 alertNow("You have created too many accounts from this ip, please try again after an hour", endEvent); 1754 return; 1755 } 1756 1757 if (response.responseText == 'success') { 1758 alertNow("You have successfully registered", function () { 1759 window.location.reload(); 1760 }); 1761 } 1762 else if (response.responseText == "Email used before") { 1763 alertNow("Your email is registered before. Please use forget password link or try different email.", endEvent); 1764 } 1765 else { 1766 alertNow("There has been a problem. Please try again later.", endEvent); 1767 } 1768 }); 1769 } 1770 1771 function validateProfilePostcodeAndAddressThenUpdate(data) { 1772 var rawPostcode = (data.postcode || "").trim(); 1773 1774 if (!rawPostcode) { 1775 alertUser("Please enter your postcode"); 1776 endEvent(); 1777 return; 1778 } 1779 1780 var roughPattern = /^[A-Z]{1,2}\d[A-Z\d]?\s*\d[A-Z]{2}$/i; 1781 if (!roughPattern.test(rawPostcode)) { 1782 alertUser("Your postcode doesn't look right. Please check it."); 1783 endEvent(); 1784 return; 1785 } 1786 1787 var url = "https://api.postcodes.io/postcodes/" + encodeURIComponent(rawPostcode); 1788 1789 $.ajax({ 1790 url: url, 1791 method: "GET", 1792 dataType: "json", 1793 timeout: 7000 1794 }) 1795 1796 // ---------- 200 OK ---------- 1797 .done(function (resp, status, xhr) { 1798 if (resp && resp.status === 200 && resp.result && resp.result.postcode) { 1799 var formattedPc = resp.result.postcode; 1800 data.postcode = formattedPc; 1801 $('#postcode1x').val(formattedPc); 1802 1803 if (data.addressConfirmed) { 1804 $('#addressConfirmed').val("1"); 1805 sendProfileUpdateAjax(data); 1806 return; 1807 } 1808 1809 if (isSuspiciousAddress(data.address, formattedPc)) { 1810 var typedAddr = data.address || ""; 1811 fetchAddressSuggestionsFromServer(formattedPc, typedAddr, function (suggestions) { 1812 showAddressIssueModal( 1813 "YOUR ADDRESS IS INCOMPLETE.\n\n" + 1814 "We cannot deliver your order without a house/flat number or house name and postcode.\n\n" + 1815 "Please select your complete address below or press Edit address.", 1816 1817 suggestions, 1818 1819 function onPick(addr) { 1820 1821 const parts = addr.split(',').map(p => p.trim()); 1822 const shortAddress = parts.slice(0, 2).join(', '); 1823 1824 $('#address1x').val(shortAddress); 1825 $('#profileAddressConfirmed').val('yes'); 1826 1827 data.address = shortAddress; 1828 data.addressConfirmed = true; 1829 1830 sendProfileUpdateAjax(data); 1831 }, 1832
1833 null, // Do not allow an incomplete address to be used 1834 1835 function onEdit() { 1836 $('#address1x').focus(); 1837 endEvent(); 1838 } 1839 ); 1840}); 1841 } else { 1842 sendProfileUpdateAjax(data); 1843 } 1844 return; 1845 } 1846 sendProfileUpdateAjax(data); 1847 }) 1848 1849 // ---------- FAIL (404 / 0 / others) ---------- 1850 .fail(function (xhr, status, error) { 1851 if (xhr.status === 404) { 1852 var typedPc = rawPostcode; 1853 var typedAddr = data.address || ""; 1854 1855 fetchAddressSuggestionsFromServer(typedPc, typedAddr, function (suggestions) { 1856 showAddressIssueModal( 1857 "We couldn't find this postcode.\n\n" + 1858 "Please pick a suggested address below or edit your address.", 1859 suggestions, 1860 function onPick(addr) { 1861 const parts = addr.split(',').map(p => p.trim()); 1862 const shortAddress = parts.slice(0, 2).join(', '); 1863 1864 $('#address1x').val(shortAddress); 1865 $('#profileAddressConfirmed').val('yes'); 1866 1867 data.address = shortAddress; 1868 data.addressConfirmed = true; 1869 1870 sendProfileUpdateAjax(data); 1871}, 1872 function onUseTyped() { 1873 $('#profileAddressConfirmed').val('yes'); 1874 data.addressConfirmed = true; 1875 sendProfileUpdateAjax(data); 1876 }, 1877 function onEdit() { 1878 $('#address1x').focus(); 1879 endEvent(); 1880 } 1881 ); 1882 }); 1883 return; 1884 } 1885 1886 // 0 â network 1887 if (xhr.status === 0) { 1888 if (isSuspiciousAddress(data.address, data.postcode) && !data.addressConfirmed) { 1889 showAddressIssueModal( 1890 "This address looks incomplete (e.g. missing house/flat number).\n\n" + 1891 "Please edit or continue with what you typed.", 1892 [], 1893 function onPick() { 1894 sendProfileUpdateAjax(data); 1895 }, 1896 function onUseTyped() { 1897 $('#profileAddressConfirmed').val('yes'); 1898 data.addressConfirmed = true; 1899 sendProfileUpdateAjax(data); 1900 }, 1901 function onEdit() { 1902 $('#address1x').focus(); 1903 endEvent(); 1904 } 1905 ); 1906 } else { 1907 sendProfileUpdateAjax(data); 1908 } 1909 return; 1910 } 1911 sendProfileUpdateAjax(data); 1912 }); 1913 } 1914 1915//profile update 1916 function sendProfileUpdateAjax(data) { 1917 var sendUrl = "/updateInformation"; 1918 ajaxHandler("POST", sendUrl, data, function (response) { 1919 if (response.responseText == "Email Same") { 1920 alertUser("Your email is registered before. Please use forget password link or try different email."); 1921 endEvent(); 1922 return; 1923 } 1924 else if (response.responseText == "error") { 1925 endEvent(); 1926 alertUser("There has been a problem. Please try again later."); 1927 return; 1928 } 1929 try { 1930 var y = response.responseJSON; 1931 $('#getDistance').val(y.distance); 1932 $('#profileModal').modal('hide'); 1933 alertIos("Success", "You have updated your information"); 1934 updateC(data); 1935 endEvent(); 1936 return; 1937 } catch (e) { 1938 endEvent(); 1939 alertUser("There has been a problem. Please try again later."); 1940 return; 1941 } 1942 }); 1943 } 1944 1945 1946 $('#address1x, #postcode1x').on('input', function () { 1947 $('#profileAddressConfirmed').val('no'); 1948 }); 1949 1950 function getValidTelephone(inputSelector) { 1951 1952 console.log("input selector",inputSelector); 1953 var telephone = ($(inputSelector).val() || '').trim(); 1954 1955 // Remove spaces, brackets, dots and hyphens 1956 telephone = telephone.replace(/[\s().-]/g, ''); 1957 1958 // Convert 00 international prefix into + 1959 if (telephone.indexOf('00') === 0) { 1960 telephone = '+' + telephone.substring(2); 1961 } 1962 1963 // Convert UK +44 into leading 0 1964 if (telephone.indexOf('+44') === 0) { 1965 telephone = '0' + telephone.substring(3); 1966 } 1967
1968 var validUkNumber = /^0\d{10}$/.test(telephone); 1969 var validInternationalNumber = 1970 /^\+[1-9]\d{7,14}$/.test(telephone); 1971 1972 if (!validUkNumber && !validInternationalNumber) { 1973 alertUser( 1974 'Please enter an 11-digit UK number (e.g. 07761111111), or an international number including the country code (e.g. +447761111111).' 1975 ); 1976 1977 $(inputSelector).focus(); 1978 endEvent(); 1979 1980 return false; 1981 } 1982 1983 return telephone; 1984} 1985 1986 $("#myProfileForm").submit(function (e) { 1987 stopForm(e); 1988 var data = {}; 1989 data.name = $('#name1x').val(); 1990 data.email = ($('#email1x').val() || "").toLowerCase(); 1991 data.address = $('#address1x').val(); 1992 data.postcode = $('#postcode1x').val(); 1993 data.telephone = getValidTelephone('#telephone1x'); 1994if (!data.telephone) { 1995 endEvent(); 1996 return; 1997} 1998 data.addressConfirmed = ($('#profileAddressConfirmed').val() === 'yes'); 1999 2000 if (!data.address || data.address.length < 2) { 2001 alertUser("Your address should have more than 2 characters"); 2002 endEvent(); 2003 return; 2004 } 2005 if (!data.postcode || data.postcode.length < 4) { 2006 alertUser("Your postcode should have more than 4 characters"); 2007 endEvent(); 2008 return; 2009 } 2010 var emailMe = $('#emailswitch').prop("checked"); 2011 data.emailOrder = emailMe ? 1 : 0; 2012 validateProfilePostcodeAndAddressThenUpdate(data); 2013 }); 2014 2015 function validatePostcodeAndAddressThenRegister(data) { 2016 2017 console.log("test"); 2018 var rawPostcode = (data.postcode || "").trim(); 2019 if (!rawPostcode) { 2020 alertNow("Please enter your postcode", endEvent); 2021 return; 2022 } 2023 var roughPattern = /^[A-Z]{1,2}\d[A-Z\d]?\s*\d[A-Z]{2}$/i; 2024 if (!roughPattern.test(rawPostcode)) { 2025 alertNow("Your postcode doesn't look right. Please check it.", endEvent); 2026 return; 2027 } 2028 2029 var url = "https://api.postcodes.io/postcodes/" + encodeURIComponent(rawPostcode); 2030 $.ajax({ 2031 url: url, 2032 method: "GET", 2033 dataType: "json", 2034 timeout: 5000 2035 }) 2036 .done(function (resp, status, xhr) { 2037 if (resp && resp.status === 200 && resp.result && resp.result.postcode) { 2038 var formattedPc = resp.result.postcode; 2039 data.postcode = formattedPc; 2040 $('#postcode1').val(formattedPc); 2041 if (data.addressConfirmed) { 2042 sendRegisterAjax(data); 2043 return; 2044 } 2045 if (isSuspiciousAddress(data.address, formattedPc)) { 2046 var typedAddr = data.address || ""; 2047 fetchAddressSuggestionsFromServer(formattedPc, typedAddr, function (suggestions) { 2048 showAddressIssueModal( 2049 "This address looks incomplete (e.g. missing house/flat number).\n\n" + 2050 "Please pick one of the suggestions below or edit your address.", 2051 suggestions, 2052 function onPick(addr) { 2053 2054 const parts = addr.split(',').map(p => p.trim()); 2055 const shortAddress = parts.slice(0, 2).join(', '); 2056 $('#address1').val(shortAddress); 2057 data.address = shortAddress; 2058 sendRegisterAjax(data); 2059 }, 2060 function onUseTyped() { 2061 sendRegisterAjax(data); 2062 }, 2063 function onEdit() { 2064 $('#address1').focus(); 2065 endEvent(); 2066 } 2067 ); 2068 }); 2069 } else { 2070 sendRegisterAjax(data); 2071 } 2072 return; 2073 } 2074 sendRegisterAjax(data); 2075 }) 2076 2077 .fail(function (xhr, status, error) { 2078 if (xhr.status === 404) { 2079 var typedPc = rawPostcode; 2080 var typedAddr = data.address || ""; 2081 2082 fetchAddressSuggestionsFromServer(typedPc, typedAddr, function (suggestions) { 2083 showAddressIssueModal( 2084 "We couldn't find this postcode.\n\n" + 2085 "Please pick a suggested address below or edit your address.", 2086 suggestions, 2087 function onPick(addr) { 2088 2089 const parts = addr.split(',').map(p => p.trim()); 2090 const shortAddress = parts.slice(0, 2).join(', '); 2091 2092 2093 $('#address1').val(shortAddress); 2094 data.address = shortAddress; 2095 sendRegisterAjax(data); 2096 }, 2097 function onUseTyped() { 2098 sendRegisterAjax(data); 2099 }, 2100 function onEdit() { 2101 $('#address1').focus(); 2102 endEvent(); 2103 } 2104 ); 2105 }); 2106 return; 2107 } 2108 2109 if (xhr.status === 0) { 2110 if (isSuspiciousAddress(data.address, data.postcode)) { 2111 showAddressIssueModal( 2112 "This address looks incomplete (e.g. missing house/flat number).\n\n" + 2113 "Please edit or continue with what you typed.", 2114 [], 2115 function onPick() { 2116 sendRegisterAjax(data); 2117 }, 2118 function onUseTyped() { 2119 sendRegisterAjax(data); 2120 }, 2121 function onEdit() { 2122 $('#address1').focus(); 2123 endEvent(); 2124 } 2125 ); 2126 } else { 2127 sendRegisterAjax(data); 2128 } 2129 return; 2130 } 2131 sendRegisterAjax(data); 2132 }); 2133 } 2134function togglePasswordField(el) { 2135 var input = $(el).siblings('input').first(); 2136 2137 if (!input.length) return; 2138 2139 if (input.attr('type') === 'password') { 2140 input.attr('type', 'text'); 2141 } else { 2142 input.attr('type', 'password'); 2143 } 2144}
2145 function fetchAddressSuggestionsFromServer(postcode, typedAddress, cb) { 2146 $.getJSON('/address-suggestions', { 2147 postcode: postcode, 2148 address: typedAddress 2149 }) 2150 .done(function (res) { 2151 if (res && Array.isArray(res.suggestions)) { 2152 cb(res.suggestions); 2153 } else { 2154 cb([]); 2155 } 2156 }) 2157 .fail(function (xhr, status, error) { 2158 cb([]); 2159 }); 2160 } 2161 2162 $("#registerForm").submit(function (e) { 2163 stopForm(e); 2164 2165 var data = {}; 2166 data.name = $('#name1').val(); 2167 data.username = ($('#email1').val() || "").toLowerCase(); 2168 data.password = $('#password1').val(); 2169 data.verifypassword = $('#verifypassword1').val(); 2170 data.address = $('#address1').val(); 2171 data.postcode = $('#postcode1').val(); 2172 2173 data.telephone = getValidTelephone('#telephone1'); 2174if (!data.telephone) { 2175 endEvent(); 2176 return; 2177} 2178 2179$('#telephone1').val(data.telephone); 2180 2181 2182 2183 if (data.password.length < 5) { 2184 alertNow("Your password can not be lower than 5 characters", endEvent); 2185 return; 2186 } 2187 2188 if (data.password != data.verifypassword) { 2189 alertNow("Passwords don't match", endEvent); 2190 return; 2191 } 2192 2193 if (!data.address || data.address.length < 2) { 2194 alertNow("Your address should have more than 2 characters", endEvent); 2195 return; 2196 } 2197 validatePostcodeAndAddressThenRegister(data); 2198 }); 2199 2200 function updateC(data) { 2201 $('#customerName').val(data.name); 2202 $('#emailCustomer').val(data.email); 2203 $('#telCustomer').val(data.telephone); 2204 $('#addressCustomer').val(data.address); 2205 $('#postcodeCustomer').val(data.postcode); 2206 } 2207 2208$("#telephoneModal").submit(function (e) { 2209 stopForm(e); 2210 2211 var data = {}; 2212 2213 data.telephone = ($('#telephone3x').val() || '').trim(); 2214 data.name = $('#contactName3x').val(); 2215 2216 data.telephone = getValidTelephone('#telephone3x'); 2217 2218if (!data.telephone) { 2219 endEvent(); 2220 return; 2221} 2222 2223 var sendUrl = "/updatePhone"; 2224 2225 ajaxHandler("POST", sendUrl, data, function (response) { 2226 if (response.responseText == 'Success') { 2227 $('#telephoneModal').modal('hide'); 2228 alertUser("You have updated your information"); 2229 2230 // Uses the cleaned number 2231 $('#telCustomer').val(data.telephone); 2232 2233 endEvent(); 2234 return; 2235 } 2236 2237 endEvent(); 2238 alertUser("There has been a problem. Please try again later."); 2239 }); 2240}); 2241 2242 $("#addressModal").submit(function (e) { 2243 2244 stopForm(e); 2245 var data = {}; 2246 data.telephone = $('#telephone2x').val(); 2247 data.name = $('#contactName2x').val(); 2248 data.address = $('#address2x').val(); 2249 data.postcode = $('#postcode2x').val(); 2250 if (data.address == "" || (data.address).length < 2) { alertUser("Your address should have more than 2 characters"); endEvent(); return; } 2251 if (data.postcode == "" || (data.postcode).length < 4) { alertUser("Your postcode should have more than 4 characters"); endEvent(); return; } 2252 2253data.telephone = getValidTelephone('#telephone2x'); 2254 2255if (!data.telephone) { 2256 endEvent(); 2257 return; 2258} 2259 2260 var sendUrl = "/updateAddress"; 2261 ajaxHandler("POST", sendUrl, data, function (response) { 2262 2263 if (response.responseText == 'error') { 2264 endEvent(); alertUser("There has been a problem. Please try again later."); return; 2265 } 2266 else { 2267 try { var y = response.responseJSON; } catch (e) { endEvent(); alertUser("There has been a problem. Please try again later."); return; } 2268 $('#addressModal').modal('hide'); alertUser("You have updated your information"); 2269 $('#addressCustomer').val(data.address); 2270 $('#postcodeCustomer').val(data.postcode); 2271 $('#telCustomer').val(data.telephone); 2272 if (y.distance != "not found") { 2273 $('#getDistance').val(y.distance); 2274 } 2275 else { 2276 alert("Your postcode could not be found. Please make sure you enter a correct UK postcode"); 2277 } 2278 endEvent(); return; 2279 } 2280 }); 2281 }); 2282 2283 $("#changePassForm").submit(function (e) { 2284 stopForm(e); 2285 var data = {}; 2286 data.password = $('#password3x').val(); 2287 data.verifypassword = $('#retypex').val(); 2288 if (data.password.length < 5) { alertUser("Your password can not be lower than 5 characters"); endEvent(); return; } 2289 if (data.password != data.verifypassword) { alertUser("Passwords don't match"); endEvent(); return; } 2290 var sendUrl = "/passwordChange"; 2291 ajaxHandler("POST", sendUrl, data, function (response) { 2292 if (response.responseText == 'Successfully Updated') { alertUser("You have successfully updated your password"); endEvent(); $('#passChangeModal').modal('hide'); return; } 2293 else { endEvent(); alertUser("There has been a problem. Please try again later."); } 2294 }); 2295 }); 2296 2297 $("#changefpassword").submit(function (e) { 2298 stopForm(e); 2299 var data = {}; 2300 data.password = $('#password1xx').val(); 2301 data.verifypassword = $('#verifypassword1xx').val(); 2302 data.reset = $('#resetcode').val(); 2303 data.username = $('#forgetEmailxx').val().toLowerCase(); 2304 if (data.password.length < 5) { alertUser("Your password can not be lower than 5 characters"); endEvent(); return; } 2305 if (data.password != data.verifypassword) { alertUser("Passwords don't match"); endEvent(); return; } 2306 var sendUrl = "/resetPasswordCode"; 2307 ajaxHandler("POST", sendUrl, data, function (response) { 2308 if (response.responseText == 'success') { window.location.reload(); } 2309 else if (response.responseText == "Expired") { 2310 endEvent(); alertIos("Expired", "Your reset code expired. Please visit send reset link again"); 2311 return; 2312 } 2313 else { 2314 endEvent(); alertIos("Unsuccessfull", "Please check the reset code or email address and try again."); 2315 return; 2316 } 2317 }); 2318 }); 2319 2320 function triggerIosCheckout() {
2321 try { window.webkit.messageHandlers["scriptHandler"].postMessage("go checkout"); } catch (e) { window.location.href = "/xx12"; } 2322 $('#popupModal').modal('hide'); 2323 } 2324 2325 function alertIos(title, text) { 2326 $('#titlex1').text(title); 2327 $('#textx1').text(text); 2328 $('#iosAlert').modal('show'); 2329 } 2330 2331 function alertIosx(title, text, footer) { 2332 $('#titlex').text(title); 2333 $('#textx').text(text); 2334 $('#coolal-btnWrapperx').html(footer); 2335 $('#iosAlertx').modal('show'); 2336 } 2337 2338 2339 function iosFbLog() { 2340 try { window.webkit.messageHandlers["scriptHandler"].postMessage("fblog"); } catch (e) { } 2341 } 2342 2343 function iosGLog() { 2344 try { window.webkit.messageHandlers["scriptHandler"].postMessage("glog"); } catch (e) { } 2345 } 2346 2347 function iosAsign() { 2348 try { window.webkit.messageHandlers["scriptHandler"].postMessage("asign"); } catch (e) { } 2349 } 2350 2351 2352 function appleSign(sign) { 2353 var sendUrl = '/auth/apple/callback?id_token=' + sign.id_token; 2354 ajaxHandler("GET", sendUrl, "data", function (response) { 2355 if (response.responseText == "access") { 2356 window.location.reload(); 2357 } 2358 else { 2359 alertUser("There has been a problem, please try again or use a different login method"); 2360 } 2361 }); 2362 } 2363 2364 function faSign(sign) { faSignF(sign.access_token); } 2365 function faSignG(sign) { faSignF(sign); } 2366 2367 function faSignF(sign) {
2368 var sendUrl = '/fsign?access_token=' + sign; 2369 ajaxHandler("GET", sendUrl, "", function (response) { 2370 if (response.responseText == "access") { 2371 window.location.reload(); 2372 } 2373 else { 2374 alertUser("There has been a problem, please try again or use a different login method"); 2375 } 2376 }); 2377 } 2378 2379 function ffmessage(messagex) { 2380 var sendUrl = '/ffmessage?id_token=' + messagex; 2381 ajaxHandler("GET", sendUrl, "data", function (response) { 2382 if (response.responseText == "error") { 2383 alertUser("There has been a problem, please try again or use a different login method"); 2384 } 2385 }); 2386 } 2387 2388 function ggSign(sign) { gSignG(sign); } 2389 function gaSign(sign) { gSignG(sign.id_token); } 2390 2391 2392 function gSignG(sign) { 2393 var sendUrl = '/gsign?id_token=' + sign; 2394 ajaxHandler("GET", sendUrl, "data", function (response) { 2395 if (response.responseText == "access") { 2396 try { window.webkit.messageHandlers["scriptHandler"].postMessage("refresh"); } catch (e) { window.location.reload(); } 2397 } 2398 else { 2399 alertUser("There has been a problem, please try again or use a different login method"); 2400 } 2401 }); 2402 } 2403 2404 document.addEventListener('AppleIDSignInOnSuccess', (event) => { 2405 2406 // console.log("APPLE SUCCESS EVENT", event); 2407 2408 // alert( 2409 // "APPLE SUCCESS EVENT\n\n" + 2410 // "Has code: " + 2411 // !!event?.detail?.authorization?.code 2412 // ); 2413 2414 var sendUrl = '/auth/apple/callback?code=' + event.detail.authorization.code; 2415 ajaxHandler("GET", sendUrl, "", function (response) { 2416 if (response.responseText == "access") { 2417 window.location.reload(); 2418 } 2419 else { 2420 alertUser("There has been a problem, please try again or use a different login method"); 2421 endEvent(); 2422 } 2423 }); 2424 }); 2425 2426// document.addEventListener("click", function (event) { 2427// if (event.target.closest("#appleid-signin")) { 2428// alert( 2429// "APPLE BUTTON COUNT:" +document.querySelectorAll("#appleid-signin").length 2430// ); 2431// } 2432// }); 2433 2434 function startAppleLogin() { 2435 2436 var btn = document.querySelector("#appleid-signin"); 2437 2438 if (btn) { 2439 btn.click(); 2440 } 2441} 2442 2443// document.addEventListener("AppleIDSignInOnSuccess", function (event) { 2444// alert( 2445// "APPLE SUCCESS EVENT\n\n" + 2446// JSON.stringify(event.detail, null, 2) 2447// ); 2448 2449// if ( 2450// !event.detail || 2451// !event.detail.authorization || 2452// !event.detail.authorization.code 2453// ) { 2454// alert("Apple success event fired, but no code was returned."); 2455// return; 2456// } 2457 2458// var sendUrl = 2459// "/auth/apple/callback?code=" + 2460// encodeURIComponent(event.detail.authorization.code); 2461 2462// ajaxHandler("GET", sendUrl, "", function (response) { 2463// alert( 2464// "APPLE AJAX FINISHED\n\n" + 2465// "Status: " + response.status + "\n" + 2466// "ReadyState: " + response.readyState + "\n" + 2467// "Response: " + response.responseText 2468// ); 2469 2470// if (response.responseText === "access") { 2471// window.location.reload(); 2472// } else { 2473// alertUser( 2474// "There has been a problem, please try again or use a different login method" 2475// ); 2476// endEvent(); 2477// } 2478// }); 2479// }); 2480 2481// document.addEventListener("AppleIDSignInOnFailure", function (event) { 2482// alert( 2483// "APPLE FAILURE EVENT\n\n" + 2484// JSON.stringify(event.detail, null, 2) 2485// ); 2486// }); 2487 2488// (function watchAppleSignIn() { 2489// var timer = setInterval(function () { 2490// if ( 2491// window.AppleID && 2492// AppleID.auth && 2493// typeof AppleID.auth.signIn === "function" && 2494// !AppleID.auth.signIn.__watched 2495// ) { 2496// clearInterval(timer); 2497 2498// var originalAppleSignIn = AppleID.auth.signIn.bind(AppleID.auth); 2499
2500// function watchedAppleSignIn() { 2501// alert( 2502// "APPLE SIGN-IN CALLED\n\n" + 2503// "Time: " + new Date().toISOString() + "\n\n" + 2504// "Stack:\n" + new Error().stack 2505// ); 2506 2507// return originalAppleSignIn.apply(null, arguments); 2508// } 2509 2510// watchedAppleSignIn.__watched = true; 2511// AppleID.auth.signIn = watchedAppleSignIn; 2512// } 2513// }, 100); 2514// })(); 2515 2516// document.addEventListener("click", function (event) { 2517// var appleButton = event.target.closest( 2518// "#appleid-signin, .appleid-signin, [data-appleid-signin]" 2519// ); 2520 2521// if (!appleButton) { 2522// return; 2523// } 2524 2525// alert( 2526// "APPLE BUTTON CLICK\n\n" + 2527// "Time: " + new Date().toISOString() + "\n" + 2528// "Target: " + event.target.tagName + "\n" + 2529// "Button ID: " + appleButton.id + "\n" + 2530// "Button class: " + appleButton.className 2531// ); 2532// }, true); 2533 2534// setTimeout(function () { 2535// var buttons = document.querySelectorAll( 2536// "#appleid-signin, .appleid-signin, [data-appleid-signin]" 2537// ); 2538 2539// alert( 2540// "APPLE BUTTON COUNT: " + buttons.length + "\n\n" + 2541// Array.from(buttons).map(function (button, index) { 2542// return ( 2543// (index + 1) + ": " + 2544// button.outerHTML.substring(0, 300) 2545// ); 2546// }).join("\n\n") 2547// ); 2548// }, 1500); 2549 2550 document.addEventListener('AppleIDSignInOnFailure', (event) => { 2551 alertUser("An error occured while signing in with AppleId") 2552 }); 2553 2554 function myProfile() { 2555 var sendUrl = "/profilx"; var sendData = {}; 2556 ajaxHandler("GET", sendUrl, "", function (response) { 2557 if (response.responseText == "error") { alertUser("An error occured while loading your information from server. Please try again."); } 2558 else { 2559 try { var y = response.responseJSON; } catch (e) { alertUser("An error occured while loading your information from server. Please try again."); return; } 2560 $('#email1x').val(y.email); 2561 $('#name1x').val(y.name); 2562 $('#telephone1x').val(y.telephone); 2563 $('#address1x').val(y.address); 2564 $('#postcode1x').val(y.postcode); 2565 if (y.emailOrder == 1) { 2566 $('#emailswitch').prop('checked', true); 2567 } 2568 $('#profileModal').modal('show'); 2569 } 2570 }); 2571 } 2572 2573 $("#addressModal").submit(function (e) { 2574 2575 stopForm(e); 2576 var data = {}; 2577 data.name = $('#contactName2x').val(); 2578 data.telephone = $('#telephone2x').val(); 2579 data.address = $('#address2x').val(); 2580 data.postcode = $('#postcode2x').val(); 2581 if (data.address == "" || (data.address).length < 2) { alertUser("Your address should have more than 2 characters"); endEvent(); return; } 2582 if (data.postcode == "" || (data.postcode).length < 4) { alertUser("Please enter a valid postcode"); endEvent(); return; } 2583 2584 2585 data.telephone = getValidTelephone('#telephone2x'); 2586 2587if (!data.telephone) { 2588 endEvent(); 2589 return; 2590} 2591 2592 2593 var sendUrl = "/updateAddress"; 2594 ajaxHandler("POST", sendUrl, data, function (response) { 2595 if (response.responseText == 'Success') { 2596 $('#addressModal').modal('hide'); alertUser("You have updated your information"); 2597 $('#addressCustomer').val(data.address); 2598 $('#postcodeCustomer').val(data.postcode); 2599 $('#telCustomer').val(data.telephone); 2600 $('#customerName').val(data.name); 2601 endEvent(); return; 2602 } 2603 else { endEvent(); alertUser("There has been a problem. Please try again later."); } 2604 }); 2605 }); 2606 2607 function lostPassword() { 2608 $('#loginModal').modal('hide'); 2609 $('#fgModal').modal('show'); 2610 } 2611 2612 function loginFormOpen() { 2613 $("#lostPassword").hide(); 2614 $("#lostPasswordOpen").show(); 2615 $("#loginFormOpen").hide(); 2616 $("#loginForm").show(); 2617 $('#loginHeader').text("Login"); 2618 $("#forgotPass2").hide(); 2619 } 2620
2621 function showMessage(cmessage, subject, situation, reply) { 2622 var shopTel = $('#shopTel').text(); 2623 $('#situation').text(situation); 2624 $('#yourMessage').html("<h1 class='yourMessage'>Your Message</h1>" + "<h1 class='yourMessagex'>" + cmessage + "</h1>"); 2625 if (reply) { 2626 $('#shopReply').html("<h1 class='shopReply'>Shop's Reply</h1>" + "<h1 class='shopReplyx'>" + reply + "</h1>"); 2627 $('#generic').html("<h1 class='shopGeneric'>If this reply did not satisfy you please give us a call. <span style='color:red; width: 100%;'>" + shopTel + "</span></h1>"); 2628 } 2629 else { 2630 $('#shopReply').html("<h1 class='shopGeneric'>Your message hos not been replied by shop. Please allow us some time or give us a call</h1>"); 2631 } 2632 $('#messageModal').modal('show'); 2633 } 2634 2635 $(".cookieConsentOK").on("click", function () { 2636 $("#cookieConsent").css("display", "none"); 2637 sessionStorage.setItem("999", "Cookies Ok"); 2638 var sendUrl = "/cookie"; 2639 ajaxHandler("GET", sendUrl, "noData", function (response) { 2640 if (response.responseText == 'success') { } 2641 else { endEvent(); } 2642 }); 2643 }); 2644 2645 function repeatOrder(orderId, rtype) { 2646 var sendUrl = '/repeatOrder' + '?id=' + orderId + '&rtype=' + rtype; 2647 ajaxHandler("GET", sendUrl, "noData", function (response) { 2648 if (response.responseText == 'error') { alertUser("Order Could Not be Found"); } 2649 else { 2650 var y = response.responseJSON; var currentLength = "", itemInfo = ""; 2651 for (var i = 0; i < y.length; ++i) { 2652 currentLength = localStorage.length + 1; while (localStorage.getItem(currentLength) != null) { ++currentLength; } 2653 y[i].basePrice = parseFloat(y[i].basePrice); 2654 y[i].fullPrice = parseFloat(y[i].fullPrice); 2655 if (y[i].availability == 0) { 2656 console.log("yi ney",y[i]); 2657 if(y[i].basePrice!=0){ 2658 alertUser(y[i].name + " is not available at the moment. The remainder of your order is added to your basket"); 2659 } 2660 2661 } 2662 else { 2663 localStorage.setItem(currentLength, JSON.stringify(y[i])); 2664 2665 } 2666 } 2667 loadPopUp(); 2668 $('#popupModal').modal('show'); 2669 } 2670 }); 2671 } 2672 2673 function stopForm(event) { 2674 event.preventDefault(); 2675 event.stopPropagation(); 2676 event.stopImmediatePropagation(); 2677 $('.submitButtons').prop('disabled', true); 2678 } 2679 2680 2681 $("#formAddress").submit(function (e) { 2682 stopForm(e); 2683 var sendData = {}; 2684 var sendUrl = '/addressChange'; 2685 sendData.address = $('#addressChange1').val(); 2686 sendData.postcode = $('#postChange1').val(); 2687 ajaxHandler("POST", sendUrl, sendData, function (response) { 2688 if (response.responseText == "Successfully Updated") { 2689 $("#ajaxMessage3").text("Your Address Successfully Updated"); 2690 alertUser("Your Address Successfully Updated"); 2691 } 2692 else { $("#ajaxMessage3").text("An error occured please try later"); } 2693 endEvent(); 2694 }); 2695 }); 2696 2697 $("#formPassword").submit(function (e) { 2698 stopForm(e); 2699 var sendData = {}; 2700 var sendUrl = '/passwordChange'; 2701 sendData.password = $("#password3").val(); 2702 sendData.verifypassword = $("#retype").val(); 2703 if (sendData.password != sendData.verifypassword) { 2704 $("#ajaxMessage2").text("Passwords do not match").fadeIn("slow").delay(1500).fadeOut("slow"); 2705 endEvent(); 2706 return; 2707 } 2708 ajaxHandler("POST", sendUrl, sendData, function (response) { 2709 if (response.responseText == "Successfully Updated") { alertUser("Your password is updated"); } 2710 else { alertUser("An error occured"); } 2711 endEvent(); 2712 }); 2713 }); 2714 2715 $("#formDetails").submit(function (e) { 2716 stopForm(e); 2717 var sendData = {}; 2718 var sendUrl = '/profileUpdate'; 2719 var sendData = {}; 2720 sendData.name = $("#nameC").val(); 2721 sendData.email = $("#emailC").val(); 2722 sendData.telephone = $("#telephoneC").val(); 2723 var emailMe = document.getElementById("emailPreferences").checked; 2724 if (emailMe == false) { sendData.emailPreferences = 0; } else { sendData.emailPreferences = 1; } 2725 ajaxHandler("POST", sendUrl, sendData, function (response) { 2726 if (response.responseText == "Successfully Updated") { 2727 $("#ajaxMessage1").html('Your Details Successfully Updated'); 2728 alertUser("Your details successfully updated"); 2729 } 2730 else { $("#ajaxMessage1").html('This Email is Used By Another User.'); } 2731 endEvent(); 2732 }); 2733 }); 2734 2735 function termsconditions() { 2736 $('#termsModalBody').load('/terms?q=pop'); 2737 $('#termsModal').modal('show'); 2738 $('#termheader').text('Terms and privacy policy for our applications and website'); 2739 } 2740 2741 function allergy() { 2742 $('#termsModalBody').load('/allergy?q=pop'); 2743 $('#termsModal').modal('show'); 2744 $('#termheader').text('Allergen Information'); 2745 } 2746 2747 2748 function triggerAlert(message) { alertUser(message + ' can not be empty.'); } 2749 function endEvent() { $('.submitButtons').removeAttr('disabled'); } 2750 2751 function stripeTokenHandler(token) { var sendData = {}; var form = document.getElementById('payment-form'); var hiddenInput = document.createElement('input'); hiddenInput.setAttribute('type', 'hidden'); hiddenInput.setAttribute('name', 'stripeToken'); hiddenInput.setAttribute('value', token.id); form.appendChild(hiddenInput); form.submit(); $("payment-form").trigger("reset"); } 2752 2753 function clearCarts() { 2754 localStorage.clear(); 2755 loadPopUp(); 2756 $('.cart-item').remove(); 2757 fullPriceTotal = 0;
2758 try { window.location.reload(); } catch (e) { } 2759 } 2760 2761 function modalHide() { 2762 setTimeout(function () { 2763 $('#alertUser').modal('hide'); 2764 $('.modal-backdrop').remove(); 2765 }, 60); 2766 } 2767 2768 $('#alertUser').on('hidden.bs.modal', function () { 2769 //remove the backdrop 2770 $('.modal-backdrop').remove(); 2771 }) 2772 2773 function alertUser(message) { 2774 if (message.length < 1) { return; } 2775 var body = ''; 2776 body += '<div class="modal fade " id="alertUser" tabindex="-1" role="dialog" aria-labelledby="alertUser" style="z-index: 99999;" ><div class="modal-dialog modal-sm" role="dialog" style="text-align: center; top: 17%;"><div class="modal-content" style="margin-top: 2%; background: #f4f2ed; border:none;"> <button type="button" class="close_new2x" data-backdrop="" data-dismiss="modal" aria-label="Close" onclick="modalHide();"> Ã </button><div class="modal-body modal-alertxx" >' + message + '</div> </div></div></div>'; 2777 document.getElementById("modalArea3").innerHTML = body; 2778 $('#alertUser').modal('show'); 2779 } 2780 $(document).on('hidden.bs.modal', '.modal', function () { 2781 $('.modal:visible').length && $(document.body).addClass('modal-open'); 2782 }); 2783 document.addEventListener('touchmove', function (event) { 2784 if (event.scale !== 1) { event.preventDefault(); } 2785 }, false); 2786 2787 function enableCart() { 2788 $('#popupModal').modal('show'); 2789 } 2790 2791 function notavailable() { 2792 alertUser("Sorry this item is out of stock for today."); 2793 } 2794 2795 2796 2797 $(window).ready(function () { loadPopUp(); }); 2798 2799 2800function getCartKeys() { 2801 return Object.keys(localStorage) 2802 .filter(k => /^\d+$/.test(k)) // ONLY numeric keys are cart items 2803 .sort((a, b) => Number(a) - Number(b)); 2804} 2805 2806function normalizeItem(raw) { 2807 2808 //const item = raw && typeof raw === 'object' ? raw : {}; 2809 const item = (raw && typeof raw === 'object' && !Array.isArray(raw)) ? raw : {}; 2810 if (!item.rName) item.rName = item.name || ''; 2811 item.customization = item.customization || {}; 2812 item.customization.additions = item.customization.additions || ''; 2813 item.customization.features = item.customization.features || ''; 2814 item.customization.extraxyz = item.customization.extraxyz || ''; 2815 2816 item.amount = Number(item.amount || 1); 2817 item.basePrice = Number(item.basePrice || 0); 2818 item.fullPrice = Number(item.fullPrice || item.basePrice || 0); 2819 2820 // Keep your existing BOGO model fields stable 2821 2822 if (item.rPrice == null) { 2823 item.rPrice = Number(item.basePrice || item.fullPrice || 0); 2824} 2825 2826 //if (item.rPrice == null) item.rPrice = item.basePrice; 2827 if (item.ePrice == null) { 2828 // extra cost = full - base (never negative) 2829 const ep = Number(item.fullPrice) - Number(item.basePrice); 2830 item.ePrice = ep > 0 ? ep : 0; 2831 } 2832 2833 // Normalize typex 2834 if (item.typex == null) item.typex = 'no'; 2835 2836 return item; 2837} 2838 2839// Apply BOGO pricing to items in storage (only if needed) 2840// function applyBogoPricingIfNeeded() { 2841// const keys = getCartKeys(); 2842// if (!keys.length) return; 2843 2844// const items = []; 2845// const rest = []; 2846// const groupedUnits = {}; 2847// let hasBogo = false; 2848 2849// for (const key of keys) { 2850// const raw = localStorage.getItem(key); 2851// if (!raw) { localStorage.removeItem(key); continue; } 2852 2853// let temp; 2854// try { temp = JSON.parse(raw); } 2855// catch (e) { localStorage.removeItem(key); continue; } 2856 2857// temp = normalizeItem(temp); 2858// temp._key = key; 2859 2860// if (isBogoEligibleClient(temp)) { 2861// hasBogo = true; 2862// items.push(temp); 2863 2864// const groupKey = getPromoGroupKeyClient(temp); 2865// if (!groupedUnits[groupKey]) groupedUnits[groupKey] = []; 2866 2867// const amount = parseInt(temp.amount, 10) || 1; 2868// for (let q = 0; q < amount; q++) { 2869// groupedUnits[groupKey].push({ 2870// key: key, 2871// basePrice: Number(temp.rPrice || temp.basePrice || 0) 2872// }); 2873// } 2874// } else { 2875// rest.push(temp); 2876// } 2877// } 2878 2879// if (!hasBogo) return; 2880 2881// const discountedCounts = {}; 2882 2883// for (const groupKey in groupedUnits) { 2884// const units = groupedUnits[groupKey]; 2885// units.sort((a, b) => a.basePrice - b.basePrice); 2886 2887// let divider = parseInt(groupKey.split("|")[0], 10); 2888// if (!isFinite(divider) || divider <= 0) divider = 2; 2889 2890// const discountCount = Math.floor(units.length / divider); 2891 2892// for (let i = 0; i < discountCount; i++) { 2893// discountedCounts[units[i].key] = (discountedCounts[units[i].key] || 0) + 1; 2894// } 2895// } 2896 2897// for (let i = 0; i < items.length; i++) { 2898// const it = items[i]; 2899 2900// const amount = parseInt(it.amount, 10) || 1; 2901// let discountedCount = discountedCounts[it._key] || 0; 2902// if (discountedCount > amount) discountedCount = amount; 2903 2904// const normalCount = amount - discountedCount; 2905 2906// const rawTypex = String(it.typex || '').trim().toLowerCase(); 2907// const pct = Math.max(0, Math.min(100, parseFloat(rawTypex) || 0)); 2908 2909// const normalBase = Number(it.rPrice || it.basePrice || 0); 2910// const extra = Number(it.ePrice || 0); 2911// const discountedBase = getDiscountedBaseClient(it); 2912 2913// it.basePrice = Number(((normalCount * normalBase) + (discountedCount * discountedBase)).toFixed(2)); 2914// it.fullPrice = Number((it.basePrice + (extra * amount)).toFixed(2)); 2915 2916// const originalName = it.rName || it.name || ''; 2917// it.displayName = originalName;
2918// it.name = originalName; 2919 2920// if (discountedCount > 0) { 2921// if (rawTypex === "0") { 2922// it.displayName = originalName + " (FREE)"; 2923// it.name = originalName + " (FREE)"; 2924// } else if (rawTypex.indexOf("fixed_") === 0) { 2925// const fixedPrice = getFixedPriceFromTypexClient(it.typex, it.portion); 2926// if (fixedPrice !== null) { 2927// it.displayName = originalName + " (£" + fixedPrice.toFixed(2) + ")"; 2928// it.name = originalName + " (£" + fixedPrice.toFixed(2) + ")"; 2929// } 2930// } else if (pct < 100) { 2931// it.displayName = originalName + " (" + pct + "% OFF)"; 2932// it.name = originalName + " (" + pct + "% OFF)"; 2933// } 2934// } 2935// } 2936 2937// const all = items.concat(rest).sort((a, b) => Number(a.fullPrice) - Number(b.fullPrice)); 2938 2939// for (const k of keys) localStorage.removeItem(k); 2940 2941// for (let i = 0; i < all.length; i++) { 2942// delete all[i]._key; 2943// localStorage.setItem(String(i + 1), JSON.stringify(all[i])); 2944// } 2945// } 2946 2947function applyBogoPricingIfNeeded() { 2948 const keys = getCartKeys(); 2949 if (!keys.length) return; 2950 2951 const items = []; 2952 const rest = []; 2953 const groupedUnits = {}; 2954 let hasBogo = false; 2955 2956 for (const key of keys) { 2957 const raw = localStorage.getItem(key); 2958 if (!raw) { localStorage.removeItem(key); continue; } 2959 2960 let temp; 2961 try { temp = JSON.parse(raw); } 2962 catch (e) { localStorage.removeItem(key); continue; } 2963 2964 temp = normalizeItem(temp); 2965 temp._key = key; 2966 2967 if (isBogoEligibleClient(temp)) { 2968 hasBogo = true; 2969 items.push(temp); 2970 2971 const groupKey = getPromoGroupKeyClient(temp); 2972 if (!groupedUnits[groupKey]) groupedUnits[groupKey] = []; 2973 2974 const amount = parseInt(temp.amount, 10) || 1; 2975 for (let q = 0; q < amount; q++) { 2976 groupedUnits[groupKey].push({ 2977 key: key, 2978 basePrice: Number(temp.rPrice || temp.basePrice || 0) 2979 }); 2980 } 2981 } else { 2982 rest.push(temp); 2983 } 2984 } 2985 2986 if (!hasBogo) return; 2987 2988const discountedCounts = {}; 2989 2990for (const groupKey in groupedUnits) { 2991 const units = groupedUnits[groupKey]; 2992 2993 2994 units.sort((a, b) => b.basePrice - a.basePrice); 2995 2996 let divider = parseInt(groupKey.split("|")[0], 10); 2997 if (!isFinite(divider) || divider <= 0) divider = 2; 2998 2999 for (let i = divider - 1; i < units.length; i += divider) { 3000 discountedCounts[units[i].key] = 3001 (discountedCounts[units[i].key] || 0) + 1; 3002 } 3003} 3004 3005 for (let i = 0; i < items.length; i++) { 3006 const it = items[i]; 3007 3008 const amount = parseInt(it.amount, 10) || 1; 3009 let discountedCount = discountedCounts[it._key] || 0; 3010 if (discountedCount > amount) discountedCount = amount; 3011 3012 const normalCount = amount - discountedCount; 3013 3014 const rawTypex = String(it.typex || '').trim().toLowerCase(); 3015 const pct = Math.max(0, Math.min(100, parseFloat(rawTypex) || 0)); 3016 3017 const normalBase = Number(it.rPrice || it.basePrice || 0); 3018 const extra = Number(it.ePrice || 0); 3019 const discountedBase = getDiscountedBaseClient(it); 3020 3021 it.basePrice = Number(((normalCount * normalBase) + (discountedCount * discountedBase)).toFixed(2)); 3022 it.fullPrice = Number((it.basePrice + (extra * amount)).toFixed(2)); 3023 3024 const originalName = it.rName || it.name || ''; 3025 it.displayName = originalName; 3026 it.name = originalName; 3027 3028 if (discountedCount > 0) { 3029 if (rawTypex === "0") { 3030 it.displayName = originalName + " (FREE)"; 3031 it.name = originalName + " (FREE)"; 3032 } else if (rawTypex.indexOf("fixed_") === 0) { 3033 const fixedPrice = getFixedPriceFromTypexClient(it.typex, it.portion); 3034 if (fixedPrice !== null) { 3035 it.displayName = originalName + " (£" + fixedPrice.toFixed(2) + ")"; 3036 it.name = originalName + " (£" + fixedPrice.toFixed(2) + ")"; 3037 } 3038 } else if (pct < 100) { 3039 it.displayName = originalName + " (" + pct + "% OFF)"; 3040 it.name = originalName + " (" + pct + "% OFF)"; 3041 } 3042 } 3043 } 3044 3045 const all = items.concat(rest).sort((a, b) => Number(a.fullPrice) - Number(b.fullPrice)); 3046 3047 for (const k of keys) localStorage.removeItem(k); 3048 3049 for (let i = 0; i < all.length; i++) { 3050 delete all[i]._key; 3051 localStorage.setItem(String(i + 1), JSON.stringify(all[i])); 3052 } 3053} 3054 3055 3056 3057function popupNumber() { 3058 const count = getCartKeys().length; // numeric cart keys only 3059 const total = (Number(fullPriceTotal) || 0).toFixed(2); 3060 3061 $('.basketxyz').html(` ${count} Items - £${total}`); 3062 try { window.webkit.messageHandlers["scriptHandler"].postMessage((getCartKeys().length).toString()); } catch (e) { } 3063} 3064 3065 3066// Single entry point: rebuild prices (BOGO if needed) then render from scratch 3067function loadPopUp() { 3068 // clear UI + totals so no duplicates ever 3069 3070 fullPriceTotal = 0; 3071 3072 // clear ALL possible render targets (pick the ones you actually use) 3073 try { $('.popupxyz').html(''); } catch (e) {} 3074 3075 3076 3077 3078 // adjust prices if BOGO items exist 3079 applyBogoPricingIfNeeded(); 3080 3081 // render all cart items 3082 const keys = getCartKeys(); 3083 for (const key of keys) { 3084 popupCart(key); 3085 } 3086 3087 if (keys.length <= 0) { 3088 $('.basketxyz').html(' 0 Items'); 3089 } else { 3090 popupNumber(); 3091 } 3092} 3093 3094// Remove: simplest + correct for BOGO (full redraw) 3095function removePopUp(removeId, priceId) { 3096 localStorage.removeItem(String(removeId)); 3097 loadPopUp(); 3098 try { lcheckout(); } catch (e) { } 3099} 3100 3101// Core render for one item (defensive) â based on your normal version :contentReference[oaicite:2]{index=2} 3102var fullPriceTotal = 0; 3103 3104function popupCart(sessionKey) { 3105 const raw = localStorage.getItem(sessionKey); 3106 if (!raw) return; 3107 3108 let itemInfo; 3109 try { 3110 itemInfo = JSON.parse(raw); 3111 } catch (e) { 3112 localStorage.removeItem(sessionKey); 3113 return; 3114 } 3115 3116 itemInfo = normalizeItem(itemInfo); 3117 const itemFeatures = itemInfo.customization; 3118 const additions = itemFeatures.additions || ''; 3119 const features = itemFeatures.features || ''; 3120 3121 const portion = itemInfo.portion || ''; 3122 const amount = Number(itemInfo.amount) || 0; 3123 const fullPrice = Number(itemInfo.fullPrice) || 0; 3124 const image = itemInfo.image || ''; 3125 //const name = itemInfo.name || ''; 3126 const name = itemInfo.displayName || itemInfo.name || ''; 3127 3128 3129 let popupBody = ''; 3130 3131 popupBody += '<div class="cart-item col-xs-8 popupId' + sessionKey + '">'; 3132 popupBody += ' <div class="cart-item-left">
3132<img src="' + image + '" class="cartItemImages"></div>'; 3133 popupBody += ' <div class="cart-item-right">'; 3134 popupBody += ' <h6 class="cartItemNames">' + amount + ' x ' + portion + ' - ' + name; 3135 3136 popupBody += ' <button type="button" class="close_new2" ' + 3137 ' onclick="removePopUp(' + sessionKey + ',' + fullPrice + ')" ' + 3138 ' data-json="' + sessionKey + '" data-pricefull="' + fullPrice + '">' + 3139 ' <svg viewBox="0 0 24 24" class="close_new3 cart-remove-icon"><path d="M3 6h18"></path><path d="M8 6V4h8v2"></path><path d="M6 6l1 15h10l1-15"></path><path d="M10 10v7"></path><path d="M14 10v7"></path></svg> </button>'; 3140 popupBody += ' </h6>'; 3141 3142 popupBody += additions + features; 3143 3144 popupBody += ' <h6 class="ptotal">Product Total' + 3145 ' <span style="float:right; right:0; position:absolute; color:black;">' + 3146 ' £' + fullPrice.toFixed(2) + 3147 ' </span>' + 3148 ' </h6>'; 3149 popupBody += ' </div>'; 3150 popupBody += '</div>'; 3151 3152 // If you also use .popupxyz container in some templates 3153 var el1 = document.getElementById("cartPopUpx"); 3154if (el1) el1.innerHTML += popupBody; 3155else { try { $('.popupxyz').append(popupBody); } catch (e) {} } 3156 3157 3158 fullPriceTotal += fullPrice; 3159 fullPriceTotal = Math.round(fullPriceTotal * 100) / 100; 3160} 3161 3162function cartChanged() { 3163 loadPopUp(); // recalculates BOGO + redraws + updates basketxyz 3164 try { lcheckout(); } catch(e) {} 3165} 3166 3167 3168 3169 3170 3171 3172 // Core modal builder 3173 window.showBoostModal = function (opts) { 3174 opts = opts || {}; 3175 var id = 'boost-generic-modal-overlay'; 3176 3177 // Avoid duplicates 3178 var existing = document.getElementById(id); 3179 if (existing) existing.remove(); 3180 3181 var overlay = document.createElement('div'); 3182 overlay.id = id; 3183 overlay.style.position = 'fixed'; 3184 overlay.style.inset = '0'; 3185 overlay.style.background = 'rgba(0, 0, 0, 0.6)'; 3186 overlay.style.zIndex = '999999'; 3187 overlay.style.display = 'flex'; 3188 overlay.style.alignItems = 'center'; 3189 overlay.style.justifyContent = 'center'; 3190 3191 var box = document.createElement('div'); 3192 box.style.background = '#ffffff'; 3193 box.style.borderRadius = '10px'; 3194 box.style.padding = '18px 16px'; 3195 box.style.maxWidth = '320px'; 3196 box.style.width = '80%'; 3197 box.style.boxShadow = '0 8px 20px rgba(0,0,0,0.3)'; 3198 box.style.textAlign = 'center'; 3199 box.style.fontFamily = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'; 3200 3201 var title = document.createElement('div'); 3202 title.textContent = opts.title || 'Notice'; 3203 title.style.fontWeight = '700'; 3204 title.style.fontSize = '18px'; 3205 title.style.marginBottom = '8px'; 3206 3207 var msg = document.createElement('div'); 3208 msg.textContent = opts.message || ''; 3209 msg.style.fontSize = '14px'; 3210 msg.style.marginBottom = '14px'; 3211 msg.style.whiteSpace = 'pre-line'; 3212 3213 var buttonsWrap = document.createElement('div'); 3214 buttonsWrap.style.display = 'flex'; 3215 buttonsWrap.style.justifyContent = opts.showCancel ? 'space-between' : 'center'; 3216 buttonsWrap.style.gap = '10px'; 3217 3218 function close(result) { 3219 overlay.remove(); 3220 if (typeof opts.onResult === 'function') { 3221 opts.onResult(result); 3222 } 3223 } 3224 3225 // OK button 3226 var okBtn = document.createElement('button'); 3227 okBtn.textContent = opts.okText || 'OK'; 3228 okBtn.style.border = 'none'; 3229 okBtn.style.borderRadius = '999px'; 3230 okBtn.style.padding = '8px 20px'; 3231 okBtn.style.fontSize = '14px'; 3232 okBtn.style.fontWeight = '600'; 3233 okBtn.style.cursor = 'pointer'; 3234 okBtn.style.background = '#e53935'; 3235 okBtn.style.color = '#fff'; 3236 okBtn.style.flex = '1'; 3237 okBtn.onclick = function () { close(true); }; 3238 3239 buttonsWrap.appendChild(okBtn); 3240 3241 // Cancel button (for confirm) 3242 if (opts.showCancel) { 3243 var cancelBtn = document.createElement('button'); 3244 cancelBtn.textContent = opts.cancelText || 'Cancel'; 3245 cancelBtn.style.border = '1px solid #ccc'; 3246 cancelBtn.style.borderRadius = '999px'; 3247 cancelBtn.style.padding = '8px 20px'; 3248 cancelBtn.style.fontSize = '14px'; 3249 cancelBtn.style.fontWeight = '500'; 3250 cancelBtn.style.cursor = 'pointer'; 3251 cancelBtn.style.background = '#f5f5f5'; 3252 cancelBtn.style.color = '#333'; 3253 cancelBtn.style.flex = '1'; 3254 cancelBtn.onclick = function () { close(false); }; 3255 buttonsWrap.appendChild(cancelBtn); 3256 } 3257 3258 box.appendChild(title); 3259 box.appendChild(msg); 3260 box.appendChild(buttonsWrap); 3261 overlay.appendChild(box); 3262 document.body.appendChild(overlay); 3263 }; 3264 3265 // Simple alert: one button 3266 window.alertNow = function (message, cb) { 3267 window.showBoostModal({ 3268 title: 'Notice', 3269 message: message, 3270 showCancel: false, 3271 okText: 'OK', 3272 onResult: function () { 3273 if (typeof cb === 'function') cb(); 3274 } 3275 }); 3276 }; 3277 3278 // Confirm-style: two buttons, callback(true/false) 3279 window.confirmNow = function (message, cb) { 3280 window.showBoostModal({ 3281 title: 'Please confirm', 3282 message: message, 3283 showCancel: true, 3284 okText: 'Yes', 3285 cancelText: 'No', 3286 onResult: function (result) { 3287 if (typeof cb === 'function') cb(result); 3288 } 3289 }); 3290 }; 3291 3292 3293 window.showAddressIssueModal = function (message, suggestions, onPick, onUseTyped, onEdit) { 3294 var id = 'boost-address-issue-overlay'; 3295 var existing = document.getElementById(id); 3296 if (existing) existing.remove(); 3297
3298 var overlay = document.createElement('div'); 3299 overlay.id = id; 3300 overlay.style.position = 'fixed'; 3301 overlay.style.inset = '0'; 3302 overlay.style.background = 'rgba(0, 0, 0, 0.6)'; 3303 overlay.style.zIndex = '999999'; 3304 overlay.style.display = 'flex'; 3305 overlay.style.alignItems = 'center'; 3306 overlay.style.justifyContent = 'center'; 3307 overlay.style.color = 'red'; 3308 3309 var box = document.createElement('div'); 3310 box.style.background = '#ffffff'; 3311 box.style.borderRadius = '10px'; 3312 box.style.padding = '18px 20px'; 3313 box.style.maxWidth = '340px'; 3314 box.style.width = '90%'; 3315 box.style.boxShadow = '0 8px 20px rgba(0,0,0,0.3)'; 3316 box.style.fontFamily = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'; 3317 3318 var title = document.createElement('div'); 3319 title.textContent = 'Address check'; 3320 title.style.fontWeight = '700'; 3321 title.style.fontSize = '18px'; 3322 title.style.marginBottom = '8px'; 3323 3324 var msg = document.createElement('div'); 3325 msg.textContent = message || 'We could not confirm this address.'; 3326 msg.style.fontSize = '14px'; 3327 msg.style.marginBottom = '10px'; 3328 msg.style.whiteSpace = 'pre-line'; 3329 3330 box.appendChild(title); 3331 box.appendChild(msg); 3332 3333 3334 if (suggestions && suggestions.length) { 3335 var listWrap = document.createElement('div'); 3336 listWrap.style.maxHeight = '180px'; 3337 listWrap.style.overflowY = 'auto'; 3338 listWrap.style.marginBottom = '10px'; 3339 3340 suggestions.forEach(function (addr) { 3341 var item = document.createElement('button'); 3342 item.textContent = addr; 3343 item.style.display = 'block'; 3344 item.style.width = '100%'; 3345 item.style.textAlign = 'left'; 3346 item.style.marginBottom = '6px'; 3347 item.style.border = '1px solid #ddd'; 3348 item.style.borderRadius = '6px'; 3349 item.style.padding = '6px 8px'; 3350 item.style.fontSize = '13px'; 3351 item.style.cursor = 'pointer'; 3352 item.style.background = '#f7f7f7'; 3353 3354 item.onclick = function () { 3355 overlay.remove(); 3356 if (typeof onPick === 'function') onPick(addr); 3357 }; 3358 3359 listWrap.appendChild(item); 3360 }); 3361 3362 box.appendChild(listWrap); 3363 } 3364var buttonsWrap = document.createElement('div'); 3365buttonsWrap.style.display = 'flex'; 3366buttonsWrap.style.justifyContent = 'space-between'; 3367buttonsWrap.style.gap = '10px'; 3368 3369var hasSuggestions = suggestions && suggestions.length > 0; 3370 3371// Edit button 3372var editBtn = document.createElement('button'); 3373editBtn.textContent = 'Edit address'; 3374editBtn.style.flex = '1'; 3375editBtn.style.border = 'none'; 3376editBtn.style.borderRadius = '999px'; 3377editBtn.style.padding = '8px 10px'; 3378editBtn.style.fontSize = '13px'; 3379editBtn.style.cursor = 'pointer'; 3380editBtn.style.background = '#e53935'; 3381editBtn.style.color = '#fff'; 3382 3383editBtn.onclick = function () { 3384 overlay.remove(); 3385 3386 if (typeof onEdit === 'function') { 3387 onEdit(); 3388 } 3389}; 3390 3391buttonsWrap.appendChild(editBtn); 3392 3393// Only allow the typed address when no suggestions were found 3394if (!hasSuggestions) { 3395 var useTypedBtn = document.createElement('button'); 3396 3397 useTypedBtn.textContent = 'Use address I typed'; 3398 useTypedBtn.style.flex = '1'; 3399 useTypedBtn.style.border = '1px solid #ccc'; 3400 useTypedBtn.style.borderRadius = '999px'; 3401 useTypedBtn.style.padding = '8px 10px'; 3402 useTypedBtn.style.fontSize = '13px'; 3403 useTypedBtn.style.cursor = 'pointer'; 3404 useTypedBtn.style.background = '#f5f5f5'; 3405 3406 useTypedBtn.onclick = function () { 3407 overlay.remove(); 3408 3409 if (typeof onUseTyped === 'function') { 3410 onUseTyped(); 3411 } 3412 }; 3413 3414 buttonsWrap.appendChild(useTypedBtn); 3415} 3416 3417var editNote = document.createElement('div'); 3418 3419editNote.textContent = hasSuggestions 3420 ? 'Only edit your address if you cannot find it in the list above.' 3421 : 'No matching address was found. Check your details or continue with the address you entered.'; 3422 3423editNote.style.fontSize = '13px'; 3424editNote.style.fontWeight = '600'; 3425editNote.style.textAlign = 'center'; 3426editNote.style.color = hasSuggestions ? '#3044c5' : '#e53935'; 3427editNote.style.margin = '8px 0'; 3428 3429box.appendChild(editNote); 3430box.appendChild(buttonsWrap); 3431 overlay.appendChild(box); 3432 document.body.appendChild(overlay); 3433 }; 3434 3435 function getFixedPriceFromTypexClient(typex, portion) { 3436 var rawTypex = String(typex || "").trim().toLowerCase();
3437 var rawPortion = String(portion || "").toLowerCase(); 3438 3439 if (rawTypex.indexOf("fixed_") !== 0) return null; 3440 3441 var config = rawTypex.slice(6); 3442 3443 // fixed_1.99 3444 if (config.indexOf(":") === -1 && config.indexOf("|") === -1) { 3445 var fixedOne = parseFloat(config); 3446 if (isFinite(fixedOne)) return +fixedOne.toFixed(2); 3447 } 3448 3449 // fixed_9:1.99|12:2.99 3450 var portionMatch = rawPortion.match(/\d+(\.\d+)?/); 3451 if (!portionMatch) return null; 3452 3453 var portionNumber = portionMatch[0]; 3454 var pairs = config.split("|"); 3455 3456 for (var i = 0; i < pairs.length; i++) { 3457 var parts = pairs[i].split(":"); 3458 if (parts.length !== 2) continue; 3459 3460 var sizeKey = String(parts[0]).trim().toLowerCase(); 3461 var price = parseFloat(parts[1]); 3462 3463 if (sizeKey === portionNumber && isFinite(price)) { 3464 return +price.toFixed(2); 3465 } 3466 } 3467 3468 return null; 3469} 3470 3471function isBogoEligibleClient(item) { 3472 if (!item) return false; 3473 if (item.name === "Delivery Fee") return false; 3474 if (item.typex == null) return false; 3475 3476 const rawTypex = String(item.typex).trim().toLowerCase(); 3477 if (rawTypex === "" || rawTypex === "no") return false; 3478 if (rawTypex.indexOf("fixed_") === 0) return true; 3479 3480 const pct = parseFloat(rawTypex); 3481 return isFinite(pct) && pct >= 0 && pct <= 100; 3482} 3483 3484// function getPromoGroupKeyClient(item) { 3485// let divider = parseInt(item.divider, 10); 3486// if (!isFinite(divider) || divider <= 0) divider = 2; 3487 3488// const portion = String(item.portion || "").trim().toLowerCase(); 3489 3490// return divider + "|" + portion; 3491// } 3492 3493function getPromoGroupKeyClient(item) { 3494 let divider = parseInt(item.divider, 10); 3495 if (!isFinite(divider) || divider <= 0) divider = 2; 3496 3497 const rawTypex = String(item.typex || "").trim().toLowerCase(); 3498 const portion = String(item.portion || "").trim().toLowerCase(); 3499 3500 if (rawTypex.indexOf("fixed_") === 0 && rawTypex.indexOf(":") !== -1) { 3501 return divider + "|" + rawTypex + "|" + portion; 3502 } 3503 3504 3505 return divider + "|" + rawTypex; 3506} 3507 3508 3509 3510function getDiscountedBaseClient(item) { 3511 const rawTypex = String(item.typex || "").trim().toLowerCase(); 3512 3513 if (rawTypex.indexOf("fixed_") === 0) { 3514 const fixedPrice = getFixedPriceFromTypexClient(item.typex, item.portion); 3515 if (fixedPrice !== null) return fixedPrice; 3516 3517 return Number(item.rPrice || item.basePrice || 0); 3518 } 3519 3520 const pct = parseFloat(rawTypex); 3521 if (!isFinite(pct)) return Number(item.rPrice || item.basePrice || 0); 3522 3523 return Number((Number(item.rPrice || item.basePrice || 0) * (pct / 100)).toFixed(2)); 3524} 3525 3526 </script>
vendor: 1 bytes, line 3526
3526
3527<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"e832242647d14aff82e944cbc7b36671","r":1,"spa":2}' crossorigin="anonymous"></script>
vendor: 1 bytes, line 3527
3527
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.