Find recipes for your favourite cocktails, with alcohols suggested by SAQ powered by a Coveo search API. Alter your alcohol selections to fit your budget, find out how many drinks you will be able to make, and your cost per drink!
See it in action here.
- Clone the repo.
- Install dependencies by running
npm i --no-optional
. - Install the angular CLI globally by running
npm i -g @angular/cli
. - In
src/cfg/config.ts
, verify you have a valid value forCOVEO_ACCESS_TOKEN
so calls to the Coveo API work.
Run ng serve
for a dev server. Navigate to http://localhost:4200/
. The app will automatically reload if you change any of the source files.
Run ng test
to execute the unit tests via Karma.
Run ng build
to build the project. The build artifacts will be stored in the dist/
directory. Use the -prod
flag for a production build.
Run ng lint
to lint the project.
This project was generated with angular-cli version 1.0.0-beta.28.3.
The application is built using four components having the following relationship:
App
│
└───Search Bar
│
└───Recipe
│
└───Ingredient Card
│
└───Info Card
The application uses two services:
-
Cocktail Service: displays a list of cocktails, and tracks the one that has been selected. The service retrieves data locally from
src/data/cocktail-recipes
; it does not communicate with external parties. -
Saq Service: communicates with SAQ via a Coveo search API, retrieving results for a queried alcohol category. Every alcohol Ingredient Card component subscribes to a unique Saq service instance.
- A user searches for a cocktail recipe using the
Search Bar component
powered byCocktail service
. - Upon making a selection, an event is emitted by a
Cocktail service
observable with the selected cocktail recipe. - The
Recipe component
intercepts the event and generates as manyIngredient Card components
as needed by the recipe. It specifies whether ingredients are alcoholic or non-alcoholic. It also creates the firstInfo Card component
containing instructions on how to perpare the cocktail. Ingredient Card component
displays all information related to its assigned ingredient, including the name, quantity and an image. In addition, for alcoholic ingredients, it will retrieve results usingSaq service
, and provide navigation buttons to switch between them. The active reult is sent back and aggregated inRecipe component
.Recipe component
uses the aggregated alcohol results to calculate the total price of alcohol selections, the number of cocktails that can be made, and the price per cocktail. The information is diplayed in a secondInfo Card component
.
All recipes are stored in src/data/cocktail-recipes
. To add a new cocktail recipe, you will need to:
- Add the name of the cocktail to the
cocktails
object. - Add the alcohol ingredients to the
alcohols
object if they are not already there. If the alcohol has a different name in French, also add an entry to thealcoholsFR
object. This is needed because queries to the Coveo API need to be in French. - Add non-alcoholic ingredients to the
ingredients
object if they are not already there. - Add your recipe to the
cocktailInfos
object, by creating a new instance of theCocktailInfo
class and associating it to your cocktail.- Please use a number to describe the quantity of an alcohol ingredient.
- Non-alcoholic ingredient quantities can be a number or a string.
- All numbers should be in ounces.
e.g. Mojito recipe
[cocktails.MOJITO]: new CocktailInfo(
cocktails.MOJITO, // cocktail name
{[alcohols.WHITE_RUM]: 2}, // alcohol ingredients
{[ingredients.CLUB_SODA]: 1, [ingredients.LIME_JUICE]: 1, [ingredients.MINT_LEAVES]: '12', [ingredients.SUGAR]: '2 teaspoons of'}, // non-alcoholic ingredients
'Fill a glass with ice. Crush the mint leaves to release their oils and flavour. Stir the ingredients together until the sugar has dissolved and pour into the chilled glass.') // preparation instructions
- If you added non-alcoholic ingredients, add a .jpg or .jpeg image for each new ingredient to the
src/assets/ingredient-photos
folder. Make sure the image name matches the lowercase name of the ingredient as written in theingredients
object, with spaces replaced with underscores.
e.g. The image for 'Lemon juice' should be labelled 'lemon_juice'.