Belay Board Simple Part 5: Dashboard
Published: 2023-11-24 16:59:14

A user needs a way to view availabilities ordered by start time. A user may want to search availabilities by status. Originally i named the status :accepted, :rejected, :pending and this is how the event creator views them. I thought it would be a nice touch if the event guests viewed more friendly statuses like Confirmed, Canceled, and Pending. Furthermore, a guest can filter requests by a range of start and end times as well as search by event names.    

### Routes
```rb
Rails.application.routes.draw do
  root "availabilities#index"

  devise_for :users

  resources :availabilities do
    resources :comments, only: [:create, :destroy]
  end
  
  resources :event_requests, only: [:create] do
    member do
      post :accept
      post :reject
    end
  end

  get '/dashboard', to: 'users#dashboard'
end
```

### Dashboard action in controller 
```rb
class UsersController < ApplicationController
  before_action :authenticate_user!

  def dashboard
    @event_requests = current_user.event_requests.includes(:availability)
  
    if params[:status].present?
      @event_requests = @event_requests.where(status: params[:status])
    end
  
    if params[:event_name].present?
      @event_requests = @event_requests.joins(:availability).where('availabilities.event_name ILIKE ?', "%#{params[:event_name]}%")
    end
  
    if params[:start_time].present? && params[:end_time].present?
      start_time = Date.parse(params[:start_time])
      end_time = Date.parse(params[:end_time])
      @event_requests = @event_requests.joins(:availability).where('availabilities.start_time >= ? AND availabilities.end_time <= ?', start_time, end_time)
    end

    @event_requests = @event_requests.joins(:availability).order('availabilities.start_time ASC')
  end
end
```
### View
```html
<div class="container">

<h2>Event Requests</h2>

<%= form_tag dashboard_path, method: :get, class: "row g-3" do %>
  <div class="col-md-3">
    <%= label_tag :start_time, "Start Time", class: 'form-label' %>
    <%= date_field_tag :start_time, params[:start_time], class: 'form-control' %>
  </div>

  <div class="col-md-3">
    <%= label_tag :end_time, "End Time", class: 'form-label' %>
    <%= date_field_tag :end_time, params[:end_time], class: 'form-control' %>
  </div>

 <div class="col-md-3">
  <%= label_tag :status, "Status", class: 'form-label' %>
  <%= select_tag :status, 
      options_for_select(
        {
          'Any' => '',
          'Pending' => 'pending',
          'Confirmed' => 'accepted',
          'Canceled' => 'rejected'
        }, 
        params[:status]
      ), 
      class: 'form-select' 
  %>
</div>

  <div class="col-md-3">
    <%= label_tag :event_name, "Event Name", class: 'form-label' %>
    <%= text_field_tag :event_name, params[:event_name], class: 'form-control', placeholder: 'Search Event Names' %>
  </div>

  <div class="col-12">
    <%= submit_tag "Filter", class: 'btn btn-primary' %>
  </div>
<% end %>

<table class="table">
  <thead>
    <tr>
      <th scope="col">Event Name</th>
      <th scope="col">Start Time</th>
      <th scope="col">End Time</th>
      <th scope="col">Status</th>
    </tr>
  </thead>
  <tbody>
    <% @event_requests.each do |request| %>
      <tr>
        <td><%= link_to request.availability.event_name, availability_path(request.availability) %></td>
        <td><%= request.availability.start_time.strftime('%b %d, %Y %I:%M %p') %></td>
        <td><%= request.availability.end_time.strftime('%b %d, %Y %I:%M %p') %></td>
        <td>
          <% case request.status %>
          <% when 'accepted' %>
            Confirmed
          <% when 'rejected' %>
            Canceled
          <% else %>
            <%= request.status.capitalize %>
          <% end %>
        </td>
      </tr>
    <% end %>
  </tbody>
</table>
</div>
```