skip to Main Content

In my restaurant clone project, restaurant item details are not getting wrapped inside the component. My project also uses Tailwind css, is it possible just to use it to adjust the data inside component? If its using react how can warp those inside the component?
example image

RestaurantCard.js

import { CDN_URL } from "../utils/constants";

const styleCard = {
    backgroundColor: "#f0f0f0"
 };

const RestaurantCard =(props) =>{
    const {resData} = props;
    const {cloudinaryImageId,name,cuisines,avgRating,costForTwo} = resData?.info;
    return(
       <div className="m-4 p-4 w-[300px] rounded-lg" style={styleCard}>
          <img className = "rounded-lg w-full h-[180px] object-cover" src ={CDN_URL + cloudinaryImageId}/>
          <h3 className="font-bold text-lg truncate">{name}</h3> 
          <h4>{cuisines.join(",")}</h4>
          <h4> {avgRating}</h4>
          <h4> {costForTwo}</h4>
       </div>
    )
 }

 export const withPromotedLabel = (RestuarantCard) => {
   return (props) => {
      return (
         <div>
            <label>Promoted</label>
            <RestaurantCard {...props}/>
         </div>
      )
   }
 }
 export default RestaurantCard;

Body.js

import RestaurantCard, {withPromotedLabel} from "./RestaurantCard";
import { useEffect, useState } from "react";
import Shimmer from "./Shimmer";
import { Link } from "react-router-dom";


const Body = () =>{
   const [listOfRestaurants, setListOfRestraunt] = useState([]); 
   // as soon as we call setListOfRestaurant the  react will call the diff and update the UI
   const [filteredRestuarant, setfilteredRestuarant] = useState([]);
   const [searchText, setsearchText] = useState("");
   
   const RestaurantCardPromoted = withPromotedLabel(RestuarantCard);
   
   
   useEffect(() => {      //react Hook
      fetchData();
    }, []);

    const fetchData = async () =>
    {
      const data = await fetch(
        "https://thingproxy.freeboard.io/fetch/https://www.swiggy.com/dapi/restaurants/list/v5?lat=12.9352403&lng=77.624532&is-seo-homepage-enabled=true&page_type=DESKTOP_WEB_LISTING" 
      );
      const json = await data.json();
      console.log(json);
      /*const restaurants = json?.data?.cards[1]?.card?.card?.gridElements?.infoWithStyle?.restaurants || [];
      setListOfRestraunt(restaurants); // Keep the full list here 
      setfilteredRestuarant(restaurants); */
      setListOfRestraunt(json?.data?.cards[1]?.card?.card?.gridElements?.infoWithStyle?.restaurants); 
      setfilteredRestuarant(json?.data?.cards[1]?.card?.card?.gridElements?.infoWithStyle?.restaurants); 
     };
   //conditional Rendering
   if(listOfRestaurants.length === 0){
      return <Shimmer />;
   }
   
   
   return(
       <div className="body">
          <div className="filter flex items-center">
          

          <input type="text" className="border border-solid border-black px-3 py-1 ml-5" value ={searchText} onChange={(e) => {setsearchText(e.target.value);}}/>
         
          <button className="search-container  px-4 py-2 bg-green-100 ml-3 rounded-lg" onClick={() => {
               console.log(searchText);
             const filteredRestuarant =  listOfRestaurants.filter((res) => res.info.name.toLowerCase().includes(searchText.toLowerCase()));
         
             setfilteredRestuarant(filteredRestuarant);
            }}>Search</button>
       
          

      
            <div className="search m-3 p-3 items-center">
            <button className="px-5 py-4 bg-grey-500 rounded-lg" 
            onClick={() => {
               const filteredList = listOfRestaurants.filter
               ((res) => res.info.avgRating > 4.3);
               setListOfRestraunt(filteredList);
            }} >Top Rated Restuarant</button>
            </div>
           
            </div>
            <div className="flex flex-wrap">
          { filteredRestuarant.map(restaurant => (
            <Link to = {"/restauarants/" + restaurant.info.id} >{
              restaurant.info.promoted ? (<RestaurantCardPromoted resData={restaurant}/>) : (<RestuarantCard key={restaurant.info.id} resData={restaurant}/>)
            }
               
               </Link> ))//We have looped using map function, also each of item should have unique key(property)
         //The resList is an array of objects, where each object contains a key info, and inside info, there is another key id. Therefore, to access the id field, you need to drill into the info object within each resList item 
          }

 
             </div>  
           
 
             </div>
    )
 }
export default Body; 

RestaurantMenu.js

import useRestaurantMenu from "../utils/useRestaurantMenu";
import Shimmer from "./Shimmer";
import { useParams } from "react-router-dom";



const RestaurantMenu = () => {
    const { resid } = useParams();
    const resInfo = useRestaurantMenu(resid);


    if ( resInfo === null) return <Shimmer />;

 
    const { name, cuisines, costForTwoMessage } = resInfo?.cards[2]?.card?.card?.info;
    const { itemCards } = resInfo?.cards[4]?.groupedCard?.cardGroupMap?.REGULAR?.cards[2]?.card?.card;
    console.log(itemCards);
   return (<div className="Menu">
             <h1>{name}</h1>
             <h2>{cuisines?.join(", ")} - {costForTwoMessage}</h2>
    
            <h2>Menu</h2>
            <ul>   
                {itemCards?.map((item) => (<li  key = {item.card.info.id}>{item?.card?.info?.name} : {item?.card?.info?.price} </li> //map function, dynamically fetch
            ))}
         
            
            </ul>

            
        </div>
    );
};

export default RestaurantMenu;

How can wrap the text inside my restaurant component? Please help

2

Answers


  1. use "whitespace-normal overflow-hidden text-ellipsis" class for the cuisines list h4 tag

    so that text will not overflow from the card

    Login or Signup to reply.
  2. You can try Tailwind CSS like this:

    import { CDN_URL } from "../utils/constants";
    
    const styleCard = {
      backgroundColor: "#f0f0f0"
    };
    
    const RestaurantCard = (props) => {
      const { resData } = props;
      const { cloudinaryImageId, name, cuisines, avgRating, costForTwo } = resData?.info;
      return (
        <div className="m-4 p-4 w-[300px] rounded-lg" style={styleCard}>
          <img className="rounded-lg w-full h-[180px] object-cover" src={CDN_URL + cloudinaryImageId} />
          <h3 className="font-bold text-lg break-words">{name}</h3> 
          <h4 className="break-words">{cuisines.join(",")}</h4>
          <h4> {avgRating}</h4>
          <h4> {costForTwo}</h4>
        </div>
      );
    };
    
    export const withPromotedLabel = (RestaurantCard) => {
      return (props) => {
        return (
          <div>
            <label className="block text-sm font-medium text-gray-700">Promoted</label>
            <RestaurantCard {...props} />
          </div>
        );
      };
    };
    export default RestaurantCard;
    

    Explanation:

    1. Class break-words: This ensures that long words will break to the next line, preventing overflow.
    2. Component Update: Include break-words class for the text elements to ensure proper wrapping.

    Hope this helps!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search