Changeset e15e8d9
- Timestamp:
- 04/30/25 18:24:41 (2 weeks ago)
- Branches:
- main
- Children:
- 2518b3a
- Parents:
- deea3c4
- Files:
-
- 4 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
my-react-app/src/components/ReservationConfirmation.js
rdeea3c4 re15e8d9 3 3 import axios from 'axios'; 4 4 import { useNavigate } from 'react-router-dom'; 5 import {jwtDecode} from "jwt-decode"; 5 import { useLocation } from 'react-router-dom'; 6 import { jwtDecode } from "jwt-decode"; 6 7 import {request} from "../axios_helper"; 7 8 import restaurants from "./Restaurants"; … … 10 11 const navigate = useNavigate(); 11 12 13 const location = useLocation(); 14 const preOrderedItems = location.state?.preOrderedItems || []; 12 15 const [restaurant, setRestaurant] = useState({}); 13 16 const [user, setUser] = useState({}); … … 59 62 specialRequests: specialRequests.trim(), 60 63 paymentStatus: 'Pending', 64 preOrderedItems: preOrderedItems.map(item => `${item.itemName}:${item.quantity}:${item.price}`) 61 65 }; 62 66 … … 117 121 return `${formattedDate} - ${formattedTime}`; 118 122 }; 123 124 const grandTotal = preOrderedItems.reduce((acc, item) => acc + item.price * item.quantity, 0).toFixed(2); 125 const itemQuantityString = preOrderedItems 126 .map(item => `${item.itemName}:${item.quantity}`) 127 .join(','); 119 128 120 129 return ( … … 156 165 <br /> 157 166 </p> 167 {preOrderedItems.length > 0 ? ( 168 <div className="row"> 169 {preOrderedItems.map((item) => ( 170 <div key={item.menuID} className="col-md-4 mb-4"> 171 <div className="list-group shadow-sm p-3"> 172 <p className="item"><strong>Item:</strong> {item.itemName}</p> 173 <p className="item"><strong>Price:</strong> ${item.price.toFixed(2)}</p> 174 <p className="item"><strong>Quantity:</strong> {item.quantity}</p> 175 <p className="item"><strong>Total:</strong> ${(item.price * item.quantity).toFixed(2)}</p> 176 </div> 177 </div> 178 ))} 179 180 <div className="col-12 mt-4"> 181 <div className="list-group shadow-sm p-4 text-center"> 182 <h4>Grand Total: ${grandTotal}</h4> 183 </div> 184 </div> 185 </div> 186 ) : ( 187 <p>No pre-ordered items.</p> 188 )} 158 189 </div> 159 190 <div className="card-footer"> -
my-react-app/src/components/ReservationEdit.js
rdeea3c4 re15e8d9 65 65 }, [table]); 66 66 67 const generateTimeSlots = (operatingHours, interval) => {68 const slots = [];69 const [startTimeStr, endTimeStr] = operatingHours.split('-');70 const [startHours, startMinutes] = startTimeStr.split(':').map(Number);71 const [endHours, endMinutes] = endTimeStr.split(':').map(Number);72 73 const startTime = new Date();74 startTime.setHours(startHours, startMinutes, 0, 0);75 76 const endTime = new Date();77 endTime.setHours(endHours, endMinutes, 0, 0);78 79 let currentTime = startTime;80 while (currentTime <= endTime) {81 slots.push(new Date(currentTime).toISOString());82 currentTime = new Date(currentTime.getTime() + interval * 60000);83 }84 85 return slots;86 };87 88 67 const generateTimeOptions = (operatingHours) => { 89 const { startTime, endTime } = parseOperatingHours(operatingHours);90 68 const now = new Date(); 91 92 69 const selectedDateObj = new Date(selectedDate); 70 71 const { startTime, endTime } = parseOperatingHours(operatingHours, selectedDateObj); 72 93 73 const isToday = selectedDateObj.toDateString() === now.toDateString(); 94 const isTomorrow = selectedDateObj > now && selectedDateObj.getDate() === now.getDate() + 1;95 74 96 75 let currentTime; 97 76 98 77 if (isToday) { 99 currentTime = roundToNext15Minutes(new Date()); 78 const roundedNow = roundToNext15Minutes(now); 79 80 if (roundedNow < startTime) { 81 currentTime = startTime; 82 } else if (roundedNow > endTime) { 83 return []; 84 } else { 85 currentTime = roundedNow; 86 } 100 87 } else { 101 currentTime = new Date(startTime);88 currentTime = startTime; 102 89 } 103 90 … … 111 98 }; 112 99 113 useEffect(() => { 114 const operatingHours = table?.restaurant?.operatingHours || "09:00-00:00"; 115 const allTimeSlots = generateTimeSlots(operatingHours, timeSlotInterval); 116 117 const availableSlots = allTimeSlots.filter((slot) => 118 !tableReservations.includes(slot) 119 ); 120 121 setFilteredTimeSlots(availableSlots); 122 }, [tableReservations, table]); 100 const roundToNext15Minutes = (date) => { 101 const ms = 1000 * 60 * 15; 102 return new Date(Math.ceil(date.getTime() / ms) * ms); 103 }; 104 105 useEffect(() => { 106 if (table?.restaurant?.operatingHours && selectedDate) { 107 const options = generateTimeOptions(table.restaurant.operatingHours); 108 setTimeOptions(options); 109 } 110 }, [table, selectedDate]); 111 123 112 124 113 const handleInputChange = (e) => { … … 189 178 const formattedDate = `${year}-${month}-${day}`; 190 179 191 const parseOperatingHours = (operatingHours ) => {180 const parseOperatingHours = (operatingHours, forDate) => { 192 181 const [start, end] = operatingHours.split('-'); 193 return { 194 startTime: new Date(`1970-01-01T${start}:00`), 195 endTime: new Date(`1970-01-01T${end}:00`) 196 }; 182 183 const [startHour, startMinute] = start.split(':').map(Number); 184 const [endHour, endMinute] = end.split(':').map(Number); 185 186 const startTime = new Date(forDate); 187 startTime.setHours(startHour, startMinute, 0, 0); 188 189 const endTime = new Date(forDate); 190 endTime.setHours(endHour, endMinute, 0, 0); 191 192 return { startTime, endTime }; 197 193 }; 198 194 -
my-react-app/src/components/Reservations.js
rdeea3c4 re15e8d9 24 24 const response = await axios.get(`http://localhost:8081/api/reservations/by/${userId}`); 25 25 setReservations(response.data); 26 console.log(response.data) 26 27 } catch (error) { 27 28 console.error('Error fetching reservations:', error); … … 88 89 "Not specified"} </p> 89 90 <p className="card-text">Party Size: {reservation.partySize || "Not specified"}</p> 91 {reservation.preOrderedItems && reservation.preOrderedItems.length > 0 ? ( 92 <div className="mt-3"> 93 <h5 className="text-primary">Pre-Ordered Items:</h5> 94 <ul className="list-group mb-3"> 95 {reservation.preOrderedItems.map((itemStr, index) => { 96 const parts = itemStr.split(':'); 97 const name = parts[0]; 98 const quantity = parseInt(parts[1], 10) || 0; 99 const price = parseFloat(parts[2]) || 0; 100 101 return ( 102 <li key={index} className="list-group-item d-flex justify-content-between align-items-center"> 103 <span><strong>{name}</strong> × {quantity}</span> 104 <span className="badge bg-success rounded-pill">${(price * quantity).toFixed(2)}</span> 105 </li> 106 ); 107 })} 108 </ul> 109 110 <div className="alert alert-info text-center" role="alert"> 111 <h5>Grand Total: ${reservation.preOrderedItems.reduce((acc, itemStr) => { 112 const parts = itemStr.split(':'); 113 const quantity = parseInt(parts[1], 10) || 0; 114 const price = parseFloat(parts[2]) || 0; 115 return acc + (quantity * price); 116 }, 0).toFixed(2)}</h5> 117 </div> 118 </div> 119 ) : ( 120 <p>No pre-ordered items.</p> 121 )} 90 122 <p className="card-text text-danger">Special Requests: {reservation.specialRequests || "None"}</p> 91 123 <p className="card-text">Status: {reservation.status || "Pending"}</p> -
my-react-app/src/components/RestaurantDetails.js
rdeea3c4 re15e8d9 5 5 import { useParams } from 'react-router-dom'; 6 6 import StarRating from "./StarRating"; 7 import MenuList from "./MenuList"; 7 8 8 9 … … 10 11 const navigate = useNavigate(); 11 12 const { id } = useParams(); 13 const [preOrderedItems, setPreOrderedItems] = useState([]); 12 14 13 15 const [restaurant, setRestaurant] = useState(null); … … 100 102 const encodedRestaurantId = encodeURIComponent(restaurant.restaurantId); 101 103 102 navigate(`/reservationConfirmation/${encodedTableId}/${encodedDateTime}/${encodedRestaurantId}`); 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 104 114 105 115 const roundToNext15Minutes = (date) => { … … 174 184 </> 175 185 )} 176 186 <MenuList 187 restaurantId={restaurant.restaurantId} 188 setPreOrderedItems={setPreOrderedItems} 189 preOrderedItems={preOrderedItems} 190 /> 177 191 <br /> 178 192 <button 179 193 className="btn btn-primary" 180 194 onClick={handleReservationConfirmation} 181 disabled={!selectedTableId || !selectedDate || !selectedTime} 182 > 195 disabled={!selectedTableId || !selectedDate || !selectedTime}> 183 196 Confirm Reservation 184 197 </button> -
my-react-app/src/components/RestaurantInfo.js
rdeea3c4 re15e8d9 1 1 import React from 'react'; 2 2 import StarRating from "./StarRating"; 3 import MenuList from "./MenuList"; 3 4 4 5 const RestaurantInfo = ({ restaurant }) => { … … 8 9 {restaurant.name} <StarRating key={restaurant.id} rating={restaurant.rating}/> 9 10 </h2> 10 <p className="card-text">{restaurant.cuisineType}</p> {/* Assuming cuisineType is provided */} 11 <p className="card-text">{restaurant.operatingHours}</p> {/* Assuming operatingHours is provided */} 12 <p className="card-text">Ul. {restaurant.address}</p> {/* Assuming address is provided */} 11 <p className="card-text">{restaurant.cuisineType}</p> 12 <p className="card-text">{restaurant.operatingHours}</p> 13 <p className="card-text">Ul. {restaurant.address}</p> 14 <MenuList restaurantId={restaurant.id} /> 13 15 </div> 14 16 ); -
src/main/java/com/example/rezevirajmasa/demo/dto/ReservationDTO.java
rdeea3c4 re15e8d9 6 6 import java.math.BigDecimal; 7 7 import java.time.LocalDateTime; 8 import java.util.List; 8 9 9 10 public class ReservationDTO { … … 19 20 private String specialRequests; 20 21 private String paymentStatus; 22 private List<String> preOrderedItems; 23 21 24 22 25 public ReservationDTO() { 23 26 } 24 27 25 public ReservationDTO(Long reservationID, String userEmail, BigDecimal rating, Long tableNumber, LocalDateTime reservationDateTime, LocalDateTime checkInTime, Restaurant restaurant, int partySize, String status, String specialRequests, String paymentStatus ) {28 public ReservationDTO(Long reservationID, String userEmail, BigDecimal rating, Long tableNumber, LocalDateTime reservationDateTime, LocalDateTime checkInTime, Restaurant restaurant, int partySize, String status, String specialRequests, String paymentStatus, List<String> preOrderedItems) { 26 29 this.reservationID = reservationID; 27 30 this.userEmail = userEmail; … … 35 38 this.specialRequests = specialRequests; 36 39 this.paymentStatus = paymentStatus; 40 this.preOrderedItems = preOrderedItems; 37 41 } 38 42 … … 49 53 this.specialRequests = reservation.getSpecialRequests(); 50 54 this.paymentStatus = reservation.getPaymentStatus(); 55 this.preOrderedItems = reservation.getPreOrderedItems(); 56 } 57 58 public List<String> getPreOrderedItems() { 59 return preOrderedItems; 60 } 61 62 public void setPreOrderedItems(List<String> preOrderedItems) { 63 this.preOrderedItems = preOrderedItems; 51 64 } 52 65 -
src/main/java/com/example/rezevirajmasa/demo/model/Menu.java
rdeea3c4 re15e8d9 1 1 package com.example.rezevirajmasa.demo.model; 2 2 3 import com.fasterxml.jackson.annotation.JsonIgnore; 3 4 import jakarta.persistence.*; 5 import lombok.Data; 4 6 5 7 import java.math.BigDecimal; … … 7 9 @Entity 8 10 @Table(name = "menus") 11 @Data 9 12 public class Menu { 10 13 @Id … … 15 18 @ManyToOne 16 19 @JoinColumn(name = "RestaurantID", nullable = false) 20 @JsonIgnore 17 21 private Restaurant restaurant; 18 22 -
src/main/java/com/example/rezevirajmasa/demo/model/Reservation.java
rdeea3c4 re15e8d9 4 4 import com.fasterxml.jackson.annotation.JsonManagedReference; 5 5 import jakarta.persistence.*; 6 import lombok.Data; 7 import lombok.Getter; 8 import lombok.Setter; 6 9 7 10 import java.math.BigDecimal; 8 11 import java.time.LocalDateTime; 9 12 import java.time.LocalTime; 13 import java.util.ArrayList; 14 import java.util.List; 10 15 11 16 @Entity 12 17 @Table(name = "reservations") 18 @Data 13 19 public class Reservation { 14 20 … … 47 53 private LocalDateTime checkInTime; 48 54 55 @Getter 49 56 @Column(name = "CheckOutTime") 50 57 private LocalDateTime checkOutTime; 51 58 52 // @Column(name = "TotalAmount", precision = 8, scale = 2) 53 // private BigDecimal totalAmount; 59 @ElementCollection 60 @CollectionTable(name = "reservation_preordered_items", joinColumns = @JoinColumn(name = "reservation_id")) 61 @Column(name = "item") 62 private List<String> preOrderedItems = new ArrayList<>(); 54 63 55 64 @Column(name = "PaymentStatus", length = 20, nullable = false, columnDefinition = "VARCHAR default 'Unpaid'") … … 71 80 72 81 public Reservation(User user, TableEntity table, Restaurant restaurant, LocalDateTime reservationDateTime, int partySize, String specialRequests, String status, LocalDateTime checkInTime, LocalDateTime checkOutTime, String paymentStatus) { 73 // this.customer = customer;74 82 this.table = table; 75 83 this.user = user; … … 84 92 } 85 93 86 public User getUser() {87 return user;88 }89 90 public void setUser(User user) {91 this.user = user;92 }93 94 public Long getReservationID() {95 return reservationID;96 }97 98 public void setReservationID(Long reservationID) {99 this.reservationID = reservationID;100 }101 102 103 public TableEntity getTable() {104 return table;105 }106 107 public void setTable(TableEntity table) {108 this.table = table;109 }110 111 public Restaurant getRestaurant() {112 return restaurant;113 }114 115 public void setRestaurant(Restaurant restaurant) {116 this.restaurant = restaurant;117 }118 119 public LocalDateTime getReservationDateTime() {120 return reservationDateTime;121 }122 123 public void setReservationDateTime(LocalDateTime reservationDateTime) {124 this.reservationDateTime = reservationDateTime;125 }126 127 public int getPartySize() {128 return partySize;129 }130 131 public void setPartySize(int partySize) {132 this.partySize = partySize;133 }134 135 public String getSpecialRequests() {136 return specialRequests;137 }138 139 public void setSpecialRequests(String specialRequests) {140 this.specialRequests = specialRequests;141 }142 143 public String getStatus() {144 return status;145 }146 147 public void setStatus(String status) {148 this.status = status;149 }150 151 public LocalDateTime getCheckInTime() {152 return checkInTime;153 }154 155 public void setCheckInTime(LocalDateTime checkInTime) {156 this.checkInTime = checkInTime;157 }158 159 public LocalDateTime getCheckOutTime() {160 return checkOutTime;161 }162 163 public void setCheckOutTime(LocalDateTime checkOutTime) {164 this.checkOutTime = checkOutTime;165 }166 167 public String getPaymentStatus() {168 return paymentStatus;169 }170 171 public void setPaymentStatus(String paymentStatus) {172 this.paymentStatus = paymentStatus;173 }174 94 175 95 @Override -
src/main/java/com/example/rezevirajmasa/demo/service/impl/ReservationImpl.java
rdeea3c4 re15e8d9 63 63 TableEntity table = optionalTable.get(); 64 64 65 LocalDateTime reservationTime = reservationDTO.getReservationDateTime(); 66 LocalDateTime startTime = reservationTime.minusHours(2); 67 LocalDateTime endTime = reservationTime.plusHours(2); 65 LocalDateTime startTime = reservationDTO.getReservationDateTime().plusHours(1); 66 LocalDateTime endTime = reservationDTO.getReservationDateTime().plusHours(3); 68 67 69 68 boolean hasConflict = table.getReservations().stream() … … 93 92 reservation.setPaymentStatus(reservationDTO.getPaymentStatus() != null ? reservationDTO.getPaymentStatus() : "Unpaid"); 94 93 reservation.setUser(user); 94 reservation.setPreOrderedItems(reservationDTO.getPreOrderedItems()); 95 95 reservation.setRestaurant(reservationDTO.getRestaurant()); 96 reservation.setCheckInTime(reservation Time);96 reservation.setCheckInTime(reservationDTO.getReservationDateTime().plusHours(1)); 97 97 reservation.setReservationDateTime(LocalDateTime.now()); 98 reservation.setCheckOutTime(reservation Time.plusHours(2));98 reservation.setCheckOutTime(reservationDTO.getReservationDateTime().plusHours(3)); 99 99 reservation.setRestaurant(reservationDTO.getRestaurant()); 100 100 -
src/main/java/com/example/rezevirajmasa/demo/web/rest/testController.java
rdeea3c4 re15e8d9 37 37 private final ReservationHistoryService reservationHistoryService; 38 38 private final TableService tableService; 39 private final MenuService menuService; 39 40 private final UserMapper userMapper; 40 41 private final TokenService tokenService; 41 public testController(RestaurantService restaurantService, CustomerService customerService, UserService userService, ReservationService reservationService, ReservationHistoryService reservationHistoryService, TableService tableService, UserMapper userMapper, TokenService tokenService) {42 public testController(RestaurantService restaurantService, CustomerService customerService, UserService userService, ReservationService reservationService, ReservationHistoryService reservationHistoryService, TableService tableService, MenuService menuService, UserMapper userMapper, TokenService tokenService) { 42 43 this.restaurantService = restaurantService; 43 44 this.customerService = customerService; … … 46 47 this.reservationHistoryService = reservationHistoryService; 47 48 this.tableService = tableService; 49 this.menuService = menuService; 48 50 this.userMapper = userMapper; 49 51 this.tokenService = tokenService; … … 272 274 return new ResponseEntity<>(reservations, HttpStatus.OK); 273 275 } 276 277 // menu calls 278 @GetMapping("/api/restaurant-menu/{restaurantId}") 279 public List<Menu> getMenuByRestaurantId(@PathVariable Long restaurantId) { 280 return menuService.getMenuByRestaurantId(restaurantId); 281 } 274 282 }
Note:
See TracChangeset
for help on using the changeset viewer.