List and filter ingredients (wip)

Co-authored-by: grgrce <grgrce@users.noreply.github.com>
master
km0 3 years ago
parent 143559040e
commit 825dab6019

@ -1,3 +1,14 @@
# SOUP-GEN 🍜 # SOUP-GEN 🍜
A web-to-print cookbook with a collaborative attitude and generative outputs A web-to-print cookbook with a collaborative attitude and generative outputs.
For now you can add a recipe only if you are from XPUB, but we are working to make this open access.
To add a recipe:
1. Enter your Jupiter, and go to `~/shared/html/soup-gen/`
2. Open the notebook `add_recipe.ipynb`
3. Run the first snippet, it will ask you for some info about the recipe: fill the blank space in the
output message.
4. Run the second snippet, it will save the recipe in the Soupboat.
5. You added a recipe!
6. **\_\_CONGRATS\_\_**

119
cms.js

@ -1,6 +1,14 @@
const cookbook = document.getElementById("cookbook"); const cookbook = document.getElementById("cookbook");
const cookbookInfo = document.getElementById("cookbookInfo"); const cookbookInfo = document.getElementById("cookbookInfo");
const ingredientsContainer = document.getElementById("ingredients-container");
const activeAllButton = document.getElementById("active-all");
let selectedIngredients = new Set();
let ingredientsList = []; // list of unique ingredients
let tagList;
let recipesList;
fetch("./cms.json") fetch("./cms.json")
.then((response) => { .then((response) => {
return response.json(); return response.json();
@ -8,10 +16,14 @@ fetch("./cms.json")
.then((data) => { .then((data) => {
populateContents(data); populateContents(data);
recipesInfo(data.recipes); recipesInfo(data.recipes);
ingredientsTag();
showAllTags();
showSelectedRecipes();
}); });
function populateContents(data) { function populateContents(data) {
data.recipes.forEach((recipe) => addRecipe(recipe)); data.recipes.forEach((recipe) => addRecipe(recipe));
recipesList = [...document.getElementsByClassName("recipe")];
} }
function addRecipe(recipe) { function addRecipe(recipe) {
@ -51,6 +63,8 @@ function addRecipe(recipe) {
let ingredient = document.createElement("li"); let ingredient = document.createElement("li");
ingredient.innerHTML = item; ingredient.innerHTML = item;
ingredientsList.appendChild(ingredient); ingredientsList.appendChild(ingredient);
item = item.replaceAll(" ", "-");
card.classList.add(item);
}); });
ingredients.appendChild(ingredientsList); ingredients.appendChild(ingredientsList);
card.appendChild(ingredients); card.appendChild(ingredients);
@ -79,6 +93,111 @@ function recipesInfo(recipes) {
let ingredients = []; let ingredients = [];
recipes.forEach((recipe) => (ingredients = [...ingredients, ...recipe.ingredients])); recipes.forEach((recipe) => (ingredients = [...ingredients, ...recipe.ingredients]));
let unique = [...new Set(ingredients)]; let unique = [...new Set(ingredients)];
ingredientsList = Array.from(unique);
cookbookInfo.innerHTML = `There are ${recipes.length} recipes in the cookbook, with a total of ${unique.length} different ingredients`; cookbookInfo.innerHTML = `There are ${recipes.length} recipes in the cookbook, with a total of ${unique.length} different ingredients`;
} }
// Create tags from the ingredients list of the recipes
function ingredientsTag() {
ingredientsList.forEach((ingredient) => {
let tag = document.createElement("li");
tag.classList.add("tag");
tag.setAttribute("data-tag", ingredient);
tag.setAttribute("tabindex", 0);
tag.innerHTML = ingredient;
ingredientsContainer.appendChild(tag);
});
tagList = document.querySelectorAll("[data-tag]");
}
let allActive = true;
function conditionalToggle(element) {
if (allActive) {
tagList.forEach((tag) => {
selectedIngredients.delete(tag.getAttribute("data-tag"));
tag.classList.remove("active");
tag.setAttribute("aria-expanded", "false");
});
activeAllButton.classList.remove("active");
allActive = false;
}
// conditional toggle ecc
if (element.classList.contains("active")) {
element.classList.remove("active");
element.setAttribute("aria-expanded", "false");
selectedIngredients.delete(element.getAttribute("data-tag"));
} else {
element.classList.add("active");
element.setAttribute("aria-expanded", "true");
selectedIngredients.add(element.getAttribute("data-tag"));
}
// final check
allActive = tagList.length == selectedIngredients.size;
if (allActive) {
activeAllButton.classList.add("active");
activeAllButton.setAttribute("aria-expanded", "true");
}
}
function showAllTags() {
tagList.forEach((tag) => {
selectedIngredients.add(tag.getAttribute("data-tag"));
tag.classList.add("active");
tag.setAttribute("aria-expanded", "true");
});
allActive = true;
showSelectedRecipes();
}
function showSelectedRecipes() {
recipesList.forEach((recipe) => {
recipe.classList.remove("active");
});
selectedIngredients.forEach((ingredient) => {
//filter function
let selectedRecipes = recipesList.filter((el) => {
ingredient = ingredient.replaceAll(" ", "-");
return el.classList.contains(ingredient);
});
selectedRecipes.forEach((recipe) => {
recipe.classList.add("active");
});
});
allActiveCheck();
}
function allActiveCheck() {
if (tagList.length === selectedIngredients.size) {
allActive = true;
tagList.forEach((tag) => tag.classList.add("all"));
// categoriesContainer.firstElementChild.classList.add("active");
} else {
allActive = false;
tagList.forEach((tag) => tag.classList.remove("all"));
// categoriesContainer.firstElementChild.classList.remove("active");
}
}
// Event Listeners
ingredientsContainer.addEventListener("click", (e) => {
//if click is on a tag/LIst element, then execute conditional toggle
if (e.target.tagName === "LI") {
conditionalToggle(e.target);
showSelectedRecipes();
}
});
activeAllButton.addEventListener("click", (e) => {
activeAllButton.classList.add("active");
activeAllButton.setAttribute("aria-expanded", "true");
showAllTags();
});

@ -1 +1 @@
{"recipes": [{"title": "Pizza and fruit salad soup", "description": "Minim laborum ipsum sunt minim nulla officia cillum quis labore ad voluptate enim deserunt nulla.", "chef": "chef Malvozzo", "ingredients": ["\ud83c\udf55", "\ud83e\udd6d", "\ud83c\udf49", "\ud83c\udf48"], "instructions": ["Id est velit ullamco ea sint aliqua laboris incididunt consectetur do aliqua sint eiusmod.", "Mescola", "Pariatur eu exercitation ipsum qui e", "Quis pariatur magna id pariatur consectetur irure in sint.", "Culpa sunt non consequat consequat excepteur amet ut veniam cupidatat in occaecat consectetur velit.", "servire ben caldo!"]}, {"title": "Kip & Ice Kream Siup", "description": "Id consequat deserunt laborum ea commodo sit voluptate sunt commodo excepteur sit incididunt amet.", "chef": "Mad Moonfish", "ingredients": ["\ud83c\udf57", "\ud83c\udf5a", "funghetti", "\ud83c\udf49", "\ud83e\udd57"], "instructions": ["Exercitation eiusmod adipisicing ex ut amet qui minim est anim reprehenderit nulla voluptate quis.", "Occaecat anim veniam occaecat ut pariatur culpa sit reprehenderit ullamco cupidatat.", "Et reprehenderit mollit cillum Lorem est.", "Magna aliquip sint aliqua proident.", "sluuuurp"]}, {"title": "NLTK Soupa", "description": "A delicious soup made with natural language tomato and kiwi", "chef": "Python", "ingredients": ["pasta", "mushroom", "pizza", "internet"], "instructions": ["Cook the pasta in the internet", "Dig a hole near a mushroom", "Bury the pizza in the hole", "Turn off internet", "Drain the pasta", "Turn internet on again"]}, {"title": "A new sup", "description": "just a test soup to see how does the cms taste like", "chef": "python", "ingredients": ["computer", "soupboat", "jupiter", "zen"], "instructions": ["turn on the computer", "enter the soupboat", "access jupiter", "start the kernel with little zen", "put python to boil", "wait and shift enter"]}, {"title": "Misu sup", "description": "A tasty misu sup yes yes yes", "chef": "Mitsos", "ingredients": ["Miso", "Water", "Salt", "Hash", "Egg", "Oil", "Pepper", "Glitter", "Mushrooms"], "instructions": ["Take the glitter and put them on your face", "Boil the water", "Throw the mushrooms in the boiling water", "Throw an egg against your neighbour", "Add salt and pepper", "Enjoy"]}, {"title": "A visual studio soup", "description": "A soup from the jupiter lab in visual studio ecc ecc really testy", "chef": "Visual sudo", "ingredients": ["Visual Studio", "Zen", "soup-gen repo", "git", "soupboat"], "instructions": ["Open visual studio and pull the repo from git", "Follow the jupiter notebook", "hope it works", "commit and push all the changes", "update the soupboat"]}]} {"recipes": [{"title": "Pizza and fruit salad soup", "description": "Minim laborum ipsum sunt minim nulla officia cillum quis labore ad voluptate enim deserunt nulla.", "chef": "chef Malvozzo", "ingredients": ["\ud83c\udf55", "\ud83e\udd6d", "\ud83c\udf49", "\ud83c\udf48"], "instructions": ["Id est velit ullamco ea sint aliqua laboris incididunt consectetur do aliqua sint eiusmod.", "Mescola", "Pariatur eu exercitation ipsum qui e", "Quis pariatur magna id pariatur consectetur irure in sint.", "Culpa sunt non consequat consequat excepteur amet ut veniam cupidatat in occaecat consectetur velit.", "servire ben caldo!"]}, {"title": "Kip & Ice Kream Siup", "description": "Id consequat deserunt laborum ea commodo sit voluptate sunt commodo excepteur sit incididunt amet.", "chef": "Mad Moonfish", "ingredients": ["\ud83c\udf57", "\ud83c\udf5a", "funghetti", "\ud83c\udf49", "\ud83e\udd57"], "instructions": ["Exercitation eiusmod adipisicing ex ut amet qui minim est anim reprehenderit nulla voluptate quis.", "Occaecat anim veniam occaecat ut pariatur culpa sit reprehenderit ullamco cupidatat.", "Et reprehenderit mollit cillum Lorem est.", "Magna aliquip sint aliqua proident.", "sluuuurp"]}, {"title": "NLTK Soupa", "description": "A delicious soup made with natural language tomato and kiwi", "chef": "Python", "ingredients": ["pasta", "Mushrooms", "pizza", "internet"], "instructions": ["Cook the pasta in the internet", "Dig a hole near a Mushrooms", "Bury the pizza in the hole", "Turn off internet", "Drain the pasta", "Turn internet on again"]}, {"title": "A new sup", "description": "just a test soup to see how does the cms taste like", "chef": "python", "ingredients": ["computer", "soupboat", "jupiter", "zen"], "instructions": ["turn on the computer", "enter the soupboat", "access jupiter", "start the kernel with little zen", "put python to boil", "wait and shift enter"]}, {"title": "Misu sup", "description": "A tasty misu sup yes yes yes", "chef": "Mitsos", "ingredients": ["Miso", "Water", "Salt", "Hash", "Egg", "Oil", "Pepper", "Glitter", "Mushrooms"], "instructions": ["Take the glitter and put them on your face", "Boil the water", "Throw the mushrooms in the boiling water", "Throw an egg against your neighbour", "Add salt and pepper", "Enjoy"]}, {"title": "A visual studio soup", "description": "A soup from the jupiter lab in visual studio ecc ecc really testy", "chef": "Visual sudo", "ingredients": ["Visual Studio", "Zen", "soup-gen repo", "git", "soupboat"], "instructions": ["Open visual studio and pull the repo from git", "Follow the jupiter notebook", "hope it works", "commit and push all the changes", "update the soupboat"]}]}

@ -47,7 +47,7 @@
Each soup has: Each soup has:
</div> </div>
<div class="recipe"> <div class="recipe-info">
<div class="info"> <div class="info">
<h2 class="title">Title</h2> <h2 class="title">Title</h2>
<div class="description">Description</div> <div class="description">Description</div>
@ -76,6 +76,9 @@
<div class="cookbook"> <div class="cookbook">
<h2>Soup Gen Cookbook</h2> <h2>Soup Gen Cookbook</h2>
<div class="cookbook-info" id="cookbookInfo"></div> <div class="cookbook-info" id="cookbookInfo"></div>
<ul id="ingredients-container">
<button class="tag active" id="active-all" role="button">All Tags</button>
</ul>
<div class="recipes" id="cookbook"></div> <div class="recipes" id="cookbook"></div>
</div> </div>
@ -83,11 +86,12 @@
<div class="todo"> <div class="todo">
<ul> <ul>
<em>TODO short term:</em> <em>TODO short term:</em>
<li>💻 Receive recipe as a form ?</li> <li class="done">🔍 Ingredients list and filter!!! (like chat reader)</li>
<li>🔍 Ingredients list and filter!!! (like chat reader)</li> <li>🚫 Inclusive / Exclusive filters</li>
<li>💬 Different types of entries for the cms: recipe, diary, ecc.</li> <li>💬 Different types of entries for the cms: recipe, diary, ecc.</li>
<li>📷 Add recipe picture ?</li>
<li>🎨 Design</li> <li>🎨 Design</li>
<li>💻 Receive recipe as a form ?</li>
<li>📷 Add recipe picture ?</li>
<em>TODO long term:</em> <em>TODO long term:</em>
<li>💾 Better CMS (and not just a JSON file ah ah)</li> <li>💾 Better CMS (and not just a JSON file ah ah)</li>
@ -100,6 +104,7 @@
<ul class="questions"> <ul class="questions">
<em>Questions:</em> <em>Questions:</em>
<li> <li>
What is the best solution to receive recipes from users??? We imagine it to be What is the best solution to receive recipes from users??? We imagine it to be
something like an HTML form that the NGNIX server could parse and then put in something like an HTML form that the NGNIX server could parse and then put in

@ -13,8 +13,6 @@ body {
border: 1px solid currentColor; border: 1px solid currentColor;
} }
h1, h1,
h2, h2,
h3 { h3 {
@ -27,6 +25,10 @@ ol {
list-style-position: inside; list-style-position: inside;
} }
ul {
list-style: none;
}
em { em {
display: block; display: block;
margin-top: 1.6em; margin-top: 1.6em;
@ -62,6 +64,23 @@ em {
font-style: italic; font-style: italic;
} }
.tag,
button.tag {
background-color: transparent;
font-size: 20px;
display: inline-block;
border: 1px solid currentColor;
padding: 0 0.5ch;
border-radius: 1em;
margin: 4px;
text-transform: capitalize;
user-select: none;
}
.tag.active {
background-color: white;
}
.recipes { .recipes {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
@ -72,8 +91,9 @@ em {
column-gap: 16px; column-gap: 16px;
} }
.recipe { .recipe,
display: inline-block; .recipe-info {
display: none;
background-color: #ffffff; background-color: #ffffff;
flex-grow: 1; flex-grow: 1;
flex-basis: 55ch; flex-basis: 55ch;
@ -82,6 +102,16 @@ em {
padding: 1ch; padding: 1ch;
} }
.recipe.active {
display: inline-block;
}
.recipe-info {
display: inline-block;
border: 1px solid currentColor;
margin: 16px 0;
}
.recipe .title { .recipe .title {
margin-bottom: 8px; margin-bottom: 8px;
} }
@ -123,3 +153,8 @@ em {
.intro .recipe { .intro .recipe {
margin: 16px 0; margin: 16px 0;
} }
.done {
text-decoration: line-through;
opacity: 0.75;
}

Loading…
Cancel
Save