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/components/Restaurants.js

    r8ca35dc rf5b256e  
    44import { useNavigate } from 'react-router-dom';
    55import {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};
    623
    724const Restaurants = () => {
     
    1431    }, [restaurantContext]);
    1532
     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
    1657    const handleDetailClick = (restaurantId) => {
    1758        navigate(`/restaurants/${restaurantId}`);
    18     }
     59    };
    1960
    2061    const handleTimeSlotClick = (table, timeSlot, restaurant) => {
     
    2364        const restaurantId = restaurant.restaurantId;
    2465
    25         const encodedTableNumber = encodeURI(tableNumber);
     66        const encodedTableNumber = encodeURIComponent(tableNumber);
    2667        const encodedTimeSlot = encodeURIComponent(formattedTimeSlot);
    2768        const encodedRestaurantId = encodeURIComponent(restaurantId);
    2869
    2970        navigate(`/reservationConfirmation/${encodedTableNumber}/${encodedTimeSlot}/${encodedRestaurantId}`);
    30     }
     71    };
    3172
    3273    const renderTimeSlots = (tablesList, restaurant) => {
    3374        const currentTime = new Date().getTime();
    34         let renderedTimeSlots = {}; // Object to store rendered slots for each table capacity
     75        let renderedTimeSlots = {};
    3576
    36         return tablesList.flatMap(table => {
    37             // Render capacity header when encountering a new capacity
     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
    3884            if (!renderedTimeSlots[table.capacity]) {
    3985                renderedTimeSlots[table.capacity] = 0;
    4086                return (
    4187                    <div key={table.capacity}>
    42                         <h3>Table for: {table.capacity}</h3>
    43                         {table.timeSlots.map((timeSlot, index) => {
     88                        <h3>Table for {table.capacity} guests</h3>
     89                        {tableTimeSlots.map((timeSlot, index) => {
    4490                            const timeSlotTime = new Date(timeSlot).getTime();
    45                             const tableCapacity = table.capacity;
    4691
    47                             // Check if the time slot is after the current time and limit to 3 slots
    48                             if (timeSlotTime > currentTime && renderedTimeSlots[tableCapacity] < 3) {
    49                                 renderedTimeSlots[tableCapacity]++;
     92                            if (timeSlotTime > currentTime && renderedTimeSlots[table.capacity] < 3) {
     93                                renderedTimeSlots[table.capacity]++;
    5094                                const timeSlotDateTime = new Date(timeSlot);
    51                                 const formattedTime = timeSlotDateTime.toLocaleTimeString();
    52                                 const formattedDateTime = timeSlotDateTime.toLocaleString(); // Format for both date and time
     95                                const formattedTime = timeSlotDateTime.toLocaleTimeString([], {
     96                                    hour: '2-digit',
     97                                    minute: '2-digit'
     98                                });
    5399
    54100                                return (
    55                                     <button key={index} className="btn btn-primary me-2 mb-2" onClick={() => handleTimeSlotClick(table, timeSlot, restaurant)}>
    56                                         {formattedDateTime} {/* Display both date and time */}
     101                                    <button
     102                                        key={index}
     103                                        className="btn btn-primary me-2 mb-2"
     104                                        onClick={() => handleTimeSlotClick(table, timeSlot, restaurant)}
     105                                    >
     106                                        {formattedTime} {}
    57107                                    </button>
    58108                                );
    59109                            } else {
    60                                 return null; // Render nothing if the condition is not met
     110                                return null;
    61111                            }
    62112                        })}
     
    64114                );
    65115            } else {
    66                 // If capacity has been rendered, return null to avoid duplicate rendering
    67116                return null;
    68117            }
    69118        });
    70 
    71     }
    72 
     119    };
    73120
    74121    return (
     
    77124            <div className="row">
    78125                {restaurants.map((restaurant) => (
    79                     <div key={restaurant.id} className="col-md-4 mb-4">
     126                    <div key={restaurant.restaurantId} className="col-md-4 mb-4">
    80127                        <div className="card">
    81128                            <div className="card-body">
    82129                                <h5 className="card-title">
    83                                     {restaurant.name} <StarRating key={restaurant.id} rating={restaurant.rating}/>
     130                                    {restaurant.name}
    84131                                </h5>
    85132                                <p className="card-text">{restaurant.cuisineType}</p>
    86133                                <p className="card-text">{restaurant.operatingHours}</p>
    87134                                <p className="card-text">Ul. {restaurant.address}</p>
    88                                 <div className="d-flex flex-wrap">
    89                                     {renderTimeSlots(restaurant.tablesList.flatMap((table) => table), restaurant)}
    90                                 </div>
     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                                )}
    91143                            </div>
    92                             <button onClick={() => handleDetailClick(restaurant.restaurantId)}
    93                                     className="btn btn-primary">View Details
     144                            <button onClick={() => handleDetailClick(restaurant.restaurantId)} className="btn btn-primary">
     145                                View Details
    94146                            </button>
    95147                        </div>
Note: See TracChangeset for help on using the changeset viewer.