Changeset c44c5ed for my-react-app
- Timestamp:
- 05/02/25 15:06:42 (2 weeks ago)
- Branches:
- main
- Children:
- 142c0f8
- Parents:
- 2518b3a
- Location:
- my-react-app/src
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
my-react-app/src/App.js
r2518b3a rc44c5ed 19 19 import ReservationHistory from "./components/ReservationHistory"; 20 20 import AuthContent from "./components/AuthContent"; 21 import MenuList from "./components/MenuList"; 22 import ReadOnlyMenuList from "./components/ReadOnlyMenuList"; 21 23 22 24 const ProtectedRoute = ({ element, isAuthenticated }) => { … … 326 328 <div key={restaurant.id} className="card mb-3"> 327 329 <div className="card-body"> 328 < RestaurantInfo key={restaurant.id} restaurant={restaurant}/>329 {/*<p>Available time slots</p>*/}330 <div className="d-flex flex-wrap">331 {restaurant.tablesList && restaurant.tablesList.length > 0 ? (330 <div className="row"> 331 {/* Narrow left column: info and actions */} 332 <div className="col-md-4"> 333 <RestaurantInfo key={restaurant.id} restaurant={restaurant}/> 332 334 <div className="d-flex flex-wrap"> 333 {renderTimeSlots(restaurant.tablesList, restaurant)} 335 {restaurant.tablesList && restaurant.tablesList.length > 0 ? ( 336 renderTimeSlots(restaurant.tablesList, restaurant) 337 ) : ( 338 <p>No tables available for reservations at this restaurant</p> 339 )} 334 340 </div> 335 ) : ( 336 <p>No tables available for reservations at this restaurant</p> 337 )} 341 <button 342 className="btn btn-secondary mt-3" 343 onClick={() => handleGoToRestaurant(restaurant.restaurantId)} 344 > 345 Go to Restaurant 346 </button> 347 </div> 348 349 {/* Wide right column: menu */} 350 <div className="col-md-8"> 351 <ReadOnlyMenuList restaurantId={restaurant.restaurantId}/> 352 </div> 338 353 </div> 339 <button340 className="btn btn-secondary"341 onClick={() => handleGoToRestaurant(restaurant.restaurantId)}342 >343 Go to Restaurant344 </button>345 354 </div> 346 355 </div> 347 356 ))} 348 357 </div> 358 349 359 350 360 {showCuisineSearch && ( -
my-react-app/src/components/MenuList.js
r2518b3a rc44c5ed 58 58 return ( 59 59 <div className="container mt-4"> 60 <h3 className="text-center">Menu</h3>60 {menuItems.length > 0 && <h3 className="text-center">Menu</h3>} 61 61 <div className="row"> 62 62 {menuItems.map((item) => ( -
my-react-app/src/components/ReservationHistory.js
r2518b3a rc44c5ed 1 1 import React, { useEffect, useState } from "react"; 2 import { jwtDecode} from "jwt-decode";2 import { jwtDecode } from "jwt-decode"; 3 3 import axios from "axios"; 4 import 'bootstrap/dist/css/bootstrap.min.css'; 5 import 'bootstrap/dist/js/bootstrap.bundle.min'; 4 6 5 7 const ReservationHistory = () => { 6 8 const [reservations, setReservations] = useState([]); 7 9 const [filteredReservations, setFilteredReservations] = useState([]); 10 const [selectedReservation, setSelectedReservation] = useState(null); 8 11 const [loading, setLoading] = useState(true); 9 12 const [error, setError] = useState(null); … … 14 17 const [statusFilter, setStatusFilter] = useState(""); 15 18 const [cancellationReasonFilter, setCancellationReasonFilter] = useState(""); 16 17 19 const [startDate, setStartDate] = useState(""); 18 20 const [endDate, setEndDate] = useState(""); … … 113 115 if (error) return <div className="alert alert-danger">{error}</div>; 114 116 117 const formatDateTime = (dateString) => { 118 if (!dateString) return "N/A"; 119 const date = new Date(dateString); 120 return date.toLocaleString("en-GB", { 121 day: "2-digit", 122 month: "short", 123 year: "numeric", 124 hour: "2-digit", 125 minute: "2-digit", 126 }); 127 }; 128 115 129 return ( 116 130 <div className="container mt-5"> … … 140 154 type="date" 141 155 className="form-control" 142 placeholder="Start date"143 156 value={startDate} 144 157 onChange={(e) => setStartDate(e.target.value)} … … 147 160 type="date" 148 161 className="form-control" 149 placeholder="End date"150 162 value={endDate} 151 163 onChange={(e) => setEndDate(e.target.value)} … … 156 168 type="number" 157 169 className="form-control" 158 placeholder=" Filter byParty Size"170 placeholder="Party Size" 159 171 value={partySizeFilter} 160 172 onChange={(e) => setPartySizeFilter(e.target.value)} … … 167 179 className="form-control" 168 180 > 169 <option value="">Filter by status</option>181 <option value="">Filter by Status</option> 170 182 <option value="successful">Successful</option> 171 183 <option value="canceled">Canceled</option> … … 176 188 type="text" 177 189 className="form-control" 178 placeholder=" Filter byCancellation Reason"190 placeholder="Cancellation Reason" 179 191 value={cancellationReasonFilter} 180 192 onChange={(e) => setCancellationReasonFilter(e.target.value)} … … 198 210 <th>Restaurant</th> 199 211 <th>Table</th> 200 <th>Date & Time</th> 212 <th>Check In Date</th> 213 <th>Reserved on</th> 201 214 <th>Party Size</th> 202 215 <th>Special Requests</th> … … 208 221 {filteredReservations.length > 0 ? ( 209 222 filteredReservations.map((res, index) => ( 210 <tr key={res.id} >223 <tr key={res.id} onClick={() => setSelectedReservation(res)} style={{ cursor: "pointer" }}> 211 224 <td>{index + 1}</td> 212 225 <td>{res.restaurant?.name || "N/A"}</td> 213 226 <td>{res.table?.id || "N/A"}</td> 227 <td>{formatDateTime(res.checkInDate)}</td> 214 228 <td>{new Date(res.reservationDateTime).toLocaleString()}</td> 215 229 <td>{res.partySize}</td> … … 221 235 ) : ( 222 236 <tr> 223 <td colSpan=" 8" className="text-center">No reservations found.</td>237 <td colSpan="9" className="text-center">No reservations found.</td> 224 238 </tr> 225 239 )} … … 227 241 </table> 228 242 </div> 243 244 {/* Modal for reservation details */} 245 {selectedReservation && ( 246 <div className="modal fade show d-block" tabIndex="-1" style={{ backgroundColor: "rgba(0,0,0,0.5)" }} onClick={() => setSelectedReservation(null)}> 247 <div className="modal-dialog modal-lg" onClick={(e) => e.stopPropagation()}> 248 <div className="modal-content"> 249 <div className="modal-header"> 250 <h5 className="modal-title">Reservation Details</h5> 251 <button type="button" className="btn-close" onClick={() => setSelectedReservation(null)}></button> 252 </div> 253 <div className="modal-body"> 254 <h6>🍽️ Restaurant Info</h6> 255 <p><strong>Name:</strong> {selectedReservation.restaurant?.name}</p> 256 <p><strong>Address:</strong> {selectedReservation.restaurant?.address}</p> 257 <p><strong>Phone:</strong> {selectedReservation.restaurant?.phone}</p> 258 <p><strong>Rating:</strong> {selectedReservation.restaurant?.rating} ⭐</p> 259 <p><strong>Cuisine:</strong> {selectedReservation.restaurant?.cuisineType}</p> 260 <p><strong>Hours:</strong> {selectedReservation.restaurant?.operatingHours}</p> 261 {selectedReservation.restaurant?.website && ( 262 <p><strong>Website:</strong> <a href={`https://${selectedReservation.restaurant.website}`} target="_blank" rel="noopener noreferrer">{selectedReservation.restaurant.website}</a></p> 263 )} 264 265 <hr /> 266 267 <h6>🪑 Table Info</h6> 268 <p><strong>Location:</strong> {selectedReservation.table?.location}</p> 269 <p><strong>Capacity:</strong> {selectedReservation.table?.capacity}</p> 270 <p><strong>Smoking Area:</strong> {selectedReservation.table?.smokingArea ? "Yes" : "No"}</p> 271 <p><strong>Description:</strong> {selectedReservation.table?.description}</p> 272 <p><strong>Reservation Duration:</strong> {selectedReservation.table?.reservationDurationHours} hours</p> 273 274 <hr /> 275 276 <h6>📋 Reservation Info</h6> 277 <p><strong>Check-In Date:</strong> {formatDateTime(selectedReservation.checkInDate)}</p> 278 <p><strong>Reserved on:</strong> {new Date(selectedReservation.reservationDateTime).toLocaleString()}</p> 279 <p><strong>Party Size:</strong> {selectedReservation.partySize}</p> 280 <p><strong>Special Requests:</strong> {selectedReservation.specialRequests || "None"}</p> 281 <p><strong>Status:</strong> {selectedReservation.status}</p> 282 <p><strong>Cancellation Reason:</strong> {selectedReservation.cancellationReason || "None"}</p> 283 </div> 284 <div className="modal-footer"> 285 <button className="btn btn-secondary" onClick={() => setSelectedReservation(null)}>Close</button> 286 </div> 287 </div> 288 </div> 289 </div> 290 )} 229 291 </div> 230 292 ); -
my-react-app/src/components/RestaurantContext.js
r2518b3a rc44c5ed 12 12 try { 13 13 const response = await axios.get('http://localhost:8081/api/restaurants'); 14 console.log("Fetched once", response.data);15 14 setRestaurants(response.data); 16 15 } catch (error) { -
my-react-app/src/components/Restaurants.js
r2518b3a rc44c5ed 26 26 const navigate = useNavigate(); 27 27 const restaurantContext = useContext(RestaurantContext); 28 console.log(restaurantContext)29 28 30 29 useEffect(() => {
Note:
See TracChangeset
for help on using the changeset viewer.