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/ReservationHistory.js

    r8ca35dc rf5b256e  
    55const ReservationHistory = () => {
    66    const [reservations, setReservations] = useState([]);
     7    const [filteredReservations, setFilteredReservations] = useState([]);
    78    const [loading, setLoading] = useState(true);
    89    const [error, setError] = useState(null);
     10
     11    const [restaurantFilter, setRestaurantFilter] = useState("");
     12    const [tableFilter, setTableFilter] = useState("");
     13    const [partySizeFilter, setPartySizeFilter] = useState("");
     14    const [statusFilter, setStatusFilter] = useState("");
     15    const [cancellationReasonFilter, setCancellationReasonFilter] = useState("");
     16
     17    const [startDate, setStartDate] = useState("");
     18    const [endDate, setEndDate] = useState("");
    919
    1020    useEffect(() => {
     
    2939
    3040                setReservations(response.data);
     41                setFilteredReservations(response.data);
    3142            } catch (err) {
    3243                setError("Failed to fetch reservations.");
     
    3950    }, []);
    4051
     52    useEffect(() => {
     53        let tempReservations = reservations;
     54
     55        if (restaurantFilter) {
     56            tempReservations = tempReservations.filter(res =>
     57                res.restaurant?.name.toLowerCase().includes(restaurantFilter.toLowerCase())
     58            );
     59        }
     60        if (tableFilter) {
     61            tempReservations = tempReservations.filter(res =>
     62                res.table?.id?.toString() === tableFilter
     63            );
     64        }
     65        if (partySizeFilter) {
     66            tempReservations = tempReservations.filter(res =>
     67                res.partySize?.toString() === partySizeFilter
     68            );
     69        }
     70        if (statusFilter) {
     71            tempReservations = tempReservations.filter(res =>
     72                res.status.toLowerCase().includes(statusFilter.toLowerCase())
     73            );
     74        }
     75        if (cancellationReasonFilter) {
     76            tempReservations = tempReservations.filter(res =>
     77                (res.cancellationReason || "None").toLowerCase().includes(cancellationReasonFilter.toLowerCase())
     78            );
     79        }
     80        if (startDate && endDate) {
     81            const start = new Date(startDate);
     82            const end = new Date(endDate);
     83
     84            tempReservations = tempReservations.filter(res => {
     85                const reservationDate = new Date(res.reservationDateTime);
     86                return reservationDate >= start && reservationDate <= end;
     87            });
     88        }
     89
     90        setFilteredReservations(tempReservations);
     91    }, [
     92        restaurantFilter,
     93        tableFilter,
     94        partySizeFilter,
     95        statusFilter,
     96        cancellationReasonFilter,
     97        startDate,
     98        endDate,
     99        reservations
     100    ]);
     101
     102    const resetFilters = () => {
     103        setRestaurantFilter("");
     104        setTableFilter("");
     105        setPartySizeFilter("");
     106        setStatusFilter("");
     107        setCancellationReasonFilter("");
     108        setStartDate("");
     109        setEndDate("");
     110    };
     111
    41112    if (loading) return <div>Loading...</div>;
    42113    if (error) return <div className="alert alert-danger">{error}</div>;
     
    44115    return (
    45116        <div className="container mt-5">
    46             <h3>Past Reservations</h3>
    47             <table className="table table-bordered">
    48                 <thead className="thead-dark">
    49                 <tr>
    50                     <th>#</th>
    51                     <th>Restaurant</th>
    52                     <th>Table</th>
    53                     <th>Date & Time</th>
    54                     <th>Party Size</th>
    55                     <th>Special Requests</th>
    56                     <th>Status</th>
    57                     <th>Cancellation Reason</th>
    58                 </tr>
    59                 </thead>
    60                 <tbody>
    61                 {reservations.map((res, index) => (
    62                     <tr key={res.id}>
    63                         <td>{index + 1}</td>
    64                         <td>{res.restaurant?.name || "N/A"}</td>
    65                         <td>{res.table?.id || "N/A"}</td>
    66                         <td>{new Date(res.reservationDateTime).toLocaleString()}</td>
    67                         <td>{res.partySize}</td>
    68                         <td>{res.specialRequests || "None"}</td>
    69                         <td>{res.status}</td>
    70                         <td>{res.cancellationReason || "None"}</td>
     117            <h3 className="mb-4 text-center">Past Reservations</h3>
     118
     119            <div className="row mb-4 align-items-end">
     120                <div className="col-md-2">
     121                    <input
     122                        type="text"
     123                        className="form-control"
     124                        placeholder="Filter by Restaurant"
     125                        value={restaurantFilter}
     126                        onChange={(e) => setRestaurantFilter(e.target.value)}
     127                    />
     128                </div>
     129                <div className="col-md-2">
     130                    <input
     131                        type="number"
     132                        className="form-control"
     133                        placeholder="Filter by Table ID"
     134                        value={tableFilter}
     135                        onChange={(e) => setTableFilter(e.target.value)}
     136                    />
     137                </div>
     138                <div className="col-md-4 d-flex gap-2">
     139                    <input
     140                        type="date"
     141                        className="form-control"
     142                        placeholder="Start date"
     143                        value={startDate}
     144                        onChange={(e) => setStartDate(e.target.value)}
     145                    />
     146                    <input
     147                        type="date"
     148                        className="form-control"
     149                        placeholder="End date"
     150                        value={endDate}
     151                        onChange={(e) => setEndDate(e.target.value)}
     152                    />
     153                </div>
     154                <div className="col-md-2">
     155                    <input
     156                        type="number"
     157                        className="form-control"
     158                        placeholder="Filter by Party Size"
     159                        value={partySizeFilter}
     160                        onChange={(e) => setPartySizeFilter(e.target.value)}
     161                    />
     162                </div>
     163                <div className="col-md-2">
     164                    <select
     165                        value={statusFilter}
     166                        onChange={(e) => setStatusFilter(e.target.value)}
     167                        className="form-control"
     168                    >
     169                        <option value="">Filter by status</option>
     170                        <option value="successful">Successful</option>
     171                        <option value="canceled">Canceled</option>
     172                    </select>
     173                </div>
     174                <div className="col-md-2 mt-2">
     175                    <input
     176                        type="text"
     177                        className="form-control"
     178                        placeholder="Filter by Cancellation Reason"
     179                        value={cancellationReasonFilter}
     180                        onChange={(e) => setCancellationReasonFilter(e.target.value)}
     181                    />
     182                </div>
     183                <div className="col-md-2 mt-2">
     184                    <button
     185                        onClick={resetFilters}
     186                        className="btn btn-outline-secondary w-100"
     187                    >
     188                        Reset Filters
     189                    </button>
     190                </div>
     191            </div>
     192
     193            <div className="table-responsive">
     194                <table className="table table-striped table-hover table-bordered align-middle">
     195                    <thead className="table-dark text-center">
     196                    <tr>
     197                        <th>#</th>
     198                        <th>Restaurant</th>
     199                        <th>Table</th>
     200                        <th>Date & Time</th>
     201                        <th>Party Size</th>
     202                        <th>Special Requests</th>
     203                        <th>Status</th>
     204                        <th>Cancellation Reason</th>
    71205                    </tr>
    72                 ))}
    73                 </tbody>
    74             </table>
     206                    </thead>
     207                    <tbody>
     208                    {filteredReservations.length > 0 ? (
     209                        filteredReservations.map((res, index) => (
     210                            <tr key={res.id}>
     211                                <td>{index + 1}</td>
     212                                <td>{res.restaurant?.name || "N/A"}</td>
     213                                <td>{res.table?.id || "N/A"}</td>
     214                                <td>{new Date(res.reservationDateTime).toLocaleString()}</td>
     215                                <td>{res.partySize}</td>
     216                                <td>{res.specialRequests || "None"}</td>
     217                                <td>{res.status}</td>
     218                                <td>{res.cancellationReason || "None"}</td>
     219                            </tr>
     220                        ))
     221                    ) : (
     222                        <tr>
     223                            <td colSpan="8" className="text-center">No reservations found.</td>
     224                        </tr>
     225                    )}
     226                    </tbody>
     227                </table>
     228            </div>
    75229        </div>
    76230    );
Note: See TracChangeset for help on using the changeset viewer.