source: my-react-app/src/components/RestaurantDetails.js

main
Last change on this file was e48199a, checked in by Aleksandar Panovski <apano77@…>, 10 days ago

Final version for DB

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