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

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

Normalization needed to continue, till here done

  • 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 console.log(preOrderedItems)
115
116 const roundToNext15Minutes = (date) => {
117 const minutes = date.getMinutes();
118 const remainder = minutes % 15;
119 if (remainder === 0) return date;
120
121 date.setMinutes(minutes + 15 - remainder);
122 date.setSeconds(0, 0);
123 return date;
124 };
125
126 return (
127 <div className="container">
128 {restaurant && (
129 <>
130 <h2 className="card-title">
131 {restaurant.name} <StarRating key={restaurant.id} rating={restaurant.rating} />
132 </h2>
133 <div className="restaurant-details">
134 <p>Operating hours: {restaurant.operatingHours}</p>
135 <p>Cuisine: {restaurant.cuisineType}</p>
136 <p>Address: {restaurant.address}</p>
137 <p>Phone: {restaurant.phone}</p>
138 <p>
139 Website: <a href={restaurant.website}>{restaurant.website}</a>
140 </p>
141 <p>Social Media Links: {restaurant.socialMediaLinks}</p>
142
143 <label>Select Table:</label>
144 <select
145 className="form-select"
146 aria-label="Select Table"
147 onChange={handleTableSelect}
148 value={selectedTableId}
149 >
150 <option value="">Select Table</option>
151 {restaurant.tablesList.map((table) => (
152 <option key={table.id} value={table.id}>
153 {`Capacity: ${table.capacity} - ${table.location}`}
154 </option>
155 ))}
156 </select>
157
158 {selectedTable && (
159 <>
160 <label>Select Date:</label>
161 <input
162 type="date"
163 className="form-control mt-2"
164 onChange={(event) => setSelectedDate(event.target.value)}
165 value={selectedDate}
166 min={formattedDate}
167 onKeyDown={(e) => e.preventDefault()}
168 />
169 {!selectedDate && <p style={{ color: "red" }}>Please select a valid date.</p>}
170
171 <label>Select Time:</label>
172 <select
173 className="form-select mt-2"
174 onChange={(event) => setSelectedTime(event.target.value)}
175 value={selectedTime}
176 disabled={!selectedDate}
177 >
178 <option value="">Select Time</option>
179 {timeOptions.map((time, index) => (
180 <option key={index} value={time}>
181 {time}
182 </option>
183 ))}
184 </select>
185 </>
186 )}
187 <MenuList
188 restaurantId={restaurant.restaurantId}
189 setPreOrderedItems={setPreOrderedItems}
190 preOrderedItems={preOrderedItems}
191 />
192 <br />
193 <button
194 className="btn btn-primary"
195 onClick={handleReservationConfirmation}
196 disabled={!selectedTableId || !selectedDate || !selectedTime}>
197 Confirm Reservation
198 </button>
199 </div>
200 </>
201 )}
202 </div>
203 );
204};
205
206export default RestaurantDetails;
Note: See TracBrowser for help on using the repository browser.