source: my-react-app/src/components/Restaurants.js@ c44c5ed

main
Last change on this file since c44c5ed was c44c5ed, checked in by Aleksandar Panovski <apano77@…>, 2 weeks ago

Fixed bugs and fully developed menu now. Readonly added.

  • Property mode set to 100644
File size: 6.0 KB
Line 
1import React, {useState, useEffect, useContext} from 'react';
2import 'bootstrap/dist/css/bootstrap.min.css';
3import StarRating from './StarRating';
4import { useNavigate } from 'react-router-dom';
5import {RestaurantContext} from "./RestaurantContext";
6import {Alert} from "bootstrap";
7
8const parseTime = (timeString) => {
9 const [hours, minutes] = timeString.trim().split(':').map(Number);
10 return new Date().setHours(hours, minutes, 0, 0);
11};
12
13const roundToNextQuarter = (date) => {
14 const minutes = date.getMinutes();
15 const roundedMinutes = Math.floor(minutes / 15) * 15;
16 date.setMinutes(roundedMinutes, 0, 0);
17 return date;
18};
19
20const shouldMoveToNextDay = (currentTime, endTime) => {
21 return (endTime - currentTime) <= 2 * 60 * 60 * 1000;
22};
23
24const Restaurants = () => {
25 const [restaurants, setRestaurants] = useState([]);
26 const navigate = useNavigate();
27 const restaurantContext = useContext(RestaurantContext);
28
29 useEffect(() => {
30 setRestaurants(restaurantContext.restaurants);
31 }, [restaurantContext]);
32
33
34 const generateTimeSlots = (operatingHours) => {
35 const timeSlots = [];
36 const [startTimeStr, endTimeStr] = operatingHours.split('-').map((time) => time.trim());
37
38 const startTime = parseTime(startTimeStr);
39 let endTime = parseTime(endTimeStr);
40
41 const currentTime = new Date().getTime();
42 if (shouldMoveToNextDay(currentTime, endTime)) {
43 endTime += 24 * 60 * 60 * 1000;
44 }
45
46 let currentTimeSlot = new Date(startTime);
47 currentTimeSlot = roundToNextQuarter(currentTimeSlot);
48
49 while (currentTimeSlot.getTime() < endTime) {
50 timeSlots.push(currentTimeSlot.toISOString());
51 currentTimeSlot.setMinutes(currentTimeSlot.getMinutes() + 15);
52 }
53
54 return timeSlots;
55 };
56
57 const handleDetailClick = (restaurantId) => {
58 navigate(`/restaurants/${restaurantId}`);
59 };
60
61 const handleTimeSlotClick = (table, timeSlot, restaurant) => {
62 const tableNumber = table.id;
63 const formattedTimeSlot = timeSlot;
64 const restaurantId = restaurant.restaurantId;
65
66 const encodedTableNumber = encodeURIComponent(tableNumber);
67 const encodedTimeSlot = encodeURIComponent(formattedTimeSlot);
68 const encodedRestaurantId = encodeURIComponent(restaurantId);
69
70 navigate(`/reservationConfirmation/${encodedTableNumber}/${encodedTimeSlot}/${encodedRestaurantId}`);
71 };
72
73 const renderTimeSlots = (tablesList, restaurant) => {
74 const currentTime = new Date().getTime();
75 let renderedTimeSlots = {};
76
77 if (tablesList.length === 0) {
78 return <p>No tables available for reservations at this restaurant.</p>;
79 }
80
81 return tablesList.flatMap((table) => {
82 const tableTimeSlots = generateTimeSlots(restaurant.operatingHours);
83
84 if (!renderedTimeSlots[table.capacity]) {
85 renderedTimeSlots[table.capacity] = 0;
86 return (
87 <div key={table.capacity}>
88 <h3>Table for {table.capacity} guests</h3>
89 {tableTimeSlots.map((timeSlot, index) => {
90 const timeSlotTime = new Date(timeSlot).getTime();
91
92 if (timeSlotTime > currentTime && renderedTimeSlots[table.capacity] < 3) {
93 renderedTimeSlots[table.capacity]++;
94 const timeSlotDateTime = new Date(timeSlot);
95 const formattedTime = timeSlotDateTime.toLocaleTimeString([], {
96 hour: '2-digit',
97 minute: '2-digit'
98 });
99
100 return (
101 <button
102 key={index}
103 className="btn btn-primary me-2 mb-2"
104 onClick={() => handleTimeSlotClick(table, timeSlot, restaurant)}
105 >
106 {formattedTime} {}
107 </button>
108 );
109 } else {
110 return null;
111 }
112 })}
113 </div>
114 );
115 } else {
116 return null;
117 }
118 });
119 };
120
121 return (
122 <div className="container">
123 <h2>Restaurants</h2>
124 <div className="row">
125 {restaurants.map((restaurant) => (
126 <div key={restaurant.restaurantId} className="col-md-4 mb-4">
127 <div className="card">
128 <div className="card-body">
129 <h5 className="card-title">
130 {restaurant.name}
131 </h5>
132 <p className="card-text">{restaurant.cuisineType}</p>
133 <p className="card-text">{restaurant.operatingHours}</p>
134 <p className="card-text">Ul. {restaurant.address}</p>
135
136 {restaurant.tablesList && restaurant.tablesList.length > 0 ? (
137 <div className="d-flex flex-wrap">
138 {renderTimeSlots(restaurant.tablesList, restaurant)}
139 </div>
140 ) : (
141 <p>No tables available for reservations at this restaurant.</p>
142 )}
143 </div>
144 <button onClick={() => handleDetailClick(restaurant.restaurantId)} className="btn btn-primary">
145 View Details
146 </button>
147 </div>
148 </div>
149 ))}
150 </div>
151 </div>
152 );
153};
154
155export default Restaurants;
Note: See TracBrowser for help on using the repository browser.