/
home
/
obinna
/
html
/
cravings
/
resources
/
views
/
places
/
Upload File
HOME
@extends('layouts.list') @section('meta') <meta content="Cravvings - {{ $searchTitle }}" property="og:title"> <meta content="{!! $url !!}" property="og:url"> <meta content="Find and review food from your favourite places" property="og:description"> <meta content="{{ $image }}" property="og:image"> <meta content="480" property="og:image:width"> <meta content="360" property="og:image:height"> <meta name="twitter:title" content="Cravvings - {{ $searchTitle }}"> <meta name="twitter:description" content="Find and review food from your favourite places."> <meta name="twitter:image" content="{{ $image }}"> <meta name="twitter:image:width" content="1200"> <meta name="twitter:image:height" content="630"> <meta name="search_token" value="{{ $token }}"> <title>Cravvings - {{ $searchTitle }}</title> @endsection @section('extracss') <style> html, .search-list { scroll-behavior: smooth; } .search-top { width: 100%; z-index: 1000; } .search-options { display: flex; align-items: center; padding-right: 20px; justify-content: flex-end; padding: 5px; } .form-check { display: flex; padding-right: 5px; align-items: center; } .form-check { padding-left: 0; } .enter-location { color: var(--red); } .search-wrapper { display: grid; } .search-list { flex: 0 0 50%; padding: 0; } @media (max-width: 860px) { .search-wrapper { display: block; } } @media (min-width: 700px) { .search-top { padding: 0 2.5% 0; } .suggest { width: 80%; } .option .form-check-label { padding-left: 10px; padding-right: 10px; } } @media (min-width: 561px) { .search-list { max-height: 100vh; overflow-y: scroll; overflow-y: scroll; /* scrollbar-width: none; */ /* -ms-overflow-style: none; */ } } @media (min-width: 520px){ .search-options { justify-content: flex-start; /*width: 100%;*/ margin: 0 auto; border-top: 0; padding-left: 10px; } .enter-location { /* padding-left: 15px; */ } } .search-options label { margin-bottom: 0; padding-left: 5px; } .vex, .vex-overlay { z-index: 1000; } .customVex .vex-content { border-radius: 0; } .fa.fa-times { color: red; padding-left: 10px; } #footer { display: none; } @media (max-width: 520px){ .search-top { width: 100%; z-index: 1000; padding-right: 2.5%; padding-left: 2.5%; padding-top: 10px; } } @media (min-width: 500px){ .actual-result hr { display: none; } } .top-of-page { position: fixed; right: 20px; bottom: 50px; border: none; display: none; z-index: 10000; } .button.top-of-page { background-color: var(--red); color: #fff; border-radius: 30px; } @media (min-width: 850px) { .top-of-page { right: 51%; } } </style> @endsection @section('content') <div class="search-wrapper"> <div class="search-list"> <section class="search-top"> <form action="/search" class="search-input location-form search-input search-page-form search-form" id="nearby"> <div class="address-input"> <input type="text" name="food" data-type="food" class="form-control" autocomplete="off" id="food" placeholder="What do you feel like eating?" /> </div> <button class="button button-primary inline-button" style="padding: 10px 30px;"> <i class="fa fa-search"></i> </button> </form> <div class="search-address optional-address" id="opt-add"> </div> {{-- <div class="search-filters"> <button class="button button-secondary btn-circle">Delivery</button> <button class="button button-secondary btn-circle">Delivery</button> <button class="button button-secondary btn-circle">Delivery</button> </div> --}} </section> <div class="search-actual-results" style="position: relative;"> <div class="results-title"> <div id="search-title"></div> {{-- <div class="search-options"> <input class="check-input" name="delivery" type="checkbox" id="deliveryCheck" value="delivery"> <label class="check-label" for="deliveryCheck"> Delivery </label> </div> --}} </div> <div class="results-list" id="places-list"> @for($i=0; $i<12; $i++) <div class="actual-result"> <div class="search-place-image"> <div class="skeleton-background"></div> </div> <div class="search-place-details"> <div class="search-highlight"> <div class="skeleton-background"></div> <div class="skeleton-background"></div> <div class="skeleton-background"></div> </div> <div class="place-title"> <h3><div class="skeleton-background"></div></h3> </div> <p class="place-address"><div class="skeleton-background"></div></p> <hr> </div> </div> @endfor </div> <button class="button button-secondary top-of-page" onclick="goToTop();"><i class="fa fa-arrow-up"></i></button> </div> <div class="load-more"> <i class="fa fa-spinner fa-spin"></i> </div> <footer id="footer" class="footer-five"> <div class="suggest-wrapper"> <div class="suggest"> <div class="suggest-image"> <img src="/images/hanburg.svg" alt="Suggest a place"> </div> <div class="suggest-content"> <h3>Can't find a restaurant?</h3> <p>Did we miss out your favourite restaurant? Our apologies! Suggest a place and we will make sure you see it the next time you search.</p> <a href="/place/suggest" class="button button-warning suggest-a-place">SUGGEST A PLACE</a> </div> </div> </div> <div class="container"> <div class="footer-inner wow pixFadeUp"> <div class="row"> <div class="col-sm-3 col-md-6"> <img src="/images/icon.png" alt="" class="logo"> </div> </div> <div class="row"> <div class="col-lg-4 col-md-6"> <div class="widget footer-widget"> <!-- <h3 class="widget-title">Cravvings</h3> --> <ul class="footer-menu"> <li><a href="/business/register">Register/Claim your business</a></li> {{-- <li><a href="#">How does Cravvings work?</a></li> --}} {{-- <li><a href="#">About Us</a></li> --}} <li><a href="/contact">Contact Us</a></li> </ul> </div> </div> <div class="col-lg-3 col-md-6"> <div class="widget footer-widget"> <!-- <h3 class="widget-title">Services</h3> --> <ul class="footer-menu"> <li><a href="/privacy">Privacy Policy</a></li> <li><a href="#">Terms of use</a></li> </ul> </div> </div> <div class="col-lg-3 col-md-6"> <div class="widget footer-widget"> <!-- <h3 class="widget-title">Our Address</h3> --> <ul class="footer-menu"> <li><a href="https://instagram.com/cravvingsapp" rel="noreferrer" target="_blank"><i class="fa fa-instagram"></i> Instagram</a></li> <li><a href="https://twitter.com/cravvingsapp" rel="noreferrer" target="_blank"><i class="fa fa-twitter"></i> Twitter</a></li> <li><a href="https://facebook.com/cravvingsapp" rel="noreferrer" target="_blank"><i class="fa fa-facebook"></i> Facebook</a></li> </ul> </div> </div> </div> </div> <div class="site-info"> <div class="copyright"> <p>© 2020 Cravvings. All Rights Reserved.</p> </div> </div> </div> </footer> </div> <div class="places-map search-map" id="map" style="max-height: 100vh;"> </div> </div> @endsection @section('javascript') @parent <script src="/js/searchInput.js"></script> <script src="/js/cravvings.js"></script> <script> var state = {page: 1, ...deserialize(location.search)}; var loadMore = document.querySelector('.load-more'); var placeListContainer = document.getElementById('places-list'); const placePicture = (place) => ` <a href="/places/${place.slug}?q=${state.food || ''}" data-slug="${place.slug}" class="place-image"> <div class="search-place-image" style="background-image: url(${place.image || '/images/cravvings.png'}); background-color: #F9F9F9; background-position: center; background-size: ${place.image ? 'cover' : 'contain'}; background-repeat: no-repeat"> </div> </a> ` const placeTemplate = (place) => { const searched = state.food; const truncated_address = place.address.slice(0, 50); const shown_address = `${truncated_address}${place.address.length > truncated_address.length ? '...' : ''}` return ` <div class="actual-result"> ${place.image ? placePicture(place) : ''} <div class="search-place-details"> <div style="display: flex; justify-content: space-between;"> <a class="place-title" href="/places/${place.slug}?q=${state.food || ''}" data-slug="${place.slug}">${place.name}</a> <button type="button" data-slug="${place.slug}" class="like-place" style="background-color: transparent; padding: 0; border: 0;"><i class="fa fa-heart${place.liked ? '' : '-o'}"></i></button> </div> <div>${starred(place.avg_rate)}</div> ${place.phones && place.phones.length ? getPhones(place.phones) : ''} <p class="place-address">${shown_address || ''}</p> <div class="search-highlight"> ${place.food && state.food ? place.food.map( food => `<span class="badge badge-warning">${capitalize(food.name)}</span>` ).join(" ") : ''} </div> ${place.delivery && place.delivery.length ? getDelivery(place.delivery) : ''} </div> </div> `; } function loadMap(list) { if (/Mobi|Android/i.test(navigator.userAgent)) { // mobile! }else { list.length && list[0]['coords'] && initMap(list, document.getElementById('map'), [state.longitude, state.latitude, state.address]) } } function Places(places){ console.log('reduce') return places.length ? places.reduce((all, one) => all + placeTemplate(one), '') : ''; } // const placeList = loadPlaces(); const optAdd = document.getElementById('opt-add'); optAdd.innerHTML = state.address ? optionTemplate(state.address) : '<a href="#" class="enter-location">Enter location</a>'; document.getElementById('food').value = state.food ? state.food : ""; // document.getElementById('deliveryCheck').checked = state.delivery || false; const phones = (phone) => `<a href="tel:${phone}">${phone}</a>`; const delivery = (delivery) => { if (delivery && delivery.length) { return `<div class="place-delivery"> <i class="fa fa-motorcycle"></i> <span class="deliveries"> ${delivery.map(area => area).join(", ")} </span> </div>` ; } return ''; } var loading; var next = true; const loadMoreItems = () => { if (!loading && next) { loading = true; state = {...state, page: parseInt(state.page)+1}; loadMore.style.display = 'block'; pullstuff(state, placeList); }else { const results = document.querySelectorAll('.actual-result'); if(!state.longitude && results.length >= 15) { loading = true; enterLocation(); } document.querySelector('#footer').style.display = 'block'; } } const footerHeight = document.getElementById('footer').offsetHeight + document.querySelector('.suggest').offsetHeight; var searchList = document.querySelector('.search-list') searchList.onscroll = () => { const scrolltop = searchList.scrollTop const resultHeight = searchList.offsetHeight const results = document.querySelectorAll('.actual-result'); const loadingFrom = results[results.length-2] if(scrolltop > window.innerHeight) { document.querySelector('.top-of-page').style.display = 'block'; }else { document.querySelector('.top-of-page').style.display = 'none'; } if ((scrolltop+resultHeight >= loadingFrom.offsetTop) && !loading) { loadMoreItems(); } } window.onscroll = () => { if (window.innerWidth <= 520) { if(((window.innerHeight + window.scrollY) >= (document.body.offsetHeight)) && !loading) { loadMoreItems(); document.querySelector('.top-of-page').style.display = 'block'; } } } const placeList = (function (placeTem, wrapper){ let page = 1; return function(places){ console.log({places}) const placesToAdd = places.data.map(place => placeTemplate(place)).join("") loadMap(places.data) next = places.next; if(page == 1){ wrapper.innerHTML = places.data.length ? Places(places.data) : `<h5>We couldn't find ${state.food || 'anything'} around ${state.address}. Why don't you find something else or change location</h5>`; if(next === false && places.others && places.others.length){ wrapper.innerHTML += '<h3 class="others"> - Other places nearby</h3>' wrapper.innerHTML += Places(places.others) } }else { wrapper.innerHTML += placesToAdd } document.querySelectorAll('.actual-result .like-place').forEach(likeButton => { likeButton.addEventListener('click', likePlace) }); page++; let response = ''; if (places.other && places.other.length) { response = `<h5>Couldn't find any places with <em>${places.query}</em> but here are some other places near you</h5>`; }else if (places.query) { response = `<h3>${places.query}</h3>`; }else { response = ''; } document.querySelector('#search-title').innerHTML = response; } })(placeTemplate, placeListContainer); // A utility function that takes search params and a callback function // and passes it the list of places function pullstuff(state, handlePlaceList){ fetchApi({...state}) .then(places => { handlePlaceList(places) }) .catch(error => console.log(error)) .finally(() => { loading = false; loadMore.style.display = 'none'; }) } pullstuff(state, placeList); const getPhones = (phones) => ` <div class="place-phones"> <svg stroke="currentColor" fill="#222222" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M426.666 330.667a250.385 250.385 0 0 1-75.729-11.729c-7.469-2.136-16-1.073-21.332 5.333l-46.939 46.928c-60.802-30.928-109.864-80-140.802-140.803l46.939-46.927c5.332-5.333 7.462-13.864 5.332-21.333-8.537-24.531-12.802-50.136-12.802-76.803C181.333 73.604 171.734 64 160 64H85.333C73.599 64 64 73.604 64 85.333 64 285.864 226.136 448 426.666 448c11.73 0 21.334-9.604 21.334-21.333V352c0-11.729-9.604-21.333-21.334-21.333z"></path></svg> <a href="tel:${phones[0]}">${phones[0]}</a> </div> `; const getDelivery = (delivery) => ` <span class="deliveries"> <i class="fa fa-motorcycle"></i> ${delivery.map(area => area).join(", ")} </span> `; function optionTemplate(add) { const truncated = add.slice(0, 27); const shown = `${truncated}${add > truncated ? '...' : ''}` return ` <div class="option"> <div class="form-check"> <label class="form-check-label" for="option-location"> <i class="fa fa-map-marker"></i> <span class="actual-address">${shown}</span> </label> <a href="#" class="enter-location">Change</a> </div> </div> `; } const starred = (avgRating) => { if(!avgRating) return ''; let rat = ""; const avg = avgRating && avgRating.rate ? avgRating.rate : avgRating; for (var i = 0; i < Math.floor(avg); i++) { rat += `<i class="fa fa-star"></i>`; } return rat; }; function enterLocation(e){ e && e.preventDefault(); searchInput(state.address, state.food).then(loc => { state = {...state, ...loc}; submit(); }).catch(error => console.log(error)) } document.querySelector('.enter-location').addEventListener('click', enterLocation) function submit(){ var foodInput = document.getElementById('food').value; state = {...state, food: foodInput ? foodInput : "", page: 1}; window.location.href = `/search?${serialize(state)}` } document.querySelector('.search-form').addEventListener('submit', function (e) { e.preventDefault(); submit(); }) function goToTop() { searchList.scrollTop = 0; window.scrollTo(0, 0); document.querySelector('.top-of-page').style.display = 'none'; } document.querySelector('.page-title a').addEventListener('click', function(e){ e.preventDefault(); goToTop(); }); // var loading; // var next = true; // const loadMoreItems = () => { // if (!loading && next) { // loading = true; // state = {...state, page: parseInt(state.page)+1}; // loadMore.style.display = 'block'; // pullstuff(state, placeList); // } // } // const footerHeight = document.getElementById('footer').offsetHeight + document.querySelector('.suggest').offsetHeight; // var searchList = document.querySelector('.search-list') // searchList.onscroll = () => { // const scrolltop = searchList.scrollTop // const resultHeight = searchList.offsetHeight // const results = document.querySelectorAll('.actual-result'); // const loadingFrom = results[results.length-2] // if(scrolltop > window.innerHeight) { // document.querySelector('.top-of-page').style.display = 'block'; // }else { // document.querySelector('.top-of-page').style.display = 'none'; // } // if ((scrolltop+resultHeight >= loadingFrom.offsetTop) && !loading) { // loadMoreItems(); // } // } // window.onscroll = () => { // if (window.innerWidth <= 520) { // if(((window.innerHeight + window.scrollY) >= (document.body.offsetHeight)) && !loading) { // loadMoreItems(); // document.querySelector('.top-of-page').style.display = 'block'; // } // } // } // const placeList = (function (placeTem, wrapper){ // let page = 1; // return function(places){ // const placesToAdd = places.data.map(place => placeTemplate(place)).join("") // loadMap(places.data) // next = places.next; // if(page == 1){ // wrapper.innerHTML = places.data.length ? Places(places.data) : `<h5>We couldn't find <span class="not-found">${state.food || 'anything'}</span> around <span class="not-found">${state.address}</span>. Why don't you find something else or change location</h5>`; // if(next === false && places.others && places.others.length){ // wrapper.innerHTML += '<h3 class="others"> - Other places nearby</h3>' // wrapper.innerHTML += Places(places.others) // } // }else { // wrapper.innerHTML += placesToAdd // } // document.querySelectorAll('.actual-result .like-place').forEach(likeButton => { // likeButton.addEventListener('click', likePlace) // }); // page++; // let response = ''; // if (places.other && places.other.length) { // response = `<h5>Couldn't find any places with <em>${places.query}</em> but here are some other places near you</h5>`; // }else if (places.query) { // response = `<h3>${places.query}</h3>`; // }else { // response = ''; // } // document.querySelector('#search-title').innerHTML = response; // } // })(placeTemplate, placeListContainer); // // A utility function that takes search params and a callback function // // and passes it the list of places // function pullstuff(state, handlePlaceList){ // fetchApi({...state}) // .then(places => { // handlePlaceList(places) // }) // .catch(error => console.log(error)) // .finally(() => { // loading = false; // loadMore.style.display = 'none'; // }) // } // pullstuff(state, placeList); </script> @endsection