Solving the Hotel Reservation Problem using Vue js with Vite

0 %
Gervis Bermudez
Front-end Developer
Ui/UX Designer
  • Residence:
    Argentina
  • City:
    Buenos Aires
  • Age:
    30
English
React / Redux
Node / Typescript
PHP / Laravel
Figma / Xd
mongodb / Firebase
  • React, Angular, Vue
  • Stylus, Sass, Less
  • Gulp, Webpack, Grunt
  • GIT knowledge

Solving the Hotel Reservation Problem using Vue js with Vite

07 Feb 2025

Hello everyone! I wanted to share how I tackled the technical test for hotel reservation, which I completed as part of a job application process. Here’s the problem:

Hotel Reservation problem:

Some points we evaluate include:

  • Solution design
  • Readability
  • Ease of installation, maintenance, and application extension
  • TDD (Test Driven Development)
  • Layout
  • Use of Agile best practices
  • Operational features
  • Application architecture

Please consider:

  • For the solution, we require you to use JavaScript and Vue.js.
  • The application must run.
  • There should be sufficient evidence that the solution is complete and functions correctly with the provided test data.
  • This is a great opportunity for us to closely assess your technical skills and potential. Please refrain from using elements not authored by you in the construction of the source code unless absolutely necessary, and if so, specify the source reference.

Rules:

  • Do not use CSS frameworks.
  • Send the project’s URL in a repository.
  • In addition to the code, please attach a README with an explanation of your solution’s design, your assumptions about the problem, and detailed instructions on how to run your application.
  • We request that you submit the solution to the chosen problem within three days from the time of receipt.

Introduction to the Problem:

The application must run. You should provide sufficient evidence that your solution is complete by indicating that it works correctly against the supplied test data, at a minimum. Please note that you will be assessed on your judgment as well as your execution. The visual design of the app is optional.

Hotel Reservation Problem:

A hotel chain operating in Miami wants to offer room reservation services over the internet. They operate three hotels in Miami: Lakewood, Bridgewood, and Ridgewood. Each hotel has separate weekday and weekend (Saturday and Sunday) rates, with special rates for rewards customers as part of a loyalty program. Each hotel also has an assigned rating.

  • Lakewood, with a rating of 3, has weekday rates of $110 for regular customers and $80 for rewards customers. Weekend rates are $90 for regular customers and $80 for rewards customers.
  • Bridgewood, with a rating of 4, has weekday rates of $160 for regular customers and $110 for rewards customers. Weekend rates are $60 for regular customers and $50 for rewards customers.
  • Ridgewood, with a rating of 5, has weekday rates of $220 for regular customers and $100 for rewards customers. Weekend rates are $150 for regular customers and $40 for rewards customers.

Design:

  • Input should allow entry of various dates.
  • Provide a toggle to allow users to select between regular and reward.
  • Each hotel card should contain:

– Hotel name

– Rating displayed visually as stars

– Display all possible price options for regular, reward, weekday, and weekend (the output card should only display the selected date’s price)

Write a program to assist an online customer in finding the cheapest hotel. Initially, display all hotels as a grid of cards. The input can be one or more dates for a regular or rewards customer. The output should be the cheapest available hotel based on customer type and dates. In case of a tie, return the hotel with the highest rating. The answer should stand out from the list of hotels.

Input Format:

<customer_type> <date1> <date2> …

Output Format:

<card_of_the_cheapest_hotel>

Input 1:

Regular: 16Mar2009(mon), 17Mar2009(tues), 18Mar2009(wed)

Output 1:

Lakewood

Input 2:

Rewards: 26Mar2009(thur), 27Mar2009(fri), 28Mar2009(sat)

Output 2:

Ridgewood

Resolution

The challenge at hand involved developing an algorithm capable of recommending the most economical option among several hotels, considering different variables such as hotel prices, user types (regular or not), and normal versus weekend rates. Below, I’ve broken down the variables:

Hotel Estrellas Normal Customer   Rewards customers  
    Weekdays Weekends Weekdays Weekends
Lakewood 3 110 90 80 80
Bridgewood 4 160 60 110 50
Ridgewood 5 220 150 100 40

To tackle this challenge, I decided to start by defining an interface containing relevant information for each hotel. Here’s how I structured the interface:

export interface Hotel {
  id: number;
  name: string;
  location: string;
  rating: number;
  weekdayRates: {
    regular: number;
    rewards: number;
  };
  weekendRates: {
    regular: number;
    rewards: number;
  };
  photos: string[];
}

Once the interface was established, I moved on to develop the algorithm itself. Basically, the process involved looping through each day between the start date and the end date, evaluating whether it was a weekend and whether the user had selected the rewards program. Below, I provide a detailed flowchart of the algorithm:

Translating this algorithm into code, I obtained the following:

async calculateTotalCost(
    userType: "regular" | "rewards",
    startDate: Date,
    endDate: Date
): Promise {
    this.loading = true;
    try {
        const response = await getHotels();
        let hotels = response;
        let resultByHotels: TotalCost[] = [];
        hotels.forEach((hotel: Hotel) => {
            let totalCost = 0;
            let countWeekends = 0;
            let countWeekDays = 0;
            const currentDate = new Date(startDate);
            while (currentDate <= endDate) {
                const isWeekend =
                    currentDate.getDay() === 0 || currentDate.getDay() === 6; // 0: Sunday, 6: Saturday
                const rate = isWeekend
                    ? hotel.weekendRates[userType]
                    : hotel.weekdayRates[userType];
                totalCost += rate;
                currentDate.setDate(currentDate.getDate() + 1); // Move to the next day
                isWeekend ? countWeekends++ : countWeekDays++;
            }
            resultByHotels.push({
                hotel,
                totalCost,
                countWeekends,
                countWeekDays,
            });
        });
        return resultByHotels.sort((a, b) => {
            if (a.totalCost === b.totalCost) {
                return b.hotel.rating - a.hotel.rating;
            }
            return a.totalCost - b.totalCost;
        });
    } catch (error) {
        console.error("Error fetching data:", error);
    } finally {
        this.loading = false;
    }
}

With the function in place, it was time to embark on the most exciting part of the process: application development.

Interface Design: Inspiration and Execution

Since this was a web application for hotel booking, I dedicated time to analyzing current interfaces to draw inspiration from common user experiences. Here’s what I discovered:

Color Palette: Interfaces in this domain often use blue tones as primary colors and yellow tones as secondary ones. Based on this observation, I selected the following color palette:

Based on the above, I selected the following colors:

Content Distribution: Booking websites typically feature a large header with images and 3 to 4 input fields for search criteria. Inspired by this common layout, I designed the following content distribution, which you can see in full on Figma: 

As you can see, I prioritized the search criteria input fields at the top of the screen, followed by the results. Initially, all hotels are displayed without any additional filtering criteria.

Application Development: Configuration and Structure

I started by creating a new project with Vue.js and using Pinia as the state manager. The installation details can be found in the official documentation here, and the resulting folder structure is as follows:

Project Structure:

  • public/: Contains the application’s static files.
  • src/: Contains the application’s source code.
    • assets/: Resource files such as images, icons, etc.
    • components/: Reusable components of the application.
    • store/: Configuration and Pinia modules for state management.
    • utils/: Utility and helper functions.
    • App.vue: Main component of the application.
    • main.ts: Entry point of the application.

Additionally, I developed common components such as buttons, cards, headers, footers, input fields, selections, loading spinners, etc., resulting in the following:

Global Storage Implementation:

The official state management tool of Vue.js is Pinia. Here’s how I did it:

Using defineStore, I initialized the global storage of the application, passing it the initial state and actions that would interact with the global state, resulting in the following:

// src/stores/hotels.store.ts
import { defineStore } from "pinia";
import { Hotel, TotalCost } from "../models/Hotels";
import { getHotels, getReviews } from "../services";
import { Review } from "../models/Review";

export interface State {
    hotels: Hotel[];
    hotel: Hotel | null;
    reviews: Review[];
    loading: boolean;
}

export const useHotelsStore = defineStore("store", {
    state: (): State => {
        return {
            hotels: [],
            hotel: null,
            reviews: [],
            loading: false,
        };
    },
    actions: {
        async fetchData() {
            // Implementation here
        },
        async calculateTotalCost() {
            // Implementation here
        },
        async fetchReviews() {
            // Implementation here
        },
        async fetchReviewsByHotelID(hotel_id: number) {
            // Implementation here
        },
    },
});

This way, we were able to consume the functions provided by the global storage in our application.

// src/App.vue
const store = useHotelsStore();
const { loading } = storeToRefs(store);
const userType = ref<"regular" | "rewards">("regular");
const hotelsList = ref([]);
const reviews = ref([]);
const searchResult = ref(null);
const dates: Dates = reactive({
  initial_date: null,
  final_date: null,
});

onMounted(() => {
  getHotels().then((result) => {
    hotelsList.value = result;
  });
  getReviews().then((result) => {
    reviews.value = result.splice(0, 6);
  });
});

const handleSelectChange = (data: string) => {
  userType.value = data as "regular" | "rewards";
};

const handleInputChange = (name: string, data: string) => {
  dates[name] = data;
};

const handleSearchBooking = () => {
  if (dates.initial_date && dates.final_date) {
    store
      .calculateTotalCost(userType.value, dates.initial_date, dates.final_date)
      .then((result) => {
        if (result) {
          searchResult.value = result[0];
        }
      });
  }
};

const resetSearch = () => {
  searchResult.value = null;
};

For those interested in reviewing the complete code, it’s available on GitHub:  https://github.com/gervisbermudez/hotel-booking-app

With this, I conclude my process of solving the hotel reservation technical test. It has been an exciting and enriching experience, and I look forward to continuing to develop skills and facing new challenges in the future!

Ready to order your project?

Let's work together!
Contact me
Posted in