source: my-react-app/src/components/RestaurantDetails.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 { useNavigate } from 'react-router-dom';
3import axios from 'axios';
4import 'bootstrap/dist/css/bootstrap.min.css';
5import { useParams } from 'react-router-dom';
6import StarRating from "./StarRating";
7
8
9const RestaurantDetails = () => {
10 const navigate = useNavigate();
11 const { id } = useParams();
12
13 const [restaurant, setRestaurant] = useState(null);
14 const [selectedTableId, setSelectedTableId] = useState('');
15 const [selectedDate, setSelectedDate] = useState('');
16 const [selectedTime, setSelectedTime] = useState('');
17 const [timeOptions, setTimeOptions] = useState([]);
18 const [selectedTable, setSelectedTable] = useState(null);
19
20 useEffect(() => {
21 const fetchRestaurantDetails = async () => {
22 try {
23 if (!id) return;
24 const response = await axios.get(`http://localhost:8081/api/restaurants/${id}`);
25 setRestaurant(response.data);
26 } catch (error) {
27 console.error('Error fetching restaurant details:', error);
28 }
29 };
30
31 fetchRestaurantDetails();
32 }, [id]);
33
34 useEffect(() => {
35 if (!selectedTableId) return;
36
37 const fetchTableDetails = async () => {
38 try {
39 const response = await axios.get(`http://localhost:8081/api/tables/${selectedTableId}`);
40 setSelectedTable(response.data);
41 } catch (error) {
42 console.error('Error fetching table details:', error);
43 }
44 };
45
46 fetchTableDetails();
47 }, [selectedTableId]);
48
49 const today = new Date();
50 const year = today.getFullYear();
51 const month = String(today.getMonth() + 1).padStart(2, '0');
52 const day = String(today.getDate()).padStart(2, '0');
53 const formattedDate = `${year}-${month}-${day}`;
54 const parseOperatingHours = (operatingHours) => {
55 const [start, end] = operatingHours.split('-');
56 const [startHour, startMinute] = start.split(':').map(Number);
57 const [endHour, endMinute] = end.split(':').map(Number);
58
59 const startTime = new Date();
60 startTime.setHours(startHour, startMinute, 0, 0);
61
62 const endTime = new Date();
63 endTime.setHours(endHour < startHour ? endHour + 24 : endHour, endMinute, 0, 0);
64
65 return { startTime, endTime };
66 };
67
68 const generateTimeOptions = (operatingHours) => {
69 const { startTime, endTime } = parseOperatingHours(operatingHours);
70 const now = new Date();
71
72 const selectedDateObj = new Date(selectedDate);
73 const isToday = selectedDateObj.toDateString() === now.toDateString();
74
75 let currentTime = isToday ? roundToNext15Minutes(new Date()) : new Date(startTime);
76
77 const options = [];
78 while (currentTime <= endTime) {
79 options.push(currentTime.toTimeString().slice(0, 5));
80 currentTime = new Date(currentTime.getTime() + 15 * 60 * 1000);
81 }
82
83 return options;
84 };
85
86 useEffect(() => {
87 if (restaurant && selectedDate) {
88 const options = generateTimeOptions(restaurant.operatingHours);
89 setTimeOptions(options);
90 }
91 }, [restaurant, selectedDate]);
92
93 const handleTableSelect = (event) => {
94 setSelectedTableId(event.target.value);
95 };
96
97 const handleReservationConfirmation = () => {
98 const encodedTableId = encodeURIComponent(selectedTableId);
99 const encodedDateTime = encodeURIComponent(`${selectedDate}T${selectedTime}`);
100 const encodedRestaurantId = encodeURIComponent(restaurant.restaurantId);
101
102 navigate(`/reservationConfirmation/${encodedTableId}/${encodedDateTime}/${encodedRestaurantId}`);
103 };
104
105 const roundToNext15Minutes = (date) => {
106 const minutes = date.getMinutes();
107 const remainder = minutes % 15;
108 if (remainder === 0) return date;
109
110 date.setMinutes(minutes + 15 - remainder);
111 date.setSeconds(0, 0);
112 return date;
113 };
114
115 return (
116 <div className="container">
117 {restaurant && (
118 <>
119 <h2 className="card-title">
120 {restaurant.name} <StarRating key={restaurant.id} rating={restaurant.rating} />
121 </h2>
122 <div className="restaurant-details">
123 <p>Operating hours: {restaurant.operatingHours}</p>
124 <p>Cuisine: {restaurant.cuisineType}</p>
125 <p>Address: {restaurant.address}</p>
126 <p>Phone: {restaurant.phone}</p>
127 <p>
128 Website: <a href={restaurant.website}>{restaurant.website}</a>
129 </p>
130 <p>Social Media Links: {restaurant.socialMediaLinks}</p>
131
132 <label>Select Table:</label>
133 <select
134 className="form-select"
135 aria-label="Select Table"
136 onChange={handleTableSelect}
137 value={selectedTableId}
138 >
139 <option value="">Select Table</option>
140 {restaurant.tablesList.map((table) => (
141 <option key={table.id} value={table.id}>
142 {`Capacity: ${table.capacity} - ${table.location}`}
143 </option>
144 ))}
145 </select>
146
147 {selectedTable && (
148 <>
149 <label>Select Date:</label>
150 <input
151 type="date"
152 className="form-control mt-2"
153 onChange={(event) => setSelectedDate(event.target.value)}
154 value={selectedDate}
155 min={formattedDate}
156 onKeyDown={(e) => e.preventDefault()}
157 />
158 {!selectedDate && <p style={{ color: "red" }}>Please select a valid date.</p>}
159
160 <label>Select Time:</label>
161 <select
162 className="form-select mt-2"
163 onChange={(event) => setSelectedTime(event.target.value)}
164 value={selectedTime}
165 disabled={!selectedDate}
166 >
167 <option value="">Select Time</option>
168 {timeOptions.map((time, index) => (
169 <option key={index} value={time}>
170 {time}
171 </option>
172 ))}
173 </select>
174 </>
175 )}
176
177 <br />
178 <button
179 className="btn btn-primary"
180 onClick={handleReservationConfirmation}
181 disabled={!selectedTableId || !selectedDate || !selectedTime}
182 >
183 Confirm Reservation
184 </button>
185 </div>
186 </>
187 )}
188 </div>
189 );
190};
191
192export default RestaurantDetails;
Note: See TracBrowser for help on using the repository browser.