Peruse allows users to search at a products & services level in the shops and stores around them.
The brick and mortar retail experience still remains a mainstay of the procurement experience. The user problem Peruse aims to solve is that despite the proclivity of online shopping, shoppers still have a reason to buy in person; they want to see it in person first, they need it right away, they're in a place they don't know or a place they can't take delivery.
“I should be able to just search for what I want, and I'm told the stores nearby that have it”
The idea came from arriving at my gym in London Bridge to find I didn't have my shorts. I asked the desk staff if they had any available and they said the nearest place to buy them would be two stops away on the tube. I ended up running around the nearby area while Googling places I thought may sell shorts but I didn't know if they had a nearby location and shops that I knew were nearby but I wasn't sure if they would sell what I need.
The initial proto-personas were two clear user groups - shoppers and shop owners. Shop owners became the inital catch-all term for those that would maintain the inventory of each shop. Each with different needs to the data; shoppers would need to write data to each shop that they own, while shoppers need read ability on location based data.
There were numerous sub-categories to each user group, for example;
One Time Shopper
Indie Shop Owner
For confidentiality purposes I will keep user characteristics and persona details quite high-level here.
Peruse was as much a passion project as it was a chance to practice my design and development skills, so with all the time in the world it wen't straight to high-fi designs rather than wireframing.
With the term 'MVP' in mind I designed a mobile experience for the shoppers, given that the primary use case for shoppers was that they were 'on-the-go' and a desktop experience for shop-owners, given that their engagement was during administrative tasks at their computer/laptop. This would give Peruse the two components of core functionality; shop owners can upload store data and shoppers can find it.
“A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.”
- Antoine de Saint-Exupery
My design philosophy ers towards that of minimalism, which I've always been concerned is just laziness, but after I wrote an article on how to put my approach into practice, it remains one of my few practices which have changed very little over the years.
I chose a colour pallette similar to that of modern art; soft, with a few veins of strong colour and got to work on a logo and the skeleton of the designs. In hybrid wireframe/high-fi designs I mapped out the user flow, in what would become the answer to our user stories.
After placing them in InVision and getting some quick user feedback the designs were in a position to move to coding.
The idea, as well as the technical foundation to implement it was a 2 year story of continuous design ideation and self teaching NodeJS, React & React Native.
Something that may seem somewhat naive, but something that I'm very proud of, is that I left my job without fully knowing how to code with the tech stack I intended to use. For some reason or other I just felt the confidence to be able to learn React & React Native on the fly.
Additionally right before leaving work I made the decision to move from Angular & Ionic to React Native. Ionic came from my background of using Angular 1 but Angular had moved on so much by 2019 I was practically learning a new language. Coupling that with Ionic's inability (at least at the time) to make use of native functionality such as the camera, the React Native decision came quite easily.
MongoDB was a strong contender for my database of choice but the fact that Google Firebase would come with an Authentication API as well as a Database (and real-time DB if I wanted it); Firebase became the easy winner. AWS offers a similar service to Firebase but I liked the documentation and online reviews of Firebase a little more.
Stripe needs little introduction and explanation for why it was chosen as the payment gateway. Furthermore their documentation is world class.
Expo with React Native was again a simple choice. There is the ability to 'eject' from Expo with React Native but I couldn't find many use cases, particularly given what I was trying to achieve I found no reason why I should do that.
Algolia was a kind of beautiful solution I sort of stumbled across. The types of SQL-like searches I wanted to achieve with Firebase weren't possible with the setup of their Database. Furthermore I was hesitant to give the mobile app direct access to the live database and even Google themselves recommend Algolia. Algolia is actually a copy of your database, easily transferred with something called 'Firebase Functions'. This also allowed me to reshape the data for better geo-location based search.
Deploying the NodeJS middleware I had created for both applications on AWS was a decision made totally on the ease of the deployment process and with 'MVP' at the heart of the project - speed was key.
IxD Micro Case Study
One of the most surprising challenges of the design process was implying to the user the ability to slide the tray. The tray would allow the users to choose between a full-screen view of search results, a mid sized view, or a minimized view.
Jakobs law pushed me to decide that the best design for MVP would be to mimic the design found in Google Maps and other popular apps, a simple line the user is able to grab on to.
However I was really interested in the slide and drop as a challenge algorithmically too. The final solution was quite elegant (if I do say so!);
There were 3 states;
FullHeight, MedHeight, LowHeight
If the gesture was 20 visual units away from it's current state, in the case of MedHeight go to either FullHeight or LowHeight depending on drag direction. However if the state was either FullHeight or LowHeight, monitor the finger release point and if it is below or above (respectively), half of the screen height, go to the opposing state.
To further help the user, I used a spring animate so that the user understands this element is maleable as it moves from state to state.