const express = require("express"); const db = require("./db"); const port = 3000; const app = express(); app.use(express.json()); // ####### ROUTES ####### app.get("/test", async (req, res) => { console.log('test') res.json({ test: 'test' }) }); // ### GET ALL RECIPES ### app.get("/recipes", async (req, res) => { try { const recipes = await db('recipes').select('id', 'name', 'cuisine'); res.json(recipes); } catch (err) { console.log(err); res.status(500).json({ error: err.message }); } }); // ### GET RECIPE ### app.get("/recipe/:id", async (req, res) => { const id = req.params.id try { const recipeQuery = db('recipes').where('id', '=', id).select('id', 'name', 'cuisine'); const ingredientsQuery = db.from('recipe_ingredients as ri') .join('ingredients as i', 'ri.ingredient_id', 'i.id') .where('ri.recipe_id', id) .select('i.name', 'ri.quantity', 'ri.unit'); const stepsQuery = db('recipe_steps').where('recipe_id', id).select('step_number', 'instruction'); const [recipe, ingredients, steps] = await Promise.all([recipeQuery, ingredientsQuery, stepsQuery]); const result = { details: recipe[0], ingredients: ingredients.map(ingredient => ({ name: ingredient.name, quantity: ingredient.quantity, unit: ingredient.unit })), steps: steps.reduce((acc, step) => { acc[step.step_number] = step.instruction; return acc; }, {}) }; res.json(result); } catch (err) { console.log(err); res.status(500).json({ error: err.message }); } }); // ### ADD RECIPE ### app.post("/add-recipe", async (req, res) => { const { name, cuisine, ingredients, steps } = req.body; try { const [id] = await db('recipes').insert({ name: name, cuisine: cuisine }, ['id']) const existingIngredients = await db('ingredients').whereIn('name', ingredients.map(ing => ing.name)); let ingredientData = []; for (let ingredient of ingredients) { const existingIngredient = existingIngredients.find(ing => ing.name === ingredient.name); if (!existingIngredient) { // create the ingredient if there is no entry const [newIngredient] = await db('ingredients').insert({ name: ingredient.name }, ['id']); ingredientData.push({ id: newIngredient.id, quantity: ingredient.quantity, unit: ingredient.unit }); } else { // if the ingredient exists use existing entry ingredientData.push({ id: existingIngredient.id, quantity: ingredient.quantity, unit: ingredient.unit }); } } const ingredientInserts = ingredientData.map(ing => ({ ingredient_id: ing.id, quantity: ing.quantity, unit: ing.unit, recipe_id: id.id })); await db('recipe_ingredients').insert(ingredientInserts); // Step 4: Insert steps into recipe_steps const stepInserts = Object.keys(steps).map(stepNumber => ({ recipe_id: id.id, step_number: parseInt(stepNumber), instruction: steps[stepNumber] })); await db('recipe_steps').insert(stepInserts); res.status(200).send({ message: "Recipe added", id: id.id }); } catch (err) { console.log(err); res.status(500).json({ error: err.message }); } }); // ### DELETE RECIPE ### app.delete("/delete-recipe", async (req, res) => { const { id } = req.body; try { await db('recipes').where({ id: id }).del(); res.status(200).send({ message: "Recipe deleted" }); } catch (err) { console.log(err); res.status(500).json({ error: err.message }); } }); app.listen(port, () => console.log(`Server has started on port: ${port}`)); process.on('SIGINT', async () => { console.log('Closing database connection...'); await db.destroy(); process.exit(0); });