The Booking Form
The seat picker has its form now, under the summary: the Name and Email fields and the Book button, turned into JSX (where for has become htmlFor and novalidate noValidate). Bring it to life as in the Forms lesson: the fields are controlled, with the states name and email, and the form calls handleSubmit, which starts with event.preventDefault().
Checking. Then handleSubmit checks the form, one thing after another, as in the exercise Error Messages: an empty name, an email without @, no seat selected. The first problem goes into the state error, which the form shows, and return ends the handler, so nothing is booked. The visitor fixes it and clicks Book again. The old page showed all three messages at once. This way, there's one message, under the button, and the code is shorter.
Booking. When everything's right, the picker makes a ticket: an object with an id from Date.now(), the showtime, the seats, the name and the email. But where does it go? The tickets are needed by the picker, to show the booked seats as taken, and by the list Your tickets in Showtimes. So they're state of Showtimes, tickets, and the picker gets them in its props, with a function that adds one, as the form for your own words did in the Final Project of the React course:
onBook({
id: Date.now(),
showtime: showtime,
seats: selected,
name: name.trim(),
email: email.trim(),
});A ticket keeps the whole showtime, so that the list can show its day, time and film. Then the picker empties selected and both fields. The booked seats are taken from now on: isTaken() also checks with some() whether one of the tickets for this showtime has the seat, as the old script did:
return tickets.some(
(ticket) =>
ticket.showtime.id === showtime.id && ticket.seats.includes(seat),
);Finally, the picker says which seats were booked, Booked! Your seats: A3, A4, in one more state, confirmation. Its text can come from selected even after setSelected([]): as you know from the State lesson, the new value only comes with the next render.
Instructions
- 1
In
SeatPicker, add the statesname,emailanderror, all""at first, and make both fields controlled. Give the formonSubmit={handleSubmit}.handleSubmit(event)callsevent.preventDefault(), and then it setserrorand returns when the name is empty (name.trim() === ""):Enter your name., when the email has no@:Enter a valid email address., and when no seat is selected:Choose at least one seat.Show the error under the button in<p className="mt-4 text-sm text-red-700">when there is one. Click Book with empty fields. - 2
In
Showtimes, add the statetickets, an empty array, and the handlerhandleBook(ticket), which adds the ticket to the end oftickets. Give the picker the propstickets={tickets}andonBook={handleBook}. InSeatPicker, when everything's right, seterrorback to"", callonBook()as above, and emptyselectedand both fields. LetisTaken()check the tickets too, as above. Book a seat: it turns gray. - 3
After booking, put
Booked! Your seats: A3, A4into the new stateconfirmation, with the seats fromselected.join(", "), and show it under the form in<p className="mt-4 font-semibold text-green-700">. In the list Your tickets (its section with the heading is ready inShowtimes), show anlifor each ticket, with its key, the classesrounded-lg border border-stone-200 bg-white px-4 py-2and the textFriday 5:30 pm, Robots on Vacation: A3, A4, fromticket.showtimeandticket.seats.join(", ").