I redid my file structure and moved my axiosinstance into a folder in components called services. Then made api.jsx
import AxiosInstance from "./AxiosInstance"; // ✅ Fix import
// Fetch user's bookings
export const fetchBookings = async () => {
try {
const response = await AxiosInstance.get("/bookings/"); // ✅ Use AxiosInstance
return response.data;
} catch (error) {
console.error("❌ Error fetching bookings:", error.response?.data || error.message);
throw error;
}
};
// Create a new booking
export const createBooking = async (bookingData) => {
try {
const response = await AxiosInstance.post("/bookings/", bookingData); // ✅ Use AxiosInstance
return response.data;
} catch (error) {
console.error("❌ Error creating booking:", error.response?.data || error.message);
throw error;
}
};
// Delete a booking
export const deleteBooking = async (bookingId) => {
try {
await AxiosInstance.delete(`/bookings/${bookingId}/`); // ✅ Use AxiosInstance
} catch (error) {
console.error("❌ Error deleting booking:", error.response?.data || error.message);
throw error;
}
};
We now make bookings components in components folder
Booking form
import React, { useState } from "react";
import { createBooking } from "./services/api";
const BookingForm = ({ onBookingCreated }) => {
const [bookingType, setBookingType] = useState("booking");
const [bookingDate, setBookingDate] = useState("");
const handleSubmit = async (e) => {
e.preventDefault();
// Ensure the date is in the future
const today = new Date().toISOString().split("T")[0]; // Get today's date in YYYY-MM-DD format
if (bookingDate <= today) {
alert("Please select a future date.");
return;
}
try {
const newBooking = await createBooking({
booking_type: bookingType,
booking_date: bookingDate,
});
alert("Booking created successfully!");
onBookingCreated(newBooking); // Update the UI with the new booking
} catch (error) {
alert("Failed to create booking. Please try again.");
}
};
return (
<div className="max-w-md mx-auto bg-white p-6 rounded-lg shadow-md">
<h2 className="text-xl font-semibold mb-4">Schedule a Booking</h2>
<form onSubmit={handleSubmit}>
<div className="mb-4">
<label className="block font-medium">Booking Type:</label>
<select
className="w-full p-2 border rounded"
value={bookingType}
onChange={(e) => setBookingType(e.target.value)}
>
<option value="booking">Consultation</option>
<option value="installation">Installation</option>
</select>
</div>
<div className="mb-4">
<label className="block font-medium">Select Date:</label>
<input
type="date"
className="w-full p-2 border rounded"
value={bookingDate}
onChange={(e) => setBookingDate(e.target.value)}
/>
</div>
<button
type="submit"
className="w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600"
>
Schedule
</button>
</form>
</div>
);
};
export default BookingForm;
Then booking list
import React, { useEffect, useState } from "react";
import { fetchBookings, deleteBooking } from "./services/api";
const BookingList = () => {
const [bookings, setBookings] = useState([]); // ✅ Ensure an array as the initial state
const [loading, setLoading] = useState(true); // Track loading state
useEffect(() => {
loadBookings();
}, []);
const loadBookings = async () => {
try {
setLoading(true);
const data = await fetchBookings();
if (Array.isArray(data)) {
setBookings(data); // ✅ Ensure only an array is set
} else {
console.error("Unexpected response format:", data);
setBookings([]); // Set an empty array to prevent errors
}
} catch (error) {
console.error("Error loading bookings:", error);
setBookings([]); // Prevent crash if error occurs
} finally {
setLoading(false);
}
};
const handleDelete = async (bookingId) => {
if (window.confirm("Are you sure you want to cancel this booking?")) {
try {
await deleteBooking(bookingId);
setBookings(bookings.filter((booking) => booking.id !== bookingId));
alert("Booking canceled.");
} catch (error) {
alert("Failed to cancel booking.");
}
}
};
return (
<div className="max-w-md mx-auto bg-white p-6 rounded-lg shadow-md">
<h2 className="text-xl font-semibold mb-4">My Bookings</h2>
{loading ? (
<p>Loading...</p> // Show loading state
) : bookings.length === 0 ? (
<p>No bookings found.</p>
) : (
<ul>
{bookings.map((booking) => (
<li key={booking.booking_id} className="border-b p-2 flex justify-between items-center">
<div>
<p className="font-medium">{booking.booking_type.toUpperCase()}</p>
<p className="text-sm text-gray-500">{booking.booking_date}</p>
</div>
<button
onClick={() => handleDelete(booking.booking_id)}
className="text-red-500 hover:text-red-700"
>
Cancel
</button>
</li>
))}
</ul>
)}
</div>
);
};
export default BookingList;
then BookingsPage
import React, { useState } from "react";
import BookingForm from "../components/BookingForm";
import BookingList from "../components/BookingList";
const BookingsPage = () => {
const [refresh, setRefresh] = useState(false);
return (
<div className="container mx-auto p-4">
<h1 className="text-2xl font-bold text-center mb-6">Manage Your Bookings</h1>
<BookingForm onBookingCreated={() => setRefresh(!refresh)} />
<BookingList key={refresh} />
</div>
);
};
export default BookingsPage;
Finally add bookings route to app.jsx
import BookingsPage from './components/BookingsPage'
<Route path="/bookings" element={<BookingsPage/>}/>
dun
Top comments (0)