Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

MrRobot993's avatar

multiple equal components should have different states

Hi, I'm working with Inertia and React and I have a page with inside multple cards product which every one have 2 buttons and a counter for select the quantity. if pass a counter setCounter from the page to the component the count value is the same for every component but I need every component with it's own quantity. how could i do it?

` import LayoutApp from '@/Layouts/LayoutApp'; import { Head, usePage } from '@inertiajs/inertia-react'; import PageTitle from '@/Components/PageTitle'; import OrderHorizontalCard from '@/Components/OrderHorizontalCard'; import ShoppingCart from '@/Components/ShoppingCart'; import { useState } from 'react';

export default function MakeOrderPage(props) { const tableNumber = props.table_number; const menu = props.menu[0]; const dishes = props.menu[0].dishes;

const [menuOpen, setMenuOpen] = useState(false);
const [productCounter, setProductCounter] = useState(0);

return (
    <>
        <LayoutApp auth={props.auth}>
            <Head title={menu.name} />
            <PageTitle text={`Ordine tavolo: ${tableNumber}`} className={'text-center'}/>
            <div className="cards-container max-w-xs md:max-w-lg flex flex-col items-center justify-center md:py-3 space-y-9 mx-auto">
                {dishes.map(dish => {
                    return(
                        <OrderHorizontalCard key={dish.id} title={dish.name} description={dish.description} image={dish.image} price={dish.price} category={dish.dish_category.name} productCounter={productCounter} setProductCounter={setProductCounter} />
                    )
                })}
            </div>
            <ShoppingCart menuOpen={menuOpen} setMenuOpen={setMenuOpen} />
            <div className="fixed bottom-4 -left-4 text-end w-full">
                <span className="absolute right-0 -top-3 badge mb-3 bg-red-800 rounded-full px-2 py-1 text-center object-right-top text-white text-sm mr-1">{productCounter}</span>
                <button title="Concludi l'ordine" onClick={() => {setMenuOpen(!menuOpen)}} className="p-1 w-12 h-12 bg-blue-800 rounded-full hover:bg-blue-900 active:shadow-lg mouse shadow transition ease-in duration-200 focus:outline-none">
                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6 inline-block">
                    <path stroke='#fff' strokeLinecap="round" strokeLinejoin="round" d="M15.75 10.5V6a3.75 3.75 0 10-7.5 0v4.5m11.356-1.993l1.263 12c.07.665-.45 1.243-1.119 1.243H4.25a1.125 1.125 0 01-1.12-1.243l1.264-12A1.125 1.125 0 015.513 7.5h12.974c.576 0 1.059.435 1.119 1.007zM8.625 10.5a.375.375 0 11-.75 0 .375.375 0 01.75 0zm7.5 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" />
                </svg>
                </button>
            </div>
        </LayoutApp>
   </>
);

} import { useState } from 'react';

export default function OrderHorizontalCard({title, description, image, price, category, productCounter, setProductCounter}) { const [count, setCount] = useState(0);

const addProduct = () => {
    setProductCounter(productCounter => productCounter + 1);
}

const removeProduct = () => {
    if(productCounter > 0) {
        setProductCounter(productCounter => productCounter - 1);
    }
}

const dishImage = image ? '/storage/avatars/'+image : '/media/qr_order_app_default_dish_image.png';
return (
        <>
            <div className="w-full lg:flex">
                <div className="border-b border-l border-t border-grey-light h-48 lg:h-auto lg:w-48 flex-none bg-cover rounded-t lg:rounded-t-none lg:rounded-l text-center overflow-hidden" style={{backgroundImage: `url(${dishImage})`, backgroundPosition: "center"}} title={title}>
                </div>
                <div className="border-r border-b border-l border-grey-light lg:border-l-0 lg:border-t lg:border-grey-light bg-white rounded-b lg:rounded-b-none lg:rounded-r p-4 flex flex-col justify-between leading-normal">
                    <div className="mb-8">
                    <span className={`${category === 'Starters' ? "bg-green-400" : ""}${category === 'Primi' ? "bg-blue-400" : ""}${category === 'Secondi' ? "bg-red-400" : ""}${category === 'Contorni' ? "bg-yellow-400" : ""}${category === 'Dolci' ? "bg-pink-400" : ""}${category === 'Bibite' ? "bg-purple-400" : ""} text-white text-sm font-medium mr-2 px-2.5 py-0.5 rounded`}>{category}</span>
                    <div className="text-black font-bold text-xl mt-2 mb-2">{title}</div>
                    <p className="text-grey-darker text-base">{description}</p>
                    </div>
                    <div className="flex items-center justify-between font-bold">
                        <div className='flex items-center'>
                            <div>
                                <button onClick={removeProduct} type="button" className="text-white bg-red-700 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm p-2.5 text-center inline-flex items-center mx-2">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
                                        <path strokeLinecap="round" strokeLinejoin="round" d="M15 12H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z" />
                                    </svg>
                                    <span className="sr-only">Icon description</span>
                                </button>
                            </div>
                                <p className="text-black leading-none mx-2">{productCounter}</p>
                            <div>
                                <button onClick={addProduct} type="button" className="text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:outline-none focus:ring-green-300 font-medium rounded-lg text-sm p-2.5 text-center inline-flex items-center mx-2">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
                                        <path strokeLinecap="round" strokeLinejoin="round" d="M12 9v6m3-3H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z" />
                                    </svg>
                                    <span className="sr-only">Icon description</span>
                                </button>
                            </div>
                        </div>
                        <p className="text-black leading-none">€{price}</p>
                    </div>
                </div>
            </div>
        </>
)

} `

0 likes
0 replies

Please or to participate in this conversation.