<div id="app"></div>
h2{
  position:absolute;
}

.main-container{
  width:100%;
  display:flex;
  justify-content:center;

}

.flex-wrapper{
  display:flex;
  margin-left:100px;
} 

.flex-container{
  width:100%;
  display:flex;
  flex-direction:column;
  align-items:center;

}
.searchbar{
  border:solid black;
  width:250px;
  height:25px;
}

.search-results{
text-align:left;
width: 250px;
border:solid black;
margin-top:5px;

}
.search-result-item{
  margin: 0 0 8px 2px;
}
.search-result-item:hover{
  cursor:pointer;
  color:red;
}
.shopping-list{
  display:flex;
  flex-direction:column;
  margin-top:78px;
  width: 300px;
}
/*
* https://frontendeval.com/questions/shopping-list
*
* Create a shopping list app with autocomplete item entry
*/

const SearchBar=()=>{
  const[userInput,setUserInput]=React.useState(null)
  const [searchResults,setSearchResults]=React.useState(null)
  const apiBaseUrl="https://api.frontendeval.com/fake/food/"
  const [shoppingList,setShoppingList] = React.useState([])
  const [isChecked,setIsChecked]=React.useState(false)
  
  
  //render input element
  //call api upon input element change
  //

    const debounce = (func, wait) => {
  let timeout;

  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };

    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
};
  
  
  React.useEffect(()=>{
  let apiUrl = apiBaseUrl+userInput
  //debounce userInput
  if(userInput!==null || userInput!==''){
    fetch(apiUrl)
    .then(response => response.text())
    .then(data =>debounce(setSearchResults(JSON.parse(data)),500))
   }
    
  },[userInput])
  

  
  const handleInputChange=(e)=>{
    let value=e.target.value===''?null:e.target.value
    setUserInput(value)
  }
  
 const addItem=(item)=>{
   //set state to clicked item
   let updatedShoppingList=[...shoppingList]
   updatedShoppingList.push(item)
   setShoppingList(updatedShoppingList)
 }
 
 const removeItem=(id)=>{
  let filteredList=shoppingList.filter((itemObj)=>itemObj.id!==id)
  console.log("id",id)
  setShoppingList(filteredList)
 }
  
 const checkedHandler=(e,id)=>{
   //map through shoppingListCopy
   //if same id => update isChecked val
   let shoppingListCopy=[...shoppingList]
   let newShoppingList=shoppingListCopy.map((itemObj)=>{
     if(itemObj.id===id){
       itemObj.isChecked=e.target.checked
       return itemObj
     }
     else{
       return itemObj
     }
     
   })
   
   setShoppingList(newShoppingList)
 }
 
  return(
 <div className="flex-wrapper">
   <div className="flex-container">
    <h1>My Shopping List</h1>
    <input className="searchbar" onChange={handleInputChange}/>
    {searchResults && searchResults.length>0&&
       <div className="search-results">
      {searchResults.map((item,index)=>
     <div className="search-result-item" onClick={()=>setShoppingList(shoppingList.concat({item,id:shoppingList.length,isChecked:false}))}>{item}</div>             
     )}
      </div>
    }  
      </div>

      <div className="shopping-list">
        {shoppingList.length>0 && shoppingList.map((itemObj,index)=>
        <span className="shopping-list-item">
          <input onChange={(e)=>checkedHandler(e,itemObj.id)} type="checkbox" name={itemObj.item} id={`${itemObj.item}-${index}`}/>
          <label style={{textDecoration:itemObj.isChecked?'line-through':'none'}}  id ={`label-${itemObj.id}`} for={`${itemObj.item}-${index}`}>
            {itemObj.item}
            </label> 
          <span onClick={()=>removeItem(itemObj.id)} style={{color:'red',              marginLeft:'6px', cursor:'pointer'}}>
            X
           </span>
        </span>)}
      </div>

    </div>
  )
}


const App = () => {
  return(
    <div className="main-container">
    <SearchBar/>
      </div>
  ) 
}

ReactDOM.render(<App />, document.getElementById('app'));
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js