Changeset f5b256e for my-react-app/src/App.js
- Timestamp:
- 04/28/25 14:20:18 (3 weeks ago)
- Branches:
- main
- Children:
- deea3c4
- Parents:
- 8ca35dc
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
my-react-app/src/App.js
r8ca35dc rf5b256e 1 1 import {BrowserRouter as Router, Navigate, Route, Routes, useNavigate} from 'react-router-dom'; 2 2 3 import Customers from './components/Customers'; 3 4 import Layout from "./components/Layout"; … … 17 18 import AppContent from "./components/AppContent"; 18 19 import ReservationHistory from "./components/ReservationHistory"; 20 import AuthContent from "./components/AuthContent"; 19 21 20 22 const ProtectedRoute = ({ element, isAuthenticated }) => { … … 23 25 24 26 const App = () => { 25 const [isAuthenticated, setIsAuthenticated] = React.useState(false);26 27 React.useEffect(() => {27 const [isAuthenticated, setIsAuthenticated] = useState(false); 28 29 useEffect(() => { 28 30 const token = localStorage.getItem('token'); 29 31 if (token) { … … 60 62 const navigate = useNavigate(); 61 63 62 const todayDate = new Date().toISOString().split('T')[0]; // Get today's date in 'YYYY-MM-DD' format64 const todayDate = new Date().toISOString().split('T')[0]; 63 65 64 66 const [date, setDate] = useState(todayDate); … … 80 82 const isToday = selectedDate.toDateString() === today.toDateString(); 81 83 82 // Determine the start hour and minute83 84 let startHour = 9; 84 85 let startMinute = 0; … … 86 87 const currentHour = today.getHours(); 87 88 const currentMinute = today.getMinutes(); 88 // If current time is later than 09:00, start from the current hour and minute89 89 if (currentHour > 9 || (currentHour === 9 && currentMinute >= 0)) { 90 90 startHour = currentHour; … … 93 93 } 94 94 95 // Create the start time and end time96 95 const startTime = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate(), startHour, startMinute); 97 96 const endTime = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate(), 23, 30); 98 97 99 // Generate time slots from start time to end time in 15-minute intervals100 98 const slots = []; 101 99 let currentTime = new Date(startTime); … … 106 104 } 107 105 108 // Update the timeSlots state109 106 setTimeSlots(slots); 110 107 } 111 108 }, [date]); 109 110 const handleGoToRestaurant = (restaurantId) => { 111 navigate(`/restaurants/${restaurantId}`); 112 }; 112 113 113 114 const handleDateChange = (e) => { … … 134 135 if (selectedTime) { 135 136 const [selectedHours, selectedMinutes] = selectedTime.split(":"); 136 // Check if selectedHours and selectedMinutes are valid numbers137 137 if (!isNaN(selectedHours) && !isNaN(selectedMinutes)) { 138 138 const dateTime = new Date(Date.UTC(year, month - 1, day, selectedHours, selectedMinutes)); … … 141 141 } 142 142 } else { 143 // Find the first available time slot after the current time144 143 const now = new Date(); 145 const currentTime = now.getHours() * 60 + now.getMinutes(); // Current time in minutes144 const currentTime = now.getHours() * 60 + now.getMinutes(); 146 145 const nextSlot = timeSlots.find(slot => { 147 146 const [hours, minutes] = slot.split(":"); 148 const slotTime = parseInt(hours) * 60 + parseInt(minutes); // Time of the slot in minutes147 const slotTime = parseInt(hours) * 60 + parseInt(minutes); 149 148 return slotTime > currentTime; 150 149 }); 151 150 152 // If no slot is found after the current time, use the first slot of the day153 151 formattedDateTime = nextSlot ? `${date} ${nextSlot}` : `${date} ${timeSlots[0]}`; 154 152 } … … 160 158 }; 161 159 162 console.log("Data to be submitted:");163 console.log(data);164 165 160 try { 166 161 const response = await axios.post('http://localhost:8081/api/search', data); 167 162 const filteredRestaurants = response.data; 168 163 setFilteredRestaurants(filteredRestaurants); 169 console.log(filteredRestaurants) ;164 console.log(filteredRestaurants) 170 165 setShowCuisineSearch(false); 171 // Handle response accordingly172 166 } catch (error) { 173 167 console.error('Error:', error); … … 179 173 try { 180 174 const response = await axios.post(`http://localhost:8081/api/search/shortcut/${cuisineName}`, cuisineName); 181 console.log(response.data);182 175 setFilteredRestaurants(response.data) 176 console.log(response.data) 183 177 } catch (error) { 184 178 console.error('Error searching by cuisine:', error); … … 186 180 setShowCuisineSearch(false); 187 181 }; 182 const parseTime = (timeString) => { 183 const [hours, minutes] = timeString.trim().split(':').map(Number); 184 return new Date().setHours(hours, minutes, 0, 0); 185 }; 186 const roundToNextQuarter = (date) => { 187 const minutes = date.getMinutes(); 188 const roundedMinutes = Math.floor(minutes / 15) * 15; 189 date.setMinutes(roundedMinutes, 0, 0); 190 return date; 191 }; 192 193 const shouldMoveToNextDay = (currentTime, endTime) => { 194 return (endTime - currentTime) <= 2 * 60 * 60 * 1000; 195 }; 196 const generateTimeSlots = (operatingHours) => { 197 const timeSlots = []; 198 const [startTimeStr, endTimeStr] = operatingHours.split('-').map((time) => time.trim()); 199 200 const startTime = parseTime(startTimeStr); 201 let endTime = parseTime(endTimeStr); 202 203 const currentTime = new Date().getTime(); 204 if (shouldMoveToNextDay(currentTime, endTime)) { 205 endTime += 24 * 60 * 60 * 1000; 206 } 207 208 let currentTimeSlot = new Date(startTime); 209 currentTimeSlot = roundToNextQuarter(currentTimeSlot); 210 211 while (currentTimeSlot.getTime() < endTime) { 212 timeSlots.push(currentTimeSlot.toISOString()); 213 currentTimeSlot.setMinutes(currentTimeSlot.getMinutes() + 15); 214 } 215 216 return timeSlots; 217 }; 218 219 const today = new Date(); 220 const year = today.getFullYear(); 221 const month = String(today.getMonth() + 1).padStart(2, '0'); 222 const day = String(today.getDate()).padStart(2, '0'); 223 const formattedDate = `${year}-${month}-${day}`; 188 224 189 225 const handleTimeSlotClick = (table, timeSlot, restaurant) => { … … 192 228 const restaurantId = restaurant.restaurantId; 193 229 194 const encodedTableNumber = encodeURI (tableNumber);230 const encodedTableNumber = encodeURIComponent(tableNumber); 195 231 const encodedTimeSlot = encodeURIComponent(formattedTimeSlot); 196 232 const encodedRestaurantId = encodeURIComponent(restaurantId); 197 233 198 234 navigate(`/reservationConfirmation/${encodedTableNumber}/${encodedTimeSlot}/${encodedRestaurantId}`); 199 } 235 }; 200 236 201 237 const renderTimeSlots = (tablesList, restaurant) => { 202 const [year, month, day] = date.split("-"); 203 const [hours, minutes] = selectedTime.split(":"); 204 const dateTime = new Date(year, month - 1, day, hours, minutes); // month is zero-based 205 206 let timestamp = dateTime.getTime(); 207 if (isNaN(timestamp)) { 208 timestamp = Date.now(); 209 } 210 211 let renderedTimeSlots = {}; // Object to store rendered slots for each table capacity 212 213 return tablesList.flatMap(table => { 214 // Render capacity header when encountering a new capacity 215 if (!renderedTimeSlots[table.capacity] && numPeople <= table.capacity) { 238 const currentTime = new Date().getTime(); 239 let renderedTimeSlots = {}; 240 241 if (tablesList.length === 0) { 242 return <p>No tables available for reservations at this restaurant.</p>; 243 } 244 245 return tablesList.flatMap((table) => { 246 const tableTimeSlots = generateTimeSlots(restaurant.operatingHours); 247 248 if (!renderedTimeSlots[table.capacity]) { 216 249 renderedTimeSlots[table.capacity] = 0; 217 250 return ( 218 251 <div key={table.capacity}> 219 <h3>Table for: {table.capacity}</h3> 220 {table.timeSlots.map((timeSlot, index) => { 221 let timeSlotTime = new Date(timeSlot).getTime(); 222 223 const tableCapacity = table.capacity; 224 // Check if the time slot is after the current time, numPeople is less than or equal to tableCapacity, and limit to 5 slots 225 if (timeSlotTime >= timestamp && numPeople <= tableCapacity && renderedTimeSlots[tableCapacity] < 5) { 226 renderedTimeSlots[tableCapacity]++; 252 <h3>Table for {table.capacity} guests</h3> 253 {tableTimeSlots.map((timeSlot, index) => { 254 const timeSlotTime = new Date(timeSlot).getTime(); 255 256 if (timeSlotTime > currentTime && renderedTimeSlots[table.capacity] < 3) { 257 renderedTimeSlots[table.capacity]++; 227 258 const timeSlotDateTime = new Date(timeSlot); 228 const formattedDateTime = timeSlotDateTime.toLocaleString(); // Format for both date and time 259 const formattedTime = timeSlotDateTime.toLocaleTimeString([], { 260 hour: '2-digit', 261 minute: '2-digit' 262 }); 229 263 230 264 return ( 231 <button key={index} className="btn btn-primary me-2 mb-2" onClick={() => handleTimeSlotClick(table, timeSlot, restaurant)}> 232 {formattedDateTime} {/* Display both date and time */} 265 <button 266 key={index} 267 className="btn btn-primary me-2 mb-2" 268 onClick={() => handleTimeSlotClick(table, timeSlot, restaurant)} 269 > 270 {formattedTime} {} 233 271 </button> 234 272 ); 273 <br/> 235 274 } else { 236 return null; // Render nothing if the condition is not met275 return null; 237 276 } 238 277 })} … … 240 279 ); 241 280 } else { 242 // If capacity has been rendered, return null to avoid duplicate rendering243 281 return null; 244 282 } 245 283 }); 246 } 247 248 249 250 // Rest of your component code... 251 252 const today = new Date(); 253 const year = today.getFullYear(); 254 const month = String(today.getMonth() + 1).padStart(2, '0'); 255 const day = String(today.getDate()).padStart(2, '0'); 256 const formattedDate = `${year}-${month}-${day}`; 284 }; 257 285 258 286 … … 286 314 placeholder="Restaurant or Cuisine" 287 315 aria-label="Search" 288 value={searchValue} // Set the value of the input field289 onChange={handleInputChange} // Call the event handler on change316 value={searchValue} 317 onChange={handleInputChange} 290 318 /> 291 319 </div> … … 299 327 <div className="card-body"> 300 328 <RestaurantInfo key={restaurant.id} restaurant={restaurant}/> 301 <p>Available time slots</p>329 {/*<p>Available time slots</p>*/} 302 330 <div className="d-flex flex-wrap"> 303 {renderTimeSlots(restaurant.tablesList.flatMap((table) => table), restaurant)} 331 {restaurant.tablesList && restaurant.tablesList.length > 0 ? ( 332 <div className="d-flex flex-wrap"> 333 {renderTimeSlots(restaurant.tablesList, restaurant)} 334 </div> 335 ) : ( 336 <p>No tables available for reservations at this restaurant</p> 337 )} 304 338 </div> 339 <button 340 className="btn btn-secondary" 341 onClick={() => handleGoToRestaurant(restaurant.restaurantId)} 342 > 343 Go to Restaurant 344 </button> 305 345 </div> 306 346 </div> … … 308 348 </div> 309 349 310 311 350 {showCuisineSearch && ( 312 351 <div className="mb-3"> 313 352 <h2 className="display-2">Search by cuisine type</h2> 314 <ul className="list-group"> 315 {cuisineTypes.map((cuisine, index) => ( 316 <li key={index} className="list-group-item"> 317 <button type="button" className="btn btn-outline-primary" 318 onClick={() => handleSearchByCuisine(cuisine)}> 319 {cuisine} 320 </button> 321 </li> 322 ))} 323 </ul> 324 </div>)} 353 <ul className="list-group"> 354 {cuisineTypes.map((cuisine, index) => ( 355 <li key={index} className="list-group-item"> 356 <button type="button" className="btn btn-outline-primary" 357 onClick={() => handleSearchByCuisine(cuisine)}> 358 {cuisine} 359 </button> 360 </li> 361 ))} 362 </ul> 363 </div> 364 )} 325 365 </form> 326 366 </div>
Note:
See TracChangeset
for help on using the changeset viewer.