I am building an app where I have different seats that the user can book, and the logic is that when you click on one seat, the modal shows up, and you click on confirm, then you will be redirected to another screen that shows that seat is incremented by one. What I need is that when I click on a single seat, it should display the name of that seat (for example, "you have selected seat 1"), and when I click confirm, it should only increment the number of that seat on another screen. The help I need is in figuring out how I can render a specific title on the modal and how I can fire different functions that increment the number of each item so I can avoid repeating the code in several components. Thank you in advance. Here is my code:
Seat.jsx:
import React, { useEffect, useState } from "react";
import "./zones.css";
import { RxCross2 } from "react-icons/rx";
import {
addSeat_1,
add_2,
addSeat_3,
addSeat_4,
addSeat_5,
} from "../../../features/trolleys/trolleySlice";
import { useDispatch } from "react-redux";
import { Link } from "react-router-dom";
const Seats = () => {
const [show, setShow] = useState(false);
const [title, setTitle] = useState({
data: [
{
value: "Seat 1",
id: 1,
},
{
value: "Seat 2",
id: 2,
},
{
value: "Seat 3",
id: 3,
},
{
value: "Seat 4",
id: 4,
},
{
value: "Seat 5",
id: 5,
},
],
});
const toggleTitle = () => {
setTitle(title.data.map((item) => item.value === item.id && item.value));
};
const dispatch = useDispatch();
useEffect(() => {
document.title = "Zones";
});
return (
<div className="seat__container">
<div onClick={() => setShow(true)} className="seat seat__fresh">
<img src="/assets/freshGoods.png" alt="fresh" />
<p className="seat__text">Seat 1</p>
</div>
<div onClick={() => setShow(true)} className="seat seat__fruits">
<img src="/assets/fruit_veg.png" alt="dry/good" />
<p className="seat__text">Seat 2</p>
</div>
<div onClick={() => setShow(true)} className="seat seat__deli">
<img src="/assets/deli.png" alt="dry/good" />
<p className="seat__text">Seat 3</p>
</div>
<div onClick={() => setShow(true)} className="seat seat__frozen">
<img src="/assets/frozen.png" alt="dry/good" />
<p className="seat__frozen">Seat 4</p>
</div>
<div onClick={() => setShow(true)} className="seat seat__WindSpritz">
<img src="/assets/wine_spritz.png" alt="electronic" />
<p className="seat__text">Seat 5</p>
</div>
<div className="seat seat__undraw">
<img
className="undraw"
src="/assets/undraw_gone_shopping_re_2lau 1.png"
alt="undraw"
/>
</div>
{show && (
<div className="modal">
<div className="inner__modal">
<RxCross2 onClick={() => setShow(false)} />
<p className="selected__text">You have selected</p>
<p onClick={toggleTitle} className="item__name">
{/*a specific name for a seat about should be displayed here*/}
</p>
{title.data.map((item) =>(
<Link
onClick={() => {
item.value==="seat 1"&&dispatch(addSeat_1())
item.value==="seat 1"&&dispatch(addSeat_2())
item.value==="seat 1"&&dispatch(addSeat_3())
item.value==="seat 1"&&dispatch(addSeat_4())
item.value==="seat 1"&&dispatch(addSeat_5())
}}
to="/room"
className="confirm__btn"
>
Confirm
</Link>
))}
<button onClick={() => setShow(false)} className="cancel__btn">
Cancel
</button>
</div>
</div>
)}
</div>
);
};
export default Seats;
Room.jsx:
import "./room.css";
import { GiCancel } from "react-icons/gi";
import { useEffect } from "react";
import { useSelector } from "react-redux";
const Room = () => {
const roomQty = useSelector((state) => state.room);
useEffect(() => {
document.title = "Room";
});
return (
<div className="room__container">
<div className="room__list">
<div className="room__item__box room__item__box__fresh">
<div className="left__items">
<div className="image__box">
<img src="/assets/seat1s.png" alt="img" />
</div>
<p className="room__text">Seat1</p>
</div>
<div className="right__items">
<span className="item__count">{roomQty.seat1Qty}</span>
<div className="button__items">
<GiCancel className="cancel" />
<button className="cancel">Cancel</button>
</div>
</div>
</div>
<div className="room__item__box room__item__box__fruit-veg">
<div className="left__items">
<div className="image__box">
<img src="/assets/seat2.png" alt="img" />
</div>
<p className="room__text">Seat2</p>
</div>
<div className="right__items">
<span className="item__count">{roomQty.seat2Qty}</span>
<div className="button__items">
<GiCancel className="cancel" />
<button className="cancel">Cancel</button>
</div>
</div>
</div>
<div className="room__item__box">
<div className="left__items">
<div className="image__box">
<img src="/assets/seat3.png" alt="img" />
</div>
<p className="room__text">Seat3</p>
</div>
<div className="right__items">
<span className="item__count">{roomQty.seat3Qty}</span>
<div className="button__items">
<GiCancel className="cancel" />
<button className="cancel">Cancel</button>
</div>
</div>
</div>
<div className="room__item__box room__item__box__frozen">
<div className="left__items">
<div className="image__box">
<img src="/assets/seat4.png" alt="img" />
</div>
<p className="room__text">Seat4</p>
</div>
<div className="right__items">
<span className="item__count">{roomQty.seat4Qty}</span>
<div className="button__items">
<GiCancel className="cancel" />
<button className="cancel">Cancel</button>
</div>
</div>
</div>
<div className="room__item__box room__item__box__wineSpritz">
<div className="left__items">
<div className="image__box">
<img src="/assets/seat5.png" alt="img" />
</div>
<p className="room__text">Seat5</p>
</div>
<div className="right__items">
<span className="item__count">{roomQty.seat5Qty}</span>
<div className="button__items">
<GiCancel className="cancel" />
<button className="cancel">Cancel</button>
</div>
</div>
</div>
</div>
</div>
);
};
export default Room;
There is nothing in the Seats
that associates a specific "seat" element to any specific title pr action. I'd suggest refactoring the component a bit to take a seat configuration array that is mapped to the UI, and to use a single selected seat
state is either null
(to indicate no seat is selected) or is set to a specific seat object value.
...
import {
addSeat_1,
addSeat_2,
addSeat_3,
addSeat_4,
addSeat_5,
} from "../../../features/trolleys/trolleySlice";
...
const seats = [
{
action: addSeat_1,
value: "Seat 1",
id: 1,
className: "seat__fresh",
img: {
src: "/assets/freshGoods.png",
alt: "fresh",
},
},
{
action: addSeat_2,
value: "Seat 2",
id: 2,
className: "seat__fruits",
img: {
src: "/assets/fruit_veg.png",
alt: "dry/good",
},
},
{
action: addSeat_3,
value: "Seat 3",
id: 3,
className: "seat__deli",
img: {
src: "/assets/deli.png",
alt: "dry/good",
},
},
{
action: addSeat_4,
value: "Seat 4",
id: 4,
className: "seat__frozen",
img: {
src: "/assets/frozen.png",
alt: "dry/good",
},
},
{
action: addSeat_5,
value: "Seat 5",
id: 5,
className: "seat__WindSpritz",
img: {
src: "/assets/wine_spritz.png",
alt: "electronic",
},
},
];
const Seats = () => {
const dispatch = useDispatch();
const [selectedSeat, setSelectedSeat] = useState(null);
useEffect(() => {
document.title = "Zones";
}, []);
return (
<div className="seat__container">
{seats.map((seat) => {
const { className, id, img, value } = seat;
return (
<div
key={id}
onClick={() => setSelectedSeat(seat)}
className={["seat", className].filter(Boolean).join(" ")}
>
<img {...img} />
<p className="seat__text">{label}</p>
</div>
);
})}
<div className="seat seat__undraw">
<img
className="undraw"
src="/assets/undraw_gone_shopping_re_2lau 1.png"
alt="undraw"
/>
</div>
{selectedSeat && (
<div className="modal">
<div className="inner__modal">
<RxCross2 onClick={() => setSelectedSeat(null)} />
<p className="selected__text">
You have selected
</p>
<p className="item__name">
{seat.label}
</p>
<Link
onClick={() => dispatch(selectedSeat.action())}
to="/room"
className="confirm__btn"
>
Confirm
</Link>
<button
onClick={() => setSelectedSeat(null)}
className="cancel__btn"
>
Cancel
</button>
</div>
</div>
)}
</div>
);
};