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

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

Final version for DB

  • Property mode set to 100644
File size: 8.1 KB
RevLine 
[d24f17c]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";
[e15e8d9]7import MenuList from "./MenuList";
[d24f17c]8
[f5b256e]9
[d24f17c]10const RestaurantDetails = () => {
11 const navigate = useNavigate();
12 const { id } = useParams();
[e15e8d9]13 const [preOrderedItems, setPreOrderedItems] = useState([]);
[f5b256e]14
[d24f17c]15 const [restaurant, setRestaurant] = useState(null);
16 const [selectedTableId, setSelectedTableId] = useState('');
[f5b256e]17 const [selectedDate, setSelectedDate] = useState('');
18 const [selectedTime, setSelectedTime] = useState('');
19 const [timeOptions, setTimeOptions] = useState([]);
[d24f17c]20 const [selectedTable, setSelectedTable] = useState(null);
21
22 useEffect(() => {
23 const fetchRestaurantDetails = async () => {
24 try {
25 if (!id) return;
[8ca35dc]26 const response = await axios.get(`http://localhost:8081/api/restaurants/${id}`);
[d24f17c]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(() => {
[f5b256e]37 if (!selectedTableId) return;
[d24f17c]38
39 const fetchTableDetails = async () => {
40 try {
[8ca35dc]41 const response = await axios.get(`http://localhost:8081/api/tables/${selectedTableId}`);
[d24f17c]42 setSelectedTable(response.data);
43 } catch (error) {
44 console.error('Error fetching table details:', error);
45 }
46 };
47
48 fetchTableDetails();
49 }, [selectedTableId]);
50
[f5b256e]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);
[d24f17c]60
[f5b256e]61 const startTime = new Date();
62 startTime.setHours(startHour, startMinute, 0, 0);
[d24f17c]63
[f5b256e]64 const endTime = new Date();
65 endTime.setHours(endHour < startHour ? endHour + 24 : endHour, endMinute, 0, 0);
[d24f17c]66
[f5b256e]67 return { startTime, endTime };
[d24f17c]68 };
69
[f5b256e]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 }
[d24f17c]84
[f5b256e]85 return options;
[d24f17c]86 };
87
[f5b256e]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 };
[d24f17c]98
[f5b256e]99 const handleReservationConfirmation = () => {
100 const encodedTableId = encodeURIComponent(selectedTableId);
101 const encodedDateTime = encodeURIComponent(`${selectedDate}T${selectedTime}`);
102 const encodedRestaurantId = encodeURIComponent(restaurant.restaurantId);
[d24f17c]103
[e15e8d9]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 });
[d24f17c]112 };
113
[f5b256e]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 };
[d24f17c]123
124 return (
125 <div className="container">
126 {restaurant && (
127 <>
128 <h2 className="card-title">
[f5b256e]129 {restaurant.name} <StarRating key={restaurant.id} rating={restaurant.rating} />
[d24f17c]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>
[f5b256e]136 <p>
137 Website: <a href={restaurant.website}>{restaurant.website}</a>
138 </p>
[d24f17c]139 <p>Social Media Links: {restaurant.socialMediaLinks}</p>
140
141 <label>Select Table:</label>
[f5b256e]142 <select
143 className="form-select"
144 aria-label="Select Table"
145 onChange={handleTableSelect}
146 value={selectedTableId}
147 >
[d24f17c]148 <option value="">Select Table</option>
[f5b256e]149 {restaurant.tablesList.map((table) => (
150 <option key={table.id} value={table.id}>
151 {`Capacity: ${table.capacity} - ${table.location}`}
152 </option>
[d24f17c]153 ))}
154 </select>
[f5b256e]155
[d24f17c]156 {selectedTable && (
157 <>
[f5b256e]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>
[d24f17c]181 ))}
182 </select>
183 </>
184 )}
[e15e8d9]185 <MenuList
186 restaurantId={restaurant.restaurantId}
187 setPreOrderedItems={setPreOrderedItems}
188 preOrderedItems={preOrderedItems}
189 />
[f5b256e]190 <br />
191 <button
192 className="btn btn-primary"
193 onClick={handleReservationConfirmation}
[e15e8d9]194 disabled={!selectedTableId || !selectedDate || !selectedTime}>
[d24f17c]195 Confirm Reservation
196 </button>
197 </div>
198 </>
199 )}
200 </div>
201 );
202};
203
[f5b256e]204export default RestaurantDetails;
Note: See TracBrowser for help on using the repository browser.