Skip to content

Commit

Permalink
implement find and search recipes b00tc4mp#407
Browse files Browse the repository at this point in the history
  • Loading branch information
berlem committed Apr 23, 2024
1 parent bcdc562 commit 81643ec
Show file tree
Hide file tree
Showing 19 changed files with 380 additions and 105 deletions.
2 changes: 1 addition & 1 deletion staff/belen-ivars/project/api/.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ MONGODB_URL = mongodb://127.0.0.1:27017/project
TEST_MONGODB_URL = mongodb://127.0.0.1:27017/test
PORT = 9000
JWT_SECRET = no recuerdo que comí ayer
JWT_EXP = 1h
JWT_EXP = 100h
4 changes: 3 additions & 1 deletion staff/belen-ivars/project/api/handlers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import deleteRecipeHandler from './deleteRecipeHandler.js'
import editRecipeHandler from './editeRecipeHandler.js'
import toggleFavRecipeHandler from './toggleFavRecipeHandler.js'
import retrieveFavRecipesHandler from './retrieveFavRecipesHandler.js'
import searchRecipesHandler from './searchRecipesHandler.js'


export {
Expand All @@ -18,5 +19,6 @@ export {
deleteRecipeHandler,
editRecipeHandler,
toggleFavRecipeHandler,
retrieveFavRecipesHandler
retrieveFavRecipesHandler,
searchRecipesHandler
}
45 changes: 45 additions & 0 deletions staff/belen-ivars/project/api/handlers/searchRecipesHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { ContentError, NotFoundError } from 'com/errors.js'
import logic from '../logic/index.js'
import { validate } from "com"
import jwt from 'jsonwebtoken'


const searchRecipesHandler = async (req, res) => {
const token = req.headers.authorization.substring(7)

const payload = jwt.verify(token, process.env.JWT_SECRET)
const { sub: userId } = payload
const { ingredients, diet } = req.query

let ingredientsList
if (ingredients) {
ingredientsList = ingredients.split('-')
}

let dietList
if (diet) {
dietList = diet.split('-')
}
try {
validate.id(userId, 'id')
} catch (error) {

return res.status(400).send()
}

try {
const foundRecipes = await logic.findRecipes(userId, ingredientsList, dietList)
res.status(200).send(foundRecipes)
} catch (error) {
if (error instanceof NotFoundError) {
res.status(404).send(error)
}
else if (error instanceof ContentError) {
res.status(400).send(error)
} else {
res.status(500).send(error)
}
}
}

export default searchRecipesHandler
5 changes: 4 additions & 1 deletion staff/belen-ivars/project/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
deleteRecipeHandler,
editRecipeHandler,
toggleFavRecipeHandler,
retrieveFavRecipesHandler
retrieveFavRecipesHandler,
searchRecipesHandler

} from './handlers/index.js'

Expand Down Expand Up @@ -46,6 +47,8 @@ mongoose.connect(process.env.MONGODB_URL)

server.patch('/recipes/:recipeId/favs', toggleFavRecipeHandler)

server.get('/recipes/search', searchRecipesHandler)

server.listen(process.env.PORT, () => console.log(`server running on port ${process.env.PORT}`))
})

Expand Down
31 changes: 20 additions & 11 deletions staff/belen-ivars/project/api/logic/findRecipes.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
import { Recipe } from '../data/models.js'
import { Recipe, Ingredient } from '../data/models.js'

async function findRecipes(userId, ingredients, diet) {

console.log(ingredients, diet, 'prueba')

async function findRecipes() {
// const { diet, ingredients } = req.query
const filter = {}
if (diet) filter.diet = diet
if (method) filter.method = method
if (complexity) filter.complexity = complexity
if (time) {
filter.time = { $lte: parseInt(tiempo) }
}

if (diet) filter.diet = { $in: diet }
// if (method) filter.method = method
// if (complexity) filter.complexity = complexity
// if (time) {
// filter.time = { $lte: parseInt(tiempo) }
// }
if (ingredients) {
const ingredientList = ingredients.split('-')
filter.ingredients = { $in: ingredientList }
let ingredientsList = []
for (let ingredient of ingredients) {
const _ingredient = await Ingredient.findOne({ name: ingredient })
ingredientsList.push(_ingredient)
}
filter.ingredients = { $in: ingredientsList }
}


const recipes = await Recipe.find(filter)
console.log(recipes)
return recipes
}

export default findRecipes
16 changes: 16 additions & 0 deletions staff/belen-ivars/project/api/logic/findRecipes.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import dotenv from 'dotenv'
dotenv.config()
import mongoose from 'mongoose'

import findRecipes from './findRecipes.js'

(async () => {
await mongoose.connect(process.env.MONGODB_URL)
try {
const recipe = await findRecipes('65f85ac7883fd3713c8bd3a3', ['huevo', 'plátano'])

console.log(recipe)
} catch (error) {
console.log(error)
}
})()
4 changes: 3 additions & 1 deletion staff/belen-ivars/project/api/logic/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import editRecipe from './editRecipe.js'
import toggleFavRecipe from './toggleFavRecipe.js'
import retrieveFavRecipes from './retrieveFavRecipes.js'
import checkIngredient from './checkIngredient.js'
import findRecipes from './findRecipes.js'

const logic = {
registerUser,
Expand All @@ -19,7 +20,8 @@ const logic = {
editRecipe,
toggleFavRecipe,
retrieveFavRecipes,
checkIngredient
checkIngredient,
findRecipes
}

export default logic
59 changes: 56 additions & 3 deletions staff/belen-ivars/project/app/src/components/DietOptions.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,59 @@
import OptionsFilters from "./OptionsFilters"

export default function DietOptions() {
const options = ['glutenfree', 'vegetarian', 'vegan', 'omnivorous']
return <OptionsFilters title="Diet type" options={options} />
import { useState } from "react"

export default function DietOptions(props) {
const [isGlutenChecked, setIsGlutenChecked] = useState(false);
const [isVeganChecked, setIsVeganChecked] = useState(false);
const [isVeggieChecked, setIsVeggieChecked] = useState(false);

const handleGlutenOnChange = () => {
setIsGlutenChecked(!isGlutenChecked);
props.dietChange('glutenfree')
};

const handleVeganOnChange = () => {
setIsVeganChecked(!isVeganChecked);
props.dietChange('vegan')
};

const handleVeggieOnChange = () => {
setIsVeggieChecked(!isVeggieChecked);
props.dietChange('vegetarian')
};

return (
<div>
Select your diet:
<div>
<input
type="checkbox"
id="gluten"
name="gluten"
value="GlutenFree"
checked={isGlutenChecked}
onChange={handleGlutenOnChange}
/>
Gluten Free
<input
type="checkbox"
id="vegan"
name="vegan"
value="Vegan"
checked={isVeganChecked}
onChange={handleVeganOnChange}
/>
Vegan
<input
type="checkbox"
id="veggie"
name="veggie"
value="Vegeterian"
checked={isVeggieChecked}
onChange={handleVeggieOnChange}
/>
Vegeterian
</div>
</div>
);
}
22 changes: 20 additions & 2 deletions staff/belen-ivars/project/app/src/components/MethodOptions.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
import { Container } from "../library"
import OptionsFilters from "./OptionsFilters"
import { useState } from "react"

export default function MethodOptions() {
const options = ['steamed', 'oven', 'microwave', 'grill', 'fresh']
return <OptionsFilters title="Method" options={options} />
const [isOpen, setIsOpen] = useState(false)

const options = ['steamed', 'oven', 'microwave', 'grill', 'fresh', 'cook']

function handleMethodlick(event) {
event.preventDefault()

setIsOpen(!isOpen)

if (isOpen) {
setIsOpen(false)
}
}
return <Container className="options" onClick={handleMethodlick}>
{isOpen &&
<OptionsFilters title="Method" options={options} />
}
</Container>
}
55 changes: 55 additions & 0 deletions staff/belen-ivars/project/app/src/components/NewSearch.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { useState } from "react"
import { Button, Field, Link, Form, Container } from "../library"
import DietOptions from "./DietOptions"

export default function NewSearch(props) {
const [diet, setDiet] = useState([])

function handleChangeDiet(dietType) {
const index = diet.indexOf(dietType)

let newDiet
if (index === -1) {
newDiet = diet.concat(dietType)
} else {
newDiet = diet.filter((_, _index) => _index !== index);
}
setDiet(newDiet)
}

function handleSubmit(event) {
event.preventDefault()

const ingredients = event.target.querySelector('#search-elements').value
if (ingredients.length > 0) {
const formatedIngredients = ingredients.split(', ').join('-')
props.setIngredients(formatedIngredients)
}
if (diet.length > 0) {
const formatedDiet = diet.join('-')
props.setDiet(formatedDiet)
}
props.onPublish()
}

function handleCancel(event) {
event.preventDefault()

props.onCancel()
}

return <Container className="new-recipe">
<Form onSubmit={handleSubmit}>
<Field id="search-elements" placeholder="Search..." className="search" />

<DietOptions dietChange={handleChangeDiet}></DietOptions>


<div>
<Button type='submit'>🔍</Button>
<Button onClick={handleCancel}>Cancel</Button>
</div>
</Form>
</Container>
}

69 changes: 49 additions & 20 deletions staff/belen-ivars/project/app/src/components/OptionsFilters.jsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,54 @@
import { Container, Label } from "../library"
import { useState } from "react"

export default function OptionsFilters({ options, title }) {
export default function OptionsFilters(props) {
const [isGlutenChecked, setIsGlutenChecked] = useState(false);
const [isVeganChecked, setIsVeganChecked] = useState(false);
const [isVeggieChecked, setIsVeggieChecked] = useState(false);

return (
<Container>
<span><u>{title}</u></span>
<ul id="checklist">
{
options.map((o, index) => (
const handleGlutenOnChange = () => {
setIsGlutenChecked(!isGlutenChecked);
};

const handleVeganOnChange = () => {
setIsVeganChecked(!isVeganChecked);
};

<li key={index}>
const handleVeggieOnChange = () => {
setIsVeggieChecked(!isVeggieChecked);
};

<input
type="checkbox"
value={o}
/>
<Label>{o}</Label>
</li>
))
}
</ul>
</Container>
)
return (
<div>
Select your diet:
<div>
<input
type="checkbox"
id="gluten"
name="gluten"
value="GlutenFree"
checked={isGlutenChecked}
onChange={handleGlutenOnChange}
/>
Gluten Free
<input
type="checkbox"
id="vegan"
name="vegan"
value="Vegan"
checked={isVeganChecked}
onChange={handleVeganOnChange}
/>
Vegan
<input
type="checkbox"
id="veggie"
name="veggie"
value="Vegeterian"
checked={isVeggieChecked}
onChange={handleVeggieOnChange}
/>
Vegeterian
</div>
</div>
);
}
Loading

0 comments on commit 81643ec

Please sign in to comment.