From 7df60dc84ab6e8908a05b2238eef8617425d6e48 Mon Sep 17 00:00:00 2001 From: haseebzaki-07 Date: Tue, 22 Oct 2024 22:46:14 +0530 Subject: [PATCH] Add trains --- backend/controllers/trainController.js | 62 ++++++++ backend/index.js | 2 + backend/models/Trains.js | 82 ++++++++++ backend/routes/trainRoutes.js | 13 ++ frontend/src/Pages/schedule.jsx | 211 ++++++++++++++----------- 5 files changed, 274 insertions(+), 96 deletions(-) create mode 100644 backend/controllers/trainController.js create mode 100644 backend/models/Trains.js create mode 100644 backend/routes/trainRoutes.js diff --git a/backend/controllers/trainController.js b/backend/controllers/trainController.js new file mode 100644 index 0000000..caee9d9 --- /dev/null +++ b/backend/controllers/trainController.js @@ -0,0 +1,62 @@ +import Train from "../models/Trains.js"; + + +// Create a new train +export const createTrain = async (req, res) => { + try { + const { trainNumber, trainName, nextStation, services, platformDetails, coachDetails } = req.body; + + + const existingTrain = await Train.findOne({ trainNumber }); + if (existingTrain) { + return res.status(400).json({ message: "Train with this number already exists" }); + } + + + const newTrain = new Train({ + trainNumber, + trainName, + nextStation, + services, + platformDetails, + coachDetails, + }); + + const savedTrain = await newTrain.save(); + + return res.status(201).json({ + message: "Train created successfully", + train: savedTrain, + }); + } catch (error) { + return res.status(500).json({ message: "Error creating train", error: error.message }); + } +}; + +// Fetch all trains +export const getAllTrains = async (req, res) => { + try { + const trains = await Train.find(); + return res.status(200).json(trains); + } catch (error) { + return res.status(500).json({ message: "Error fetching trains", error: error.message }); + } +}; + +// Fetch a single train by train number +export const getTrainByNumber = async (req, res) => { + try { + const { trainNumber } = req.params; + + const train = await Train.findOne({ trainNumber }); + + if (!train) { + return res.status(404).json({ message: "Train not found" }); + } + + return res.status(200).json(train); + } catch (error) { + return res.status(500).json({ message: "Error fetching train", error: error.message }); + } +}; + diff --git a/backend/index.js b/backend/index.js index 3ecc689..6c33177 100644 --- a/backend/index.js +++ b/backend/index.js @@ -29,10 +29,12 @@ connectDB(); import authRoutes from "./routes/authRoutes.js"; import stationRoutes from "./routes/stationRoutes.js"; +import trainRoutes from "./routes/trainRoutes.js"; app.use("/auth", authRoutes); app.use("/api", authRoutes); app.use("/station", stationRoutes); +app.use("/train", trainRoutes); app.get("/", (req, res) => { res.send("Working..."); diff --git a/backend/models/Trains.js b/backend/models/Trains.js new file mode 100644 index 0000000..9d29e6e --- /dev/null +++ b/backend/models/Trains.js @@ -0,0 +1,82 @@ +// train.js +import mongoose from "mongoose"; + +const Schema = mongoose.Schema; + +const trainSchema = new Schema( + { + trainNumber: { + type: Number, + required: true, + unique: true, + trim: true, + }, + trainName: { + type: String, + required: true, + trim: true, + }, + nextStation: { + type: { + name: { + type: String, + required: true, + trim: true, + }, + stationCode: { + type: String, + required: true, + trim: true, + }, + arrivalTime: { + type: Date, + required: true, + }, + }, + required: true, + }, + services: { + type: [String], // An array of available services like ["WiFi", "Food", "Lounge"] + required: true, + }, + platformDetails: { + platformNumber: { + type: Number, + required: true, + }, + boardingTime: { + type: Date, + required: true, + }, + }, + coachDetails: [ + { + coachNumber: { + type: String, + required: true, + trim: true, + }, + coachType: { + type: String, + enum: ['Sleeper', 'AC', 'General', 'ChairCar', 'FirstClass'], + required: true, + }, + capacity: { + type: Number, + required: true, + }, + reservedSeats: { + type: Number, + required: true, + default: 0, + }, + }, + ], + }, + { + timestamps: true, + } +); + +const Train = mongoose.model("Train", trainSchema); +export default Train; diff --git a/backend/routes/trainRoutes.js b/backend/routes/trainRoutes.js new file mode 100644 index 0000000..ec16855 --- /dev/null +++ b/backend/routes/trainRoutes.js @@ -0,0 +1,13 @@ +// routes.js +import express from 'express'; +import { createTrain, getAllTrains, getTrainByNumber } from '../controllers/trainController.js'; + + +const router = express.Router(); + +router.get('/:trainNumber', getTrainByNumber); +router.post('/', createTrain); +router.get('/', getAllTrains); + + +export default router; diff --git a/frontend/src/Pages/schedule.jsx b/frontend/src/Pages/schedule.jsx index 1ef0b6a..049310d 100644 --- a/frontend/src/Pages/schedule.jsx +++ b/frontend/src/Pages/schedule.jsx @@ -1,24 +1,47 @@ import React, { useState, useEffect } from 'react'; import { IoArrowBack, IoSearchOutline } from 'react-icons/io5'; import { useNavigate } from 'react-router-dom'; -//import DatePicker from 'react-datepicker'; -import 'react-datepicker/dist/react-datepicker.css'; + +// Placeholder API URL (replace with the actual API endpoint) +const API_URL = 'http://localhost:3000/train'; const SchedulePage = () => { useEffect(() => { document.title = 'Station Saarthi | Schedule'; }, []); - const [trainNumber, setTrainNumber] = useState('22436'); - const [trainName, setTrainName] = useState('Vande Bharat'); - const [nextStation, setNextStation] = useState('Indore Jn.'); - const [services, setServices] = useState('-SELECT-'); - const [platformDetails, setPlatformDetails] = useState('Platform 3'); - const [coachDetails, setCoachDetails] = useState('A4'); - //const [date, setDate] = useState(null); - + const [searchQuery, setSearchQuery] = useState(''); + const [trainDetails, setTrainDetails] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const navigate = useNavigate(); + // Function to search train by either number or name + const searchTrain = async () => { + if (!searchQuery) { + setError('Please enter a train number or name to search'); + return; + } + + setLoading(true); + setError(null); + + try { + const response = await fetch(`${API_URL}/${searchQuery}`); + if (!response.ok) { + throw new Error('Train not found'); + } + + const data = await response.json(); + setTrainDetails(data); // Assuming the API returns a train object + } catch (error) { + setError(error.message || 'An error occurred while fetching the train details'); + } finally { + setLoading(false); + } + }; + return (
{
+ {/* Search input */}
- +
setSearchQuery(e.target.value)} className="w-full px-4 py-2 pr-10 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-300" /> - -
-
- -
- -
- setTrainNumber(e.target.value)} - className="w-full px-4 py-2 pr-10 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-300" + -
+ {error &&

{error}

}
-
- -
- setTrainName(e.target.value)} - className="w-full px-4 py-2 pr-10 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-300" - /> - + {/* Display train details */} + {loading &&

Loading...

} + {trainDetails && ( +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + `${coach.coachNumber} (${coach.coachType})`).join(', ')} + readOnly + className="w-full px-4 py-2 border border-gray-300 rounded-lg" + /> +
-
- -
- - setNextStation(e.target.value)} - 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" - /> -
- -
- - -
- -
- - setPlatformDetails(e.target.value)} - 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" - /> -
- -
- - setCoachDetails(e.target.value)} - 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" - /> -
- - {/*
- -
- {/* setDate(date)} - dateFormat="dd/MM/yyyy" - placeholderText="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" - popperClassName="z-50" - /> } -
-
*/} + )} + + {/* Button to search */} +
- -