From 014722a327862e5d90d4d19c97c989563c569982 Mon Sep 17 00:00:00 2001 From: haseebzaki-07 Date: Sun, 13 Oct 2024 01:35:13 +0530 Subject: [PATCH 1/3] Add station bookings --- backend/controllers/StationController.js | 59 +++++ backend/controllers/WheelchairController.js | 2 +- .../controllers/stationBookingsController.js | 74 +++++++ backend/index.js | 3 + backend/models/CloakroomBooking.js | 5 +- backend/models/CoolieBooking.js | 6 +- backend/models/Stations.js | 15 +- backend/models/WheelchairBooking.js | 16 +- backend/routes/stationRoutes.js | 19 ++ frontend/package-lock.json | 1 - frontend/src/App.jsx | 3 +- frontend/src/Pages/booking.jsx | 116 +--------- frontend/src/components/Bookingform.jsx | 201 ++++++++++++++++++ 13 files changed, 393 insertions(+), 127 deletions(-) create mode 100644 backend/controllers/StationController.js create mode 100644 backend/controllers/stationBookingsController.js create mode 100644 backend/routes/stationRoutes.js create mode 100644 frontend/src/components/Bookingform.jsx diff --git a/backend/controllers/StationController.js b/backend/controllers/StationController.js new file mode 100644 index 0000000..b5d29f6 --- /dev/null +++ b/backend/controllers/StationController.js @@ -0,0 +1,59 @@ +// controllers/stationController.js +import Station from '../models/Stations.js'; + +export const createStation = async (req, res) => { + try { + const { + name, + location, // Location object with postalCode, city, and state + stationCode, + capacity, + services + } = req.body; + + // Create a new station document + const newStation = new Station({ + name, + location, + stationCode, + capacity, + services + }); + + // Save the station document in the database + const savedStation = await newStation.save(); + + res.status(201).json({ + message: 'Station created successfully', + station: savedStation + }); + } catch (error) { + console.error('Error creating station:', error); + res.status(500).json({ + message: 'Failed to create station', + error: error.message + }); + } +}; + + +export const getAllStations = async (req, res) => { + try { + // Fetch all stations from the database + const stations = await Station.find() + .populate('coolies', 'name') // Populating the coolies field with only their name + .populate('wheelchairs', 'name') // Populating the wheelchairs field with only their name + .populate('cloakrooms', 'name'); // Populating the cloakrooms field with only their name + + // If no stations are found, return a 404 error + if (!stations || stations.length === 0) { + return res.status(404).json({ message: 'No stations found' }); + } + + // Return the stations as JSON + return res.status(200).json(stations); + } catch (error) { + // Return a 500 error if something goes wrong + return res.status(500).json({ message: 'Server error', error: error.message }); + } +}; \ No newline at end of file diff --git a/backend/controllers/WheelchairController.js b/backend/controllers/WheelchairController.js index ed57e49..d164961 100644 --- a/backend/controllers/WheelchairController.js +++ b/backend/controllers/WheelchairController.js @@ -1,4 +1,4 @@ -import WheelchairBooking from "../models/WheelChairBooking.js"; +import WheelchairBooking from "../models/WheelchairBooking.js"; import { io } from "../index.js"; // Controller to handle booking creation diff --git a/backend/controllers/stationBookingsController.js b/backend/controllers/stationBookingsController.js new file mode 100644 index 0000000..c6f072c --- /dev/null +++ b/backend/controllers/stationBookingsController.js @@ -0,0 +1,74 @@ +// stationController.js +import Station from '../models/Stations.js'; +import CoolieBooking from '../models/CoolieBooking.js'; +import WheelchairBooking from '../models/WheelchairBooking.js'; +import CloakroomBooking from '../models/CloakroomBooking.js'; + +// Fetch all bookings associated with a station by ID +export const getStationBookings = async (req, res) => { + try { + const stationId = req.params.id; + + // Check if the station exists + const station = await Station.findById(stationId); + if (!station) { + return res.status(404).json({ message: "Station not found" }); + } + + // Retrieve bookings for this station + const coolieBookings = await CoolieBooking.find({ station: stationId }); + const wheelchairBookings = await WheelchairBooking.find({ station: stationId }); + const cloakroomBookings = await CloakroomBooking.find({ station: stationId }); + + // Construct the response object + const response = { + station: station, + coolieBookings: coolieBookings, + wheelchairBookings: wheelchairBookings, + cloakroomBookings: cloakroomBookings + }; + + return res.status(200).json(response); + } catch (error) { + return res.status(500).json({ message: error.message }); + } +}; + +// Fetch coolie bookings by station ID +export const getCoolieBookingsByStation = async (req, res) => { + try { + const stationId = req.params.id; + + const coolieBookings = await CoolieBooking.find({ station: stationId }); + + return res.status(200).json(coolieBookings); + } catch (error) { + return res.status(500).json({ message: error.message }); + } +}; + +// Fetch wheelchair bookings by station ID +export const getWheelchairBookingsByStation = async (req, res) => { + try { + const stationId = req.params.id; + + const wheelchairBookings = await WheelchairBooking.find({ station: stationId }); + + return res.status(200).json(wheelchairBookings); + } catch (error) { + return res.status(500).json({ message: error.message }); + } +}; + +// Fetch cloakroom bookings by station ID +export const getCloakroomBookingsByStation = async (req, res) => { + try { + const stationId = req.params.id; + + const cloakroomBookings = await CloakroomBooking.find({ station: stationId }); + + return res.status(200).json(cloakroomBookings); + } catch (error) { + return res.status(500).json({ message: error.message }); + } +}; diff --git a/backend/index.js b/backend/index.js index e61a50a..eeec415 100644 --- a/backend/index.js +++ b/backend/index.js @@ -26,9 +26,12 @@ app.use(express.urlencoded({ extended: true })); connectDB(); import authRoutes from "./routes/authRoutes.js"; +import stationRoutes from "./routes/stationRoutes.js"; app.use("/auth", authRoutes); app.use("/api", authRoutes); +app.use("/station", stationRoutes); + app.get("/", (req, res) => { res.send("Working..."); diff --git a/backend/models/CloakroomBooking.js b/backend/models/CloakroomBooking.js index 8199e85..debd803 100644 --- a/backend/models/CloakroomBooking.js +++ b/backend/models/CloakroomBooking.js @@ -1,3 +1,4 @@ +// cloakroomBooking.js import mongoose from "mongoose"; const Schema = mongoose.Schema; @@ -5,9 +6,9 @@ const Schema = mongoose.Schema; const cloakroomBookingSchema = new Schema( { station: { - type: String, + type: Schema.Types.ObjectId, + ref: 'Station', required: true, - trim: true, }, items: { type: String, diff --git a/backend/models/CoolieBooking.js b/backend/models/CoolieBooking.js index 2092ccc..02f120c 100644 --- a/backend/models/CoolieBooking.js +++ b/backend/models/CoolieBooking.js @@ -1,3 +1,4 @@ +// coolieBooking.js import mongoose from "mongoose"; const Schema = mongoose.Schema; @@ -5,9 +6,9 @@ const Schema = mongoose.Schema; const coolieBookingSchema = new Schema( { station: { - type: String, + type: Schema.Types.ObjectId, + ref: 'Station', required: true, - trim: true, }, pickupLocation: { type: String, @@ -39,5 +40,4 @@ const coolieBookingSchema = new Schema( ); const CoolieBooking = mongoose.model("CoolieBooking", coolieBookingSchema); - export default CoolieBooking; diff --git a/backend/models/Stations.js b/backend/models/Stations.js index ac29f5e..c7479bd 100644 --- a/backend/models/Stations.js +++ b/backend/models/Stations.js @@ -1,3 +1,4 @@ +// station.js import mongoose from "mongoose"; const Schema = mongoose.Schema; @@ -40,9 +41,21 @@ const stationSchema = new Schema( required: true, }, services: { - type: [String], // An array to list services like cloakroom, parking, restrooms, etc. + type: [String], required: true, }, + coolies: [{ + type: Schema.Types.ObjectId, + ref: 'CoolieBooking', + }], + wheelchairs: [{ + type: Schema.Types.ObjectId, + ref: 'WheelchairBooking', + }], + cloakrooms: [{ + type: Schema.Types.ObjectId, + ref: 'CloakroomBooking', + }], }, { timestamps: true, diff --git a/backend/models/WheelchairBooking.js b/backend/models/WheelchairBooking.js index b1d8a06..2b6b7fb 100644 --- a/backend/models/WheelchairBooking.js +++ b/backend/models/WheelchairBooking.js @@ -1,30 +1,30 @@ +// wheelchairBooking.js import mongoose from 'mongoose'; const Schema = mongoose.Schema; const wheelchairBookingSchema = new Schema({ station: { - type: String, + type: Schema.Types.ObjectId, + ref: 'Station', required: true, - trim: true }, bookingDate: { type: Date, - required: true + required: true, }, bookingTime: { type: String, - required: true + required: true, }, wheelchairType: { type: String, enum: ['manual', 'electric', 'standard'], - default: 'manual' + default: 'manual', }, }, { - timestamps: true + timestamps: true, }); -const WheelchairBooking = mongoose.model('WheelchairBooking', wheelchairBookingSchema); - +const WheelchairBooking = mongoose.models.WheelchairBooking || mongoose.model('WheelchairBooking', wheelchairBookingSchema); export default WheelchairBooking; diff --git a/backend/routes/stationRoutes.js b/backend/routes/stationRoutes.js new file mode 100644 index 0000000..1629b20 --- /dev/null +++ b/backend/routes/stationRoutes.js @@ -0,0 +1,19 @@ +// routes.js +import express from 'express'; +import { getCloakroomBookingsByStation, getCoolieBookingsByStation, getStationBookings, getWheelchairBookingsByStation } from '../controllers/stationBookingsController.js'; +import { createStation, getAllStations } from '../controllers/StationController.js'; + +const router = express.Router(); + +// Route to fetch all bookings for a station +router.get('/:id/bookings', getStationBookings); +router.get('/', getAllStations) +router.post('/', createStation); + + +// Routes to fetch specific types of bookings by station ID +router.get('/:id/coolies', getCoolieBookingsByStation); +router.get('/:id/wheelchairs', getWheelchairBookingsByStation); +router.get('/:id/cloakrooms', getCloakroomBookingsByStation); + +export default router; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index c15de30..cb01e9e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1317,7 +1317,6 @@ "version": "0.12.1", "resolved": "https://registry.npmjs.org/@react-oauth/google/-/google-0.12.1.tgz", "integrity": "sha512-qagsy22t+7UdkYAiT5ZhfM4StXi9PPNvw0zuwNmabrWyMKddczMtBIOARflbaIj+wHiQjnMAsZmzsUYuXeyoSg==", - "license": "MIT", "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 575e5c3..6d9b014 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -18,6 +18,7 @@ import Settings from './components/Settings'; import Help from './components/help'; import About from './components/about'; import Contributor from './Pages/contributor'; +import Booking from './Pages/booking'; function App() { @@ -31,7 +32,7 @@ function App() { } /> } /> } /> - } /> + } /> } /> } /> } /> diff --git a/frontend/src/Pages/booking.jsx b/frontend/src/Pages/booking.jsx index 42a5f26..ea6209e 100644 --- a/frontend/src/Pages/booking.jsx +++ b/frontend/src/Pages/booking.jsx @@ -1,111 +1,7 @@ -import React, { useState } from 'react'; -import { IoCalendarOutline } from 'react-icons/io5'; -import { IoArrowBack } from 'react-icons/io5'; -import { useNavigate } from 'react-router-dom'; +import BookingPage from "../components/Bookingform"; -const BookingPage = () => { - const [station, setStation] = useState(''); - const [date, setDate] = useState(''); - const navigate = useNavigate(); - - const services = [ - { - id: 'cloak', - name: 'Cloak Room Booking', - availability: 20 - }, - { - id: 'wheelchair', - name: 'Wheel Chair Booking', - availability: 5 - }, - { - id: 'coolie', - name: 'Coolie Booking', - availability: 12 - } - ]; - - return ( -
- {/* Background wrapper */} -
- - {/* Content wrapper */} -
- {/* Back button container */} -
- -
- - {/* Main Content Card */} -
-

- Station Services -

- - {/* Station input */} -
- - setStation(e.target.value)} - placeholder="Enter Station Name" - className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-300" - /> -
- - {/* Date input */} -
- -
- setDate(e.target.value)} - placeholder="DD/MM/YY" - className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-300" - /> - -
-
- - {/* Services */} -
- {services.map((service) => ( -
-
-

{service.name}

- - - Available: {service.availability} - -
- -
- ))} -
-
-
-
- ); -}; - -export default BookingPage; +export default function Booking() { + return
+ +
+} \ No newline at end of file diff --git a/frontend/src/components/Bookingform.jsx b/frontend/src/components/Bookingform.jsx new file mode 100644 index 0000000..07dbc73 --- /dev/null +++ b/frontend/src/components/Bookingform.jsx @@ -0,0 +1,201 @@ +import React, { useState, useEffect } from 'react'; +import { IoCalendarOutline, IoArrowBack } from 'react-icons/io5'; +import { useNavigate } from 'react-router-dom'; +import axios from 'axios'; + + +const BookingPage = () => { + const [station, setStation] = useState(''); // Holds the typed input + const [selectedStation, setSelectedStation] = useState(null); // Holds the selected station + const [date, setDate] = useState(''); + const [services, setServices] = useState([ + { id: 'cloak', name: 'Cloak Room Booking', availability: 0 }, + { id: 'wheelchair', name: 'Wheelchair Booking', availability: 0 }, + { id: 'coolie', name: 'Coolie Booking', availability: 0 } + ]); + const [stationSuggestions, setStationSuggestions] = useState([]); // Holds station suggestions + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); // Track errors + const [noResults, setNoResults] = useState(false); // Track if no stations are found + const navigate = useNavigate(); + + // Fetch stations suggestions as the user types + const fetchStationSuggestions = async (query) => { + try { + const response = await axios.get(`http://localhost:3000/station/`); + + if (response.data.length > 0) { + setStationSuggestions(response.data); // The response should include station _id and name + setNoResults(false); // Reset no results flag + } else { + setStationSuggestions([]); + setNoResults(true); // Set flag if no matching stations are found + } + } catch (err) { + setError("Error fetching station suggestions. Please try again."); + setNoResults(false); // Clear no results if there’s an error + } + }; + + + // Function to fetch service availability data from the backend + const fetchServiceData = async (stationId) => { + try { + setLoading(true); + const response = await axios.get(`http://localhost:3000/station/${stationId}/bookings`); + const { coolieBookings, wheelchairBookings, cloakroomBookings } = response.data; + + // Update the availability in the services array + setServices([ + { id: 'cloak', name: 'Cloak Room Booking', availability: cloakroomBookings.length }, + { id: 'wheelchair', name: 'Wheelchair Booking', availability: wheelchairBookings.length }, + { id: 'coolie', name: 'Coolie Booking', availability: coolieBookings.length } + ]); + + setLoading(false); + } catch (err) { + setError('Error fetching service data. Please try again.'); + setLoading(false); + } + }; + + // Fetch service availability when the selected station is updated + useEffect(() => { + if (selectedStation) { + fetchServiceData(selectedStation._id); // Assuming station ID is _id + } + }, [selectedStation]); + + // Handle station input change + const handleStationInputChange = (e) => { + const value = e.target.value; + setStation(value); + setError(''); // Clear error message on input change + + if (value.length > 2) { + // Fetch station suggestions when input has more than 2 characters + fetchStationSuggestions(value); + } else { + setStationSuggestions([]); // Clear suggestions if input is too short + setNoResults(false); // Clear no results if input is too short + } + }; + + // Handle station selection from suggestions + const handleStationSelect = (station) => { + setSelectedStation(station); // Set the selected station + setStation(station.name); // Update the input value with the selected station's name + setStationSuggestions([]); // Clear the suggestions after selection + setError(''); // Clear any previous errors + }; + + return ( +
+
+ +
+
+ +
+ +
+

+ Station Services +

+ + {/* Station Input */} +
+ + + {/* Station suggestions dropdown */} + {stationSuggestions.length > 0 && ( +
    + {stationSuggestions.map((suggestion) => ( +
  • handleStationSelect(suggestion)} + className="px-4 py-2 hover:bg-blue-100 cursor-pointer" + > + {suggestion.name} +
  • + ))} +
+ )} + + {/* Handle no results found */} + {noResults && ( +

No stations found matching your search.

+ )} + + {/* Handle errors */} + {error && ( +

{error}

+ )} +
+ + {/* Date input */} +
+ +
+ setDate(e.target.value)} + placeholder="DD/MM/YY" + className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-300" + /> + +
+
+ + {/* Render Services */} + {loading ? ( +

Loading services...

+ ) : error && !stationSuggestions.length ? ( +

{error}

+ ) : ( +
+ {services.map((service) => ( +
+
+

{service.name}

+ + + Available: {service.availability} + +
+ +
+ ))} +
+ )} +
+
+
+ ); + }; + + export default BookingPage; + \ No newline at end of file From 23ba999b32eeb9bd8eaa81bf64c7514c1581dacc Mon Sep 17 00:00:00 2001 From: haseebzaki-07 Date: Sun, 13 Oct 2024 11:29:35 +0530 Subject: [PATCH 2/3] Add booking back to pages --- backend/controllers/StationController.js | 44 ++-- .../controllers/stationBookingsController.js | 40 ++-- frontend/src/App.jsx | 4 +- frontend/src/Pages/booking.jsx | 206 +++++++++++++++++- frontend/src/components/Bookingform.jsx | 201 ----------------- 5 files changed, 238 insertions(+), 257 deletions(-) diff --git a/backend/controllers/StationController.js b/backend/controllers/StationController.js index b5d29f6..d202744 100644 --- a/backend/controllers/StationController.js +++ b/backend/controllers/StationController.js @@ -1,59 +1,47 @@ -// controllers/stationController.js -import Station from '../models/Stations.js'; +import Station from "../models/Stations.js"; export const createStation = async (req, res) => { try { - const { - name, - location, // Location object with postalCode, city, and state - stationCode, - capacity, - services - } = req.body; + const { name, location, stationCode, capacity, services } = req.body; - // Create a new station document const newStation = new Station({ name, location, stationCode, capacity, - services + services, }); - // Save the station document in the database const savedStation = await newStation.save(); res.status(201).json({ - message: 'Station created successfully', - station: savedStation + message: "Station created successfully", + station: savedStation, }); } catch (error) { - console.error('Error creating station:', error); + console.error("Error creating station:", error); res.status(500).json({ - message: 'Failed to create station', - error: error.message + message: "Failed to create station", + error: error.message, }); } }; - export const getAllStations = async (req, res) => { try { - // Fetch all stations from the database const stations = await Station.find() - .populate('coolies', 'name') // Populating the coolies field with only their name - .populate('wheelchairs', 'name') // Populating the wheelchairs field with only their name - .populate('cloakrooms', 'name'); // Populating the cloakrooms field with only their name + .populate("coolies", "name") + .populate("wheelchairs", "name") + .populate("cloakrooms", "name"); - // If no stations are found, return a 404 error if (!stations || stations.length === 0) { - return res.status(404).json({ message: 'No stations found' }); + return res.status(404).json({ message: "No stations found" }); } - // Return the stations as JSON return res.status(200).json(stations); } catch (error) { - // Return a 500 error if something goes wrong - return res.status(500).json({ message: 'Server error', error: error.message }); + return res + .status(500) + .json({ message: "Server error", error: error.message }); } -}; \ No newline at end of file +}; diff --git a/backend/controllers/stationBookingsController.js b/backend/controllers/stationBookingsController.js index c6f072c..96f6654 100644 --- a/backend/controllers/stationBookingsController.js +++ b/backend/controllers/stationBookingsController.js @@ -1,31 +1,30 @@ -// stationController.js -import Station from '../models/Stations.js'; -import CoolieBooking from '../models/CoolieBooking.js'; -import WheelchairBooking from '../models/WheelchairBooking.js'; -import CloakroomBooking from '../models/CloakroomBooking.js'; +import Station from "../models/Stations.js"; +import CoolieBooking from "../models/CoolieBooking.js"; +import WheelchairBooking from "../models/WheelchairBooking.js"; +import CloakroomBooking from "../models/CloakroomBooking.js"; -// Fetch all bookings associated with a station by ID export const getStationBookings = async (req, res) => { try { const stationId = req.params.id; - // Check if the station exists const station = await Station.findById(stationId); if (!station) { return res.status(404).json({ message: "Station not found" }); } - // Retrieve bookings for this station const coolieBookings = await CoolieBooking.find({ station: stationId }); - const wheelchairBookings = await WheelchairBooking.find({ station: stationId }); - const cloakroomBookings = await CloakroomBooking.find({ station: stationId }); + const wheelchairBookings = await WheelchairBooking.find({ + station: stationId, + }); + const cloakroomBookings = await CloakroomBooking.find({ + station: stationId, + }); - // Construct the response object const response = { station: station, coolieBookings: coolieBookings, wheelchairBookings: wheelchairBookings, - cloakroomBookings: cloakroomBookings + cloakroomBookings: cloakroomBookings, }; return res.status(200).json(response); @@ -34,11 +33,10 @@ export const getStationBookings = async (req, res) => { } }; -// Fetch coolie bookings by station ID export const getCoolieBookingsByStation = async (req, res) => { try { const stationId = req.params.id; - + const coolieBookings = await CoolieBooking.find({ station: stationId }); return res.status(200).json(coolieBookings); @@ -47,12 +45,13 @@ export const getCoolieBookingsByStation = async (req, res) => { } }; -// Fetch wheelchair bookings by station ID export const getWheelchairBookingsByStation = async (req, res) => { try { const stationId = req.params.id; - - const wheelchairBookings = await WheelchairBooking.find({ station: stationId }); + + const wheelchairBookings = await WheelchairBooking.find({ + station: stationId, + }); return res.status(200).json(wheelchairBookings); } catch (error) { @@ -60,12 +59,13 @@ export const getWheelchairBookingsByStation = async (req, res) => { } }; -// Fetch cloakroom bookings by station ID export const getCloakroomBookingsByStation = async (req, res) => { try { const stationId = req.params.id; - - const cloakroomBookings = await CloakroomBooking.find({ station: stationId }); + + const cloakroomBookings = await CloakroomBooking.find({ + station: stationId, + }); return res.status(200).json(cloakroomBookings); } catch (error) { diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 6d9b014..12c9900 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -18,7 +18,7 @@ import Settings from './components/Settings'; import Help from './components/help'; import About from './components/about'; import Contributor from './Pages/contributor'; -import Booking from './Pages/booking'; + function App() { @@ -32,7 +32,7 @@ function App() { } /> } /> } /> - } /> + } /> } /> } /> } /> diff --git a/frontend/src/Pages/booking.jsx b/frontend/src/Pages/booking.jsx index ea6209e..07dbc73 100644 --- a/frontend/src/Pages/booking.jsx +++ b/frontend/src/Pages/booking.jsx @@ -1,7 +1,201 @@ -import BookingPage from "../components/Bookingform"; +import React, { useState, useEffect } from 'react'; +import { IoCalendarOutline, IoArrowBack } from 'react-icons/io5'; +import { useNavigate } from 'react-router-dom'; +import axios from 'axios'; -export default function Booking() { - return
- -
-} \ No newline at end of file + +const BookingPage = () => { + const [station, setStation] = useState(''); // Holds the typed input + const [selectedStation, setSelectedStation] = useState(null); // Holds the selected station + const [date, setDate] = useState(''); + const [services, setServices] = useState([ + { id: 'cloak', name: 'Cloak Room Booking', availability: 0 }, + { id: 'wheelchair', name: 'Wheelchair Booking', availability: 0 }, + { id: 'coolie', name: 'Coolie Booking', availability: 0 } + ]); + const [stationSuggestions, setStationSuggestions] = useState([]); // Holds station suggestions + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); // Track errors + const [noResults, setNoResults] = useState(false); // Track if no stations are found + const navigate = useNavigate(); + + // Fetch stations suggestions as the user types + const fetchStationSuggestions = async (query) => { + try { + const response = await axios.get(`http://localhost:3000/station/`); + + if (response.data.length > 0) { + setStationSuggestions(response.data); // The response should include station _id and name + setNoResults(false); // Reset no results flag + } else { + setStationSuggestions([]); + setNoResults(true); // Set flag if no matching stations are found + } + } catch (err) { + setError("Error fetching station suggestions. Please try again."); + setNoResults(false); // Clear no results if there’s an error + } + }; + + + // Function to fetch service availability data from the backend + const fetchServiceData = async (stationId) => { + try { + setLoading(true); + const response = await axios.get(`http://localhost:3000/station/${stationId}/bookings`); + const { coolieBookings, wheelchairBookings, cloakroomBookings } = response.data; + + // Update the availability in the services array + setServices([ + { id: 'cloak', name: 'Cloak Room Booking', availability: cloakroomBookings.length }, + { id: 'wheelchair', name: 'Wheelchair Booking', availability: wheelchairBookings.length }, + { id: 'coolie', name: 'Coolie Booking', availability: coolieBookings.length } + ]); + + setLoading(false); + } catch (err) { + setError('Error fetching service data. Please try again.'); + setLoading(false); + } + }; + + // Fetch service availability when the selected station is updated + useEffect(() => { + if (selectedStation) { + fetchServiceData(selectedStation._id); // Assuming station ID is _id + } + }, [selectedStation]); + + // Handle station input change + const handleStationInputChange = (e) => { + const value = e.target.value; + setStation(value); + setError(''); // Clear error message on input change + + if (value.length > 2) { + // Fetch station suggestions when input has more than 2 characters + fetchStationSuggestions(value); + } else { + setStationSuggestions([]); // Clear suggestions if input is too short + setNoResults(false); // Clear no results if input is too short + } + }; + + // Handle station selection from suggestions + const handleStationSelect = (station) => { + setSelectedStation(station); // Set the selected station + setStation(station.name); // Update the input value with the selected station's name + setStationSuggestions([]); // Clear the suggestions after selection + setError(''); // Clear any previous errors + }; + + return ( +
+
+ +
+
+ +
+ +
+

+ Station Services +

+ + {/* Station Input */} +
+ + + {/* Station suggestions dropdown */} + {stationSuggestions.length > 0 && ( +
    + {stationSuggestions.map((suggestion) => ( +
  • handleStationSelect(suggestion)} + className="px-4 py-2 hover:bg-blue-100 cursor-pointer" + > + {suggestion.name} +
  • + ))} +
+ )} + + {/* Handle no results found */} + {noResults && ( +

No stations found matching your search.

+ )} + + {/* Handle errors */} + {error && ( +

{error}

+ )} +
+ + {/* Date input */} +
+ +
+ setDate(e.target.value)} + placeholder="DD/MM/YY" + className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-300" + /> + +
+
+ + {/* Render Services */} + {loading ? ( +

Loading services...

+ ) : error && !stationSuggestions.length ? ( +

{error}

+ ) : ( +
+ {services.map((service) => ( +
+
+

{service.name}

+ + + Available: {service.availability} + +
+ +
+ ))} +
+ )} +
+
+
+ ); + }; + + export default BookingPage; + \ No newline at end of file diff --git a/frontend/src/components/Bookingform.jsx b/frontend/src/components/Bookingform.jsx index 07dbc73..e69de29 100644 --- a/frontend/src/components/Bookingform.jsx +++ b/frontend/src/components/Bookingform.jsx @@ -1,201 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { IoCalendarOutline, IoArrowBack } from 'react-icons/io5'; -import { useNavigate } from 'react-router-dom'; -import axios from 'axios'; - - -const BookingPage = () => { - const [station, setStation] = useState(''); // Holds the typed input - const [selectedStation, setSelectedStation] = useState(null); // Holds the selected station - const [date, setDate] = useState(''); - const [services, setServices] = useState([ - { id: 'cloak', name: 'Cloak Room Booking', availability: 0 }, - { id: 'wheelchair', name: 'Wheelchair Booking', availability: 0 }, - { id: 'coolie', name: 'Coolie Booking', availability: 0 } - ]); - const [stationSuggestions, setStationSuggestions] = useState([]); // Holds station suggestions - const [loading, setLoading] = useState(false); - const [error, setError] = useState(''); // Track errors - const [noResults, setNoResults] = useState(false); // Track if no stations are found - const navigate = useNavigate(); - - // Fetch stations suggestions as the user types - const fetchStationSuggestions = async (query) => { - try { - const response = await axios.get(`http://localhost:3000/station/`); - - if (response.data.length > 0) { - setStationSuggestions(response.data); // The response should include station _id and name - setNoResults(false); // Reset no results flag - } else { - setStationSuggestions([]); - setNoResults(true); // Set flag if no matching stations are found - } - } catch (err) { - setError("Error fetching station suggestions. Please try again."); - setNoResults(false); // Clear no results if there’s an error - } - }; - - - // Function to fetch service availability data from the backend - const fetchServiceData = async (stationId) => { - try { - setLoading(true); - const response = await axios.get(`http://localhost:3000/station/${stationId}/bookings`); - const { coolieBookings, wheelchairBookings, cloakroomBookings } = response.data; - - // Update the availability in the services array - setServices([ - { id: 'cloak', name: 'Cloak Room Booking', availability: cloakroomBookings.length }, - { id: 'wheelchair', name: 'Wheelchair Booking', availability: wheelchairBookings.length }, - { id: 'coolie', name: 'Coolie Booking', availability: coolieBookings.length } - ]); - - setLoading(false); - } catch (err) { - setError('Error fetching service data. Please try again.'); - setLoading(false); - } - }; - - // Fetch service availability when the selected station is updated - useEffect(() => { - if (selectedStation) { - fetchServiceData(selectedStation._id); // Assuming station ID is _id - } - }, [selectedStation]); - - // Handle station input change - const handleStationInputChange = (e) => { - const value = e.target.value; - setStation(value); - setError(''); // Clear error message on input change - - if (value.length > 2) { - // Fetch station suggestions when input has more than 2 characters - fetchStationSuggestions(value); - } else { - setStationSuggestions([]); // Clear suggestions if input is too short - setNoResults(false); // Clear no results if input is too short - } - }; - - // Handle station selection from suggestions - const handleStationSelect = (station) => { - setSelectedStation(station); // Set the selected station - setStation(station.name); // Update the input value with the selected station's name - setStationSuggestions([]); // Clear the suggestions after selection - setError(''); // Clear any previous errors - }; - - return ( -
-
- -
-
- -
- -
-

- Station Services -

- - {/* Station Input */} -
- - - {/* Station suggestions dropdown */} - {stationSuggestions.length > 0 && ( -
    - {stationSuggestions.map((suggestion) => ( -
  • handleStationSelect(suggestion)} - className="px-4 py-2 hover:bg-blue-100 cursor-pointer" - > - {suggestion.name} -
  • - ))} -
- )} - - {/* Handle no results found */} - {noResults && ( -

No stations found matching your search.

- )} - - {/* Handle errors */} - {error && ( -

{error}

- )} -
- - {/* Date input */} -
- -
- setDate(e.target.value)} - placeholder="DD/MM/YY" - className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-300" - /> - -
-
- - {/* Render Services */} - {loading ? ( -

Loading services...

- ) : error && !stationSuggestions.length ? ( -

{error}

- ) : ( -
- {services.map((service) => ( -
-
-

{service.name}

- - - Available: {service.availability} - -
- -
- ))} -
- )} -
-
-
- ); - }; - - export default BookingPage; - \ No newline at end of file From cb0a6ac0e82ef564ba8a2f014498e83326dab28d Mon Sep 17 00:00:00 2001 From: Dhairya Gothi Date: Sun, 13 Oct 2024 12:47:58 +0530 Subject: [PATCH 3/3] Update index.js --- backend/index.js | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/backend/index.js b/backend/index.js index eeec415..e1cc55b 100644 --- a/backend/index.js +++ b/backend/index.js @@ -12,7 +12,7 @@ const port = process.env.PORT || 3000; app.use( cors({ - origin: ["http://localhost:5173", "http://127.0.0.1:5500"], + origin: ["http://localhost:5173", "http://127.0.0.1:5500","https://station-guide.vercel.app/"], methods: ["GET", "POST"], allowedHeaders: ["Content-Type"], credentials: true, @@ -26,12 +26,9 @@ app.use(express.urlencoded({ extended: true })); connectDB(); import authRoutes from "./routes/authRoutes.js"; -import stationRoutes from "./routes/stationRoutes.js"; app.use("/auth", authRoutes); app.use("/api", authRoutes); -app.use("/station", stationRoutes); - app.get("/", (req, res) => { res.send("Working..."); @@ -41,23 +38,21 @@ app.get("/", (req, res) => { const io = new Server(server, { cors: { - origin: ["http://localhost:5173", "http://127.0.0.1:5500"], + origin: ["http://localhost:5173", "http://127.0.0.1:5500" , "https://station-guide.vercel.app/"], methods: ["GET", "POST"], credentials: true, }, }); -io.on("connection", (socket) => { - console.log("A user connected:", socket.id); - - socket.on("disconnect", () => { - console.log("User disconnected:", socket.id); +if (process.env.NODE_ENV !== 'production') { + const io = new Server(server, { /* CORS settings */ }); + io.on("connection", (socket) => { + console.log("A user connected:", socket.id); + socket.on("disconnect", () => { + console.log("User disconnected:", socket.id); + }); }); - - socket.on("error", (err) => { - console.error("Socket error:", err); - }); -}); +} server.listen(port, () => { console.log(`Server is running on http://localhost:${port}`);