source: my-react-app/src/components/ReservationConfirmation.js@ 8ca35dc

main
Last change on this file since 8ca35dc was 8ca35dc, checked in by Aleksandar Panovski <apano77@…>, 4 months ago

Done with stupid timeslots

  • Property mode set to 100644
File size: 6.3 KB
Line 
1import React, { useState, useEffect } from 'react';
2import { useParams } from 'react-router-dom';
3import axios from 'axios';
4import { useNavigate } from 'react-router-dom';
5import {jwtDecode} from "jwt-decode";
6
7const ReservationConfirmation = () => {
8 const navigate = useNavigate();
9
10 const [restaurant, setRestaurant] = useState({});
11 const [table, setTable] = useState({});
12 const [reservationDateTime, setReservationDateTime] = useState('');
13 const [partySize, setPartySize] = useState('');
14 const [specialRequests, setSpecialRequests] = useState('');
15 const { tableNumber, timeSlot, restaurantId } = useParams();
16
17 useEffect(() => {
18 const fetchTableDetails = async () => {
19 try {
20 const tableResponse = await axios.get(`http://localhost:8081/api/tables/${tableNumber}`);
21 setTable(tableResponse.data);
22
23 const restaurantResponse = await axios.get(`http://localhost:8081/api/restaurants/${restaurantId}`);
24 setRestaurant(restaurantResponse.data);
25 } catch (error) {
26 console.error('Error fetching table details:', error);
27 }
28 };
29 fetchTableDetails();
30 }, [tableNumber, restaurantId]);
31
32 const handleSubmit = async (e) => {
33 e.preventDefault();
34
35 if (!restaurant || !table) {
36 console.error("Restaurant or table is missing.");
37 return;
38 }
39
40 try {
41 const token = localStorage.getItem("token");
42 if (!token) {
43 console.error("No token found");
44 return;
45 }
46
47 // Decode the token to get the user email
48 const decodedToken = jwtDecode(token);
49 console.log(decodedToken)
50 const userId = decodedToken.iss;// Assuming the email is part of the decoded JWT token
51
52 const response = await axios.post(
53 `http://localhost:8081/api/reservations/${userId}`,
54 {
55 restaurant: restaurant,
56 table: table,
57 checkInTime: timeSlot,
58 partySize: partySize,
59 specialRequests: specialRequests
60 },
61 {
62 headers: {
63 Authorization: `Bearer ${token}` // Include the token here
64 }
65 }
66 );
67
68 navigate("/reservations");
69 } catch (error) {
70 console.error("Error creating reservation:", error);
71 }
72 };
73
74 const initialRemainingTime = localStorage.getItem('remainingTime') || 300;
75 const [remainingTime, setRemainingTime] = useState(parseInt(initialRemainingTime));
76
77 useEffect(() => {
78 const timer = setInterval(() => {
79 setRemainingTime((prevTime) => {
80 const newTime = prevTime - 1;
81 localStorage.setItem('remainingTime', newTime.toString()); // Update remaining time in localStorage
82 return newTime;
83 });
84 }, 1000);
85
86 return () => clearInterval(timer);
87 }, []);
88
89 useEffect(() => {
90 // Reset remaining time if it reaches zero
91 if (remainingTime <= 0) {
92 localStorage.removeItem('remainingTime');
93 // Optionally, handle releasing the hold on the table
94 }
95 }, [remainingTime]);
96
97 const formatTime = (timeInSeconds) => {
98 const minutes = Math.floor(timeInSeconds / 60);
99 const seconds = timeInSeconds % 60;
100 return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
101 };
102
103 return (
104 <div className="container mt-5">
105 <div className="row justify-content-center">
106 <div className="col-md-6">
107 <div className="card">
108 <div className="card-header">
109 <h3 className="text-center">Reservation Confirmation</h3>
110 <p>Remaining Time: {formatTime(remainingTime)}</p>
111 </div>
112 <form onSubmit={handleSubmit}>
113 <div className="card-body">
114 <h5 className="card-title">Reservation Details</h5>
115 <p className="card-text">
116 <strong>Restaurant:</strong> {restaurant.name || 'Loading...'} <br/>
117 <strong>Cuisine type:</strong> {restaurant.cuisineType || 'Loading...'} <br/>
118 <strong>Selected Time Slot:</strong> {timeSlot} <br/>
119 <strong>Party size:</strong> <input type="number" max={table.capacity}
120 value={partySize}
121 onChange={(e) => setPartySize(e.target.value)}/>
122 <strong>Table size:</strong> {table.capacity} <br/>
123 <strong>Special Requests:</strong> <input type="text" value={specialRequests}
124 onChange={(e) => setSpecialRequests(e.target.value)}/><br/>
125 </p>
126 <p className="card-text text-success">
127 <strong>Check-in Time: grace period of 15 minutes +- the slot, for more call the
128 restaurant</strong><br/>
129 </p>
130 </div>
131 <div className="card-footer">
132 <button type="submit" className="btn btn-primary">Submit</button>
133 </div>
134 <div className="card-footer">
135 <a href="/restaurants" className="btn btn-primary">Back to Restaurants</a>
136 </div>
137 <div className="card-footer">
138 <a href="/" className="btn btn-primary">Back to Home</a>
139 </div>
140 </form>
141 </div>
142 </div>
143
144 </div>
145 </div>
146 );
147};
148
149export default ReservationConfirmation;
Note: See TracBrowser for help on using the repository browser.