Open In App

Build a Car Rental System Using Next.js

Last Updated : 23 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

We will build a car rental system using Next.js, a popular React framework that provides server-side rendering and static site generation. This platform will allow users to browse and book vehicles for short-term usage.

Output Preview: Let us have a look at how the final output will look like.

ss
Build a Car Rental System Using Next.js

Prerequisites

Approach to Build a Car Rental System Using Next.js

  • Start by creating a new Next.js application.
  • Design a navigation bar that provides links to different parts of the application, such as the car listing, booking, and user profile pages.
  • Develop a CarListing component to display a grid of car cards. Each card should show basic information like the car model, price, and an image.
  • Create a CarDetail component to display detailed information about a selected car, including features, availability, and contact details.
  • Create managcars page to edit or delete the car details.
  • Create addcar page which will have form to add new car details.

Steps to Build a Car Rental System Using Next.js

Step 1: Initialized the Nextjs app.

npx create-next-app@latest car-rental-system

Step 2: It will ask you some questions, so choose as the following

Screenshot-2024-08-11-003348
Setup

Step 3: Install the necessary package for your project using the following command.

npm install bootstrap
npm install @fortawesome/react-fontawesome @fortawesome/free-solid-svg-icons

Project Structure

file
Folder Structure

Dependencies

"dependencies": {
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@fortawesome/react-fontawesome": "^0.2.2",
"bootstrap": "^5.3.3",
"next": "14.2.5",
"react": "^18",
"react-dom": "^18"
}

Example: Create the required files and write the following code.

JavaScript
// page.js

import React from "react";
import CarListing from "./components/CarListing";

const page = () => {
    return (
        <div>
            <CarListing />
        </div>
    );
};

export default page;
JavaScript
// Navbar.js

import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Link from 'next/link';

function Navbar() {
    return (
        <nav className="navbar navbar-expand-lg navbar-dark bg-dark shadow">
            <div className="container">
                <Link className="navbar-brand text-light" href="/">Car Rental</Link>
                <button className="navbar-toggler" type="button" data-bs-toggle="collapse" 
data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false"
aria-label="Toggle navigation">
                    <span className="navbar-toggler-icon"></span>
                </button>
                <div className="collapse navbar-collapse" id="navbarNav">
                    <ul className="navbar-nav">
                        <li className="nav-item">
                            <Link className="nav-link text-light" href="/">Home</Link>
                        </li>
                        <li className="nav-item">
                            <Link className="nav-link text-light" href="/addcar">Add New Car
                            </Link>
                        </li>
                        <li className="nav-item">
                            <Link className="nav-link text-light" href="/managecars">
                            Manage Cars</Link>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    );
}

export default Navbar;
JavaScript
// CarListing.js
"use client";
import React, { useState, useEffect } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Link from "next/link";
import Navbar from "./Navbar";

const CarListing = () => {
    const [cars, setCars] = useState([]);
    const [searchTerm, setSearchTerm] = useState("");

    useEffect(() => {
        if (typeof window !== "undefined") {
            const storedCars = localStorage.getItem("cars");
            const allCars = storedCars ? JSON.parse(storedCars) : [];
            setCars(allCars);
        }
    }, []);

    const handleSearchChange = (e) => {
        const search = e.target.value;
        setSearchTerm(search);
        const filteredCars = cars.filter((car) =>
            car.model.toLowerCase().includes(search.toLowerCase())
        );
        setCars(filteredCars);
    };

    return (
        <>
            <Navbar />
            <div className="container mt-5">
                <div className="row mb-3">
                    <div className="col-md-6 offset-md-3">
                        <input
                            type="text"
                            className="form-control"
                            placeholder="Search for cars..."
                            value={searchTerm}
                            onChange={handleSearchChange}
                        />
                    </div>
                </div>
                <div className="row">
                    {cars.map((car) => (
                        <div key={car.id} className="col-lg-4 col-md-6 mb-4">
                            <Link href={`/car/${car.id}`} passHref>
                                <div className="card h-100" style={{ cursor: "pointer" }}>
                                    <img
                                        src={car.imageUrl}
                                        className="card-img-top"
                                        alt={car.model}
                                        style={{ height: "200px", objectFit: "cover" }}
                                    />
                                    <div className="card-body">
                                        <h5 className="card-title">{car.model}</h5>
                                        <p className="card-text">
                                            <strong>Price per Day:</strong> ₹{car.pricePerDay}
                                        </p>
                                        <Link href={`/car/${car.id}`} passHref>
                                            <span className="btn btn-primary w-100
                                            text-decoration-none">
                                                View Details
                                            </span>
                                        </Link>
                                    </div>
                                </div>
                            </Link>
                        </div>
                    ))}
                </div>
            </div>
            <style jsx>{`
        .card:hover {
          border-radius: 8px;
          transition: box-shadow 0.3s;
          width: 101%;
          box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
        }
      `}</style>
        </>
    );
};

export default CarListing;
JavaScript
// pages/car/CarDetail.js

"use client";

import React, { useState, useEffect } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Navbar from "@/app/components/Navbar";
import { useRouter } from "next/router";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
    faSnowflake,
    faCarBattery,
    faSun,
    faCar,
    faTag,
    faUser,
    faPhoneAlt,
    faCalendarAlt,
} from "@fortawesome/free-solid-svg-icons";

const CarDetail = () => {
    const [car, setCar] = useState(null);
    const router = useRouter();
    const { id } = router.query;

    useEffect(() => {
        if (typeof window !== "undefined" && id) {
            const storedCars = localStorage.getItem("cars");
            const allCars = storedCars ? JSON.parse(storedCars) : [];
            const selectedCar = allCars.find((car) => car.id === parseInt(id));
            setCar(selectedCar);
        }
    }, [id]);

    if (!car) {
        return <div>Loading...</div>;
    }

    return (
        <>
            <Navbar />
            <div className="container mt-5">
                <div className="row">
                    <div className="col-md-6 mb-4">
                        <img
                            src={car.imageUrl}
                            alt={car.model}
                            className="img-fluid rounded shadow-sm"
                        />
                    </div>
                    <div className="col-md-6">
                        <h2 className="mb-4">{car.model}</h2>
                        <div className="mb-3">
                            <p>
                                <FontAwesomeIcon icon={faTag} 
                                className="me-2 text-primary" />{" "}
                                <strong>Price per Day:</strong> ₹{car.pricePerDay}
                            </p>
                            <p>
                                <FontAwesomeIcon icon={faUser} 
                                \className="me-2 text-primary" />{" "}
                                <strong>Owner:</strong> {car.ownerName}
                            </p>
                            <p>
                                <FontAwesomeIcon
                                    icon={faPhoneAlt}
                                    className="me-2 text-primary"
                                />{" "}
                                <strong>Contact:</strong> {car.ownerContact}
                            </p>
                            <p>
                                <FontAwesomeIcon
                                    icon={faCalendarAlt}
                                    className="me-2 text-primary"
                                />{" "}
                                <strong>Available:</strong> {car.isAvailable ? "Yes" : "No"}
                            </p>
                        </div>
                        <div className="mb-3">
                            <p>
                                <strong>Features:</strong>
                            </p>
                            <div className="row g-2">
                                {car.features.ac && (
                                    <div className="col-3">
                                        <div className="d-flex align-items-center 
                                        justify-content-center 
p-2 bg-success text-white rounded">
                                            <FontAwesomeIcon icon={faSnowflake} 
                                            className="me-2" />
                                            <span>AC</span>
                                        </div>
                                    </div>
                                )}
                                {car.features.cng && (
                                    <div className="col-3">
                                        <div className="d-flex align-items-center 
                                        justify-content-center 
p-2 bg-success text-white rounded">
                                            <FontAwesomeIcon icon={faCarBattery} 
                                            className="me-2" />
                                            <span>CNG</span>
                                        </div>
                                    </div>
                                )}
                                {car.features.sunroof && (
                                    <div className="col-3">
                                        <div className="d-flex align-items-center 
                                        justify-content-center 
p-2 bg-success text-white rounded">
                                            <FontAwesomeIcon icon={faSun} className="me-2" />
                                            <span>Sunroof</span>
                                        </div>
                                    </div>
                                )}
                                {car.features.automatic && (
                                    <div className="col-3">
                                        <div className="d-flex align-items-center
                                        justify-content-center 
p-2 bg-success text-white rounded">
                                            <FontAwesomeIcon icon={faCar} className="me-2" />
                                            <span>Automatic</span>
                                        </div>
                                    </div>
                                )}
                            </div>
                        </div>
                        <button className="btn btn-primary">Book Now</button>
                    </div>
                </div>
            </div>
        </>
    );
};

export default CarDetail;
JavaScript
// addcar.js

import React, { useState } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Navbar from "@/app/components/Navbar";

const AddCar = () => {
    const [model, setModel] = useState("");
    const [description, setDescription] = useState("");
    const [pricePerDay, setPricePerDay] = useState("");
    const [availability, setAvailability] = useState(true);
    const [ownerName, setOwnerName] = useState("");
    const [ownerContact, setOwnerContact] = useState("");
    const [imageUrl, setImageUrl] = useState("");

    // State for car features
    const [features, setFeatures] = useState({
        ac: false,
        cng: false,
        sunroof: false,
        automatic: false,
    });

    const handleSubmit = (e) => {
        e.preventDefault();
        const id = Date.now(); // Generate a unique ID using the current timestamp

        console.log({
            id,
            model,
            description,
            pricePerDay,
            availability,
            ownerName,
            ownerContact,
            imageUrl,
            features,
        });

        // Save the form data to local storage
        const carData = {
            id,
            model,
            description,
            pricePerDay,
            availability,
            ownerName,
            ownerContact,
            imageUrl,
            features,
        };
        const cars = JSON.parse(localStorage.getItem("cars")) || [];
        cars.push(carData);
        localStorage.setItem("cars", JSON.stringify(cars));

        // Reset form fields after submission
        setModel("");
        setDescription("");
        setPricePerDay("");
        setAvailability(true);
        setOwnerName("");
        setOwnerContact("");
        setImageUrl("");
        setFeatures({
            ac: false,
            cng: false,
            sunroof: false,
            automatic: false,
        });
    };

    // Handle feature checkbox changes
    const handleFeatureChange = (e) => {
        const { name, checked } = e.target;
        setFeatures((prevFeatures) => ({
            ...prevFeatures,
            [name]: checked,
        }));
    };

    return (
        <>
            <Navbar />
            <div className="container" style={{ width: "70%" }}>
                <h2 className="mt-3 mb-4">Add New Car for Rent</h2>
                <form onSubmit={handleSubmit}>
                    <div className="mb-3">
                        <label htmlFor="model" className="form-label">
                            Car Model
                        </label>
                        <input
                            type="text"
                            className="form-control"
                            id="model"
                            value={model}
                            onChange={(e) => setModel(e.target.value)}
                            required
                        />
                    </div>
                    <div className="mb-3">
                        <label htmlFor="description" className="form-label">
                            Description
                        </label>
                        <textarea
                            className="form-control"
                            id="description"
                            value={description}
                            onChange={(e) => setDescription(e.target.value)}
                            required
                        ></textarea>
                    </div>
                    <div className="mb-3">
                        <label htmlFor="pricePerDay" className="form-label">
                            Price Per Day
                        </label>
                        <input
                            type="text"
                            className="form-control"
                            id="pricePerDay"
                            value={pricePerDay}
                            onChange={(e) => setPricePerDay(e.target.value)}
                            required
                        />
                    </div>
                    <div className="mb-3">
                        <label htmlFor="availability" className="form-label">
                            Availability
                        </label>
                        <select
                            className="form-control"
                            id="availability"
                            value={availability}
                            onChange={(e) => setAvailability(e.target.value === "true")}
                            required
                        >
                            <option value="true">Available</option>
                            <option value="false">Not Available</option>
                        </select>
                    </div>
                    <div className="mb-3">
                        <label htmlFor="ownerName" className="form-label">
                            Owner Name
                        </label>
                        <input
                            type="text"
                            className="form-control"
                            id="ownerName"
                            value={ownerName}
                            onChange={(e) => setOwnerName(e.target.value)}
                            required
                        />
                    </div>
                    <div className="mb-3">
                        <label htmlFor="ownerContact" className="form-label">
                            Owner Contact
                        </label>
                        <input
                            type="text"
                            className="form-control"
                            id="ownerContact"
                            value={ownerContact}
                            onChange={(e) => setOwnerContact(e.target.value)}
                            required
                        />
                    </div>
                    <div className="mb-3">
                        <label htmlFor="imageUrl" className="form-label">
                            Image URL
                        </label>
                        <input
                            type="text"
                            className="form-control"
                            id="imageUrl"
                            value={imageUrl}
                            onChange={(e) => setImageUrl(e.target.value)}
                            required
                        />
                    </div>
                    <div className="mb-3">
                        <label className="form-label">Features</label>
                        <div className="form-check">
                            <input
                                className="form-check-input"
                                type="checkbox"
                                id="ac"
                                name="ac"
                                checked={features.ac}
                                onChange={handleFeatureChange}
                            />
                            <label className="form-check-label" htmlFor="ac">
                                AC
                            </label>
                        </div>
                        <div className="form-check">
                            <input
                                className="form-check-input"
                                type="checkbox"
                                id="cng"
                                name="cng"
                                checked={features.cng}
                                onChange={handleFeatureChange}
                            />
                            <label className="form-check-label" htmlFor="cng">
                                CNG
                            </label>
                        </div>
                        <div className="form-check">
                            <input
                                className="form-check-input"
                                type="checkbox"
                                id="sunroof"
                                name="sunroof"
                                checked={features.sunroof}
                                onChange={handleFeatureChange}
                            />
                            <label className="form-check-label" htmlFor="sunroof">
                                Sunroof
                            </label>
                        </div>
                        <div className="form-check">
                            <input
                                className="form-check-input"
                                type="checkbox"
                                id="automatic"
                                name="automatic"
                                checked={features.automatic}
                                onChange={handleFeatureChange}
                            />
                            <label className="form-check-label" htmlFor="automatic">
                                Automatic Transmission
                            </label>
                        </div>
                    </div>
                    <button type="submit" className="btn btn-primary">
                        Add Car
                    </button>
                </form>
            </div>
        </>
    );
};

export default AddCar;
JavaScript
// managecars.js

import React, { useState, useEffect } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Navbar from "@/app/components/Navbar";

const ManageCars = () => {
    const [cars, setCars] = useState([]);
    const [editingCar, setEditingCar] = useState(null);
    const [model, setModel] = useState("");
    const [description, setDescription] = useState("");
    const [pricePerDay, setPricePerDay] = useState("");
    const [ownerName, setOwnerName] = useState("");
    const [ownerContact, setOwnerContact] = useState("");
    const [imageUrl, setImageUrl] = useState("");
    const [features, setFeatures] = useState({
        ac: false,
        cng: false,
        sunroof: false,
        automatic: false,
    });

    useEffect(() => {
        const storedCars = localStorage.getItem("cars");
        if (storedCars) {
            setCars(JSON.parse(storedCars));
        }
    }, []);

    const handleEdit = (car) => {
        setEditingCar(car);
        setModel(car.model);
        setDescription(car.description);
        setPricePerDay(car.pricePerDay);
        setOwnerName(car.ownerName);
        setOwnerContact(car.ownerContact);
        setImageUrl(car.imageUrl);
        setFeatures(car.features);
    };

    const handleUpdate = (e) => {
        e.preventDefault();
        const updatedCars = cars.map((car) =>
            car.id === editingCar.id
                ? {
                    ...car,
                    model,
                    description,
                    pricePerDay,
                    ownerName,
                    ownerContact,
                    imageUrl,
                    features,
                }
                : car
        );
        setCars(updatedCars);
        localStorage.setItem("cars", JSON.stringify(updatedCars));
        resetForm();
    };

    const handleDelete = (carId) => {
        const updatedCars = cars.filter((car) => car.id !== carId);
        setCars(updatedCars);
        localStorage.setItem("cars", JSON.stringify(updatedCars));
    };

    const resetForm = () => {
        setEditingCar(null);
        setModel("");
        setDescription("");
        setPricePerDay("");
        setOwnerName("");
        setOwnerContact("");
        setImageUrl("");
        setFeatures({
            ac: false,
            cng: false,
            sunroof: false,
            automatic: false,
        });
    };

    const handleFeatureChange = (e) => {
        const { name, checked } = e.target;
        setFeatures({ ...features, [name]: checked });
    };

    return (
        <>
            <Navbar />
            <div className="container mt-5">
                <h2 className="mb-4">Manage Cars</h2>
                {editingCar ? (
                    <form onSubmit={handleUpdate}>
                        <div className="mb-3">
                            <label htmlFor="model" className="form-label">
                                Model
                            </label>
                            <input
                                type="text"
                                className="form-control"
                                id="model"
                                value={model}
                                onChange={(e) => setModel(e.target.value)}
                                required
                            />
                        </div>
                        <div className="mb-3">
                            <label htmlFor="description" className="form-label">
                                Description
                            </label>
                            <textarea
                                className="form-control"
                                id="description"
                                value={description}
                                onChange={(e) => setDescription(e.target.value)}
                                required
                            ></textarea>
                        </div>
                        <div className="mb-3">
                            <label htmlFor="pricePerDay" className="form-label">
                                Price per Day
                            </label>
                            <input
                                type="text"
                                className="form-control"
                                id="pricePerDay"
                                value={pricePerDay}
                                onChange={(e) => setPricePerDay(e.target.value)}
                                required
                            />
                        </div>
                        <div className="mb-3">
                            <label htmlFor="ownerName" className="form-label">
                                Owner Name
                            </label>
                            <input
                                type="text"
                                className="form-control"
                                id="ownerName"
                                value={ownerName}
                                onChange={(e) => setOwnerName(e.target.value)}
                                required
                            />
                        </div>
                        <div className="mb-3">
                            <label htmlFor="ownerContact" className="form-label">
                                Owner Contact
                            </label>
                            <input
                                type="text"
                                className="form-control"
                                id="ownerContact"
                                value={ownerContact}
                                onChange={(e) => setOwnerContact(e.target.value)}
                                required
                            />
                        </div>
                        <div className="mb-3">
                            <label htmlFor="imageUrl" className="form-label">
                                Image URL
                            </label>
                            <input
                                type="text"
                                className="form-control"
                                id="imageUrl"
                                value={imageUrl}
                                onChange={(e) => setImageUrl(e.target.value)}
                                required
                            />
                        </div>
                        <div className="mb-3">
                            <label className="form-label">Features</label>
                            <div className="form-check">
                                <input
                                    type="checkbox"
                                    className="form-check-input"
                                    id="ac"
                                    name="ac"
                                    checked={features.ac}
                                    onChange={handleFeatureChange}
                                />
                                <label htmlFor="ac" className="form-check-label">
                                    AC
                                </label>
                            </div>
                            <div className="form-check">
                                <input
                                    type="checkbox"
                                    className="form-check-input"
                                    id="cng"
                                    name="cng"
                                    checked={features.cng}
                                    onChange={handleFeatureChange}
                                />
                                <label htmlFor="cng" className="form-check-label">
                                    CNG
                                </label>
                            </div>
                            <div className="form-check">
                                <input
                                    type="checkbox"
                                    className="form-check-input"
                                    id="sunroof"
                                    name="sunroof"
                                    checked={features.sunroof}
                                    onChange={handleFeatureChange}
                                />
                                <label htmlFor="sunroof" className="form-check-label">
                                    Sunroof
                                </label>
                            </div>
                            <div className="form-check">
                                <input
                                    type="checkbox"
                                    className="form-check-input"
                                    id="automatic"
                                    name="automatic"
                                    checked={features.automatic}
                                    onChange={handleFeatureChange}
                                />
                                <label htmlFor="automatic" className="form-check-label">
                                    Automatic Transmission
                                </label>
                            </div>
                        </div>
                        <button type="submit" className="btn btn-primary">
                            Update Car
                        </button>
                        <button
                            type="button"
                            className="btn btn-secondary ms-2"
                            onClick={resetForm}
                        >
                            Cancel
                        </button>
                    </form>
                ) : (
                    <div className="row">
                        {cars.map((car) => (
                            <div key={car.id} className="col-lg-4 col-md-6 mb-4">
                                <div className="card">
                                    {car.imageUrl ? (
                                        <img
                                            src={car.imageUrl}
                                            className="card-img-top"
                                            alt={car.model}
                                            style={{ height: "200px", objectFit: "cover" }}
                                        />
                                    ) : (
                                        <div
                                            className="card-img-top"
                                            style={{
                                                height: "200px",
                                                backgroundColor: "#f0f0f0",
                                                display: "flex",
                                                alignItems: "center",
                                                justifyContent: "center",
                                            }}
                                        >
                                            <span>No Image</span>
                                        </div>
                                    )}
                                    <div className="card-body">
                                        <h5 className="card-title">{car.model}</h5>
                                        <p className="card-text">{car.pricePerDay} per day</p>
                                        <p className="card-text">Owner: {car.ownerName}</p>
                                        <button
                                            className="btn btn-primary"
                                            onClick={() => handleEdit(car)}
                                        >
                                            Edit
                                        </button>
                                        <button
                                            className="btn btn-danger ms-2"
                                            onClick={() => handleDelete(car.id)}
                                        >
                                            Delete
                                        </button>
                                    </div>
                                </div>
                            </div>
                        ))}
                    </div>
                )}
            </div>
            <style jsx>{`
        .card:hover {
          border-radius: 8px;
          transition: box-shadow 0.3s;
          width: 101%;
          box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
        }
      `}</style>
        </>
    );
};

export default ManageCars;

Output


Similar Reads