Changeset e48199a
- Timestamp:
- 05/07/25 18:34:01 (10 days ago)
- Branches:
- main
- Parents:
- b67dfd3
- Files:
-
- 3 added
- 1 deleted
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
my-react-app/src/App.js
rb67dfd3 re48199a 96 96 const option = currentTime.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false }); 97 97 slots.push(option); 98 currentTime.setMinutes(currentTime.getMinutes() + 15); // Increment by 15 minutes98 currentTime.setMinutes(currentTime.getMinutes() + 15); 99 99 } 100 100 … … 322 322 <div className="card-body"> 323 323 <div className="row"> 324 {/* Narrow left column: info and actions */} 324 325 325 <div className="col-md-4"> 326 326 <RestaurantInfo key={restaurant.id} restaurant={restaurant}/> … … 340 340 </div> 341 341 342 {/* Wide right column: menu */} 342 343 343 <div className="col-md-8"> 344 344 <ReadOnlyMenuList restaurantId={restaurant.restaurantId}/> -
my-react-app/src/components/ErrorPage.js
rb67dfd3 re48199a 1 // ErrorPage.js2 1 import React from 'react'; 3 2 … … 7 6 <h1>Oops! Something went wrong.</h1> 8 7 <p>Please try again later or contact support.</p> 9 {/* Add any additional content or error-specific messages */}10 8 </div> 11 9 ); -
my-react-app/src/components/Layout.js
rb67dfd3 re48199a 1 // Layout.js2 1 import React from 'react'; 3 2 import Header from './Header'; -
my-react-app/src/components/ReadOnlyMenuList.js
rb67dfd3 re48199a 14 14 const response = await axios.get(`http://localhost:8081/api/restaurant-menu/${restaurantId}`); 15 15 setMenuItems(response.data); 16 setCurrentPage(1); // Reset to first page on restaurant change16 setCurrentPage(1); 17 17 } catch (err) { 18 18 console.error('Failed to fetch menu:', err); -
my-react-app/src/components/ReservationConfirmation.js
rb67dfd3 re48199a 27 27 const tableResponse = await axios.get(`http://localhost:8081/api/tables/${tableNumber}`); 28 28 setTable(tableResponse.data); 29 console.log(tableResponse.data)30 29 const restaurantResponse = await axios.get(`http://localhost:8081/api/restaurants/${restaurantId}`); 31 30 setRestaurant(restaurantResponse.data); … … 65 64 preorderedItemName: item.itemName, 66 65 quantity: item.quantity, 67 price: item.price 66 price: item.price, 67 menuID: item.menuID 68 68 })) 69 69 }; … … 76 76 } 77 77 }); 78 console.log('Reservation created successfully:', response.data);79 78 navigate("/reservations") 80 79 } catch (error) { … … 112 111 localStorage.removeItem('remainingTime'); 113 112 alert("Time has expired. Please try reserving again."); 114 navigate('/restaurants'); // Redirect or take necessary action113 navigate('/restaurants'); 115 114 } 116 115 }, [remainingTime, navigate]); -
my-react-app/src/components/ReservationEdit.js
rb67dfd3 re48199a 30 30 setIsLoading(true); 31 31 const response = await axios.get(`http://localhost:8081/api/reservations/${reservationId}`); 32 console.log(response)33 32 setCheckInTime(response.data.reservationDateTime); 34 33 setFormData(response.data); 35 setRestaurant(response.data.restaurantName); 34 36 35 setRestaurantId(response.data.restaurantId); 36 const restaurantResponse = await axios.get(`http://localhost:8081/api/restaurants/${response.data.restaurantId}`); 37 setRestaurant(restaurantResponse.data); 37 38 38 39 setTableNumber(response.data.tableNumber); … … 45 46 } 46 47 }; 47 48 48 fetchReservation(); 49 49 }, [reservationId]); … … 64 64 } 65 65 }, [table]); 66 67 const generateTimeOptions = (operatingHours) => {68 const now = new Date();69 const selectedDateObj = new Date(selectedDate);70 71 const { startTime, endTime } = parseOperatingHours(operatingHours, selectedDateObj);72 73 const isToday = selectedDateObj.toDateString() === now.toDateString();74 75 let currentTime;76 77 if (isToday) {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 }87 } else {88 currentTime = startTime;89 }90 91 const options = [];92 while (currentTime <= endTime) {93 options.push(currentTime.toTimeString().slice(0, 5));94 currentTime = new Date(currentTime.getTime() + 15 * 60 * 1000);95 }96 97 return options;98 };99 100 const roundToNext15Minutes = (date) => {101 const ms = 1000 * 60 * 15;102 return new Date(Math.ceil(date.getTime() / ms) * ms);103 };104 66 105 67 useEffect(() => { … … 178 140 const formattedDate = `${year}-${month}-${day}`; 179 141 180 const parseOperatingHours = (operatingHours, forDate) => { 181 const [start, end] = operatingHours.split('-'); 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 }; 193 }; 194 195 useEffect(() => { 196 if (formData?.restaurant?.operatingHours && selectedDate) { 197 const options = generateTimeOptions(formData.restaurant.operatingHours); 142 const generateTimeOptions = (operatingHours) => { 143 const now = new Date(); 144 const selectedDateObj = new Date(selectedDate); 145 const isToday = selectedDateObj.toDateString() === now.toDateString(); 146 147 let options = []; 148 for (const hours of operatingHours.split(',')) { 149 const [start, end] = hours.trim().split('-'); 150 const startTime = new Date(selectedDateObj); 151 const endTime = new Date(selectedDateObj); 152 const [startHour, startMinute] = start.split(':').map(Number); 153 const [endHour, endMinute] = end.split(':').map(Number); 154 startTime.setHours(startHour, startMinute, 0); 155 endTime.setHours(endHour, endMinute, 0); 156 157 if (isToday && startTime < now) { 158 startTime.setTime(roundToNext15Minutes(now).getTime()); 159 } 160 161 if (endTime <= now) { 162 setNoAvailableMessage('No available time due to closing.'); 163 continue; 164 } 165 166 while (startTime <= endTime) { 167 options.push(startTime.toTimeString().slice(0, 5)); 168 startTime.setMinutes(startTime.getMinutes() + 15); 169 } 170 } 171 172 return options.length ? options : ['No available time']; 173 }; 174 175 const roundToNext15Minutes = (date) => { 176 const ms = 1000 * 60 * 15; 177 const roundedTime = new Date(Math.ceil(date.getTime() / ms) * ms); 178 179 if (roundedTime.getTime() === date.getTime()) { 180 roundedTime.setMinutes(roundedTime.getMinutes() + 15); 181 } 182 183 return roundedTime; 184 }; 185 186 useEffect(() => { 187 if (restaurant?.operatingHours && selectedDate) { 188 const options = generateTimeOptions(restaurant.operatingHours); 198 189 setTimeOptions(options); 199 190 } 200 191 }, [restaurant, selectedDate]); 201 192 202 // useEffect(() => {203 // if (checkInTime) {204 // const checkInDateObj = new Date(checkInTime);205 // setSelectedDate(checkInDateObj.toISOString().split("T")[0]);206 // setSelectedTime(checkInDateObj.toTimeString().slice(0, 5));207 // }208 // }, [checkInTime]);209 193 210 194 return ( … … 217 201 <div className="card-body"> 218 202 <h2 className="card-title"> 219 {formData.restaurant.name} <StarRating key={formData.restaurant.id} rating={formData.restaurant.rating} /> 203 {restaurant?.name} 204 <StarRating key={restaurant?.id} rating={restaurant?.rating || 0}/> 220 205 </h2> 221 <p className="card-text">{formData.restaurant.name}</p> 222 <p className="card-text">{formData.restaurant.operatingHours}</p> 223 <p className="card-text">Ul. {formData.restaurant.address}</p> 224 <br /> 206 <p className="card-text">Operating Hours: {restaurant?.operatingHours}</p> 207 <p className="card-text">Address: Ul. {restaurant?.address}</p> 208 <br/> 225 209 </div> 226 210 <form onSubmit={handleSubmit}> -
my-react-app/src/components/RestaurantDetails.js
rb67dfd3 re48199a 111 111 }); 112 112 }; 113 114 console.log(preOrderedItems)115 113 116 114 const roundToNext15Minutes = (date) => { -
my-react-app/src/components/StarRating.js
rb67dfd3 re48199a 2 2 3 3 const StarRating = ({ rating }) => { 4 // Convert the rating to a number between 0 and 55 4 const normalizedRating = Math.min(Math.max(0, rating), 5); 6 // Calculate the number of filled stars7 5 const filledStars = Math.floor(normalizedRating); 8 // Calculate the number of half stars9 6 const hasHalfStar = normalizedRating - filledStars >= 0.5; 10 7 … … 12 9 <div> 13 10 {[...Array(filledStars)].map((_, index) => ( 14 <span key={ index} className="star">★</span>11 <span key={`filled-${index}`} className="star">★</span> 15 12 ))} 16 {hasHalfStar && <span className="star">☆</span>} 13 14 {hasHalfStar && <span className="star half">★</span>} 15 17 16 {[...Array(5 - filledStars - (hasHalfStar ? 1 : 0))].map((_, index) => ( 18 <span key={ filledStars + index + 1} className="star">☆</span>17 <span key={`empty-${index}`} className="star">☆</span> 19 18 ))} 20 19 </div> … … 23 22 24 23 export default StarRating; 24 -
src/main/java/com/example/rezevirajmasa/demo/dto/ReservationDTO.java
rb67dfd3 re48199a 4 4 import com.example.rezevirajmasa.demo.model.Reservation; 5 5 import com.example.rezevirajmasa.demo.model.Restaurant; 6 import lombok.Setter; 6 7 7 8 import java.math.BigDecimal; 8 9 import java.time.LocalDateTime; 9 10 import java.util.List; 11 import java.util.stream.Collectors; 10 12 13 @Setter 11 14 public class ReservationDTO { 12 15 private Long reservationID; … … 21 24 private String specialRequests; 22 25 private String paymentStatus; 23 private List<PreorderedItem > preOrderedItems;26 private List<PreorderedItemDto> preOrderedItems; 24 27 25 28 public ReservationDTO() { … … 29 32 LocalDateTime reservationDateTime, LocalDateTime checkInTime, Long restaurantId, 30 33 int partySize, String reservationStatus, String specialRequests, 31 String paymentStatus, List<PreorderedItem > preOrderedItems) {34 String paymentStatus, List<PreorderedItemDto> preOrderedItems) { 32 35 this.reservationID = reservationID; 33 36 this.userEmail = userEmail; … … 56 59 this.specialRequests = reservation.getSpecialRequests(); 57 60 this.paymentStatus = reservation.getPaymentStatus(); 58 this.preOrderedItems = reservation.getPreOrderedItems(); 61 62 this.preOrderedItems = reservation.getPreOrderedItems().stream() 63 .map(preorderedItem -> new PreorderedItemDto( 64 preorderedItem.getPreorderedItemName(), 65 preorderedItem.getQuantity(), 66 preorderedItem.getPrice(), 67 preorderedItem.getMenu().getMenuID())) 68 .collect(Collectors.toList()); 59 69 } 60 70 … … 63 73 } 64 74 65 public void setReservationID(Long reservationID) {66 this.reservationID = reservationID;67 }68 69 75 public String getUserEmail() { 70 76 return userEmail; 71 }72 73 public void setUserEmail(String userEmail) {74 this.userEmail = userEmail;75 77 } 76 78 … … 79 81 } 80 82 81 public void setRating(BigDecimal rating) {82 this.rating = rating;83 }84 85 83 public Long getTableNumber() { 86 84 return tableNumber; 87 }88 89 public void setTableNumber(Long tableNumber) {90 this.tableNumber = tableNumber;91 85 } 92 86 … … 95 89 } 96 90 97 public void setReservationDateTime(LocalDateTime reservationDateTime) {98 this.reservationDateTime = reservationDateTime;99 }100 101 91 public LocalDateTime getCheckInTime() { 102 92 return checkInTime; 103 }104 105 public void setCheckInTime(LocalDateTime checkInTime) {106 this.checkInTime = checkInTime;107 93 } 108 94 … … 111 97 } 112 98 113 public void setRestaurantId(Long restaurantId) {114 this.restaurantId = restaurantId;115 }116 117 99 public int getPartySize() { 118 100 return partySize; 119 }120 121 public void setPartySize(int partySize) {122 this.partySize = partySize;123 101 } 124 102 … … 127 105 } 128 106 129 public void setReservationStatus(String reservationStatus) {130 this.reservationStatus = reservationStatus;131 }132 133 107 public String getSpecialRequests() { 134 108 return specialRequests; 135 }136 137 public void setSpecialRequests(String specialRequests) {138 this.specialRequests = specialRequests;139 109 } 140 110 … … 143 113 } 144 114 145 public void setPaymentStatus(String paymentStatus) { 146 this.paymentStatus = paymentStatus; 147 } 148 149 public List<PreorderedItem> getPreOrderedItems() { 115 public List<PreorderedItemDto> getPreOrderedItems() { 150 116 return preOrderedItems; 151 117 } 152 118 153 public void setPreOrderedItems(List<PreorderedItem> preOrderedItems) {154 this.preOrderedItems = preOrderedItems;155 }156 119 } -
src/main/java/com/example/rezevirajmasa/demo/model/Menu.java
rb67dfd3 re48199a 38 38 private List<MenuTag> tags = new ArrayList<>(); 39 39 40 @OneToMany(mappedBy = "menu", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) 41 private List<PriceHistory> priceHistoryList = new ArrayList<>(); 42 40 43 public Menu() { 41 44 } -
src/main/java/com/example/rezevirajmasa/demo/model/PreorderedItem.java
rb67dfd3 re48199a 26 26 private Integer quantity; 27 27 28 @Column(name = "price_at_order", precision = 8, scale = 2, nullable = false) 28 29 private BigDecimal price; 29 30 … … 32 33 @JoinColumn(name = "reservation_id", nullable = false) 33 34 private Reservation reservation; 35 36 @ManyToOne 37 @JoinColumn(name = "menu_id", nullable = false) 38 private Menu menu; 34 39 } -
src/main/java/com/example/rezevirajmasa/demo/model/Reservation.java
rb67dfd3 re48199a 1 1 package com.example.rezevirajmasa.demo.model; 2 2 3 import com.example.rezevirajmasa.demo.dto.PreorderedItemDto; 3 4 import com.fasterxml.jackson.annotation.JsonBackReference; 4 5 import com.fasterxml.jackson.annotation.JsonManagedReference; -
src/main/java/com/example/rezevirajmasa/demo/service/MenuService.java
rb67dfd3 re48199a 3 3 import com.example.rezevirajmasa.demo.model.Menu; 4 4 5 import java.math.BigDecimal; 5 6 import java.util.List; 6 7 7 8 public interface MenuService { 8 9 public List<Menu> getMenuByRestaurantId(Long restaurantId); 10 public void updateMenuPrice(Long menuId, BigDecimal newPrice); 11 public Menu getMenuById(Long id); 9 12 } -
src/main/java/com/example/rezevirajmasa/demo/service/impl/MenuServiceImpl.java
rb67dfd3 re48199a 2 2 3 3 import com.example.rezevirajmasa.demo.model.Menu; 4 import com.example.rezevirajmasa.demo.model.PriceHistory; 4 5 import com.example.rezevirajmasa.demo.model.Restaurant; 5 6 import com.example.rezevirajmasa.demo.repository.MenuRepository; 7 import com.example.rezevirajmasa.demo.repository.PriceHistoryRepository; 6 8 import com.example.rezevirajmasa.demo.service.MenuService; 7 9 import com.example.rezevirajmasa.demo.service.RestaurantService; 10 import org.openqa.selenium.InvalidArgumentException; 8 11 import org.springframework.stereotype.Service; 9 12 13 import java.math.BigDecimal; 14 import java.time.LocalDateTime; 10 15 import java.util.List; 11 16 … … 15 20 private final RestaurantService restaurantService; 16 21 17 public MenuServiceImpl(MenuRepository menuRepository, RestaurantService restaurantService) { 22 private final PriceHistoryRepository priceHistoryRepository; 23 24 public MenuServiceImpl(MenuRepository menuRepository, RestaurantService restaurantService, PriceHistoryRepository priceHistoryRepository) { 18 25 this.menuRepository = menuRepository; 19 26 this.restaurantService = restaurantService; 27 this.priceHistoryRepository = priceHistoryRepository; 20 28 } 21 29 … … 25 33 return menuRepository.findAllByRestaurant(restaurant); 26 34 } 35 36 @Override 37 public void updateMenuPrice(Long menuId, BigDecimal newPrice) { 38 Menu menu = menuRepository.findById(menuId) 39 .orElseThrow(() -> new IllegalArgumentException("Menu not found")); 40 41 if (menu.getPrice() != null && !menu.getPrice().equals(newPrice)) { 42 PriceHistory priceHistory = new PriceHistory(menu, menu.getPrice(), LocalDateTime.now()); 43 priceHistoryRepository.save(priceHistory); 44 } 45 46 menu.setPrice(newPrice); 47 menuRepository.save(menu); 48 } 49 50 @Override 51 public Menu getMenuById(Long id) { 52 return menuRepository.findById(id) 53 .orElseThrow(()->new InvalidArgumentException("Invalid id sent: " + id)); 54 } 27 55 } -
src/main/java/com/example/rezevirajmasa/demo/service/impl/ReservationImpl.java
rb67dfd3 re48199a 1 1 package com.example.rezevirajmasa.demo.service.impl; 2 2 3 import com.example.rezevirajmasa.demo.dto.PreorderedItemDto; 3 4 import com.example.rezevirajmasa.demo.dto.ReservationDTO; 4 5 import com.example.rezevirajmasa.demo.mappers.UserMapper; … … 8 9 import com.example.rezevirajmasa.demo.repository.ReservationRepository; 9 10 import com.example.rezevirajmasa.demo.repository.TableRepository; 11 import com.example.rezevirajmasa.demo.service.MenuService; 10 12 import com.example.rezevirajmasa.demo.service.ReservationHistoryService; 11 13 import com.example.rezevirajmasa.demo.service.ReservationService; 12 14 import com.example.rezevirajmasa.demo.service.UserService; 13 15 import org.springframework.beans.factory.annotation.Autowired; 16 import org.springframework.context.annotation.Lazy; 14 17 import org.springframework.stereotype.Service; 15 18 … … 31 34 @Autowired 32 35 private ReservationRepository reservationRepository; 36 @Autowired 37 @Lazy 38 private MenuService menuService; 33 39 34 40 public ReservationImpl(UserMapper userMapper) { … … 82 88 List<PreorderedItem> preOrderedItems = new ArrayList<>(); 83 89 84 for (PreorderedItem dtoItem : reservationDTO.getPreOrderedItems()) {90 for (PreorderedItemDto dtoItem : reservationDTO.getPreOrderedItems()) { 85 91 PreorderedItem item = new PreorderedItem(); 86 92 item.setPreorderedItemName(dtoItem.getPreorderedItemName()); … … 88 94 item.setPrice(dtoItem.getPrice()); 89 95 item.setReservation(reservation); 96 97 Menu menu = menuService.getMenuById(dtoItem.getMenuID()); 98 item.setMenu(menu); 90 99 91 100 preOrderedItems.add(item); -
src/main/java/com/example/rezevirajmasa/demo/web/rest/testController.java
rb67dfd3 re48199a 64 64 @GetMapping("/api/restaurants/{restaurantId}") 65 65 public ResponseEntity<RestaurantDTO> getRestaurantById(@PathVariable Long restaurantId) { 66 return new ResponseEntity<RestaurantDTO>(restaurantService.findById(restaurantId), HttpStatus.OK); 66 RestaurantDTO restaurantDTO = restaurantService.findById(restaurantId); 67 return new ResponseEntity<>(restaurantDTO, HttpStatus.OK); 67 68 } 68 69
Note:
See TracChangeset
for help on using the changeset viewer.