Vueで予約アプリを作るには?

予約管理は、レストランのようなスケジュールと顧客のキャパシティが重要なサービス産業では、ビジネスの不可欠な部分です。

Back4app、Twilio API、Vueを使えば、予約、確認メッセージの受信、予約枠の表示などの機能を備えたシンプルなレストラン予約アプリを構築できます。

この記事では、フロントエンドにVue、バックエンドとデプロイのニーズに対応するためにBack4app、そしてWhatsappを通してユーザーと通信するためにTwilioを使って予約アプリを構築し、デプロイします。

プロジェクト概要

このガイドでは、Vueを使ってシンプルな予約アプリケーションを作成します。予約アプリケーションには、ReservationFormビューとReservationListビューがあります。

ゲストはReservationFormビューで名前Eメール日付時間電話番号などの予約の詳細を入力します。彼らはまた、ReservationListビューですべての予約を参照してください。

以下のものを利用する:

  • Back4appバックエンド:Vueアプリケーションの予約データをデータベースに保存・管理するためのBack4appバックエンドを作成します。
  • Twilio API:Twilio APIをVueアプリケーションに統合し、予約したゲストにWhatsApp確認メッセージを送信します。
  • Back4ppのAIエージェント:Back4AppのAIエージェントで4つのクラウド機能を作成し、Vueアプリケーションに統合して処理します:
    • 予約の詳細をBack4Appのデータベースに保存する。
    • 予約日時の空き状況の確認
    • Twilio APIを使用して、予約完了を伝えるWhatsApp成功メッセージを送信する。
    • ゲストが既に行った予約をデータベースに表示する。
  • Back4appコンテナ:VueアプリケーションをBack4appコンテナにデプロイし、オンラインでアクセスできるようにします。

Vueアプリケーションの構築

このセクションでは、開発環境のセットアップと予約アプリケーションのボイラープレートの構築について説明します。

開発環境のセットアップ

Vueアプリケーションを作成するには、ターミナルで以下のコマンドを実行します:

npm create vue

上のコマンドを実行すると、アプリケーションの名前と、TypeScriptの追加やJSXのサポートなど、アプリケーションの特定の機能を有効にするプロンプトが表示されます。Vue Router “以外のオプションはすべて “no “を選択してください。ビュー間を移動するために必要です。

次に、作成したディレクトリにcdを入れ、以下のコマンドを実行して必要な依存関係をインストールする:

npm install

次に、以下のコマンドを実行してParse SDKをインストールします:

npm install parse

Parse SDKは、VueアプリケーションとBack4appバックエンド間の通信を可能にします。

開発環境のセットアップが完了したら、予約アプリケーション・ビューの作成に進みます。

アプリケーションのビューを作成する

アプリケーションのviewsディレクトリにReservationFormビューとReservationListビューを作成します。

次に、ルーターディレクトリの index.jsファイルに以下のコードを追加して、これら2つのビュー間のルーティングを有効にします:

// index.js
import { createRouter, createWebHistory } from "vue-router";
import ReservationForm from "@/views/ReservationForm.vue";

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: "/",
      name: "Home",
      component: ReservationForm,
    },
    {
      path: "/reservations",
      name: "Reservations",
      component: () => import("@/views/ReservationList.vue"),
    },
  ],
});

export default router;

上記のコードブロックは、Vueアプリケーション内でルーティングを設定します。これは、/ルートと/reservationsルートを定義します。ゲストがアプリのURLにアクセスすると、このコードブロックはHomeルートとしてReservationFormビューに誘導します。

reservationsルートはユーザーをReservationListビューに誘導します。このルートは遅延ロードされるので、アプリは必要なときだけこのルートをロードします。

次に、ユーザーが2つのルート間をナビゲートできるように、App.vueファイルを設定して、ルートリンクを表示するナビゲーションバーをレンダリングします:

//App.vue
<script setup>
import { RouterLink, RouterView } from 'vue-router'
</script>

<template>
  <header>
    <div class="wrapper" id="app">
      <nav>
        <RouterLink to="/">Home</RouterLink>
        <RouterLink to="/reservations">View Reservations</RouterLink>
      </nav>
    </div>
  </header>
  <RouterView />
</template>

上のコードブロックは、アプリケーションのメインレイアウトとして動作するApp.vueファイルを表示します。このコードブロックでは、Vue RouterライブラリからRouterLinkコンポーネントとRouterViewコンポーネントをインポートし、各ルートをRouterLinkコンポーネントで表現しています。

RouterLinkコンポーネントは、リンクが誘導するルートを指定するためにtoprop を取ります。RouterViewコンポーネントはプレースホルダとして動作し、現在のルートのコンテンツを動的にレンダリングします。

ReservationForm.vueファイルに以下のコードブロックを追加し、ユーザーが予約の詳細を入力するためのフォームを作成します:

// ReservationForm.vue
<template>
  <div>
    <form>
      <input v-model="reservation.name" placeholder="Name" required />
      <input
        v-model="reservation.email"
        type="email"
        placeholder="Email"
        required
      />
      <input
        v-model="reservation.date"
        type="date"
        placeholder="Date"
        required
      />
      <input
        v-model="reservation.time"
        type="time"
        placeholder="Time"
        required
      />
      <input
        v-model="reservation.phoneNumber"
        type="tel"
        placeholder="Phone Number"
        required
      />
      <button type="submit">Create Reservation</button>
    </form>
  </div>
</template>

<script setup>
import { ref } from "vue";
const reservation = ref({
  name: "",
  email: "",
  date: "",
  time: "",
  phoneNumber: "",
});
</script>

上のコード・ブロックは、ユーザーの名前Eメール日付時間電話番号など、さまざまな詳細情報を入力するための必須フィールドを持つフォーム要素を作成します。

上記のコードブロックは、vueライブラリのref関数を使用して、ユーザーの詳細を保存するリアクティブ予約オブジェクトを作成します。

次に、ReservationList.vueファイルに以下のコードブロックを追加し、ユーザーが行った予約のリストを表示します:

// ReservationList.vue
<template>
  <div>
    <ul v-if="reservations.length" class="wrapper">
      <li
        v-for="reservation in reservations"
        :key="reservation.objectId"
        class="card"
      >
        <p>Name: {{ reservation.name }}</p>
        <p>Date: {{ new Date(reservation.date).toLocaleDateString() }}</p>
        <p>Time: {{ reservation.time }}</p>
        <p>Phone: {{ reservation.phoneNumber }}</p>
      </li>
    </ul>
    <p v-else>No reservations found.</p>
  </div>
</template>

<script setup>
import { ref } from "vue";

const reservations = ref([]);
</script>

上記のコードブロックは、vueの条件文ディレクティブであるv-ifを使用して、既存の予約があればそれを表示します。

予約が存在する場合、このコードブロックはv-for命令でreservations配列の各予約を繰り返し、予約された予約を表示する。

アプリケーションのビューをスタイリングする

ReservationListビューに以下のスコープ付きスタイルブロックを追加し、リストや他の要素の外観を制御します:

// ReservationList.vue
<style scoped>
h1{
  margin-block-end: 2rem;
}

.card{
  background-color: #D99858;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  border-radius: 12px;
  padding: 2rem;
  align-items: center;
}

li{
  color: #FFFFFF;
}

.wrapper{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
}

div{
  padding-inline-start: 1rem;
}

</style>

以下のスコープ付きスタイルブロックをReservationFormビューに追加し、フォームの外観を制御します:

// ReservationForm.vue
<style scoped>

  form{
    display: flex;
    flex-direction: column;
    gap: 1rem;
    align-items: center;
  }

</style>

最後に、assetsディレクトリのmain.cssファイルに以下のCSSスタイルを追加して、Vueアプリケーションのグローバルスタイルを定義します:

/* main.css */
@import url('<https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap>');

*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body{
  font-family: "Montserrat", sans-serif;
  background-color: #333333;
  color: #FFFFFF;
}
nav {
  padding: 10px;
  display: flex;
  justify-content: space-between;
}
nav a{
  color: inherit;
  text-decoration: none;
  font-weight: 500;
  color: #888888;
  margin-block-end: 3rem;
}
nav a:hover{
  color: #D99858;
}
header{
  padding: 1rem;
}
button {
  background-color: #FFFFFF;
  color: #D99858;
  border: none;
  padding: 0.7rem 0.9rem;
  font-size: 14px;
  border-radius: 7px;
  font-weight: 500;
}
button:hover {
  background-color: #D99858;
  color: #FFFFFF; 
}
input{
  inline-size: 100%;
  border: none;
  border-radius: 5px;
  outline: none;
  padding: 1rem;
  font-family: "Montserrat", sans-serif;
}
.container{
  inline-size: 60%;
  margin: auto;
}

予約アプリケーションのボイラープレートを構築した後、データベースに予約の詳細を保存するためにBack4app Backendを作成します。

Back4appバックエンドの作成

Back4appでBackendを作成するには、Back4appのアカウントが必要です。アカウントをお持ちでない場合は、無料でサインアップできます。

アカウントにログインし、右上にある “NEW APP“ボタンをクリックしてください。すると、”Backend as a Service“オプションを選択するページが表示されます。

Backend as a Service“をクリックすると、アプリケーション・インスタンスに名前を付け、アプリケーションのデータベース・タイプを選択するよう促される。PostgreSQLデータベースを選択し、”Create“ボタンを押してください。

Back4appがアプリケーションをセットアップすると、以下のようにアプリケーションのインスタンスに誘導されます。

Back4app Dashboard

セキュリティとキー」セクションから「アプリケーションID」と「JavaScriptキー」を取得します。このセクションは、サイドバーの「アプリ設定」をクリックすると表示されます。

Back4appセキュリティキー

次に、.envファイルを作成し、”Application ID“と “Javascript Key“を追加して、アプリケーション内の環境変数として読み込みます:

VITE_BACK4APP_APPLICATION_ID = <YOUR_APP_ID>
VITE_BACK4APP_JAVASCRIPT_KEY = YOUR_JAVASCRIPT_KEY>

VueアプリケーションでParseを初期化するために、main.jsファイルを修正します。次のように:

//  main.js
import "./assets/main.css";
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import Parse from "parse/dist/parse.min.js";

Parse.initialize(
  `${import.meta.env.VITE_BACK4APP_APPLICATION_ID}`,
  `${import.meta.env.VITE_BACK4APP_JAVASCRIPT_KEY}`,
);

Parse.serverURL = "<https://parseapi.back4app.com/>";

const app = createApp(App);

app.use(router);

app.mount("#app");

上記のコードブロックは、VueアプリケーションでParse SDKをインポートして初期化し、アプリケーションがBack4appバックエンドと通信できるようにします。

次に、Back4appのデータベースに予約の詳細を保存する必要があります。ゲストの予約詳細を保存するには、Back4appのAIエージェントを使用してデータベース内にクラスを作成します。

このクラスは、名前Eメール日付などの予約詳細を保存します。

AIエージェントを使った予約クラスとクラウド機能の作成

画面の左上にある “AI Agent“タブを探し、以下のプロンプトをエージェントに送り、データベースにクラスを作成します:

Create database tables in my Back4app app with the following information.

1. Reservation Class:
Class Name: Reservation

Fields:
objectId (String, Automatically generated by Back4App).
name (String, Required)
email (String, Required)
date (Date, Required)
time (String, Required)
phoneNumber (String, Required)

Populate the database tables with test data.

My Parse App ID: <Your Parse App ID>

以下のような返事が返ってくるはずだ:

AIエージェントの反応

予約の詳細を保存するフィールドを持つ予約クラスを作成した後、AIエージェントで4つのクラウド関数を作成します。作成したデータベースと対話するAIエージェントで4つのクラウド関数を作成します。

AIエージェントに以下のコマンドを促し、Reservationクラスにデータを格納するクラウド関数を作成させる:

Create a Cloud Code function "createReservation" that takes in necessary 
arguments to create a new reservation in the Reservation class.

以下のような返事が返ってくるはずだ:

AIエージェントの反応

createReservation関数を作成した後、AIエージェントに以下のコマンドを送り、ゲストが予約したい日時の空き状況を確認します:

Create a Cloud Code function "checkAvailability" to check the availability of a reserved time and date. Create this second Cloud Code function in the same file.

以下のような返事が返ってくるはずだ:

AIエージェントの反応

Twilio の WhatsApp API で WhatsApp メッセージを送信するには、Twilio アカウントの作成と設定が必要です。Twilio はユーザーがアプリケーションから Whatsapp メッセージを送信できる API を提供しています。

TwilioアカウントのSID、Twilio認証トークン、Twilio Whatsapp番号をTwilioアカウントから取得し、AIエージェントにTwilioのAPIを使用してsendWhatsAppConfirmationクラウド関数を作成するよう促します:

Create a Cloud Function with Twilio's WhatsApp API to send a WhatsApp confirmation message. Here are the Twilio account details you will need:
Twilio Account SID: <Your Twilio Account SID>
Auth Token: <Your Twilio Authentication Token>
WhatsApp number: <The Twilio WhatsApp Number>

以下のような返事が返ってくるはずだ:

AIエージェントの反応

次に、AIエージェントに、データベースに保存されているすべての予約を表示する最後のクラウド機能を作成するよう促す:

Write a cloud code function to view all reservations stored in the database in the same file with the other three cloud functions.

以下のような返事が返ってくるはずだ:

AIエージェントの反応

Back4appインスタンスでアプリケーションに必要な全ての関数を作成しました。次のステップは、Back4appバックエンドのクラウド機能をVueアプリケーションに統合することです。

Vueアプリケーションにクラウド機能を統合する

このセクションでは、クラウド関数をVueアプリケーションに統合する方法を説明します。Parse.cloud.run()関数を実行することで、Back4appのBackendで定義したクラウド関数をVueアプリケーション内で呼び出すことができます。

ReservationForm.vueファイルのテンプレートブロックを修正して、フォーム送信時にsubmitReservation関数を実行するようにします:

// ReservationForm.vue
<template>
  <div>
    <form @submit.prevent="submitReservation">
      // calls the function on form submission
      <input v-model="reservation.name" placeholder="Name" required />
      <input
        v-model="reservation.email"
        type="email"
        placeholder="Email"
        required
      />
      <input
        v-model="reservation.date"
        type="date"
        placeholder="Date"
        required
      />
      <input
        v-model="reservation.time"
        type="time"
        placeholder="Time"
        required
      />
      <input
        v-model="reservation.phoneNumber"
        type="tel"
        placeholder="Phone Number"
        required
      />
      <button type="submit">Create Reservation</button>
    </form>
  </div>
</template>

次に、ReservationForm.vueファイルのスクリプトブロックを修正して、submitReservation関数を定義し、フォームの送信に関連するクラウド関数を実行します:

// ReservationForm.vue
<script setup>
import { ref } from "vue";
import Parse from "parse/dist/parse.min.js";

const reservation = ref({
  name: "",
  email: "",
  date: "",
  time: "",
  phoneNumber: "",
});

const submitReservation = async () => {
  try {
    const availabilityResult = await Parse.Cloud.run("checkAvailability", {
      date: reservation.value.date,
      time: reservation.value.time,
    });

    if (availabilityResult.available) {
      const creationResult = await Parse.Cloud.run("createReservation", {
        ...reservation.value,
        date: {
          __type: "Date",
          iso: new Date(
            reservation.value.date + "T" + reservation.value.time,
          ).toISOString(),
        },
      });

      if (creationResult) {
        await Parse.Cloud.run("sendWhatsAppConfirmation", {
          to: reservation.value.phoneNumber,
          reserveeName: reservation.value.name,
          body: "Your reservation has been confirmed.",
        });

        alert(
          "Reservation created and confirmation has been sent via WhatsApp.",
        );
      }
    } else {
      alert("Sorry, the chosen date and time are not available.");
    }
  } catch (error) {
    console.error("Error creating reservation:", error);
    alert("Error while processing your reservation: " + error.message);
  }
};
</script>

上記のコードブロックはsubmitReservation関数を呼び出し、予約の送信を処理しています。

この関数は、まずcheckAvailabilityクラウド関数を呼び出して、選択した日時が利用可能かどうかをチェックします。

指定された日時が利用可能な場合、コードブロックは別のクラウド関数であるcreateReservationを呼び出し、ゲストの詳細を含む予約を作成します。

コードブロックは次にsendWhatsAppConfirmationクラウド関数を呼び出し、WhatsAppメッセージを送信してゲストがタイムスロットの予約に成功したことを通知します。

次に、ゲストが予約したすべての時間帯を表示できるように、ReservationList.vueファイルのスクリプトブロックを変更して、getAllReservationsクラウド関数を実行します:

// ReservationList.vue
<script setup>
import { ref, onBeforeMount } from "vue";
import Parse from "parse/dist/parse.min.js";

const reservations = ref([]);

const fetchReservations = async () => {
  try {
    const result = await Parse.Cloud.run("getAllReservations");
    reservations.value = result;
  } catch (error) {
    console.error("Error retrieving reservations:", error);
    alert(error.message);
  }
};

onBeforeMount(fetchReservations);
</script>

上記のコードブロックは、VueがonBeforeMountvue関数でコンポーネントをマウントする直前にfetchReservations関数を呼び出しています。

fetchReservations関数はgetAllReservationsクラウド関数を実行し、Back4appデータベースのReservationクラスに保存されている全ての予約を取得します。

アプリケーションのテスト

アプリケーションをBack4appコンテナにデプロイする前に、アプリケーションをテストし、すべての機能が完全に機能することを確認してください。

以下のコマンドを実行してアプリケーションを起動する:

npm run dev

上記のコマンドを実行すると、アプリケーションがhttp://localhost:5173/。

下の画像のように、http://localhost:5173/に移動してアプリケーションを表示します:

予約フォーム

View Reservations“タブに移動すると、AIエージェントがデータベースに入力した予約が表示されます。

デフォルト予約リスト

フォームに必要事項を入力し、「予約作成」ボタンをクリックして、新規予約を作成します。

予約の作成

ご予約が成功したかどうかを確認するには、「予約の確認」タブに移動してください。

ご予約

最後にWhatsAppアプリケーションを開き、WhatsApp番号に送信された確認メッセージをご覧下さい。

WhatsAppの確認

Back4appのAIエージェントを使ったアプリケーションのBack4appコンテナへのデプロイ

アプリケーションをBack4appコンテナにデプロイするには、Vueアプリケーション用のDockerfileを作成する必要があります。

プロジェクトのルート・ディレクトリにDockerfileを作成し、以下のコード・ブロックを追加する:

# Dockerfile

FROM node:18

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

RUN npm run build

FROM nginx:1.19.0-alpine

COPY --from=0 /app/dist /usr/share/nginx/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

Dockerfileを作成したら、コードをGitHubリポジトリにプッシュします。AIエージェントを使ってGitHubからアプリケーションをデプロイするには、Back4appのGitHubアカウントにBack4App Containers GitHub Appをインストールする必要があります。

また、アプリケーションのコード・リポジトリにアクセスするために必要なパーミッションをアプリケーションに付与する必要があります。

次に、Back4appのホームページに移動し、ディスプレイの右上にある “New App“ボタンをクリックします。

設定画面が表示されるので、作成したいアプリの種類を選ぶ。

以下の画像のように、Back4app Agentオプションを選択します。

新しいアプリのホームページを作成する

Back4app Agentオプションを選択すると、Back4app AIエージェントのページにリダイレクトされます。

AIエージェントに以下のプロンプトを与え、アプリケーションのデプロイメントプロセスを開始します:

Deploy my "YOUR_REPOSITORY_URL" repository on GitHub to a Back4App Container.
Here are the required environmental variables:
VITE_BACK4APP_APPLICATION_ID = "BACK4APP_APP_ID"
VITE_BACK4APP_JAVASCRIPT_KEY = "BACK4APP_JAVASCRIPT_KEY"

プレースホルダを実際の値に置き換えます。上記のプロンプトが表示され、デプロイ処理が開始されます。

完了すると AI エージェントが応答し、成功またはデプロイ保留中であることを示します。保留中のデプロイが表示された場合、Back4appコンテナダッシュボードでアプリのデプロイステータスを監視できます。

下の画像のような反応が返ってくるはずだ:

AIエージェントの反応

あるいは、手動でアプリケーションをBack4appコンテナにデプロイすることもできます。

結論

この記事では、Back4app、Vue、Twilio APIを使用して、機能的なレストラン予約アプリをビルドし、デプロイしました。

あなたのアプリで、ユーザーは予約をすることができ、その予約はあなたのBack4appバックエンドに保存されます。ユーザーは、AIエージェントを使用して生成されたVueとBack4appクラウドコードによって作成されたインターフェイスを通して、予約内容を確認することができます。

さらに、Twilio APIを利用したWhatsAppメッセージで予約完了を確認できます。

このチュートリアルで使用した完全なコードは、GitHubのリポジトリで見ることができる。


Leave a reply

Your email address will not be published.