Cafe Suggestions with Geo Search

I’m keen to make some solid progress on HadCoffee over the Christmas period to hopefully get to an early 2019 v1 launch. This week I was working on the main coffee rating interface which depends on users being able to select or enter the café they visited.

I’ll add the autocomplete lookups for typed cafe names, but I also wanted some basic quick suggestions based on where the user has been before and their current location.

This would save typing for common places and maybe also hint at other nearby cafés the user mightn’t know about.

The frontend part of these feature went pretty smoothly. The Vue component watches for the users location (HTML5 Geolocation) and calls the backend to load these quick suggestions as it’s known. There’s a little debounce action to slow things down as the geolocation API can return updated positions in quick succession as it locks on a more accurate location.

Geographic Search by Proximity

The smooth progress I was making through this feature hit a wall when it came to actually querying cafés by distance though. I was hoping to use MySQL’s ST_Distance_sphere function to let the DB do that work. I’m running MariaDB though, which although it’s advertised as a ‘drop in’ replacement for MySQL does not support this feature 😞

I prefer a simpler dev environment (I’m not using Laravel Valet or Docker images) so I didn’t feel like swapping to MySQL for this project. Changing my workflow to use Valet also wasn’t very appealing when I’m otherwise happy with the setup. so I briefly tried migrating to Postgres. I know it’s a great DB, but I haven’t used it before and that’s a big change to have to make to run one type of query.

In the end I’m going with a raw SQL query to help with this. I’ll add a simple bounding box to its parameters first to avoid having to do a table scan of every cafe in the world (once my DB gets to that point 🙂)

Although it took a windy path this geo search will also provide the basis for the other cafe search features on the site such as the autocomplete (to improve relevance) and the location based search.

$query  = "SELECT id, cafe_id, lat, lng, address, locality, city,
        ( 6371 * acos( cos( radians(:lat) ) * cos( radians( lat ) ) 
        * cos( radians( lng ) - radians(:lng) ) + sin( radians(:lat2) ) * sin(radians(lat)) ) ) AS distance 
        FROM cafe_locations ";

This is a good step towards being able to add café & coffee reviews, however the next big sticking point will be letting users add new cafés as they go.

Ideally I’d like to collect a bit of meta data such as roasters, menu and seating options to help users finding cafés, but I’ll have to see how much data entry users will tolerate. I also need to be aware of how or if I can verify this community sourced data.

Designing, Decisions and Scope Creep

Photos – I’ve started to think they could be important for helping a user know if a cafe has the vibe they’re after. Implementing them does open a whole new bag of onions with regards to uploading, deleting, featuring, moderating, offloading, resizing and such.

I’m not sure if that should end up in the v1 release or if I’m just blowing up the scope unnecessarily. I’m not trying to be Instagram, but at the same time photos do tell a story of what the place is like.

Cafe Views in the Frontend

The HTML/CSS for a cafe view in the frontend are coming along. The placeholder data and characters need to be replaced with real components, but I do have the offset height panels and slanted shadow that I was after.

Seeya flat design, it’s been nice, but I need a break for a while.

Frontend Dev Progress

I’ve made some progress on the frontend interfaces for logging a coffee/rating a cafe and the cafes section for managing your preferred cafes.

Screenshot of UI to Add a coffee
Work in progress built UI

The coffee counter cup is now a working Vue component. The proportions will need a little bit of media query love to work at different sizes, but the main features of the interaction, the long shadow and the chamfer curved buttons are all in place 👌

The Cafe component of this UI will need a reasonable amount of backend work to function in order to auto-suggest cafes based on name and location.

I’m hoping that allowing users to enter new cafes not yet in the DB will be fairly straight forward. There’s a chance that managing duplicate or incorrect data could require additional processes beyond standard CRUDing. We’ll see.

My Cafes

My Cafes UI progress

This is my first use of Vue Router to provide a semi SPA type structure to this page. The Recent / Favs / To Try links are Vue Router links which dynamically swap out the component below for the appropriate content. Vue Router handles updating the browser URL to maintain back button functionality. I had to put a bit of work into detecting the current route in order to swap out the icon SVG symbol. All the icons on this screen including the active state color versions are referenced from a single SVG sprite.

I’m really happy with this approach for both performance and maintainability reasons. I can create different color variations of symbols directly in the SVG code without needing to use Sketch.

To lower the barrier to entry for using I’d like to allow anonymous users to be able to save cafes to their favs/to try lists as well. I’d likely just store cafe ids in localStorage and expand that data from the server.

Signed up users will have the more robust backend storage of all this data.

Some Development has Happened

I did some frontend dev. Specifically a Vue Router implementation to navigate Vue components on the Cafes section, with fancy SVG icons 👌

I might break out some code for a demo one day. Or just keep working on HadCoffee instead, not sure.


Icons and UI Animation

I’ve done some work on an SVG icon system using symbols for reusable, editable icon versions. This will work well for static icons. For basic animation I’ll be able to use CSS targeting SVG elements in the DOM. If I introduce any more complex SVG animations I’ll need to embed the SVG content directly in the page.

Here’s a demo of the ‘Favouriting’ UI using CSS animations to give a more interesting experience to adding a cafe to favs.

See the Pen SVG Favourite by Mike (@mike_hasarms) on CodePen.0

Get Notified with HadCoffee Launches

HadCoffee will be a mobile web app to help you discover, save and share the best specialty coffee. Launching late 2021 with a Brisbane focus at first.

If you want to try out the beta version when it’s ready drop your details here. I won’t spam you. (Privacy Policy)

Keep Updated

New ‘Home’ screen

Wow, long time no progress. Side projects am I right?

I’m thinking now that the coffee logging and cafe ratings features will probably be secondary to being able to actually find new cafes you want to try. I think fewer people will care about having their personal coffee history available to them than actually being able to find somewhere good to go.

Because of that I didn’t previously have a good ‘home’ screen that leant itself to this usage.

This design attempts to cover that need with a focus on Cafes, search and the ‘To Try’ list (name not decided). This is about searching nearby, in a given area or by name for a cafe then possibly adding it to your To Try list.

I hadn’t considered search by name too much before, but having spoken with other coffee heads in coffee shops I think people will often recommend places and it’d be helpful to add them to your list.

This design shows the cafe search field expanded (it’ll tuck away when one of those other three options are selected). I had to iterate quite a bit to get to this point, but I think it covers the bases I want.

It’s less cluttered and complex than previous revisions; the search, My Cafes and To Try elements are separated and the screen is probably a sensible splash for the main features of the app.

I had hoped to be finished UI design, but I think it was necessary to go back and reconsider what features more people will find useful. I’m not sure there are enough that care just about logging. Hopefully the cafe search is more broadly applicable.


Dev is underway. Frontend template is largely built, but will create components as needed, rather than building a complete styleguide and system up front.

Backend dev has begun too; the Laravel backend started, user auth, and initial work on the process of adding cafes. That’s got a few extra steps than a basic CRUD form because I want to geolocate cafes without the user (or me) having to manually lookup their location.

I’m using HTML5 GeoLocation + Google APIs to reverse geocode the user’s current city for a hint as to which cafe they mean when entering data; then another reverse geocode to get lat/lng and address for the cafe in question.

This will let me do some initial data entry without as much tedious Googling and copy/pasting.

It does mean I need to get a bit diverted on the structuring of the application JS though. I don’t want to go to far building ad-hoc hack scripts that are hard to organize later. I need to workout how my application JS will combine with Vue, Vue Components and future code. May also need to consider how I cache user location or reverse geocode results to reduce API demands.

UI Progress

I simplified the coffee and cafes feature by separating them onto different screens for clarity and to reduce the busyness of the interface. This was originally the equivalent of a ‘My Stats’ page with an overview of total coffee consumption, cafe listing and filtering features. That was too much for one mobile screen and users would have missed features lost in the clutter.

This UI design update

  • Moved ‘My Cafes’ to its own screen, freeing up ‘My Coffees’ to focus on that
  • This gave the Cafes screen scope to have the All, Recent, Fav filters without being lost
  • Users can Add and search cafes they’ve visited from here

Visual Changes

  • I ditched the ugly grey bar for coloured versions, different for each of the two screens to help differentiate them.
  • Brought the section icon into the header for clarity. The user avatar is probably not relevant here
  • Tried an orange/peach and blue scheme to avoid everything being variations of the orange/brown hues. I don’t want the app to be too monochromatic
  • De-emphasized the ‘back’ buttons in the top bar
  • Fleshed out the nav icons a little more (Find Cafes, My Cafes, My Coffee, Hamburger extras)
  • To Do: Unify the ‘Add New’ process. Probably bring an ‘Add coffee’ button to near the top of the My Coffee screen to be consistent with the My Cafes screen, and to avoid the awkward null space between the header and the first data card
  • Apart from the logo I’m starting to like this look and feel, but need to decide how to unify it with the previous ‘Add Coffee’ screen, which looks good, but is not consistent enough with this flatter design. The long shadows of the other screen will probably be harder to implement, so that might be the deciding factor.