Ignore:
Timestamp:
05/02/25 15:06:42 (2 weeks ago)
Author:
Aleksandar Panovski <apano77@…>
Branches:
main
Children:
142c0f8
Parents:
2518b3a
Message:

Fixed bugs and fully developed menu now. Readonly added.

File:
1 edited

Legend:

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

    r2518b3a rc44c5ed  
    11import React, { useEffect, useState } from "react";
    2 import {jwtDecode} from "jwt-decode";
     2import { jwtDecode } from "jwt-decode";
    33import axios from "axios";
     4import 'bootstrap/dist/css/bootstrap.min.css';
     5import 'bootstrap/dist/js/bootstrap.bundle.min';
    46
    57const ReservationHistory = () => {
    68    const [reservations, setReservations] = useState([]);
    79    const [filteredReservations, setFilteredReservations] = useState([]);
     10    const [selectedReservation, setSelectedReservation] = useState(null);
    811    const [loading, setLoading] = useState(true);
    912    const [error, setError] = useState(null);
     
    1417    const [statusFilter, setStatusFilter] = useState("");
    1518    const [cancellationReasonFilter, setCancellationReasonFilter] = useState("");
    16 
    1719    const [startDate, setStartDate] = useState("");
    1820    const [endDate, setEndDate] = useState("");
     
    113115    if (error) return <div className="alert alert-danger">{error}</div>;
    114116
     117    const formatDateTime = (dateString) => {
     118        if (!dateString) return "N/A";
     119        const date = new Date(dateString);
     120        return date.toLocaleString("en-GB", {
     121            day: "2-digit",
     122            month: "short",
     123            year: "numeric",
     124            hour: "2-digit",
     125            minute: "2-digit",
     126        });
     127    };
     128
    115129    return (
    116130        <div className="container mt-5">
     
    140154                        type="date"
    141155                        className="form-control"
    142                         placeholder="Start date"
    143156                        value={startDate}
    144157                        onChange={(e) => setStartDate(e.target.value)}
     
    147160                        type="date"
    148161                        className="form-control"
    149                         placeholder="End date"
    150162                        value={endDate}
    151163                        onChange={(e) => setEndDate(e.target.value)}
     
    156168                        type="number"
    157169                        className="form-control"
    158                         placeholder="Filter by Party Size"
     170                        placeholder="Party Size"
    159171                        value={partySizeFilter}
    160172                        onChange={(e) => setPartySizeFilter(e.target.value)}
     
    167179                        className="form-control"
    168180                    >
    169                         <option value="">Filter by status</option>
     181                        <option value="">Filter by Status</option>
    170182                        <option value="successful">Successful</option>
    171183                        <option value="canceled">Canceled</option>
     
    176188                        type="text"
    177189                        className="form-control"
    178                         placeholder="Filter by Cancellation Reason"
     190                        placeholder="Cancellation Reason"
    179191                        value={cancellationReasonFilter}
    180192                        onChange={(e) => setCancellationReasonFilter(e.target.value)}
     
    198210                        <th>Restaurant</th>
    199211                        <th>Table</th>
    200                         <th>Date & Time</th>
     212                        <th>Check In Date</th>
     213                        <th>Reserved on</th>
    201214                        <th>Party Size</th>
    202215                        <th>Special Requests</th>
     
    208221                    {filteredReservations.length > 0 ? (
    209222                        filteredReservations.map((res, index) => (
    210                             <tr key={res.id}>
     223                            <tr key={res.id} onClick={() => setSelectedReservation(res)} style={{ cursor: "pointer" }}>
    211224                                <td>{index + 1}</td>
    212225                                <td>{res.restaurant?.name || "N/A"}</td>
    213226                                <td>{res.table?.id || "N/A"}</td>
     227                                <td>{formatDateTime(res.checkInDate)}</td>
    214228                                <td>{new Date(res.reservationDateTime).toLocaleString()}</td>
    215229                                <td>{res.partySize}</td>
     
    221235                    ) : (
    222236                        <tr>
    223                             <td colSpan="8" className="text-center">No reservations found.</td>
     237                            <td colSpan="9" className="text-center">No reservations found.</td>
    224238                        </tr>
    225239                    )}
     
    227241                </table>
    228242            </div>
     243
     244            {/* Modal for reservation details */}
     245            {selectedReservation && (
     246                <div className="modal fade show d-block" tabIndex="-1" style={{ backgroundColor: "rgba(0,0,0,0.5)" }} onClick={() => setSelectedReservation(null)}>
     247                    <div className="modal-dialog modal-lg" onClick={(e) => e.stopPropagation()}>
     248                        <div className="modal-content">
     249                            <div className="modal-header">
     250                                <h5 className="modal-title">Reservation Details</h5>
     251                                <button type="button" className="btn-close" onClick={() => setSelectedReservation(null)}></button>
     252                            </div>
     253                            <div className="modal-body">
     254                                <h6>🍽️ Restaurant Info</h6>
     255                                <p><strong>Name:</strong> {selectedReservation.restaurant?.name}</p>
     256                                <p><strong>Address:</strong> {selectedReservation.restaurant?.address}</p>
     257                                <p><strong>Phone:</strong> {selectedReservation.restaurant?.phone}</p>
     258                                <p><strong>Rating:</strong> {selectedReservation.restaurant?.rating} ⭐</p>
     259                                <p><strong>Cuisine:</strong> {selectedReservation.restaurant?.cuisineType}</p>
     260                                <p><strong>Hours:</strong> {selectedReservation.restaurant?.operatingHours}</p>
     261                                {selectedReservation.restaurant?.website && (
     262                                    <p><strong>Website:</strong> <a href={`https://${selectedReservation.restaurant.website}`} target="_blank" rel="noopener noreferrer">{selectedReservation.restaurant.website}</a></p>
     263                                )}
     264
     265                                <hr />
     266
     267                                <h6>🪑 Table Info</h6>
     268                                <p><strong>Location:</strong> {selectedReservation.table?.location}</p>
     269                                <p><strong>Capacity:</strong> {selectedReservation.table?.capacity}</p>
     270                                <p><strong>Smoking Area:</strong> {selectedReservation.table?.smokingArea ? "Yes" : "No"}</p>
     271                                <p><strong>Description:</strong> {selectedReservation.table?.description}</p>
     272                                <p><strong>Reservation Duration:</strong> {selectedReservation.table?.reservationDurationHours} hours</p>
     273
     274                                <hr />
     275
     276                                <h6>📋 Reservation Info</h6>
     277                                <p><strong>Check-In Date:</strong> {formatDateTime(selectedReservation.checkInDate)}</p>
     278                                <p><strong>Reserved on:</strong> {new Date(selectedReservation.reservationDateTime).toLocaleString()}</p>
     279                                <p><strong>Party Size:</strong> {selectedReservation.partySize}</p>
     280                                <p><strong>Special Requests:</strong> {selectedReservation.specialRequests || "None"}</p>
     281                                <p><strong>Status:</strong> {selectedReservation.status}</p>
     282                                <p><strong>Cancellation Reason:</strong> {selectedReservation.cancellationReason || "None"}</p>
     283                            </div>
     284                            <div className="modal-footer">
     285                                <button className="btn btn-secondary" onClick={() => setSelectedReservation(null)}>Close</button>
     286                            </div>
     287                        </div>
     288                    </div>
     289                </div>
     290            )}
    229291        </div>
    230292    );
Note: See TracChangeset for help on using the changeset viewer.