<repo_name>esellors/foodoo-nodb-project<file_sep>/server/foodoo.js
require('dotenv').config();
const express = require('express');
const app = express();
const mmc = require('./controllers/MenuMealController');

const { SERVER_PORT } = process.env;

app.use(express.static(`${__dirname}/../build`));

app.use((req, res, next) => {
   console.log('...API request received');
   next();
});

app.use(express.json());

app.get("/api/menumeal", mmc.getItems);
app.post("/api/menumeal", mmc.addItem);
app.put("/api/menumeal/:section/:category/:item/:destinationSection", mmc.moveItems);
app.delete("/api/menumeal/:category/:item", mmc.deleteItem);

app.put("/api/meals/:mealOfDay", mmc.addMealToMeals)
app.delete("/api/meals/:mealOfDay", mmc.deleteMealFromMeals)

app.listen(SERVER_PORT, () => {
   console.log(`Chilling to Lo-fi ${8080} fm`);
})<file_sep>/src/components/AddItem.js
import React from 'react';

function AddItem(props) {
   function addItemHandler(e) {
      e.preventDefault();
      const tgtCategory = e.target.parentNode.id;
      const newItemInputField = e.target.previousSibling;
      
      if(newItemInputField.value === '') {
         alert("Please enter an item");
      } else {
         props.addItemRelay(tgtCategory, newItemInputField.value);
         newItemInputField.value = '';
         newItemInputField.focus();
      }
   }
   function cancelAddItem(e) {
      e = e || window.event;
      var target = e.target || e.srcElement;
      setTimeout(() => {
         target.value = '';
         target.parentNode.classList.add("hide_element");
      }, 350);
   }
   return (
      <form className="add_to_menu_form hide_element" id={props.id} onBlur={e => cancelAddItem(e)}>
         <input className="add_item" placeholder="enter item..."/>
         <input type="submit" className="add_btn" onClick={e => addItemHandler(e)} hidden />
         <span id="cancel_add_item">x</span>
      </form>
   );
}

export default AddItem;<file_sep>/src/components/Header.js
import React, {Component} from 'react';

class Header extends Component {
   constructor(props) {
      super(props);
      this.state = {
         headerTxt: 'foodoo'
      }
   }
   render() {
      return (
         <header>
            <h2>---------------<span id="site_title">{this.state.headerTxt}</span></h2>
            <h4>your daily meal planner</h4>
         </header>
      )
   }
}

export default Header;<file_sep>/src/components/RenderMenuItems.js
import React from 'react';

function RenderMenuItems(props) {
   const {categoryName, categoryData} = props;

   return (
      <>
         { categoryData
            ? categoryData.map((item, index) => {
               return (
                  <p className={categoryName} key={index} onClick={e => props.moveItem(e)}>{item}<span onClick={e => props.deleteMenuItem(e)}>x</span></p>
               )})
            : null
         }
      </>
   );
}

export default RenderMenuItems;<file_sep>/src/components/Menu.js
import React from 'react';
import AddItem from './AddItem';
import RenderMenuItems from './RenderMenuItems';

function Menu(props) {
   function toggleShowForm(e) {
      const category = e.target.parentNode.firstChild.nodeValue;
      const clickedForm = document.getElementById(category);
      const targetInputForm = clickedForm.firstChild;
      const menuInputForms = document.getElementsByClassName('add_item_form');

      Array.from(menuInputForms).forEach(el => {
         el.firstChild.value = '';
         el.classList.add("hide_element")
      })

      clickedForm.classList.remove("hide_element");
      targetInputForm.focus();
   }
   function addItemRelay(tgtCategory, newItem) {
      const newItemPackage =
      {
         category: tgtCategory,
         item: newItem
      };
      props.addItem(newItemPackage);
   }
   const { drinks, mains, sides, desserts } = props.menu;
   return (
      <section id="menu">

         <h1>MENU</h1>
         <h4 className="menu_categories">drinks<span onClick={e => toggleShowForm(e)}>+</span></h4>
         <AddItem id="drinks" addItemRelay={addItemRelay} />

         <RenderMenuItems categoryName="drinks" moveItem={props.moveItem} deleteMenuItem={props.deleteMenuItem} categoryData={drinks} />

         <h4 className="menu_categories">mains<span onClick={e => toggleShowForm(e)}>+</span></h4>
         <AddItem id="mains" addItemRelay={addItemRelay} />

         <RenderMenuItems categoryName="mains" moveItem={props.moveItem} deleteMenuItem={props.deleteMenuItem} categoryData={mains} />

         <h4 className="menu_categories">sides<span onClick={e => toggleShowForm(e)}>+</span></h4>
         <AddItem id="sides" addItemRelay={addItemRelay} />

         <RenderMenuItems categoryName="sides" moveItem={props.moveItem} deleteMenuItem={props.deleteMenuItem} categoryData={sides} />

         <h4 className="menu_categories">desserts<span onClick={e => toggleShowForm(e)}>+</span></h4>
         <AddItem id="desserts" addItemRelay={addItemRelay} />

         <RenderMenuItems categoryName="desserts" moveItem={props.moveItem} deleteMenuItem={props.deleteMenuItem} categoryData={desserts} />

      </section>
   )
}

export default Menu;<file_sep>/src/components/Meal.js
import React from 'react';
import MealsSelect from './MealsSelect';

function Meal(props) {
   const { drinks, mains, sides, desserts } = props.meal;
   return (
      <section id="meal">
         <div id="meal_header">
            <h1>MEAL</h1>
            <MealsSelect updateMealsHandler={props.updateMealsHandler} />
         </div>
         {drinks
            ? drinks.map((item, index) => {
               return (
                  <p className="drinks" key={index} onClick={e => props.moveItem(e)}>{item}<span>&#40;-&#41;</span></p>
               )
            })
            : null
         }
         {mains
            ? mains.map((item, index) => {
               return (
                  <p className="mains" key={index} onClick={e => props.moveItem(e)}>{item}<span>&#40;-&#41;</span></p>
               )
            })
            : null
         }
         {sides
            ? sides.map((item, index) => {
               return (
                  <p className="sides" key={index} onClick={e => props.moveItem(e)}>{item}<span>&#40;-&#41;</span></p>
               )
            })
            : null
         }
         {desserts
            ? desserts.map((item, index) => {
               return (
                  <p className="desserts" key={index} onClick={e => props.moveItem(e)}>{item}<span>&#40;-&#41;</span></p>
               )
            })
            : null
         }
      </section>
   )
}

export default Meal;<file_sep>/src/App.js
import React, { Component } from 'react';
import './App.css';
import axios from 'axios';
import Referrer from './components/Referrer/Referrer';
import Header from './components/Header';
import Menu from './components/Menu';
import Meal from './components/Meal';
import Meals from './components/Meals';
import Footer from './components/Footer';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      menu: {},
      meal: {},
      meals: {}
    }
    this.addItem = this.addItem.bind(this);
    this.moveItem = this.moveItem.bind(this);
    this.deleteMenuItem = this.deleteMenuItem.bind(this);
    this.updateMealsHandler = this.updateMealsHandler.bind(this);
    this.deleteMealOfDayHandler = this.deleteMealOfDayHandler.bind(this);
  }
  componentDidMount() {
    axios
      .get("/api/menumeal")
      .then(res => {
        this.setState({
          menu: res.data.menu,
          meal: res.data.meal,
        });
      })
      .catch(error => console.log(error))
  }
  addItem(newItemPackage) {
    axios
      .post("/api/menumeal/", newItemPackage)
      .then(res => {
        this.setState({
          menu: res.data.menu,
          meal: res.data.meal,
        });
      })
      .catch(error => console.log(error))
  }
  moveItem(e) {
    const section = e.target.parentNode.id;
    const category = e.target.className;
    const item = e.target.firstChild.data;
    const destinationSection = section === "menu" ? "meal" : "menu";
    axios
      .put(`/api/menumeal/${section}/${category}/${item}/${destinationSection}`)
      .then(res => {
        this.setState({
          menu: res.data.menu,
          meal: res.data.meal
        });
      })
      .catch(error => console.log(error))
  }
  deleteMenuItem(e) {
    e.stopPropagation();
    const category = e.target.parentNode.className;
    const item = e.target.parentNode.firstChild.data;
    axios
      .delete(`/api/menumeal/${category}/${item}`)
      .then(res => {
        this.setState({
          menu: res.data.menu,
        });
      })
      .catch(error => console.log(error))
  }
  updateMealsHandler(resFromMealsSelectJs) {
    const meal = resFromMealsSelectJs.data.meal;
    const meals = resFromMealsSelectJs.data.meals;
    this.setState({
      meal: meal,
      meals: meals
    })
  }
  deleteMealOfDayHandler(responseFromMealsJs) {
    this.setState({
      meals: responseFromMealsJs.data
    })
  }
  render() {
    return (
      <>
        { document.referrer === 'https://www.esellors.com/' ? <Referrer /> : null }
        <div className="wrapper">
          <Header />
          <main>

            <Meals meals={this.state.meals} deleteMealOfDayHandler={this.deleteMealOfDayHandler} />

            <div id="menu_meal_selection">

              <Menu menu={this.state.menu} addItem={this.addItem} moveItem={this.moveItem} deleteMenuItem={this.deleteMenuItem} />

              <Meal meal={this.state.meal} moveItem={this.moveItem} updateMealsHandler={this.updateMealsHandler} />

            </div>
          </main>
          <Footer />
        </div>
      </>
    );
  }
}

export default App;
<file_sep>/src/components/RenderMeals.js
import React from 'react';

function RenderMeals(props) {
   const {mealName} = props;

   return (
      <>
         {  mealName
            ? mealName.map((item, index) => {
               return <li key={`${mealName}-${index}`}>{item}</li>
            })
            : null
         }
      </>
   );
}

export default RenderMeals;<file_sep>/server/controllers/MenuMealController.js
let menuMeal = {
   menu: { drinks: ['orange juice'], mains: ['eggs'], sides: ['hash browns'], desserts: ['cake'] },
   meal: { drinks: [], mains: [], sides: [], desserts: [] },
   meals: { breakfast: [], lunch: [], dinner: [] }
};

const addMealToMeals = (req, res) => {
   const { mealOfDay } = req.params;
   let mealOfDayDrinks = menuMeal.meal.drinks.splice(0);
   let mealOfDayMains = menuMeal.meal.mains.splice(0);
   let mealOfDaySides = menuMeal.meal.sides.splice(0);
   let mealOfDayDesserts = menuMeal.meal.desserts.splice(0);

   menuMeal.meals[mealOfDay] = [...mealOfDayDrinks, ...mealOfDayMains, ...mealOfDaySides, ...mealOfDayDesserts];

   res.json(menuMeal);
}

const deleteMealFromMeals = (req, res) => {
   const { mealOfDay } = req.params;

   menuMeal.meals[mealOfDay] = [];
   res.json(menuMeal.meals);
}

const getItems = (req, res) => {
   res.json(menuMeal);
};

const addItem = (req, res) => {
   const { category, item } = req.body;
   menuMeal.menu[category].unshift(item);
   res.json(menuMeal);
}

const moveItems = (req, res) => {
   const { section, category, item, destinationSection } = req.params;
   let index = menuMeal[section][category].findIndex(arrayItem => arrayItem === item);
   let tgtItem = menuMeal[section][category].splice(index, 1).toString();

   menuMeal[destinationSection][category].unshift(tgtItem);
   res.json(menuMeal);
}

const deleteItem = (req, res) => {
   const { category, item } = req.params;
   console.log(req.params);
   let index = menuMeal.menu[category].findIndex(arrayItem => arrayItem === item);
   menuMeal.menu[category].splice([index], 1);
   res.json(menuMeal);
};

module.exports = {
   getItems,
   addItem,
   moveItems,
   deleteItem,
   addMealToMeals,
   deleteMealFromMeals
};