学生向けプログラミング入門

学生向けにプログラミングを解説。Java、C++、Ruby、PHP、データベース、Ruby on Rails

Ruby on Rails6.0 | 空き部屋を登録・予約・決済できるWebサイトを作成する 88 | Bootstrap | 承認予約

[87]Bootstrap | jQueryスライダー<< [ホームに戻る] >> [89]Bootstrap | クレジットカード決済 | Stripe(ストライプ)


「40 | 承認予約」をBootstrapの記述に書き換えます。
設定部分は省略します。


app\views\rooms\new.html.erb

<br/>
<br/>
<div class="row">
    <div class="col-sm-6" style="margin:0 auto;">

        <div class="card text-center">
            <h4 class="card-header text-center">お部屋の新規登録</h4>
                <div class="card-body" style="margin-left: 50px;">
                <br/>

                <%= form_for @room do |f| %>
                    <div class="row">

                        <div class="col-md-4 select">
                            <div class="form-group">
                                <label>お家のタイプ</label>
                                <%= f.select :home_type, [["マンション", "マンション"], ["アパート", "アパート"], ["一戸建て", "一戸建て"]],
                                    id: "home_type", prompt: "選択してください", class: "form-control" %>
                            </div>
                        </div>
                        <br/>
                        <div class="col-md-4 select">
                            <div class="form-group">
                                <label>お部屋のタイプ</label>
                                <%= f.select :room_type, [ ["プライベート", "プライベート"], ["シェア", "シェア"]],
                                    id: "room_type", prompt: "選択してください", class: "form-control" %>
                            </div>
                        </div>
                        <br/>
                        <div class="col-md-4 select">
                            <div class="form-group">
                                <label>宿泊可能人数</label>
                                <%= f.select :accommodate, [["2人", 2], ["3人", 3], ["4人", 4], ["5人", 5], ["6人", 6]],
                                    id: "accommodate", prompt: "選択してください", class: "form-control" %>
                            </div>
                        </div>
                        <br/>
                        <div class="col-md-4 select">
                            <div class="form-group">
                                <label>ベッド数</label>
                                <%= f.select :bed_room, [["1台", 1], ["2台", 2], ["3台", 3], ["4台", 4], ["5台", 5], ["6台", 6]],
                                    id: "bed_room", prompt: "選択してください", class: "form-control" %>
                            </div>
                        </div>

                        <br/>
                        <div class="col-md-4 select">
                            <div class="form-group">
                                <label>部屋数</label>
                                <%= f.select :bath_room, [["1部屋", 1], ["2部屋", 2], ["3部屋", 3], ["4部屋", 4], ["5部屋", 5], ["6部屋", 6]],
                                    id: "bath_rooms", prompt: "選択してください", class: "form-control" %>
                            </div>
                        </div>
                    </div>
                    <br/>

                    <div class="col-md-4 select">
                        <div class="form-group">
                            <label>予約種別</label>
                            <%= f.select :instant, Room.instants.map {|key,value| [key.humanize, key]}, selected: 'Instant', prompt: "選択してください", class: "form-control" %>
                        </div>
                        <span style="white-space: nowrap;">即時予約制:Instant, 承認予約制:Request</span>
                    </div>                    
                    <br/>
                    <div><%= f.submit "登録する", class: "btn btn-primary btn-block" %></div>


                    <% end %>



                </div>
        </div>      
    </div>
</div>



ブラウザ確認
http://localhost:3000/rooms/new

予約種別追加
予約種別追加



app\views\rooms\listing.html.erb

<br/>
<div class="row">
    <div class="col-md-3">
        <%= render 'room_menu' %>
    </div>
    <div class="col-md-9">

        <div class="row">
            <div class="col-sm-9">
                <br/>
                <div class="card text-center">
                    <h4 class="card-header text-center">お部屋登録情報の修正</h4>
                    <div class="card-body" style="margin-left: 50px;">
                        <br/>


                        <%= form_for @room do |f| %>
                            <div class="row">

                                <div class="col-md-4 select">
                                    <div class="form-group">
                                        <label>お家のタイプ</label>
                                        <%= f.select :home_type, [["マンション", "マンション"], ["アパート", "アパート"], ["一戸建て", "一戸建て"]],
                                            id: "home_type", prompt: "選択してください", class: "form-control" %>
                                    </div>
                                </div>
                                <br/>
                                <div class="col-md-4 select">
                                    <div class="form-group">
                                        <label>お部屋のタイプ</label>
                                        <%= f.select :room_type, [ ["プライベート", "プライベート"], ["シェア", "シェア"]],
                                            id: "room_type", prompt: "選択してください", class: "form-control" %>
                                    </div>
                                </div>
                                <br/>
                                <div class="col-md-4 select">
                                    <div class="form-group">
                                        <label>宿泊可能人数</label>
                                        <%= f.select :accommodate, [["2人", 2], ["3人", 3], ["4人", 4], ["5人", 5], ["6人", 6]],
                                            id: "accommodate", prompt: "選択してください", class: "form-control" %>
                                    </div>
                                </div>
                                <br/>
                                <div class="col-md-4 select">
                                    <div class="form-group">
                                        <label>ベッド数</label>
                                        <%= f.select :bed_room, [["1台", 1], ["2台", 2], ["3台", 3], ["4台", 4], ["5台", 5], ["6台", 6]],
                                            id: "bed_room", prompt: "選択してください", class: "form-control" %>
                                    </div>
                                </div>

                                <br/>
                                <div class="col-md-4 select">
                                    <div class="form-group">
                                        <label>部屋数</label>
                                        <%= f.select :bath_room, [["1部屋", 1], ["2部屋", 2], ["3部屋", 3], ["4部屋", 4], ["5部屋", 5], ["6部屋", 6]],
                                            id: "bath_rooms", prompt: "選択してください", class: "form-control" %>
                                    </div>
                                </div>
                            </div>
                            <br/>
                            <div class="col-md-4 select">
                                <div class="form-group">
                                    <label>予約種別</label>
                                    <%= f.select :instant, Room.instants.map {|key,value| [key.humanize, key]}, selected: 'Instant', prompt: "選択してください", class: "form-control" %>
                                </div>
                                <span style="white-space: nowrap;">即時予約制:Instant, 承認予約制:Request</span>
                            </div>
                            <br/>
                            <div><%= f.submit "修正する", class: "btn btn-primary btn-block" %></div>


                        <% end %>

                    </div>
                </div>
            </div>
        </div>
    </div>
</div>



ブラウザ確認
http://localhost:3000/rooms/4/listing

予約種別追加
予約種別追加



「app\views\reservations\_form.html.erb」ファイルを編集します。


記述更新 app\views\reservations\_form.html.erb

<%= form_for([@room, @room.reservations.new]) do |f| %>

    <div class="card" style="width: 24rem; margin-left: -70px;">
    <div class="card-header">
    <span><% if @room.Instant? %><i class="fas fa-chess-king" style="color: #ffb400"></i><% end %></span>&nbsp;&nbsp;&nbsp;1泊 <%= number_to_currency(@room.price) %>
    </div>
    <div class="card-body">
    <form>
    <div class="form-row">
      <div class="col">
        <%= f.text_field :start_date, readonly: true, placeholder: "チェックイン", class: "form-control" %>
      </div>
      <div class="col">
      <%= f.text_field :end_date, readonly: true, placeholder: "チェックアウト", class: "form-control" %>
      </div>
    </div>
  </form>
  
  <h4 class="message-alert text-center"><span id="message"></span></h4>
  <div id="preview" style="display: none">
    <table class="reservation-table">
      <tbody>
          <tr>
            <td>宿泊費用</td>
            <td class="text-right", style="white-space: nowrap"><%= number_to_currency(@room.price) %></td>
          </tr>
          <tr>
            <td>宿泊日数</td>
            <td class="text-right"><span id="reservation_nights"></span></td>
          </tr>
          <tr>
            <td class="total">合計金額</td>
            <td class="text-right", style="white-space: nowrap"><span id="reservation_total"></span></td>
          </tr>
        </tbody>
    </table>
  </div>  

    <br/>
    <% if @room.Instant? %>
      <%= f.submit "予約する", id: "btn_book", class: "btn btn-danger btn-block", disabled: true %>
    <% else %>
        <%= f.submit "予約承認申請を送る", id: "btn_book", class: "btn btn-danger btn-block", disabled: true %>
    <% end %>

    </div>
  </div>
 
<% end %>

<script>
  function checkDate(date) {
    dmy = date.getDate() + "-" + (date.getMonth() + 1) + "-" + date.getFullYear();
    return [$.inArray(dmy, unavailableDates) == -1];
  }
  $(function() {
    unavailableDates = [];
    $.ajax({
      url: '<%= preload_room_path(@room) %>',
      dateTyp: 'json',
      success: function(data) {
        $.each(data, function(arrID, arrValue) {
            for(var d = new Date(arrValue.start_date); d <= new Date(arrValue.end_date); d.setDate(d.getDate() + 1)) {
              unavailableDates.push($.datepicker.formatDate('d-m-yy', d));
            }
        });
        $('#reservation_start_date').datepicker({
          dateFormat: 'dd-mm-yy',
          //今日から3ヶ月先まで予約可能
          minDate: 0,
          maxDate: '3m',
          beforeShowDay: checkDate,
          onSelect: function(selected) {
            $('#reservation_end_date').datepicker("option", "minDate", selected);
            $('#reservation_end_date').attr("disabled", false);
            var start_date = $('#reservation_start_date').datepicker('getDate');
            var end_date = $('#reservation_end_date').datepicker('getDate');
            //2日選択すると1泊になる
            var nights = (end_date - start_date)/1000/60/60/24;
            var input = {
              'start_date': start_date,
              'end_date': end_date
            }
            $.ajax({
              url: '<%= preview_room_path(@room) %>',
              data: input,
              success: function(data) {
                if(data.conflict) {
                  $('#message').text("この日付はご利用できません。");
                  $('#preview').hide();
                  $('#btn_book').attr('disabled', true);
                } else {
                  $('#message').text("");
                  $('#preview').show();
                  $('#btn_book').attr('disabled', false);
                  var total = nights * <%= @room.price %>
                  $('#reservation_nights').text(nights);
                  $('#reservation_total').text(total);
                }
              }
            });
          }
        });
        $('#reservation_end_date').datepicker({
          dateFormat: 'dd-mm-yy',
          //今日から3ヶ月先まで予約可能
          minDate: 0,
          maxDate: '3m',
          beforeShowDay: checkDate,
          onSelect: function(selected) {
            $('#reservation_start_date').datepicker("option", "maxDate", selected);
            var start_date = $('#reservation_start_date').datepicker('getDate');
            var end_date = $('#reservation_end_date').datepicker('getDate');
            var nights = (end_date - start_date)/1000/60/60/24;
            var input = {
              'start_date': start_date,
              'end_date': end_date
            }
            $.ajax({
              url: '<%= preview_room_path(@room) %>',
              data: input,
              success: function(data) {
                if(data.conflict) {
                  $('#message').text("この日付ではご予約できません。");
                  $('#preview').hide();
                  $('#btn_book').attr('disabled', true);
                } else {
                  $('#message').text("");
                  $('#preview').show();
                  $('#btn_book').attr('disabled', false);
                  var total = nights * <%= @room.price %>
                  $('#reservation_nights').text(nights);
                  $('#reservation_total').text(total);
                }
              }
            });
          }
        });
      }
    });
  });
</script>



ブラウザ確認
http://localhost:3000/rooms/4

予約ボタン更新
予約ボタン更新



「app\views\reservations\your_reservations.html.erb」ファイルを編集していきます。


app\views\reservations\your_reservations.html.erb

<div class="row" style="margin-top: 50px; margin-left: 30px;">

        <div class="card">
    
            <h3 style="margin-top: 30px; margin-left: 30px;">受注予約の一覧</h3>
            <br/>
            <table class="table table-striped">
            <thead>
                <tr>
                    <th>申し込み日</th>
                    <th>ステータス</th>
                    <th>お部屋</th>
                    <th>ゲスト</th>
                    <th></th>
                    <th>料金</th>
                    <th>アクション</th>
                </tr>
            </thead>
            <tbody>
                <% if @rooms.blank? %>
                  <tr>
                      <td colspan="7" class="has-text-centered"><h1>表示できる受注予約はありません。</h1></td>
                  </tr>
                <% end %>
                <% @rooms.each do |room| %>
                    <% room.reservations.each do |reservation| %>
                        <tr>
                            <td style="padding-top: 30px;"><%= I18n.l(reservation.created_at, format: :full_date) %></td>
                            <!-- ステータス -->
                            <td>

                            <div class="form-inline">
                            <% if reservation.Waiting? %>
                                <%= link_to approve_reservation_path(reservation), method: :post do %> <i class="fa fa-thumbs-up fa-lg"></i> <% end %> |
                                <%= link_to decline_reservation_path(reservation), method: :post do %> <i class="fa fa-thumbs-down fa-lg"></i> <% end %>
                            <% end %>
                        </div>
                        <% if reservation.Waiting? %>
                            <p class="btn btn-outline-warning">承認待ちです。要確認</p>
                        <% elsif reservation.Approved? %>
                            <p class="btn btn-outline-success">予約を承認しました</p>
                        <% else  %>
                            <p class="btn btn-outline-danger">予約を拒否しました</p>
                        <% end  %>     

                            </td>
                            <td>
                                <%= link_to room_path(reservation.room), data: { turbolinks: false} do %>                                
                                    <%= image_tag room_cover(reservation.room), style: "width: 80px;" %><br/>
                                    <%= reservation.room.listing_name %>
                                <% end %>
                            </td>
                            <td>
                                <%= link_to user_path(reservation.user), class: "tootip" do %>

                                        <%= image_tag avatar_url(reservation.user), style: "width: 80px;", class: "bd-placeholder-img figure-img img-fluid rounded-pill" %><br/>

                                    <%= reservation.user.full_name %>
                                <% end %>
                            </td>
                            <td>
                                宿泊日:<%= I18n.l(reservation.start_date, format: :full_date) %><br/>
                                ご出発:<%= I18n.l(reservation.end_date, format: :full_date) %>
                            </td>
                            <td><%= number_to_currency(reservation.total) %></td>
                            <!-- アクション -->
                            <td>
                            <%= render partial: "reviews/host_form", locals: {reservation: reservation}  if reservation.Approved? %>
                            </td>
                        </tr>
                        
                    <% end %>
                <% end %>
            </tbody>
      
        </table>
    </div>
</div



ブラウザ確認
http://localhost:3000/your_reservations


承認予約時に「アップボタン」と「ダウンボタン」が表示されます。

承認予約時の表示
承認予約時の表示



アップボタンを押すと予約が承認され、レビューボタンが表示されます。

予約承認
予約承認



「app\views\reservations\your_trips.html.erb」ファイルを編集します。


app\views\reservations\your_trips.html.erb

<div class="row" style="margin-top: 50px; margin-left: 30px;">

    <div class="card">

        <h3 style="margin-top: 30px; margin-left: 30px;">ご予約内容</h3>
        <br/>
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>申し込み日</th>
                    <th>ステータス</th>
                    <th>お部屋</th>
                    <th>ホスト</th>
                    <th></th>
                    <th>料金</th>
                    <th>アクション</th>
                </tr>
            </thead>
            <tbody>
                <% if @trips.blank? %>
                  <tr>
                      <td colspan="7"><h1>表示できるご予約はありません。</h1></td>
                  </tr>
                <% end %>
                <% @trips.each do |trip| %>
                    <tr>
                        <td><%= I18n.l(trip.created_at, format: :full_date) %></td>
                        <!-- ステータス -->
                        <td>
                        <% if trip.Waiting? %>
                        <p class="btn btn-outline-warning">承認待ちです。しばらくお待ち下さい。</p>
                    <% elsif trip.Approved? %>
                        <p class="btn btn-outline-success">予約済みです</p>
                    <% else  %>
                        <p class="btn btn-outline-danger">予約できませんでした</p>
                    <% end  %>                        
                        </td>
                        <td>
                            <%= link_to room_path(trip.room), data: { turbolinks: false} do %>                                
                                <%= image_tag room_cover(trip.room), style: "width: 80px;" %><br/>
                                <%= trip.room.listing_name %>
                            <% end %>
                        </td>
                        <td>
                            <%= link_to user_path(trip.room.user), class: "tootip" do %>

                                    <%= image_tag avatar_url(trip.room.user), style: "width: 80px;", class: "bd-placeholder-img figure-img img-fluid rounded-pill" %><br/>

                                <%= trip.room.user.full_name %>
                            <% end %>
                        </td>
                        <td>
                            宿泊日:<%= I18n.l(trip.start_date, format: :full_date) %><br/>
                            ご出発:<%= I18n.l(trip.end_date, format: :full_date) %>
                        </td>
                        <td><%= number_to_currency(trip.total) %></td>
                        <!-- アクション -->
                        <td>
                        <%= render partial: "reviews/guest_form", locals: {reservation: trip} if trip.Approved? %>
                        </td>
                    </tr>
                <% end %>
            </tbody>
        </table>
    </div>
</div>



ブラウザ確認
http://localhost:3000/your_trips

ステータス
ステータス



[87]Bootstrap | jQueryスライダー<< [ホームに戻る] >> [89]Bootstrap | クレジットカード決済 | Stripe(ストライプ)