メインコンテンツまでスキップ

lesson-5_部屋の検索・予約ができるようにしよう

🔍 検索ができるようにしよう

このレッスンでは、宿泊希望日で部屋の検索・予約ができるようにします。

まずは、Home画面を完成させます。 表示するメッセージと日付入力のフォームを追加するために、以下のコードでHome.jsを更新しましょう。

frontend/asserts/js/pages/Home.js

import FormDate from "../components/FormDate";

const Home = () => {
return (
<>
<div className="text-center" style={{ margin: "200px" }}>
<h1>Welcome.</h1>
<h1>Select your stay dates and find a hotel!</h1>
<FormDate />
</div>
<div className="text-center">
<p>
Owners who wish to list their rooms should connect to the NEAR Wallet.
</p>
</div>
</>
);
};

export default Home;

importの追加、return文の書き換えを行いました。 これにより、ユーザーに向けたメッセージと日付を入力するフォームが表示できるようになりました!

確認のため、Home画面を表示してみましょう。

試しに、日付を入力してSearchボタンを押してみましょう。 Search画面に遷移ができればHome画面は完成です!

ここで、Search画面への遷移を設定した部分を振り返ります。

App.js

<Route path="/search/:date" element={<Search />} />

/searchのパスに:dateというキーワードを追加していました。

Search画面に遷移したブラウザのURLを見てみましょう。パスの最後に、検索をした日付が追加されているはずです。

localhost:1234/search/2022-08-09

実際に値を渡す部分は、FormDateコンポーネント内に実装しました。

FormDate.js

// URLに入力された日付を入れて遷移先へ渡す
onClick={() => navigate(`/search/${date}`)}

このように、検索された日付を遷移先に渡します。

次に、Search画面を完成させます。

この画面では検索結果の表示と、再度検索ができるように日付入力フォームを表示します。 以下のコードで、Search.jsを更新しましょう。

frontend/asserts/js/pages/Search.js

import { useEffect, useState } from "react";
import Row from "react-bootstrap/Row";
import { useParams } from "react-router-dom";

import FormDate from "../components/FormDate";
import Room from "../components/Room";
import { book_room, get_available_rooms } from "../near/utils";

const Search = () => {
// URLから検索する日付を取得する
const { date } = useParams();
// 予約できる部屋のデータを設定する
const [availableRooms, setAvailableRooms] = useState([]);

const getAvailableRooms = async () => {
setAvailableRooms(await get_available_rooms(date));
};

const booking = async (room_id, price) => {
book_room({
room_id,
date,
price,
});
getAvailableRooms();
};

// 検索する日付が更新されるたびに`getAvailableRooms`を実行する
useEffect(() => {
getAvailableRooms();
}, [date]);

return (
<>
{/* 日付を入力するフォームを表示 */}
<FormDate />
<div className="text-center" style={{ margin: "20px" }}>
<h2>{date}</h2>
{availableRooms.length === 0 ? (
<h3>Sorry, no rooms found.</h3>
) : (
<>
{/* NEAR Walletに接続されている時 */}
{window.accountId && <h3>{availableRooms.length} found.</h3>}
{/* NEAR Walletに接続していない時 */}
{!window.accountId && (
<h3>
{availableRooms.length} found. To book, you must be connected to
the NEAR Wallet.
</h3>
)}
</>
)}
</div>
{/* 予約可能な部屋を表示する */}
<Row>
{availableRooms.map((_room) => (
<Room room={{ ..._room }} key={_room.room_id} booking={booking} />
))}
</Row>
</>
);
};

export default Search;

内容を見ていきましょう。

以下の部分で日付を受け取っています。注意点として、変数名はApp.jsで指定したキーワードと同じ名前を指定します。:dateと設定したのでdateを受け取ります。

// URLから検索する日付を取得する
const { date } = useParams();

パスから受け取ったdateget_available_roomsメソッドに渡し、部屋のデータを取得します。

// 予約できる部屋のデータを設定する
const [availableRooms, setAvailableRooms] = useState([]);

const getAvailableRooms = async () => {
setAvailableRooms(await get_available_rooms(date));
};

次に定義しているのは、予約ボタンが押された際に実行される関数です。中ではbook_roomメソッドを呼んでいます。

const booking = async (room_id, price) => {
book_room({
room_id,
date,
price,
});
getAvailableRooms();
};

次のuseEffectには、dateを指定しています。Search画面には再度検索ができるように日付入力フォームを表示させます。検索が実行される度にパスが変更され、dateの値も更新されます。そこで、dateが更新されたら再度部屋のデータを取得して、検索結果を更新するために指定します。

// 検索する日付が更新されるたびに`getAvailableRooms`を実行する
useEffect(() => {
getAvailableRooms();
}, [date]);

return文では、NEAR Walletに接続されているかどうかで表示するメッセージを変える実装をしています。get_available_roomsの結果を1つずつRoomコンポーネントへ渡し、部屋を表示します。

では、実際に確認してみましょう。ブラウザの更新ボタン押して、Search画面を更新します。

登録されている部屋の一覧が表示され、NEAR Walletの接続状況によって表示が変わることが確認できたらOKです。接続されていない時には、予約ボタンが押せないことも確認しましょう!

NEAR Walletに接続していない時

NEAR Walletに接続している時

💰 トークンの転送を確認しよう

予約ボタンが押せるようになったので、実際に予約をして宿泊料がオーナーへ転送されることを確認してみましょう。任意のアカウントでNEAR Walletに接続をして予約ボタンを押します。

トークン転送を承認後、Webアプリケーションに戻ると予約した部屋が消えているでしょう。

ナビゲーションバーのメニューから、NEAR Explorerへ移動します。

トランザクション一覧から、先ほど実行されたbook_roomメソッドのトランザクションを確認してみます。

ハッシュ値のリンクから詳細を開き、Transaction Execution Planの項目を見ると、オーナーへ宿泊料が転送されていたらOKです。

最後に、オーナーのWalletを確認します。先ほど確認した項目にReceiver ID:があります。オーナーのアカウントIDをクリックしましょう。オーナーアカウントのトランザクションページが表示されるので、Ⓝ BALANCE PROFILE欄のリンクからアカウントページに移動します。

Walletのページを表示し、右下のRecent activityで宿泊料を受け取っていたら確認完了です!

これで部屋の検索・予約ができるようになりました!

🙋‍♂️ 質問する

ここまでの作業で何かわからないことがある場合は、Discordの#nearで質問をしてください。

ヘルプをするときのフローが円滑になるので、エラーレポートには下記の4点を記載してください ✨

1. 質問が関連しているセクション番号とレッスン番号
2. 何をしようとしていたか
3. エラー文をコピー&ペースト
4. エラー画面のスクリーンショット

次のレッスンに進み、予約を確認する画面を完成させましょう!