source: my-react-app/src/components/ReservationEdit.js@ e15e8d9

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

menu feature done

  • Property mode set to 100644
File size: 10.8 KB
Line 
1import React, { useState, useEffect } from 'react';
2import axios from 'axios';
3import {useNavigate, useParams} from 'react-router-dom';
4import StarRating from "./StarRating";
5import {jwtDecode} from "jwt-decode";
6
7const ReservationEdit = () => {
8 const navigate = useNavigate();
9 const { reservationId } = useParams();
10 const [isLoading, setIsLoading] = useState(true);
11 const [formData, setFormData] = useState({});
12 const [tableNumber, setTableNumber] = useState({});
13 const [table, setTable] = useState({});
14 const [restaurant, setRestaurant] = useState({});
15 const [restaurantId, setRestaurantId] = useState({});
16 const [timeSlots, setTimeSlots] = useState([]);
17 const [filteredTimeSlots, setFilteredTimeSlots] = useState([]);
18 const [checkInTime, setCheckInTime] = useState([]);
19 const [tableReservations, setTableReservations] = useState([]);
20
21 const timeSlotInterval = 15;
22
23 const [selectedDate, setSelectedDate] = useState('');
24 const [selectedTime, setSelectedTime] = useState('');
25 const [timeOptions, setTimeOptions] = useState([]);
26
27 useEffect(() => {
28 const fetchReservation = async () => {
29 try {
30 setIsLoading(true);
31 const response = await axios.get(`http://localhost:8081/api/reservations/${reservationId}`);
32 console.log(response)
33 setCheckInTime(response.data.reservationDateTime);
34 setFormData(response.data);
35 setRestaurant(response.data.restaurantName);
36 setRestaurantId(response.data.restaurantId);
37
38 setTableNumber(response.data.tableNumber);
39 const tableResponse = await axios.get(`http://localhost:8081/api/tables/${response.data.tableNumber}`);
40 setTable(tableResponse.data)
41
42 setIsLoading(false);
43 } catch (error) {
44 console.error('Error fetching reservation:', error);
45 }
46 };
47
48 fetchReservation();
49 }, [reservationId]);
50
51 useEffect(() => {
52 const fetchTableReservations = async () => {
53 try {
54 const response = await axios.get(`http://localhost:8081/api/table-reservations/${table.tableId}`);
55 setTableReservations(response.data);
56 setIsLoading(false);
57 } catch (error) {
58 console.error('Error fetching table reservations:', error);
59 }
60 };
61
62 if (table?.tableId) {
63 fetchTableReservations();
64 }
65 }, [table]);
66
67 const generateTimeOptions = (operatingHours) => {
68 const now = new Date();
69 const selectedDateObj = new Date(selectedDate);
70
71 const { startTime, endTime } = parseOperatingHours(operatingHours, selectedDateObj);
72
73 const isToday = selectedDateObj.toDateString() === now.toDateString();
74
75 let currentTime;
76
77 if (isToday) {
78 const roundedNow = roundToNext15Minutes(now);
79
80 if (roundedNow < startTime) {
81 currentTime = startTime;
82 } else if (roundedNow > endTime) {
83 return [];
84 } else {
85 currentTime = roundedNow;
86 }
87 } else {
88 currentTime = startTime;
89 }
90
91 const options = [];
92 while (currentTime <= endTime) {
93 options.push(currentTime.toTimeString().slice(0, 5));
94 currentTime = new Date(currentTime.getTime() + 15 * 60 * 1000);
95 }
96
97 return options;
98 };
99
100 const roundToNext15Minutes = (date) => {
101 const ms = 1000 * 60 * 15;
102 return new Date(Math.ceil(date.getTime() / ms) * ms);
103 };
104
105 useEffect(() => {
106 if (table?.restaurant?.operatingHours && selectedDate) {
107 const options = generateTimeOptions(table.restaurant.operatingHours);
108 setTimeOptions(options);
109 }
110 }, [table, selectedDate]);
111
112
113 const handleInputChange = (e) => {
114 const { name, value } = e.target;
115
116 if (name === 'partySize') {
117 const valueAsNumber = Math.min(value, table?.capacity);
118 setFormData(prevState => ({
119 ...prevState,
120 [name]: valueAsNumber
121 }));
122 } else {
123 setFormData(prevState => ({
124 ...prevState,
125 [name]: value
126 }));
127 }
128 };
129
130
131 const handleSubmit = async (e) => {
132 e.preventDefault();
133
134 try {
135 const token = localStorage.getItem("token");
136 if (!token) {
137 console.error("No token found");
138 return;
139 }
140
141 const decodedToken = jwtDecode(token);
142 const userId = decodedToken.iss;
143
144 const updatedReservationData = {
145 ...formData,
146 reservationDateTime: `${selectedDate}T${selectedTime}`,
147 checkInTime: checkInTime,
148 reservationID: reservationId,
149 };
150 await axios.post(
151 `http://localhost:8081/api/reservations/${reservationId}/${userId}`,
152 updatedReservationData,
153 {
154 headers: {
155 'Content-Type': 'application/json',
156 }
157 }
158 );
159 console.log(updatedReservationData)
160
161 navigate(`/reservations`);
162 } catch (error) {
163 console.error('Error updating reservation:', error);
164 }
165 };
166
167 const formatTimeSlot = (timeSlot) => {
168 const date = new Date(timeSlot);
169 const formattedDate = date.toLocaleDateString();
170 const formattedTime = date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
171 return `${formattedDate} - ${formattedTime}`;
172 };
173
174 const today = new Date();
175 const year = today.getFullYear();
176 const month = String(today.getMonth() + 1).padStart(2, '0');
177 const day = String(today.getDate()).padStart(2, '0');
178 const formattedDate = `${year}-${month}-${day}`;
179
180 const parseOperatingHours = (operatingHours, forDate) => {
181 const [start, end] = operatingHours.split('-');
182
183 const [startHour, startMinute] = start.split(':').map(Number);
184 const [endHour, endMinute] = end.split(':').map(Number);
185
186 const startTime = new Date(forDate);
187 startTime.setHours(startHour, startMinute, 0, 0);
188
189 const endTime = new Date(forDate);
190 endTime.setHours(endHour, endMinute, 0, 0);
191
192 return { startTime, endTime };
193 };
194
195 useEffect(() => {
196 if (formData?.restaurant?.operatingHours && selectedDate) {
197 const options = generateTimeOptions(formData.restaurant.operatingHours);
198 setTimeOptions(options);
199 }
200 }, [restaurant, selectedDate]);
201
202 // useEffect(() => {
203 // if (checkInTime) {
204 // const checkInDateObj = new Date(checkInTime);
205 // setSelectedDate(checkInDateObj.toISOString().split("T")[0]);
206 // setSelectedTime(checkInDateObj.toTimeString().slice(0, 5));
207 // }
208 // }, [checkInTime]);
209
210 return (
211 <div className="container">
212 {isLoading ? (
213 <p>Loading...</p>
214 ) : (
215 <>
216 <h1>Edit Reservation</h1>
217 <div className="card-body">
218 <h2 className="card-title">
219 {formData.restaurant.name} <StarRating key={formData.restaurant.id} rating={formData.restaurant.rating} />
220 </h2>
221 <p className="card-text">{formData.restaurant.name}</p>
222 <p className="card-text">{formData.restaurant.operatingHours}</p>
223 <p className="card-text">Ul. {formData.restaurant.address}</p>
224 <br />
225 </div>
226 <form onSubmit={handleSubmit}>
227 <div className="mb-3">
228 <label>Select Date:</label>
229 <input
230 type="date"
231 className="form-control mt-2"
232 onChange={(event) => setSelectedDate(event.target.value)}
233 value={selectedDate}
234 min={formattedDate}
235 />
236
237 <label>Select Time:</label>
238 <select
239 className="form-select mt-2"
240 onChange={(event) => setSelectedTime(event.target.value)}
241 value={selectedTime}
242 disabled={!selectedDate}
243 >
244 <option value="">Select Time</option>
245 {timeOptions.map((time, index) => (
246 <option key={index} value={time}>
247 {time}
248 </option>
249 ))}
250 </select>
251 <label className="text-danger">
252 Current check-in time: {formatTimeSlot(checkInTime)}
253 </label>
254 </div>
255 <div className="mb-3">
256 <label htmlFor="partySize" className="form-label">Party Size</label>
257 <input
258 type="number"
259 className="form-control"
260 id="partySize"
261 name="partySize"
262 max={table?.capacity}
263 min={1}
264 value={formData.partySize || ''}
265 onChange={handleInputChange}
266 />
267 <label className="text-danger">
268 Table capacity: {table?.capacity}
269 </label>
270 </div>
271 <div className="mb-3">
272 <label htmlFor="specialRequests" className="form-label">Special Requests</label>
273 <input
274 type="text"
275 className="form-control"
276 id="specialRequests"
277 name="specialRequests"
278 value={formData.specialRequests || ''}
279 onChange={handleInputChange}
280 />
281 </div>
282 <button type="submit" className="btn btn-primary">Submit</button>
283 </form>
284 </>
285 )}
286 </div>
287 );
288};
289
290export default ReservationEdit;
Note: See TracBrowser for help on using the repository browser.