Skip to content
Snippets Groups Projects
Commit 32083994 authored by Cross, Liam (UG - Comp Sci & Elec Eng)'s avatar Cross, Liam (UG - Comp Sci & Elec Eng)
Browse files

Flight form wiring and flight page

parent a084f326
No related branches found
No related tags found
No related merge requests found
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { IFlight } from '../../../services/Dashboard/CustomerDashboard';
import './FlightCard.scss'; import './FlightCard.scss';
interface IFlight {
id: number;
flightNumber: string;
flightPath: string;
flightPathFull: string;
}
interface IFlightCard { interface IFlightCard {
flight: IFlight; flight: IFlight;
} }
...@@ -16,9 +10,9 @@ function FlightCard({ flight }: IFlightCard) { ...@@ -16,9 +10,9 @@ function FlightCard({ flight }: IFlightCard) {
return ( return (
<> <>
<div className='flight-card'> <div className='flight-card'>
<span>{flight.flightNumber}</span> <span>{flight.id}</span>
<span className='flight-path'>{flight.flightPath}</span> {/* <span className='flight-path'>{flight.origin} - {flight.destination}</span> */}
<span>{flight.flightPathFull}</span> <span>{flight.origin} - {flight.destination}</span>
<Link to={'/flights/' + flight.id}>View Flight</Link> <Link to={'/flights/' + flight.id}>View Flight</Link>
</div> </div>
</> </>
......
.flight {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.flight-data-card {
width: 25vw;
min-width: 350px;
}
.flight-data-title {
font-size: 1.4rem;
align-self: center;
}
.flight-data-label {
font-weight: bold;
font-size: 1.2rem;
}
.flight-data-value {
font-size: 1.1rem;
}
import { useLoaderData } from 'react-router-dom';
import { IFlight } from '../../services/Dashboard/CustomerDashboard';
import './Flight.scss';
function Flight() {
const data = useLoaderData() as IFlight;
return (
<>
<div className='flight'>
<div className='card flight-data-card'>
<span className='flight-data-title'>Flight Details</span>
<div className='flight-data-item'>
<span className='flight-data-label'>ID: </span>
<span className='flight-data-value'>{data.id}</span>
</div>
<div className='flight-data-item'>
<span className='flight-data-label'>Origin: </span>
<span className='flight-data-value'>{data.origin}</span>
</div>
<div className='flight-data-item'>
<span className='flight-data-label'>Destination: </span>
<span className='flight-data-value'>{data.destination}</span>
</div>
<div className='flight-data-item'>
<span className='flight-data-label'>Departure Time: </span>
<span className='flight-data-value'>{new Date(data.departureTime).toLocaleString()}</span>
</div>
<div className='flight-data-item'>
<span className='flight-data-label'>Arrival Time: </span>
<span className='flight-data-value'>{new Date(data.arrivalTime).toLocaleString()}</span>
</div>
<div className='flight-data-item'>
<span className='flight-data-label'>Economy Capacity: </span>
<span className='flight-data-value'>{data.economyCapacity}</span>
</div>
<div className='flight-data-item'>
<span className='flight-data-label'>Business Capacity: </span>
<span className='flight-data-value'>{data.businessCapacity}</span>
</div>
<div className='flight-data-item'>
<span className='flight-data-label'>Economy Price: </span>
<span className='flight-data-value'>{data.economyPrice}</span>
</div>
<div className='flight-data-item'>
<span className='flight-data-label'>Business Price: </span>
<span className='flight-data-value'>{data.businessPrice}</span>
</div>
</div>
</div>
</>
);
}
export default Flight;
import { useState } from 'react'; import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { AxiosError } from 'axios';
import { addFlight } from '../../services/FlightForm/FlightForm';
import './FlightCreationForm.scss'; import './FlightCreationForm.scss';
interface IFlightCreationForm { export interface IFlightCreationForm {
origin: string; origin: string;
destination: string; destination: string;
departure: string; departure: string;
...@@ -14,14 +17,45 @@ interface IFlightCreationForm { ...@@ -14,14 +17,45 @@ interface IFlightCreationForm {
} }
function FlightCreationForm() { function FlightCreationForm() {
const navigate = useNavigate();
const [error, setError] = useState(''); const [error, setError] = useState('');
const { register, handleSubmit } = useForm<IFlightCreationForm>({mode: 'onChange'}); const { register, handleSubmit } = useForm<IFlightCreationForm>({mode: 'onChange'});
const onSubmit = (formValue : IFlightCreationForm) => { const onSubmit = async (formValue : IFlightCreationForm) => {
if (!Number.isInteger(formValue.businessCapacity) || !Number.isInteger(formValue.economyCapacity)) { if (!Number.isInteger(formValue.businessCapacity) || !Number.isInteger(formValue.economyCapacity)) {
setError('Please enter an integer for the capacity.') setError('Please enter an integer for the capacity.')
return; return;
} }
if (formValue.economyCapacity % 6 !== 0) {
setError('Economy capacity must be a multiple of 6');
return;
}
if (formValue.businessCapacity % 4 !== 0) {
setError('Business capacity must be a multiple of 4');
return;
}
if (formValue.origin === formValue.destination) {
setError('Destination cannot be the same as the origin');
return;
}
setError('');
try {
const result = await addFlight(formValue);
navigate(`/flight/${result.data.id}`);
} catch (error) {
const errorMessage = (error as AxiosError).response?.data;
if (typeof errorMessage == 'string') {
setError(errorMessage);
} else {
setError('An unexpected error has occurred');
}
}
} }
return ( return (
...@@ -55,22 +89,22 @@ function FlightCreationForm() { ...@@ -55,22 +89,22 @@ function FlightCreationForm() {
<div className='form-col'> <div className='form-col'>
<div className='form-group'> <div className='form-group'>
<label>Economy Class Capacity</label> <label>Economy Class Capacity</label>
<input type='number' placeholder='Enter capacity' {...register('economyCapacity', { required: true })} /> <input type='number' placeholder='Enter capacity' {...register('economyCapacity', { required: true, valueAsNumber: true })} />
</div> </div>
<div className='form-group'> <div className='form-group'>
<label>Business Class Capacity</label> <label>Business Class Capacity</label>
<input type='number' placeholder='Enter capacity' {...register('businessCapacity', { required: true })} /> <input type='number' placeholder='Enter capacity' {...register('businessCapacity', { required: true, valueAsNumber: true })} />
</div> </div>
<div className='form-group'> <div className='form-group'>
<label>Economy Class Price</label> <label>Economy Class Price</label>
<input type='number' placeholder='Enter price' {...register('economyPrice', { required: true })} /> <input type='number' placeholder='Enter price' {...register('economyPrice', { required: true, valueAsNumber: true })} />
</div> </div>
<div className='form-group'> <div className='form-group'>
<label>Business Class Price</label> <label>Business Class Price</label>
<input type='number' placeholder='Enter price' {...register('businessPrice', { required: true })} /> <input type='number' placeholder='Enter price' {...register('businessPrice', { required: true, valueAsNumber: true })} />
</div> </div>
</div> </div>
</div> </div>
......
...@@ -8,12 +8,14 @@ import Logout from './components/Logout/Logout.tsx'; ...@@ -8,12 +8,14 @@ import Logout from './components/Logout/Logout.tsx';
import ProtectedRoute from './components/ProtectedRoute/ProtectedRoute.tsx'; import ProtectedRoute from './components/ProtectedRoute/ProtectedRoute.tsx';
import InverseProtectedRoute from './components/ProtectedRoute/InverseProtectedRoute.tsx'; import InverseProtectedRoute from './components/ProtectedRoute/InverseProtectedRoute.tsx';
import Dashboard from './components/Dashboard/Dashboard.tsx'; import Dashboard from './components/Dashboard/Dashboard.tsx';
import Flight from './components/Flight/Flight.tsx';
import BookingQuery from './components/BookingQuery/BookingQuery.tsx'; import BookingQuery from './components/BookingQuery/BookingQuery.tsx';
import BookingList from './components/BookingList/BookingList.tsx'; import BookingList from './components/BookingList/BookingList.tsx';
import { AuthoriseUser } from './services/Authorise/Authorise.ts'; import { AuthoriseUser } from './services/Authorise/Authorise.ts';
import { LogoutUser } from './services/Logout/Logout.ts'; import { LogoutUser } from './services/Logout/Logout.ts';
import { GetCustomerDashboardData } from './services/Dashboard/CustomerDashboard.ts'; import { GetCustomerDashboardData } from './services/Dashboard/CustomerDashboard.ts';
import { GetAirlineDashboardData } from './services/Dashboard/AirlineDashboard.ts'; import { GetAirlineDashboardData } from './services/Dashboard/AirlineDashboard.ts';
import { GetFlightData } from './services/Flight/Flight.ts';
import { GetBookingList } from './services/BookingList/BookingList.ts'; import { GetBookingList } from './services/BookingList/BookingList.ts';
import './index.scss'; import './index.scss';
...@@ -54,6 +56,11 @@ const router = createBrowserRouter([ ...@@ -54,6 +56,11 @@ const router = createBrowserRouter([
loader: GetAirlineDashboardData, loader: GetAirlineDashboardData,
element: <Dashboard></Dashboard> element: <Dashboard></Dashboard>
}, },
{
path: 'flight/:id',
loader: GetFlightData,
element: <Flight></Flight>
},
{ {
path: 'booking/query', path: 'booking/query',
element: <BookingQuery></BookingQuery> element: <BookingQuery></BookingQuery>
......
import { getSearchParam } from '../../helpers/SearchParams'; import { getSearchParam } from '../../helpers/SearchParams';
import { IFlight } from '../Dashboard/CustomerDashboard'; import { IFlight } from '../Dashboard/CustomerDashboard';
export interface IBookingList { export interface IBookingList {
flights: IFlight[] flights: IFlight[]
} }
export async function GetBookingList({ request }: { request: Request}): Promise<IBookingList> { export async function GetBookingList({ request }: { request: Request}): Promise<IBookingList> {
const origin = getSearchParam(request.url, 'origin'); const origin = getSearchParam(request.url, 'origin');
const destination = getSearchParam(request.url, 'destination'); const destination = getSearchParam(request.url, 'destination');
...@@ -16,27 +14,6 @@ export async function GetBookingList({ request }: { request: Request}): Promise< ...@@ -16,27 +14,6 @@ export async function GetBookingList({ request }: { request: Request}): Promise<
console.log('ready to call API with:', origin, destination, date, seatType); console.log('ready to call API with:', origin, destination, date, seatType);
return { return {
flights: [ flights: []
{
id: 11,
flightNumber: '0011',
flightPath: 'LTN - MLG',
flightPathFull: 'London(LTN) - Spain(MLG)',
economyPrice: 50,
businessPrice: 100,
departureTime: '10/8/2024 11:00:00 AM',
arrivalTime: '10/8/2024 13:00:00 PM'
},
{
id: 12,
flightNumber: '0012',
flightPath: 'LTN - MLG',
flightPathFull: 'London(LTN) - Spain(MLG)',
economyPrice: 50,
businessPrice: 100,
departureTime: '11/8/2024 11:00:00 AM',
arrivalTime: '11/8/2024 13:00:00 PM'
},
]
}; };
} }
\ No newline at end of file
export interface ISeats {
}
export interface IFlight { export interface IFlight {
id: number; id: number;
flightNumber: string; origin: string;
flightPath: string; destination: string;
flightPathFull: string; arrivalTime: string;
departureTime: string;
economyCapacity: number;
businessCapacity: number;
economyPrice: number; economyPrice: number;
businessPrice: number; businessPrice: number;
departureTime: string; seats: ISeats
arrivalTime: string;
} }
export interface ICustomerDashboardData { export interface ICustomerDashboardData {
...@@ -16,72 +22,9 @@ export interface ICustomerDashboardData { ...@@ -16,72 +22,9 @@ export interface ICustomerDashboardData {
} }
export async function GetCustomerDashboardData(): Promise<ICustomerDashboardData> { export async function GetCustomerDashboardData(): Promise<ICustomerDashboardData> {
return { return {
type: 'customer', type: 'customer',
upcomingFlights: [ upcomingFlights: [],
{ flightsHistory: []
id: 4,
flightNumber: '0004',
flightPath: 'LTN - MLG',
flightPathFull: 'London(LTN) - Spain(MLG)',
economyPrice: 50,
businessPrice: 100,
departureTime: '10/8/2024 11:00:00 AM',
arrivalTime: '10/8/2024 13:00:00 PM'
},
{
id: 5,
flightNumber: '0005',
flightPath: 'LTN - MLG',
flightPathFull: 'London(LTN) - Spain(MLG)',
economyPrice: 50,
businessPrice: 100,
departureTime: '10/8/2024 11:00:00 AM',
arrivalTime: '10/8/2024 13:00:00 PM'
},
{
id: 6,
flightNumber: '0006',
flightPath: 'LTN - MLG',
flightPathFull: 'London(LTN) - Spain(MLG)',
economyPrice: 50,
businessPrice: 100,
departureTime: '10/8/2024 11:00:00 AM',
arrivalTime: '10/8/2024 13:00:00 PM'
}
],
flightsHistory: [
{
id: 1,
flightNumber: '0001',
flightPath: 'LTN - MLG',
flightPathFull: 'London(LTN) - Spain(MLG)',
economyPrice: 50,
businessPrice: 100,
departureTime: '10/8/2024 11:00:00 AM',
arrivalTime: '10/8/2024 13:00:00 PM'
},
{
id: 2,
flightNumber: '0002',
flightPath: 'LTN - MLG',
flightPathFull: 'London(LTN) - Spain(MLG)',
economyPrice: 50,
businessPrice: 100,
departureTime: '10/8/2024 11:00:00 AM',
arrivalTime: '10/8/2024 13:00:00 PM'
},
{
id: 3,
flightNumber: '0003',
flightPath: 'LTN - MLG',
flightPathFull: 'London(LTN) - Spain(MLG)',
economyPrice: 50,
businessPrice: 100,
departureTime: '10/8/2024 11:00:00 AM',
arrivalTime: '10/8/2024 13:00:00 PM'
}
]
} }
} }
import { Params } from 'react-router-dom';
import Api from '../../helpers/Api';
import { IFlight } from '../Dashboard/CustomerDashboard';
export async function GetFlightData({ params }: { params: Params }): Promise<IFlight> {
try {
const result = await Api.get(`Flight/${params.id}`, { withCredentials: true });
return result.data;
} catch (error ){
throw error;
}
}
import { AxiosResponse } from 'axios';
import Api from '../../helpers/Api';
import { IFlightCreationForm } from '../../components/FlightCreationForm/FlightCreationForm';
import { IFlight } from '../Dashboard/CustomerDashboard';
export async function addFlight(form: IFlightCreationForm): Promise<AxiosResponse<IFlight>> {
return Api.post('Flight', {
Origin: form.origin,
Destination: form.destination,
DepartureTime: form.departure,
ArrivalTime: form.arrival,
EconomyCapacity: form.economyCapacity,
BusinessCapacity: form.businessCapacity,
EconomyPrice: form.economyCapacity,
BusinessPrice: form.businessPrice
}, { withCredentials: true });
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment