Implement volunteer management

This commit is contained in:
Petko Bordjukov 2016-10-09 07:17:34 +03:00
parent 29da04d51f
commit 4fe0f870f5
9 changed files with 207 additions and 2 deletions

View File

@ -0,0 +1,37 @@
module Management
class VolunteersController < ManagementController
include CurrentConferenceAssigning
def index
@filters = params[:filters] || {}
@volunteers = VolunteerSearch.new(scope: Volunteer.where(conference: current_conference).eager_load(:volunteer_teams), filters: params[:filters]).results
end
def show
@volunteer = current_conference.volunteers.find(params[:id])
end
def edit
@volunteer = current_conference.volunteers.find(params[:id])
end
def update
@volunteer = current_conference.volunteers.find(params[:id])
if @volunteer.update volunteer_params
redirect_to management_conference_volunteer_path(@volunteer, conference_id: current_conference.id)
else
render :edit, status: :unprocessable_entity
end
end
private
def volunteer_params
params.require(:volunteer).permit(:name, :picture, :email, :phone,
:tshirt_size, :tshirt_cut,
:food_preferences, :previous_experience,
:notes, :language,
volunteer_team_ids: [])
end
end
end

View File

@ -0,0 +1,8 @@
class VolunteerSearch
include SearchObject.module(:sorting)
option(:volunteer_team_id) { |scope, value| scope.joins(:volunteer_teams).where volunteer_teams: {id: value} }
sort_by 'name'
config[:defaults]['sort'] = "#{config[:sort_attributes].first} asc"
end

View File

@ -26,8 +26,8 @@ nav.navbar.navbar-static-top.navbar-inverse role="navigation"
/ li class="#{'active' if controller_name == 'sponsorship_offers'}"
/ = link_to '#' do
/ => icon 'money', t('activerecord.models.sponsorship_offer', count: 2).mb_chars.capitalize, class: 'fa-fw'
li class="#{'active' if controller_name == 'volunteerships'}"
= link_to '#' do
li class="#{'active' if controller_name == 'volunteers'}"
= link_to management_conference_volunteers_path(current_conference) do
=> icon 'hand-o-up', t('activerecord.models.volunteership', count: 2).mb_chars.capitalize, class: 'fa-fw'
/ li class="#{'active' if controller_name == 'propositions'}"
/ = link_to [:management, current_conference, :propositions] do

View File

@ -0,0 +1,23 @@
= simple_form_for [:management, current_conference, @volunteer], wrapper: :horizontal_form, html: { class: 'form-horizontal' } do |f|
.panel.panel-default
.panel-body
.row
.col-lg-12
- if f.object.picture.present?
.col-sm-offset-3.col-sm-9
= attachment_image_tag(@volunteer, :picture, :fill, 150, 150) if @volunteer.picture.present?
= f.input :picture, as: :attachment, wrapper: :horizontal_file_input, direct: true
= f.input :name, autofocus: true
= f.input :email
= f.association :volunteer_teams, as: :check_boxes, wrapper: :horizontal_radio_and_checkboxes, collection: current_conference.volunteer_teams
= f.input :phone, input_html: {value: @volunteer.phone.try(:phony_formatted, format: :international)}
= f.input :language, as: :radio_buttons, wrapper: :horizontal_radio_and_checkboxes, collection: locale_collection, include_blank: false, checked: (@volunteer.language.presence || I18n.locale)
= f.input :tshirt_size, collection: Volunteer::TSHIRT_SIZES, as: :radio_buttons, wrapper: :horizontal_radio_and_checkboxes, checked: (@volunteer.tshirt_size.presence || :m)
= f.input :tshirt_cut, collection: Volunteer::TSHIRT_CUTS, wrapper: :horizontal_radio_and_checkboxes, as: :radio_buttons, checked: (@volunteer.tshirt_cut.presence || :unisex)
= f.input :food_preferences, collection: Volunteer::FOOD_PREFERENCES, wrapper: :horizontal_radio_and_checkboxes, as: :radio_buttons, checked: (@volunteer.food_preferences.presence || :none)
= f.input :previous_experience
= f.input :notes
.panel-footer.text-right
= f.submit class: 'btn btn-primary'

View File

@ -0,0 +1,12 @@
- content_for :title
=> t 'actions.edit.title', model: Volunteer.model_name.human
= @volunteer.name
.row
.col-xs-12
h1.page-header
= @volunteer.name
.row
.col-lg-12
= render 'form'

View File

@ -0,0 +1,16 @@
<%- csv_headers = %w{id name email language unique_id phone tshirt_size tshirt_cut food_preferences previous_experience notes teams} -%>
<%= CSV.generate_line(csv_headers).html_safe -%>
<%- @volunteers.each do |volunteer| -%>
<%= CSV.generate_line([volunteer.id,
volunteer.name,
volunteer.email,
volunteer.language,
volunteer.unique_id,
volunteer.phone,
volunteer.tshirt_size,
volunteer.tshirt_cut,
volunteer.food_preferences,
volunteer.previous_experience,
volunteer.notes,
volunteer.volunteer_teams.map(&:name).join(', ')]).html_safe -%>
<%- end -%>

View File

@ -0,0 +1,58 @@
- content_for :title
= Conference.human_attribute_name(:volunteers).mb_chars.capitalize
.row
.col-lg-12
h1.page-header
= Volunteer.model_name.human(count: 2).mb_chars.capitalize
small<
| (
= t '.total', current: @volunteers.count, total: current_conference.volunteers.count
=< Volunteer.model_name.human(count: current_conference.volunteers.count).mb_chars.downcase
| )
.row
.col-md-2.collapse#filters
.panel.panel-default
.panel-heading
= VolunteerTeam.model_name.human.mb_chars.capitalize
.panel-body
ul.nav.nav-pills.nav-stacked
= content_tag :li, role: "presentation", class: @filters[:volunteer_team_id].blank? ? 'active' : nil
= link_to management_conference_volunteers_path(current_conference, filters: @filters.except(:volunteer_team_id))
= t '.all'
- current_conference.volunteer_teams.each do |volunteer_team|
= content_tag :li, role: "presentation", class: @filters[:volunteer_team_id] == volunteer_team.id.to_s ? 'active' : nil
= link_to management_conference_volunteers_path(current_conference, filters: @filters.merge({volunteer_team_id: volunteer_team.id}))
= volunteer_team.name
.col-md-10
.panel.panel-default
table.table.table-striped.table-hover.record-table#conferences
thead
tr
th = t '.profile'
th = Volunteer.human_attribute_name :volunteer_teams
th.actions
tbody
- @volunteers.each do |volunteer|
tr
td
.media
.media-left
- if volunteer.picture.present?
= attachment_image_tag(volunteer, :picture, :fill, 50, 50)
- else
= image_tag(PictureUploader.new.thumb.url)
.media-body
h4.media-heading
= volunteer.name
p
= icon(:envelope, volunteer.email)
td
= volunteer.volunteer_teams.map(&:name).join(', ')
td.actions
div.btn-group.btn-group-sm
= action_buttons(current_conference, volunteer, [:show, :edit])
.panel-footer.text-right
= link_to management_conference_volunteers_path(current_conference, format: 'csv'), class: 'btn btn-info'
= icon :download, t('.export')

View File

@ -0,0 +1,50 @@
- content_for :title
= @volunteer.name
.row
.col-lg-12
h1.page-header
= Volunteer.model_name.human.mb_chars.titleize
.panel.panel-default
.panel-body
.media
.media-left.hidden-sm.hidden-xs
- if @volunteer.picture.present?
= attachment_image_tag(@volunteer, :picture, :fill, 150, 150)
- else
= image_tag(PictureUploader.new.medium.url)
.media-body
.text-center.visible-sm.visible-xs
- if @volunteer.picture.present?
= attachment_image_tag(@volunteer, :picture, :fill, 150, 150)
- else
= image_tag(PictureUploader.new.medium.url)
h4.media-heading
= @volunteer.name
hr
h4 = Volunteer.human_attribute_name(:volunteer_teams)
= @volunteer.volunteer_teams.map(&:name).join(', ')
- if @volunteer.previous_experience.present?
h4 = Volunteer.human_attribute_name(:previous_experience)
= simple_format @volunteer.previous_experience
- if @volunteer.notes.present?
h4 = Volunteer.human_attribute_name(:notes)
= simple_format @volunteer.notes
h4 = t '.other_info'
= icon(:language, t("locales.#{@volunteer.language}"))
br
= icon(:envelope, @volunteer.email)
br
= icon(:phone, @volunteer.phone.try(:phony_formatted, format: :international))
br
| 👕
=< t("simple_form.options.volunteer.tshirt_cut.#{@volunteer.tshirt_cut}")
=< t("simple_form.options.volunteer.tshirt_size.#{@volunteer.tshirt_size}")
br
= icon(:cutlery, t("simple_form.options.volunteer.food_preferences.#{@volunteer.food_preferences}"))
.panel-footer
.text-right
.btn-group.btn-group-sm
= action_buttons current_conference, @volunteer, [:edit, :destroy]

View File

@ -25,6 +25,7 @@ Rails.application.routes.draw do
resources :event_types, only: :index
resources :halls, only: :index
resources :slots, only: :index
resources :volunteers
end
end