Airline booking app
Tags: python, react, flask, backend
Published: 2023-10-09 03:42:12

In this blog post, we will explore a project that combines the frontend capabilities of React with the Flask backend, powered by SQLAlchemy for managing database models. This combination allows us to create a practical flight booking app, and we will break down some key components.

## **Front-End Flight Booking with React**

Flight Search
Our flight booking app begins with a user interface powered by React. The core of the app is the flight search feature, allowing users to search for flights by entering a city name. The app fetches flight data from the server based on the city they provided.

```
import React, { useState, useEffect } from 'react';

function SearchFlight() {
  // ...
  const handleFlightSearch = (e) => {
    e.preventDefault();

    if (!cityName) {
      alert('Please enter a city name for flight search.');
      return;
    }

    setLoadingFlights(true);

    // Make a POST request to search for flights based on the city name
    fetch('/api/flights/search', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ city: cityName }),
    })
      .then((response) => {
        if (response.ok) {
          return response.json();
        } else {
          throw an Error('Failed to get flight data');
        }
      })
      .then((data) => {
        setFlights(data);
        setLoadingFlights(false);
      })
      .catch((error) => {
        console.error('Error while fetching flight data:', error);
        setLoadingFlights(false);
      });
  }

  // ...
}
```

Managing the Cart

Users can add and remove flights in their cart. The cart state is managed within the React app, allowing users to interact with it easily.

```
// Define the addToCart function to add flights to the cart
const addToCart = (flight) => {
  // Check if the flight is already in the cart
  if (!cart.some((item) => item.id === flight.id)) {
    // If not, add it to the cart
    setCart([...cart, flight]);
  }
};

// Define the removeFromCart function to remove flights from the cart
const removeFromCart = (flightId) => {
  const updatedCart = cart.filter((item) => item.id !== flightId);
  setCart(updatedCart);
};
```

Booking a Flight

When users are ready to book their selected flights, they can proceed to the booking step. This initiates the booking process, where we create booking objects based on the user's cart and submit these bookings to the server.

```
const handleSubmit = async () => {
  if (flights.length is 0) {
    alert('Cart is empty. Add flights to the cart before submitting.');
    return;
  }

  try {
    setSubmitting(true);

    // Create an array of booking objects based on cart data
    const bookings = flights.map((cartItem) => ({
      user_id: userId,
      flight_id: cartItem.id,
      order_number: generateOrderNumber(),
      order_status: 0,
    }));

    // Make a POST request to create the bookings
    const bookingResponse = await fetch('/api/bookings', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(bookings),
    });

    if (bookingResponse.ok) {
      alert('Booking successfully submitted!');
    } else {
      // Handle error
      // ...
    }
  } catch (error) {
    console.error('An error occurred:', error);
    alert('An error occurred while submitting the booking.');
  } finally {
    setSubmitting(false);
  }
};
```

## Back-End with Flask-SQLAlchemy

On the server side, Flask and SQLAlchemy play a significant role. Let's take a closer look at some of the essential backend models that power our flight booking app.

User Model

The User model represents app users and includes fields such as username, email, first name, and last name. SQLAlchemy is used to hash and manage user passwords securely.

```
class User(db.Model):
    # ...
Airport and Flight Models
We define models for airports and flights to manage airport data and flight details. These models are interconnected through foreign keys, creating a seamless relationship.

class Airport(db.Model):
    # ...

class Flight(db.Model):
    # ...
```

![flights table](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a857eanys4mfwke06bxx.png)


![users table](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/udehnnzf85rszu6bv11n.png)


Booking and Payment Models

For bookings and payments, we use SQLAlchemy to manage order details. The Booking model is connected to both users and flights, linking the booking to a specific user and flight.

```
class Booking(db.Model):
    # ...
```

![Booking table](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4lht5ko3pj934r72dng.png)

User Access Management

User access is a crucial aspect of the flight booking app. Users can sign in, sign up, and sign out as needed. The UserAccess component in React manages this functionality.

```
import React, { useState } from 'react';

function UserAccess({ onSignIn, onSignUp }) {
  // ...
  const handleSignIn = async () => {
    if (!username || !password) {
      setInputError(true);
      return;
    }
    // ...
  };

  const handleSignUp = async () => {
    if (!username || !password || !firstName || !lastName || !email) {
      setInputError(true);
      return;
    }
    // ...
  };

  const handleSignOut = async () => {
    // ...
  };

  return (
    <div className="user-access">
      {/* User sign-in and sign-up components */}
    </div>
  );
}
```


![user sign up](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dkxh0xh9gllhyu7ds5nb.png)


![user sign in](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggfxbm3lwc2v6r8dg7jk.png)

Python backend routing(views):

Here is the breakdown of the app.py to receive the request from the react front end:


Find Airports (AirportSearch Class): When you're planning a trip and want to know which airports are available in your destination city, you use the "AirportSearch" feature. The app sends a request to the /api/airports/airportsearch route, which is handled by the "AirportSearch" class. This class retrieves a list of airports in your desired city and sends it back to your app.

Your Info (UserProfile Class): If you want to see your personal details stored in the app, you access the "Your Info" section. The app checks your identity and then uses the /api/users/profile route, handled by the "UserProfile" class, to fetch and display your info. It's like opening your profile page.

Join Us (Signup Class): If you're new to the app and want to create an account, you click on the "Join Us" or "Sign Up" button. This action triggers the app to send your registration details to the /api/users/signup route, managed by the "Signup" class. It's like filling out a form to become a member.

Who's Here (CheckSession Class): You can use the "Who's Here?" feature to see who else is currently using the app. The app queries the /api/users/checksession route, which is handled by the "CheckSession" class, to find out who's logged in and active in the app.

Sign In (Login Class): If you already have an account and want to log in, you click on "Sign In." The app sends your username and password to the /api/users/login route, which is managed by the "Login" class. This class checks if the provided credentials match and grants you access if they do.

Sign Out (Logout Class): When you're done using the app, you click "Sign Out" to log out. This action sends a request to the /api/users/logout route, managed by the "Logout" class, which locks the door to your account and keeps it safe.

Find Flights (FlightSearch Class): After selecting your destination, you use the "Find Flights" feature to find the perfect flight. The app queries the /api/flights/search route, which is handled by the "FlightSearch" class. This class retrieves and displays a list of flights departing from or arriving at your chosen location.

Book a Flight (BookingFlight Class): Once you've found the ideal flight, you're eager to book it. The "Book a Flight" feature uses the /api/bookings route, which is managed by the "BookingFlight" class, to make the booking official. It's like telling the app, "I'm ready to go on this journey."

These route-handler classes are like specialized workers in your app, each responsible for specific tasks, and they interact with the routes to make your app work smoothly. As a user, you interact with the features provided, and the app takes care of the rest by using the corresponding class to make it all happen.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pud8dt3akur1zlii9zcz.png)



In this blog post, we've explored how to create a practical flight booking app by combining React and Flask-SQLAlchemy. We've walked through key components, such as flight search, cart management, booking, and user access. With this information, you're all set to start building your own web applications using React and Flask. Happy coding!