Ignore:
Timestamp:
04/28/25 14:20:18 (3 weeks ago)
Author:
Aleksandar Panovski <apano77@…>
Branches:
main
Children:
deea3c4
Parents:
8ca35dc
Message:

Big change done works with handle_reservation_update() trigger

File:
1 edited

Legend:

Unmodified
Added
Removed
  • my-react-app/src/App.js

    r8ca35dc rf5b256e  
    11import {BrowserRouter as Router, Navigate, Route, Routes, useNavigate} from 'react-router-dom';
     2
    23import Customers from './components/Customers';
    34import Layout from "./components/Layout";
     
    1718import AppContent from "./components/AppContent";
    1819import ReservationHistory from "./components/ReservationHistory";
     20import AuthContent from "./components/AuthContent";
    1921
    2022const ProtectedRoute = ({ element, isAuthenticated }) => {
     
    2325
    2426const App = () => {
    25     const [isAuthenticated, setIsAuthenticated] = React.useState(false);
    26 
    27     React.useEffect(() => {
     27    const [isAuthenticated, setIsAuthenticated] = useState(false);
     28
     29    useEffect(() => {
    2830        const token = localStorage.getItem('token');
    2931        if (token) {
     
    6062    const navigate = useNavigate();
    6163
    62     const todayDate = new Date().toISOString().split('T')[0]; // Get today's date in 'YYYY-MM-DD' format
     64    const todayDate = new Date().toISOString().split('T')[0];
    6365
    6466    const [date, setDate] = useState(todayDate);
     
    8082            const isToday = selectedDate.toDateString() === today.toDateString();
    8183
    82             // Determine the start hour and minute
    8384            let startHour = 9;
    8485            let startMinute = 0;
     
    8687                const currentHour = today.getHours();
    8788                const currentMinute = today.getMinutes();
    88                 // If current time is later than 09:00, start from the current hour and minute
    8989                if (currentHour > 9 || (currentHour === 9 && currentMinute >= 0)) {
    9090                    startHour = currentHour;
     
    9393            }
    9494
    95             // Create the start time and end time
    9695            const startTime = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate(), startHour, startMinute);
    9796            const endTime = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate(), 23, 30);
    9897
    99             // Generate time slots from start time to end time in 15-minute intervals
    10098            const slots = [];
    10199            let currentTime = new Date(startTime);
     
    106104            }
    107105
    108             // Update the timeSlots state
    109106            setTimeSlots(slots);
    110107        }
    111108    }, [date]);
     109
     110    const handleGoToRestaurant = (restaurantId) => {
     111        navigate(`/restaurants/${restaurantId}`);
     112    };
    112113
    113114    const handleDateChange = (e) => {
     
    134135        if (selectedTime) {
    135136            const [selectedHours, selectedMinutes] = selectedTime.split(":");
    136             // Check if selectedHours and selectedMinutes are valid numbers
    137137            if (!isNaN(selectedHours) && !isNaN(selectedMinutes)) {
    138138                const dateTime = new Date(Date.UTC(year, month - 1, day, selectedHours, selectedMinutes));
     
    141141            }
    142142        } else {
    143             // Find the first available time slot after the current time
    144143            const now = new Date();
    145             const currentTime = now.getHours() * 60 + now.getMinutes(); // Current time in minutes
     144            const currentTime = now.getHours() * 60 + now.getMinutes();
    146145            const nextSlot = timeSlots.find(slot => {
    147146                const [hours, minutes] = slot.split(":");
    148                 const slotTime = parseInt(hours) * 60 + parseInt(minutes); // Time of the slot in minutes
     147                const slotTime = parseInt(hours) * 60 + parseInt(minutes);
    149148                return slotTime > currentTime;
    150149            });
    151150
    152             // If no slot is found after the current time, use the first slot of the day
    153151            formattedDateTime = nextSlot ? `${date} ${nextSlot}` : `${date} ${timeSlots[0]}`;
    154152        }
     
    160158        };
    161159
    162         console.log("Data to be submitted:");
    163         console.log(data);
    164 
    165160        try {
    166161            const response = await axios.post('http://localhost:8081/api/search', data);
    167162            const filteredRestaurants = response.data;
    168163            setFilteredRestaurants(filteredRestaurants);
    169             console.log(filteredRestaurants);
     164            console.log(filteredRestaurants)
    170165            setShowCuisineSearch(false);
    171             // Handle response accordingly
    172166        } catch (error) {
    173167            console.error('Error:', error);
     
    179173        try {
    180174            const response = await axios.post(`http://localhost:8081/api/search/shortcut/${cuisineName}`, cuisineName);
    181             console.log(response.data);
    182175            setFilteredRestaurants(response.data)
     176            console.log(response.data)
    183177        } catch (error) {
    184178            console.error('Error searching by cuisine:', error);
     
    186180        setShowCuisineSearch(false);
    187181    };
     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}`;
    188224
    189225    const handleTimeSlotClick = (table, timeSlot, restaurant) => {
     
    192228        const restaurantId = restaurant.restaurantId;
    193229
    194         const encodedTableNumber = encodeURI(tableNumber);
     230        const encodedTableNumber = encodeURIComponent(tableNumber);
    195231        const encodedTimeSlot = encodeURIComponent(formattedTimeSlot);
    196232        const encodedRestaurantId = encodeURIComponent(restaurantId);
    197233
    198234        navigate(`/reservationConfirmation/${encodedTableNumber}/${encodedTimeSlot}/${encodedRestaurantId}`);
    199     }
     235    };
    200236
    201237    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]) {
    216249                renderedTimeSlots[table.capacity] = 0;
    217250                return (
    218251                    <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]++;
    227258                                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                                });
    229263
    230264                                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} {}
    233271                                    </button>
    234272                                );
     273                                <br/>
    235274                            } else {
    236                                 return null; // Render nothing if the condition is not met
     275                                return null;
    237276                            }
    238277                        })}
     
    240279                );
    241280            } else {
    242                 // If capacity has been rendered, return null to avoid duplicate rendering
    243281                return null;
    244282            }
    245283        });
    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    };
    257285
    258286
     
    286314                        placeholder="Restaurant or Cuisine"
    287315                        aria-label="Search"
    288                         value={searchValue} // Set the value of the input field
    289                         onChange={handleInputChange} // Call the event handler on change
     316                        value={searchValue}
     317                        onChange={handleInputChange}
    290318                    />
    291319                </div>
     
    299327                            <div className="card-body">
    300328                                <RestaurantInfo key={restaurant.id} restaurant={restaurant}/>
    301                                 <p>Available time slots</p>
     329                                {/*<p>Available time slots</p>*/}
    302330                                <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                                    )}
    304338                                </div>
     339                                <button
     340                                    className="btn btn-secondary"
     341                                    onClick={() => handleGoToRestaurant(restaurant.restaurantId)}
     342                                >
     343                                    Go to Restaurant
     344                                </button>
    305345                            </div>
    306346                        </div>
     
    308348                </div>
    309349
    310 
    311350                {showCuisineSearch && (
    312351                    <div className="mb-3">
    313352                        <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                )}
    325365            </form>
    326366        </div>
Note: See TracChangeset for help on using the changeset viewer.