Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tickets availability #531

Merged
merged 2 commits into from
Nov 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 173 additions & 0 deletions backend/dataset/tickets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
const availableTickets = [
{
transport: 'Bus',
departureTime: '2024-11-09 08:00',
arrivalTime: '2024-11-09 12:00',
price: 30,
source: 'New York',
destination: 'Los Angeles',
},
{
transport: 'Train',
departureTime: '2024-11-09 10:00',
arrivalTime: '2024-11-09 18:00',
price: 100,
source: 'New York',
destination: 'Los Angeles',
},
{
transport: 'Flight',
departureTime: '2024-11-09 06:00',
arrivalTime: '2024-11-09 09:00',
price: 250,
source: 'New York',
destination: 'Los Angeles',
},
{
transport: 'Bus',
departureTime: '2024-11-09 15:00',
arrivalTime: '2024-11-09 19:00',
price: 35,
source: 'Chicago',
destination: 'San Francisco',
},
{
transport: 'Train',
departureTime: '2024-11-09 13:00',
arrivalTime: '2024-11-09 21:00',
price: 120,
source: 'Chicago',
destination: 'San Francisco',
},
{
transport: 'Flight',
departureTime: '2024-11-09 11:00',
arrivalTime: '2024-11-09 14:00',
price: 180,
source: 'Chicago',
destination: 'San Francisco',
},
{
transport: 'Bus',
departureTime: '2024-11-09 09:00',
arrivalTime: '2024-11-09 13:30',
price: 40,
source: 'Boston',
destination: 'Washington DC',
},
{
transport: 'Train',
departureTime: '2024-11-09 14:00',
arrivalTime: '2024-11-09 18:30',
price: 90,
source: 'Boston',
destination: 'Washington DC',
},
{
transport: 'Flight',
departureTime: '2024-11-09 07:30',
arrivalTime: '2024-11-09 09:00',
price: 160,
source: 'Boston',
destination: 'Washington DC',
},
{
transport: 'Bus',
departureTime: '2024-11-09 10:00',
arrivalTime: '2024-11-09 14:00',
price: 50,
source: 'Miami',
destination: 'Atlanta',
},
{
transport: 'Train',
departureTime: '2024-11-09 16:00',
arrivalTime: '2024-11-09 22:00',
price: 110,
source: 'Miami',
destination: 'Atlanta',
},
{
transport: 'Flight',
departureTime: '2024-11-09 08:30',
arrivalTime: '2024-11-09 10:00',
price: 190,
source: 'Miami',
destination: 'Atlanta',
},
{
transport: 'Bus',
departureTime: '2024-11-09 11:00',
arrivalTime: '2024-11-09 18:30',
price: 55,
source: 'Los Angeles',
destination: 'San Francisco',
},
{
transport: 'Train',
departureTime: '2024-11-09 18:00',
arrivalTime: '2024-11-09 22:00',
price: 75,
source: 'Los Angeles',
destination: 'San Francisco',
},
{
transport: 'Flight',
departureTime: '2024-11-09 12:00',
arrivalTime: '2024-11-09 14:00',
price: 220,
source: 'Los Angeles',
destination: 'San Francisco',
},
{
transport: 'Bus',
departureTime: '2024-11-09 13:00',
arrivalTime: '2024-11-09 19:30',
price: 60,
source: 'Dallas',
destination: 'Houston',
},
{
transport: 'Train',
departureTime: '2024-11-09 07:00',
arrivalTime: '2024-11-09 11:00',
price: 80,
source: 'Dallas',
destination: 'Houston',
},
{
transport: 'Flight',
departureTime: '2024-11-09 10:30',
arrivalTime: '2024-11-09 11:50',
price: 210,
source: 'Dallas',
destination: 'Houston',
},
{
transport: 'Bus',
departureTime: '2024-11-09 12:00',
arrivalTime: '2024-11-09 16:30',
price: 45,
source: 'Seattle',
destination: 'Portland',
},
{
transport: 'Train',
departureTime: '2024-11-09 09:30',
arrivalTime: '2024-11-09 14:00',
price: 95,
source: 'Seattle',
destination: 'Portland',
},
{
transport: 'Flight',
departureTime: '2024-11-09 08:00',
arrivalTime: '2024-11-09 09:30',
price: 175,
source: 'Seattle',
destination: 'Portland',
},
];

export default availableTickets;

5 changes: 5 additions & 0 deletions backend/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,17 @@ import stationRoutes from "./routes/stationRoutes.js";
import trainRoutes from "./routes/trainRoutes.js";
import contactUs from "./routes/contactUsRouter.js";
import complaintRoutes from "./routes/complaintRoutes.js";

import ticketRoutes from "./routes/ticketRoutes.js";

import userRoutes from "./routes/userRoutes.js";


app.use("/auth", authRoutes);
app.use("/api", authRoutes);
app.use("/api", userRoutes);
app.use("/api", complaintRoutes);
app.use("/api", ticketRoutes);
app.use("/station", stationRoutes);
app.use("/train", trainRoutes);
app.use("/contact", contactUs);
Expand Down
33 changes: 33 additions & 0 deletions backend/routes/ticketRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import availableTickets from "../dataset/tickets.js";
import express from "express";
const router = express.Router();


router.get('/get-all-tickets', function(req, res) {
res.json(availableTickets);
});


router.post('/search-tickets', (req, res) => {
const { source, destination } = req.body;

// Validate input
if (!source || !destination) {
return res.status(400).json({ error: 'Both source and destination must be provided.' });
}

// Filter tickets based on source and destination
const filteredTickets = availableTickets.filter(
(ticket) =>
ticket.source.toLowerCase() === source.toLowerCase() &&
ticket.destination.toLowerCase() === destination.toLowerCase()
);

if (filteredTickets.length === 0) {
return res.status(404).json({ message: 'No tickets found for this route.' });
}

res.json(filteredTickets);
});

export default router;
8 changes: 8 additions & 0 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,12 @@ import ComplainBox from "./Pages/ComplainBox";
import Metadata from "./metadata";
import SettingsPage from "./Pages/Settings";
import Faq from './Pages/Faq';

import TicketSearchComponent from "./Pages/TicketsAvailability";

import ProfilePage from "./Pages/Profile";


function App() {
return (
<>
Expand All @@ -50,7 +54,11 @@ function App() {
<Route path="/Notification" element={<NotificationPage />} />
<Route path="/chatbot" element={<Chatbot />} />
<Route path="/ContactUs" element={<ContactUs />} />

<Route path="/Tickets" element={<TicketSearchComponent/>} />

<Route path="/profile" element={<ProfilePage />} />


<Route path="/GoogleTranslate" element={<GoogleTranslate />} />
<Route path="/help" element={<Help />} />
Expand Down
143 changes: 143 additions & 0 deletions frontend/src/Pages/TicketsAvailability.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import React, { useState } from 'react';

const TicketSearchComponent = () => {
const [source, setSource] = useState('');
const [destination, setDestination] = useState('');
const [tickets, setTickets] = useState([]);
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);

// Handle input changes
const handleInputChange = (e) => {
const { name, value } = e.target;
if (name === 'source') {
setSource(value);
} else {
setDestination(value);
}
};

// Search for tickets
const handleSearch = async (e) => {
e.preventDefault();

if (!source || !destination) {
setError('Please enter both source and destination.');
return;
}

setError('');
setLoading(true);

try {
const ticketData = await fetchTickets(source, destination);
setTickets(ticketData);
} catch (error) {
console.error('Error fetching tickets:', error);
setError('There was an error fetching the tickets.');
} finally {
setLoading(false);
}
};

// Fetch tickets from the backend
const fetchTickets = async (source, destination) => {
try {
const response = await fetch('http://localhost:3000/api/search-tickets', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ source, destination }),
});

if (response.ok) {
const data = await response.json();
return data;
} else {
throw new Error('Failed to fetch tickets');
}
} catch (error) {
console.error('Error fetching tickets:', error);
setError('Failed to fetch tickets.');
return [];
}
};

return (
<div className="ticket-search max-w-3xl mx-auto p-6 bg-white rounded-lg shadow-lg mt-8">
<h2 className="text-3xl font-semibold text-green-600 mb-6 text-center">Tickets Availability</h2>

<form onSubmit={handleSearch} className="space-y-6">
<div>
<label htmlFor="source" className="block text-lg font-medium text-gray-700">
Departure (Source)
</label>
<input
type="text"
id="source"
name="source"
value={source}
onChange={handleInputChange}
placeholder="Enter departure location"
className="w-full p-3 mt-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-green-600 transition"
required
/>
</div>

<div>
<label htmlFor="destination" className="block text-lg font-medium text-gray-700">
Destination
</label>
<input
type="text"
id="destination"
name="destination"
value={destination}
onChange={handleInputChange}
placeholder="Enter destination location"
className="w-full p-3 mt-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-green-600 transition"
required
/>
</div>

<button
type="submit"
className="w-full py-3 bg-green-600 text-white text-lg font-medium rounded-lg hover:bg-green-500 transition-colors"
>
Search
</button>
</form>

{error && <p className="mt-4 text-red-500 text-center">{error}</p>}

{loading && <p className="mt-4 text-blue-600 text-center">Loading...</p>}

{/* Displaying search results */}
{tickets.length > 0 && (
<div className="mt-6">
<h3 className="text-2xl font-semibold text-green-600 mb-4">Available Tickets</h3>
<ul className="space-y-4">
{tickets.map((ticket, index) => (
<li
key={index}
className="p-6 bg-gray-50 border border-gray-300 rounded-lg shadow-md hover:shadow-lg transition-shadow"
>
<p className="text-xl font-semibold text-gray-800">{ticket.transport}</p>
<p><strong>Departure:</strong> {ticket.departureTime}</p>
<p><strong>Arrival:</strong> {ticket.arrivalTime}</p>
<p><strong>Price:</strong> ${ticket.price}</p>
</li>
))}
</ul>
</div>
)}

{tickets.length === 0 && source && destination && !error && !loading && (
<p className="text-green-600 text-center">No tickets found for this route.</p>
)}
</div>
);
};

export default TicketSearchComponent;
Loading