components/expand-recipe.js

class ExpandRecipe extends HTMLElement {
  constructor () {
    super();
    this.attachShadow({ mode: "open" }).innerHTML = `
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css" />`;

    // Create styles and root element
    const styles = document.createElement("style");
    const article = document.createElement("article");

    // Fill in styles and root element
    styles.innerHTML = `
        /** CREATE RECIPE SECTION **/

        .input-card {
            overflow-wrap: break-word
        }

        #create-recipe--input-wrapper {
            display: flex;
            flex-direction: row;
            justify-content: center;
            gap: 10px;
            padding-right: 50px;
            width: 85%;
            margin: auto;
            margin-top: 100px;
            margin-bottom: 100px;
          }
          .input-wrapper--column {
            width: 80%;
            margin: 0px auto;
          }
        
        /* Cards for all inputs */
        
        .input-card:not(#img-card) {
            margin-top: 5%;
            /*background-color: #f6f6f6;*/
            border-radius: 12px;
            font-size: 1.8vw;
            padding: 5%;
            box-shadow: 0px 4px 10px 1px rgba(0, 0, 0, 0.2);
            
        }
        
        /* Favorites icon */
        #create-recipe--input-wrapper > .favorite{
            position: absolute;
            margin-top: 2vh;
            right: 2%;
            height: 4vw;
            width: 4vw;
        }

        /* Card for display image */
        
        #img-card {
            margin-top: 20px;
            /*background-color: #f6f6f6;*/
            border-radius: 12px;
            box-shadow: 0px 4px 10px 1px rgba(0, 0, 0, 0.2);
            padding: 10%;
        }
        
        #display-image {
            width: 100%;
            margin: auto;
        }

        #nutrition-facts {
            margin: auto;
            width: 250px;
        }
        
        /* Card for ingredients */
        
        #ing-card {
            height: 100%;
            width: 100%%;
        }
        
        /* Card for steps */
        
        #step-card {
            background-color: transparent;
            box-shadow: none;
        }

        .card-label {
            font-family: var(--header-font);
            font-size: 24px;
            font-weight: 600;
          }
          
          .nut-info-label {
            font-family: var(--body-font);
            font-size: 18px;
            font-weight: 700;
          }
          
          .time-label {
            font-family: var(--body-font);
            font-size: 16px;
            font-weight: 700;
          }

        p {
            margin-bottom: 0;
            font-family: var(--body-font);
            font-size: 17px;
            font-weight: 400;
        }
        
        p.text:not(#input-name) {
            -webkit-transition: 0.5s;
            transition: 0.5s;
            outline: none;
            border-radius: 5px;
            font-size: 3vw;
        }  

        #input-name {
            font-family: var(--header-font);
            font-size: 48px;
            font-weight: 700;
        }

        ol, ul {
            margin-top: 10px;
            padding-left: 2vw;
            font-size: 20px;
        }

        ol li:not(:first-child) {
            margin-top: 15px;
        }

        ol li::marker {
            padding-right: 5px;
        }
        
        ul li:not(:first-child) {
            margin-top: 8px;
        }
        
        @media screen and (min-width: 800px) {
            #input-name {
                font-size: 40px;
            }
            .input-card:not(#img-card) {
                font-size: 20px;
            }
            p.text:not(#input-name) {
                font-size: 15px;
            }
        }

        @media screen and (max-width: 800px) {
            #create-recipe--input-wrapper {
                flex-direction: column;
                justify-content: center;
                align-items: center;
            }
            .input-card {
                width: 120%;
            }
            #input-name {
                font-size: 7vw;
            }
            ol, ul {
                font-size: 3vw;
            }
            #create-recipe--input-wrapper > .favorite{
                right: 1%;
                top: 23%;
                height: 7vw;
                width: 7vw;
            }
        }

        @media screen and (max-width: 425px) {
            #create-recipe--input-wrapper > .favorite{
                right: 1%;
                top: 30%;
                height: 10vw;
                width: 10vw;
            }
        }
    `;
    article.innerHTML = `
    <div id="create-recipe--input-wrapper">
    <!-- FIRST COLUMN -->
    <div class="input-wrapper--column">
        <div class="input-card" id="img-card">
            <img id="display-image"
            src="assets/images/add-image.png" />  
        </div>

        <!-- Name -->
        <div class="input-card">
            <p class="text" id="input-name"></p>
        </div>

        <!-- Description -->
        <div class="input-card">
            <label for="input-desc" class="card-label">Description</label><br>
            <p class="text" id="input-desc"></p>
        </div>

        <!-- Nutrition -->
        <div class= "input-card">
            <label for="nutrition-facts" class="card-label">Nutrition Information</label><br>
            <label for="input-calories" class="nut-info-label">Calories</label>
            <p id="input-calories"></p><br>
            <label for="input-carbs" class="nut-info-label">Carbohydrates(g)</label>
            <p id="input-carbs"></p><br>
            <label for="input-fat" class="nut-info-label">Fat(g)</label>
            <p id="input-fat"></p><br>
            <label for="input-protein" class="nut-info-label">Protein(g)</label>
            <p id="input-protein"></p>
        </div>

        <!-- Time -->
        <div class="input-card">
            <label for="input-time" class="card-label">Time</label><br>
            <div id="time-inputs">
                <p class="input-hours-mins" id="input-hours">
            </div>
        </div>

        <!-- Tags -->
        <div class="input-card">
            <div id="tag-wrapper">
                <label for="input-tags" class="card-label">Tags</label><br>
                <p class="text" id="input-tags1" class="tags"></p>
            </div>
            <br>
        </div>
    </div>

    <!-- SECOND COLUMN -->
    <div class="input-wrapper--column">
        <!-- Ingredients -->
        <div class="input-card" id="ing-card">
            <div id="ing-wrapper">
            <label class="card-label">Ingredients</label><br>
                <p id="ing-none"></p>
                <ul id="ing-list"></ul>
            </div>
            <br>
        </div>
    </div>

    <!-- THIRD COLUMN -->
    <div class="input-wrapper--column">
        <div class="input-card" id="step-card">
            <div id="step-wrapper">
            <label class="card-label">Steps</label><br>
                <p id="step-none"></p>
                <ol id="step-list"></ol>
            </div>
            <br><br>
        </div>
    </div>
</div>
    `;

    // Append elements to the shadow root
    this.shadowRoot.append(styles, article);
  }

  /**
   * @method data 
   *  Sets the data for the recipe that will be put inside the <recipe-expand> element.
   *  Overwrites the previously expanded recipe.
   * 
   * @param {JSON} data - JSON data
   */
  set data (data) {
    this.json = data;
    const returnBut = document.getElementById("return-btn");
    if(data.saveFrom==="Explore"){
        returnBut.classList.add("explore");
    }

    this.shadowRoot.querySelector("article").innerHTML = `
    <div id="create-recipe--input-wrapper">
        <!-- FIRST COLUMN -->
        <div class="input-wrapper--column">
            <div class="input-card" id="img-card">
                <img id="display-image"
                src="assets/images/add-image.png" />  
            </div>

            <!-- Name -->
            <div class="input-card">
                <p class="text" id="input-name"></p>
            </div>

            <!-- Description -->
            <div class="input-card">
                <label for="input-desc" class="card-label">Description</label><br>
                <p class="text" id="input-desc"></p>
            </div>

            <!-- Nutrition -->
            <div class= "input-card">
                <label for="nutrition-facts" class="card-label">Nutrition Information</label><br>
                <label for="input-calories" class="nut-info-label">Calories</label>
                <p id="input-calories"></p><br>
                <label for="input-carbs" class="nut-info-label">Carbohydrates(g)</label>
                <p id="input-carbs"></p><br>
                <label for="input-fat" class="nut-info-label">Fat(g)</label>
                <p id="input-fat"></p><br>
                <label for="input-protein" class="nut-info-label">Protein(g)</label>
                <p id="input-protein"></p>
            </div>

            <!-- Time -->
            <div class="input-card">
                <label for="input-time" class="card-label">Time</label><br>
                <div id="time-inputs">
                    <p class="text" id="input-hours">
                </div>
            </div>

            <!-- Tags -->
            <div class="input-card">
                <div id="tag-wrapper">
                    <label for="input-tags" class="card-label">Tags</label><br>
                    <p class="text" id="input-tags1" class="tags"></p>
                </div>
                <br>
            </div>
        </div>

        <!-- SECOND COLUMN -->
        <div class="input-wrapper--column">
            <!-- Ingredients -->
            <div class="input-card" id="ing-card">
                <div id="ing-wrapper">
                <label class="card-label">Ingredients</label><br>
                    <p id="ing-none"></p>
                    <ul id="ing-list"></ul>
                </div>
                <br>
            </div>
        </div>

        <!-- THIRD COLUMN -->
        <div class="input-wrapper--column">
            <div class="input-card" id="step-card">
                <div id="step-wrapper">
                <label class="card-label">Steps</label><br>
                    <p id="step-none"></p>
                    <ol id="step-list"></ol>
                </div>
                <br><br>
            </div>
        </div>
    </div>
    `;

    // Set title
    this.shadowRoot.querySelector("p.text").innerHTML = data.name;

    // Set image
    const image = this.shadowRoot.getElementById("display-image");
    image.setAttribute("src", data.thumbnail);

    // Set Favorite
    const expandView = this.shadowRoot.getElementById("create-recipe--input-wrapper");
    let storage = JSON.parse(localStorage.getItem(data.name.toLowerCase()));
    let love;
    let favoriteIcon;
    let favOnExpand;

    if(storage != null){
    //this should never be created if there is no favorite to add
        favOnExpand = document.createElement("input");
        favOnExpand.type = "image";
        favOnExpand.classList.add("favorite");

        love = storage.favorites;
    
        //again this should never be set if we don't know if it actually exists.
        favoriteIcon = love == 1 ? "assets/images/heart.png" : "assets/images/empty-heart.png";
        favOnExpand.setAttribute("src", favoriteIcon);
        expandView.appendChild(favOnExpand);
        favOnExpand.addEventListener("click", changeHeart);
    }    
    
    function changeHeart(){
      let storage = JSON.parse(localStorage.getItem(data.name.toLowerCase()));
      let imageOnCard = document.getElementById(data.name);
      const img = imageOnCard.shadowRoot.getElementById("favoriteOnCard");

      if(!love){
        favOnExpand.setAttribute("src", "assets/images/heart.png");
        img.setAttribute("src", "assets/images/heart.png");
        storage.favorites = 1;
        love = true;
      }
      else{
        favOnExpand.setAttribute("src", "assets/images/empty-heart.png");
        img.setAttribute("src", "assets/images/empty-heart.png");
        storage.favorites = 0;
        love = false;
      }
      localStorage.setItem(data.name.toLowerCase(), JSON.stringify(storage));
    }

    // Set description
    if (!data.description) {
        this.shadowRoot.getElementById("input-desc").innerHTML = "None";
    }
    else {
        this.shadowRoot.getElementById("input-desc").innerHTML = data.description;
    }

    // Calories
    if (!data.nutritionInfo.calories || data.nutritionInfo.calories < 0 ) {
        this.shadowRoot.getElementById("input-calories").innerHTML = "None";
    }
    else {
        this.shadowRoot.getElementById("input-calories").innerHTML = data.nutritionInfo.calories;
    }

    // Carbs
    if (!data.nutritionInfo.carbs || data.nutritionInfo.carbs < 0) {
        this.shadowRoot.getElementById("input-carbs").innerHTML = "None";
    }
    else {
        this.shadowRoot.getElementById("input-carbs").innerHTML = data.nutritionInfo.carbs;
    }

    // Fat
    if (!data.nutritionInfo.fat || data.nutritionInfo.fat < 0) {
        this.shadowRoot.getElementById("input-fat").innerHTML = "None";
    }
    else {
        this.shadowRoot.getElementById("input-fat").innerHTML = data.nutritionInfo.fat;
    }

    // Protein
    if (!data.nutritionInfo.protein || data.nutritionInfo.protein < 0) {
        this.shadowRoot.getElementById("input-protein").innerHTML = "None";
    }
    else {
        this.shadowRoot.getElementById("input-protein").innerHTML = data.nutritionInfo.protein;
    }

    // Set tags
    let tags = data.tags;
    if (tags.length === 0) {
        tags.push("None");
    }
    else {
        tags = tags.join(", ");
    }
    this.shadowRoot.getElementById("input-tags1").innerHTML = tags;

    // Detect if time or minute needs to be plural or not
    let time = "";
    if (!data.time.hours && !data.time.minutes) {
        time += `None`;
    } else {
        // Hours
        if (data.time.hours === "1") {
            time += `${data.time.hours} hour `;
        } else if (!data.time.hours) {

        } else {
            time += `${data.time.hours} hours `;
        }
        // Minutes
        if (data.time.minutes === "1") {
            time += `${data.time.minutes} minute`;
        } else if (!data.time.minutes) {

        } else {
            time += `${data.time.minutes} minutes`;
        }
    }

    // Set time
    this.shadowRoot.getElementById("input-hours").innerHTML = time;

    // Set ingredients
    const ingredients = data.ingredients;
    if (ingredients.length === 0) {
        this.shadowRoot.getElementById("ing-none").innerHTML = "None";
    } else {
        ingredients.forEach(ingredient => {
            const item = document.createElement("li");
            item.innerHTML = ingredient;
            this.shadowRoot.getElementById("ing-list").append(item);
        });
    }
    
    // Set directions
    const directions = data.directions;
    if (directions.length === 0) {
        this.shadowRoot.getElementById("step-none").innerHTML = "None";
    } else {
        directions.forEach(step => {
            const item = document.createElement("li");
            item.innerHTML = step;
            this.shadowRoot.getElementById("step-list").append(item);
        });
    }
  }
}

customElements.define("recipe-expand", ExpandRecipe);