source: my-react-app/src/components/ReservationConfirmation.js@ deea3c4

main
Last change on this file since deea3c4 was f5b256e, checked in by Aleksandar Panovski <apano77@…>, 3 weeks ago

Big change done works with handle_reservation_update() trigger

  • Property mode set to 100644
File size: 7.5 KB
Line 
1import React, { useState, useEffect } from 'react';
2import { useParams } from 'react-router-dom';
3import axios from 'axios';
4import { useNavigate } from 'react-router-dom';
5import {jwtDecode} from "jwt-decode";
6import {request} from "../axios_helper";
7import restaurants from "./Restaurants";
8
9const ReservationConfirmation = () => {
10 const navigate = useNavigate();
11
12 const [restaurant, setRestaurant] = useState({});
13 const [user, setUser] = useState({});
14 const [table, setTable] = useState({});
15 const [reservationDateTime, setReservationDateTime] = useState('');
16 const [partySize, setPartySize] = useState('');
17 const [specialRequests, setSpecialRequests] = useState('');
18 const { tableNumber, timeSlot, restaurantId } = useParams();
19
20 const adjustedTimeSlot = new Date(new Date(timeSlot).getTime() + 60 * 60 * 1000).toISOString();
21 useEffect(() => {
22 const fetchDetails = async () => {
23 try {
24 const tableResponse = await axios.get(`http://localhost:8081/api/tables/${tableNumber}`);
25 setTable(tableResponse.data);
26
27 const restaurantResponse = await axios.get(`http://localhost:8081/api/restaurants/${restaurantId}`);
28 setRestaurant(restaurantResponse.data);
29
30 const token = localStorage.getItem("token");
31 if (!token) {
32 console.error("No token found");
33 return;
34 }
35 const decodedToken = jwtDecode(token);
36 const userId = decodedToken.iss;
37
38 const userResponse = await axios.get(`http://localhost:8081/api/user/${userId}`);
39 setUser(userResponse.data);
40 } catch (error) {
41 console.error('Error fetching table or restaurant details:', error);
42 }
43 };
44 fetchDetails();
45 }, [tableNumber, restaurantId]);
46
47 const handleSubmit = async (e) => {
48 e.preventDefault();
49
50 const payload = {
51 reservationID: 0,
52 userEmail: user.email,
53 rating: parseFloat(restaurant.rating) || null,
54 tableNumber: parseInt(table.id, 10),
55 restaurant: restaurant,
56 reservationDateTime: adjustedTimeSlot,
57 partySize: parseInt(partySize, 10),
58 status: 'Reserved',
59 specialRequests: specialRequests.trim(),
60 paymentStatus: 'Pending',
61 };
62
63
64 try {
65 const response = await axios.post('http://localhost:8081/api/reservations', payload);
66 console.log('Reservation created successfully:', response.data);
67 navigate("/reservations")
68 } catch (error) {
69 if (error.response) {
70 alert('The selected time slot is no longer available. Please choose another time.');
71 } else {
72 alert('Network error. Please check your internet connection.');
73 }
74 }
75 };
76
77 const calculateCheckOutTime = (checkInTime) => {
78 const checkIn = new Date(checkInTime);
79 checkIn.setHours(checkIn.getHours() + 2);
80 return checkIn.toISOString();
81 };
82
83 const initialRemainingTime = localStorage.getItem('remainingTime') || 300;
84 const [remainingTime, setRemainingTime] = useState(parseInt(initialRemainingTime, 10));
85
86 useEffect(() => {
87 const timer = setInterval(() => {
88 setRemainingTime((prevTime) => {
89 const newTime = prevTime - 1;
90 localStorage.setItem('remainingTime', newTime.toString());
91 return newTime;
92 });
93 }, 1000);
94
95 return () => clearInterval(timer);
96 }, []);
97
98 useEffect(() => {
99 if (remainingTime <= 0) {
100 localStorage.removeItem('remainingTime');
101 alert("Time has expired. Please try reserving again.");
102 navigate('/restaurants'); // Redirect or take necessary action
103 }
104 }, [remainingTime, navigate]);
105
106 const formatTime = (timeInSeconds) => {
107 const minutes = Math.floor(timeInSeconds / 60);
108 const seconds = timeInSeconds % 60;
109 return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
110 };
111
112 const formatTimeSlot = (timeSlot) => {
113 const utcDate = new Date(timeSlot);
114 const localDate = new Date(utcDate.toLocaleString("en-US", { timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone }));
115 const formattedDate = localDate.toLocaleDateString();
116 const formattedTime = localDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
117 return `${formattedDate} - ${formattedTime}`;
118 };
119
120 return (
121 <div className="container mt-5">
122 <div className="row justify-content-center">
123 <div className="col-md-6">
124 <div className="card">
125 <div className="card-header">
126 <h3 className="text-center">Reservation Confirmation</h3>
127 <p>Remaining Time: {formatTime(remainingTime)}</p>
128 </div>
129 <form onSubmit={handleSubmit}>
130 <div className="card-body">
131 <h5 className="card-title">Reservation Details</h5>
132 <p className="card-text">
133 <strong>Restaurant:</strong> {restaurant.name || 'Loading...'} <br />
134 <strong>Cuisine type:</strong> {restaurant.cuisineType || 'Loading...'} <br />
135 <strong>Selected Time Slot:</strong> {formatTimeSlot(timeSlot)} <br />
136 <strong>Party size:</strong>{' '}
137 <input
138 type="number"
139 max={table.capacity}
140 value={partySize}
141 onChange={(e) => setPartySize(e.target.value)}
142 />
143 <strong>Table size:</strong> {table.capacity} <br />
144 <strong>Special Requests:</strong>{' '}
145 <input
146 type="text"
147 value={specialRequests}
148 onChange={(e) => setSpecialRequests(e.target.value)}
149 />
150 <br />
151 </p>
152 <p className="card-text text-success">
153 <strong>
154 Check-in Time: Grace period of 15 minutes +/- the slot. For more information, call the restaurant.
155 </strong>
156 <br />
157 </p>
158 </div>
159 <div className="card-footer">
160 <button type="submit" className="btn btn-primary">Submit</button>
161 <a href="/restaurants" className="btn btn-secondary mx-2">Back to Restaurants</a>
162 <a href="/" className="btn btn-secondary">Back to Home</a>
163 </div>
164 </form>
165 </div>
166 </div>
167 </div>
168 </div>
169 );
170};
171
172export default ReservationConfirmation;
Note: See TracBrowser for help on using the repository browser.