【必読】なぜ今、Aura ではなく LWR を選ぶべきなのか?

【B2B不動産ポータル 制作日誌 Vol.3】「ダブルブッキング」を防ぐリアルタイム予約システム:Apexマトリクス生成とLWCモーダル連携

「LWRサイト × Agentforce」 不動産ポータル開発連載、第3回です。 前回(Vol.2)は、自作スライダーによるリッチな募集住戸詳細画面を作りました。今回はその詳細画面に埋め込む、「リアルタイム内見予約カレンダー」 の実装です。

従来の不動産サイトによくある「この物件について問い合わせる」というフォームは、B2B(仲介業者間)の取引においてはスピード感が足りません。 電話確認なしで、画面上で空き枠(◎)をクリックすればその場で予約が確定する。そんなシステムを構築しました。

DXforce Point for Developers

今回の記事で作成したコンポーネントの全ソースコードをGitHubで公開しています。 ぜひ Clone して、あなたの組織で動かしてみてください。

完成イメージとアーキテクチャ

実装したカレンダーがこちらです(画面内右下)。
縦軸に「時間」、横軸に「日付(1週間)」をとったマトリクス表示です。

空き枠にだけ [◎] を表示する。

予約できることを意味する [◎] ボタンを押すと予約フォームが開きます。

[◎] ボタンを押した日時がデフォルト値になる。

このUIを実現するために、以下のアーキテクチャを採用しました。

  1. Apex: 予約データ(ViewingRequest__c)を検索し、週間マトリクスデータ(JSON)を作成して返す。
  2. LWC (Calendar): マトリクスを描画し、週の切り替え(前へ/次へ)を制御する。
  3. LWC (Modal): ボタンをクリックした際に、入力フォームをポップアップさせる。

カレンダーの「日付計算」と「モバイル対応」

カレンダー実装で一番面倒なのが「日付計算」です。 今回は connectedCallback で、「今日が何曜日であっても、強制的にその週の月曜日を開始日にする」 ロジックを組んでいます。

listingAvailabilityCalendar.js

connectedCallback() {
        // 今日の日付をベースに「今週の月曜日」を計算
        const today = new Date();
        const day = today.getDay(); // 0(Sun) - 6(Sat)
        
        // 月曜始まりにするための調整値
        const diff = day === 0 ? -6 : 1 - day; 
        
        today.setDate(today.getDate() + diff);
        today.setHours(0, 0, 0, 0);
        
        this.currentStartDate = today;
        this.loadCalendar();
    }

listingAvailabilityCalendar.css

また、このカレンダーはスマホでも閲覧されます。7日分の列をスマホの狭い画面に収めるのは不可能です。 そこで、「横スクロール」 を許容しつつ、「時間の列(左端)だけは固定する」 というUXを採用しました。これを実現するのが CSSの position: sticky です。

/* 左端(時間)列を固定する */
.sticky-column {
    position: sticky;
    left: 0;
    z-index: 10; /* 他のセルより前面に配置 */
    background-color: var(--dxp-g-root, #fff); /* 透過防止 */
    border-right: 1px solid #dddbda; /* 境界線で見やすくする */
}

最新の Lightning Modal 実装

予約フォームとなるモーダル画面 tourReservationModal は、標準の LightningModal を継承して作成します。 Aura時代のように「HTMLの中にモーダルを書いて if:true で出し分け」たりする必要はありません。

tourReservationModal.js

import LightningModal from 'lightning/modal';

export default class TourReservationModal extends LightningModal {
    @api listingId;
    @api initialTime; // 親から渡されるクリックした日時

    // ...
}
DXforce Point for Developers

実践テクニック:reduceを使った一括バリデーション
フォーム送信時の入力チェック(必須項目など)には、配列メソッドの reduce を使うと非常にスマートに書けます。

async handleSubmit() {
        // 全てのinputコンポーネントを取得してチェック
        const allValid = [...this.template.querySelectorAll('lightning-input, lightning-textarea')]
            .reduce((validSoFar, inputCmp) => {
                inputCmp.reportValidity();
                return validSoFar && inputCmp.checkValidity();
            }, true);

        if (!allValid) {
            return;
        }
        // ... 送信処理へ
    }

親コンポーネントからの呼び出しフロー

カレンダー側(親)では、このモーダルを open() メソッドで呼び出し、結果を await で待ち受けます。 非常に読みやすい、モダンな非同期フローになっています。

listingAvailabilityCalendar.js

    async handleSlotClick(event) {
        const selectedTime = event.target.dataset.time;

        // モーダルを開き、ユーザーの操作完了を待つ (Promise)
        const result = await TourReservationModal.open({
            size: 'medium',
            description: '内見予約フォーム',
            listingId: this.recordId,
            initialTime: selectedTime
        });

        // モーダルから { status: 'success' } が返ってきたら完了アラートを出す
        if (result && result.status === 'success') {
            await LightningAlert.open({
                message: '内見のお申し込みを受け付けました。',
                theme: 'success',
                label: '予約完了', 
            });
            // カレンダーを再読み込みして「×」に更新する
            this.loadCalendar();
        }
    }

まとめ

Vol.3では、LWRサイトにおけるリアルタイム予約機能を実装しました。

  • JSでの日付操作: 週初めの計算ロジック。
  • CSS Sticky: モバイルでも使いやすいテーブルUI。
  • Lightning Modal: open / close を使ったきれいなデータ受け渡しとバリデーション。

これで、ユーザーは物件を探し、詳細を見て、その場で予約できるようになりました。 次回 Vol.4 は、いよいよ最新技術 Agentforce の登場です。 ここまでは「ユーザーが自分で探す」機能でしたが、次は「AIエージェントに探させる」機能を実装します。しかしそこには API制限の壁 が…。その突破方法を解説します。

DXforceの管理人

福島 瑛二

2013年にJavaエンジニアとしてのキャリアをスタート。2019年にSalesforceと出会い、Salesforceエンジニアの道へ。

デザインや UI/UX の観点からもシステムを捉え、ユーザーにとって心地よい体験を実装することにやりがいを感じています。

CRM(顧客データ)や Data Cloud と連携した高度なサイトを目に見える形で表現できる Experience Cloud に大きな可能性を見出しており、バックエンドのデータ構造とフロントエンドの表現力を極めることがこれからの Salesforce エンジニアに求められるスキルだと確信しています。

Trailblazer: efukushima

福島 瑛二をフォローする

読者の声

タイトルとURLをコピーしました