Add new volunteer application form
This commit is contained in:
parent
1752a3bff9
commit
c7c0b20139
|
@ -0,0 +1,41 @@
|
||||||
|
module Public
|
||||||
|
class VolunteersController < Public::ApplicationController
|
||||||
|
def new
|
||||||
|
@volunteer = current_conference.volunteers.build
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@volunteer = current_conference.volunteers.find_by! unique_id: params[:id]
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@volunteer = current_conference.volunteers.build volunteer_params
|
||||||
|
if @volunteer.save
|
||||||
|
flash[:notice] = I18n.t('views.volunteers.successful_application')
|
||||||
|
redirect_to edit_volunteer_path(@volunteer.unique_id)
|
||||||
|
else
|
||||||
|
render :new, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@volunteer = current_conference.volunteers.find_by! unique_id: params[:id]
|
||||||
|
if @volunteer.update volunteer_params
|
||||||
|
flash[:notice] = I18n.t('views.volunteers.successful_application_edit')
|
||||||
|
redirect_to edit_volunteer_path(@volunteer.unique_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
|
|
@ -0,0 +1,19 @@
|
||||||
|
# coding: utf-8
|
||||||
|
class VolunteerMailer < ActionMailer::Base
|
||||||
|
def team_notification(new_volunteer)
|
||||||
|
@volunteer = new_volunteer
|
||||||
|
|
||||||
|
mail(to: @volunteer.conference.email,
|
||||||
|
subject: "Нов доброволец – #{@volunteer.name} <#{@volunteer.email}> за екипи #{@volunteer.volunteer_teams.map(&:name).join(', ')}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def volunteer_notification(new_volunteer)
|
||||||
|
@volunteer = new_volunteer
|
||||||
|
I18n.locale = @volunteer.language
|
||||||
|
mail(to: @volunteer.email,
|
||||||
|
reply_to: @volunteer.conference.email,
|
||||||
|
from: 'no-reply@openfest.org',
|
||||||
|
subject: I18n.t('volunteer_mailer.success_notification.subject',
|
||||||
|
conference_name: @volunteer.conference.title))
|
||||||
|
end
|
||||||
|
end
|
|
@ -13,6 +13,7 @@ class Conference < ActiveRecord::Base
|
||||||
has_many :event_types
|
has_many :event_types
|
||||||
has_many :events
|
has_many :events
|
||||||
has_many :volunteer_teams
|
has_many :volunteer_teams
|
||||||
|
has_many :volunteers
|
||||||
has_one :call_for_participation, dependent: :destroy
|
has_one :call_for_participation, dependent: :destroy
|
||||||
has_many :participants, class_name: 'User', through: :events
|
has_many :participants, class_name: 'User', through: :events
|
||||||
has_many :slots, through: :halls
|
has_many :slots, through: :halls
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
class Volunteer < ActiveRecord::Base
|
||||||
|
TSHIRT_SIZES = [:s, :m, :l, :xl, :xxl, :xxxl]
|
||||||
|
TSHIRT_CUTS = [:unisex, :female]
|
||||||
|
FOOD_PREFERENCES = [:none, :vegetarian, :vegan]
|
||||||
|
|
||||||
|
attachment :picture, type: :image
|
||||||
|
|
||||||
|
validates :name, :language, :tshirt_size, :tshirt_cut, :food_preferences, presence: true
|
||||||
|
validates :tshirt_size, inclusion: {in: TSHIRT_SIZES.map(&:to_s)}
|
||||||
|
validates :tshirt_cut, inclusion: {in: TSHIRT_CUTS.map(&:to_s)}
|
||||||
|
validates :food_preferences, inclusion: {in: FOOD_PREFERENCES.map(&:to_s)}
|
||||||
|
validates :email, format: {with: /\A[^@]+@[^@]+\z/}, presence: true
|
||||||
|
validates :phone, presence: true, format: {with: /\A[+\- \(\)0-9]+\z/}
|
||||||
|
validates :volunteer_teams, presence: true
|
||||||
|
|
||||||
|
phony_normalize :phone, default_country_code: 'BG'
|
||||||
|
|
||||||
|
belongs_to :conference
|
||||||
|
has_and_belongs_to_many :volunteer_teams
|
||||||
|
|
||||||
|
before_create :assign_unique_id
|
||||||
|
after_create :send_notification_to_organizers
|
||||||
|
after_create :send_notification_to_volunteer
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def assign_unique_id
|
||||||
|
self.unique_id = Digest::SHA256.hexdigest(SecureRandom.uuid)
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_notification_to_organizers
|
||||||
|
VolunteerMailer.team_notification(self).deliver_later
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_notification_to_volunteer
|
||||||
|
VolunteerMailer.volunteer_notification(self).deliver_later
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,22 @@
|
||||||
|
Здравейте,
|
||||||
|
|
||||||
|
<%= @volunteer.name %> <<%= @volunteer.email %>> изпрати кандидатура за доброволец.
|
||||||
|
|
||||||
|
Екипи: <%= @volunteer.volunteer_teams.map(&:name).join(', ') %>
|
||||||
|
|
||||||
|
Снимка: <%= attachment_url(@volunteer, :picture, host: "https://#{@volunteer.conference.host_name}/") %>
|
||||||
|
Език: <%= @volunteer.language %>
|
||||||
|
Телефон: <%= @volunteer.phone %>
|
||||||
|
Размер на тениска: <%= @volunteer.tshirt_size %>
|
||||||
|
Кройка на тениска: <%= @volunteer.tshirt_cut %>
|
||||||
|
Предпочитания за храна: <%= @volunteer.food_preferences %>
|
||||||
|
<% if @volunteer.previous_experience.present? -%>
|
||||||
|
|
||||||
|
Предходен опит:
|
||||||
|
<%= @volunteer.previous_experience %>
|
||||||
|
<% end -%>
|
||||||
|
<% if @volunteer.notes.present? -%>
|
||||||
|
|
||||||
|
Бележки:
|
||||||
|
<%= @volunteer.notes %>
|
||||||
|
<% end -%>
|
|
@ -0,0 +1,7 @@
|
||||||
|
Здравейте,
|
||||||
|
|
||||||
|
Кандидатурата Ви беше получена.
|
||||||
|
|
||||||
|
Можете да я редактирате по всяко време от този адрес:
|
||||||
|
|
||||||
|
<%= edit_volunteer_url(@volunteer.unique_id, host: @volunteer.conference.host_name, protocol: 'https') %>
|
|
@ -0,0 +1,7 @@
|
||||||
|
Hello,
|
||||||
|
|
||||||
|
Your application for volunteership was received.
|
||||||
|
|
||||||
|
You can edit it at any time on this address:
|
||||||
|
|
||||||
|
<%= edit_volunteer_url(@volunteer.unique_id, host: @volunteer.conference.host_name, protocol: 'https') %>
|
|
@ -5,6 +5,9 @@ bg:
|
||||||
event:
|
event:
|
||||||
create: "Изпрати предложение"
|
create: "Изпрати предложение"
|
||||||
update: "Обнови предложението"
|
update: "Обнови предложението"
|
||||||
|
volunteer:
|
||||||
|
create: "Изпрати кандидатура"
|
||||||
|
update: "Обнови кандидатурата"
|
||||||
actions:
|
actions:
|
||||||
are_you_sure: "Сигурен ли си?"
|
are_you_sure: "Сигурен ли си?"
|
||||||
create:
|
create:
|
||||||
|
@ -61,6 +64,16 @@ bg:
|
||||||
picture: "Снимка"
|
picture: "Снимка"
|
||||||
public_email: "Публичен e-mail"
|
public_email: "Публичен e-mail"
|
||||||
twitter: Twitter акаунт
|
twitter: Twitter акаунт
|
||||||
|
volunteer:
|
||||||
|
picture: Снимка
|
||||||
|
name: Име
|
||||||
|
email: E-mail
|
||||||
|
phone: Телефон
|
||||||
|
tshirt_size: Размер тениска
|
||||||
|
tshirt_cut: Кройка на тениска
|
||||||
|
food_preferences: Предпочитана храна
|
||||||
|
previous_experience: Предишен опит
|
||||||
|
notes: Бележки
|
||||||
track:
|
track:
|
||||||
color: "Цвят"
|
color: "Цвят"
|
||||||
description: "Описание"
|
description: "Описание"
|
||||||
|
@ -96,6 +109,10 @@ bg:
|
||||||
invalid: "не е валиден e-mail адрес"
|
invalid: "не е валиден e-mail адрес"
|
||||||
password_confirmation:
|
password_confirmation:
|
||||||
confirmation: "не съответства на паролата"
|
confirmation: "не съответства на паролата"
|
||||||
|
volunteer:
|
||||||
|
attributes:
|
||||||
|
picture:
|
||||||
|
invalid_content_type: "невалиден формат на снимката"
|
||||||
models:
|
models:
|
||||||
conference:
|
conference:
|
||||||
one: "конференция"
|
one: "конференция"
|
||||||
|
@ -130,7 +147,7 @@ bg:
|
||||||
user:
|
user:
|
||||||
one: "Потребител"
|
one: "Потребител"
|
||||||
other: "Потребители"
|
other: "Потребители"
|
||||||
volunteership:
|
volunteer:
|
||||||
one: "доброволец"
|
one: "доброволец"
|
||||||
other: "доброволци"
|
other: "доброволци"
|
||||||
workshop:
|
workshop:
|
||||||
|
@ -160,6 +177,9 @@ bg:
|
||||||
event_mailer:
|
event_mailer:
|
||||||
acceptance_notification:
|
acceptance_notification:
|
||||||
subject: "Предложението Ви за провеждане на %{submission_type} „%{title}“ на %{conference} е одобрено"
|
subject: "Предложението Ви за провеждане на %{submission_type} „%{title}“ на %{conference} е одобрено"
|
||||||
|
volunteer_mailer:
|
||||||
|
success_notification:
|
||||||
|
subject: "Кандидатурата Ви за доброволец за %{conference_name} беше получена"
|
||||||
event_states:
|
event_states:
|
||||||
approved:
|
approved:
|
||||||
one: "Одобрено"
|
one: "Одобрено"
|
||||||
|
@ -233,6 +253,22 @@ bg:
|
||||||
simple_form:
|
simple_form:
|
||||||
error_notification:
|
error_notification:
|
||||||
default_message: "Моля, разгледайте посочените грешки във формуляра:"
|
default_message: "Моля, разгледайте посочените грешки във формуляра:"
|
||||||
|
options:
|
||||||
|
volunteer:
|
||||||
|
tshirt_size:
|
||||||
|
s: S
|
||||||
|
m: M
|
||||||
|
l: L
|
||||||
|
xl: XL
|
||||||
|
xxl: XXL
|
||||||
|
xxxl: XXXL
|
||||||
|
tshirt_cut:
|
||||||
|
unisex: Унисекс
|
||||||
|
female: Дамска
|
||||||
|
food_preferences:
|
||||||
|
none: Нищо специфично
|
||||||
|
vegetarian: Вегетарианец
|
||||||
|
vegan: Веган
|
||||||
hints:
|
hints:
|
||||||
conference:
|
conference:
|
||||||
description: "Описание на конференцията"
|
description: "Описание на конференцията"
|
||||||
|
@ -262,6 +298,11 @@ bg:
|
||||||
picture: "Ваша снимка"
|
picture: "Ваша снимка"
|
||||||
public_email: E-mail адрес, който ще бъде видим за посетителите
|
public_email: E-mail адрес, който ще бъде видим за посетителите
|
||||||
twitter: "Потребителското Ви име в Twitter"
|
twitter: "Потребителското Ви име в Twitter"
|
||||||
|
volunteer:
|
||||||
|
email: "Е-mail адресът Ви, който ще бъде видим само от организаторите"
|
||||||
|
phone: "Мобилният Ви телефон, който ще бъде видим само за организаторите"
|
||||||
|
picture: "Ваша снимка в jpeg, png или gif формат"
|
||||||
|
volunteer_teams: "Доброволческите екипи, от които искате да сте част. Подробни описания на екипите можете да намерите <a href=\"/volunteer_teams\" target=\"_blank\">тук</a>"
|
||||||
user:
|
user:
|
||||||
email: e-mail адресът Ви. Ще бъде видим само от организаторите
|
email: e-mail адресът Ви. Ще бъде видим само от организаторите
|
||||||
password: "Парола с дължина между 8 и 128 символа"
|
password: "Парола с дължина между 8 и 128 символа"
|
||||||
|
@ -302,12 +343,15 @@ bg:
|
||||||
info: "Информация за потребител"
|
info: "Информация за потребител"
|
||||||
welcome:
|
welcome:
|
||||||
submit_event: "Предложи %{event_type}"
|
submit_event: "Предложи %{event_type}"
|
||||||
volunteerships:
|
volunteers:
|
||||||
apply: Кандидатствай
|
new_volunteer_title: Кандидатствай за доброволец
|
||||||
|
edit_volunteer_title: "Кандидатура за доброволец на %{name}"
|
||||||
|
apply: Кандидатствай за доброволец
|
||||||
withdraw_application: Оттегли кандидатурата си
|
withdraw_application: Оттегли кандидатурата си
|
||||||
you_successfully_applied_for: "Успешно изпратихте кандидатура за екип „%{team}“"
|
successful_application: "Успешно изпратихте кандидатурата си"
|
||||||
|
successful_application_edit: "Успешно редактирахте кандидатурата си"
|
||||||
error_occurred_while_applying: "Възникна грешка и кандидатурата Ви не беше изпратена"
|
error_occurred_while_applying: "Възникна грешка и кандидатурата Ви не беше изпратена"
|
||||||
you_successfully_retracted_your_application_for: "Успешно оттеглихте кандидатурата си за екип „%{team}“"
|
you_successfully_retracted_your_application_for: "Успешно оттеглихте кандидатурата си“"
|
||||||
welcome: "Добре дошли, %{name}"
|
welcome: "Добре дошли, %{name}"
|
||||||
what_we_ask: "Бихме искали да получим предложенията Ви за лекции и уъркшопи, принадлежащи към следните категории до 4 октомври 2015г.:"
|
what_we_ask: "Бихме искали да получим предложенията Ви за лекции и уъркшопи, принадлежащи към следните категории до 4 октомври 2015г.:"
|
||||||
workshop_was_successfully_confirmed: "Уъркшопът беше потвърден успешно"
|
workshop_was_successfully_confirmed: "Уъркшопът беше потвърден успешно"
|
||||||
|
|
|
@ -9,6 +9,7 @@ Rails.application.routes.draw do
|
||||||
get :confirm
|
get :confirm
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
resources :volunteers
|
||||||
resources :volunteerships, only: [:index, :destroy]
|
resources :volunteerships, only: [:index, :destroy]
|
||||||
resources :volunteer_teams, only: [] do
|
resources :volunteer_teams, only: [] do
|
||||||
resource :volunteership, only: :create
|
resource :volunteership, only: :create
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
class CreateVolunteers < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :volunteers do |t|
|
||||||
|
t.string :name
|
||||||
|
t.string :picture_id
|
||||||
|
t.string :email
|
||||||
|
t.string :unique_id
|
||||||
|
t.string :phone
|
||||||
|
t.string :tshirt_size
|
||||||
|
t.string :tshirt_cut
|
||||||
|
t.string :food_preferences
|
||||||
|
t.text :previous_experience
|
||||||
|
t.text :notes
|
||||||
|
|
||||||
|
t.timestamps null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index :volunteers, :unique_id, unique: true
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,8 @@
|
||||||
|
class CreateJoinTableVolunteerVolunteerTeam < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_join_table :volunteers, :volunteer_teams do |t|
|
||||||
|
t.index [:volunteer_id, :volunteer_team_id], name: 'volunteer_id_volunteer_team_id'
|
||||||
|
t.index [:volunteer_team_id, :volunteer_id], name: 'volunteer_team_id_volunteer_id'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddConferenceIdToVolunteers < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_reference :volunteers, :conference, index: true, foreign_key: true
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddLanguageToVolunteers < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :volunteers, :language, :string
|
||||||
|
end
|
||||||
|
end
|
|
@ -36,6 +36,26 @@ footer {
|
||||||
font-size: 1.7em;
|
font-size: 1.7em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.radio {
|
||||||
|
label {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span.radio + span.radio {
|
||||||
|
label {
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label.check_boxes {
|
||||||
|
height: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
@media all and (max-width: 600px) {
|
@media all and (max-width: 600px) {
|
||||||
.input label, .input input, .input span, .input .hint, .help-block, .input .error {
|
.input label, .input input, .input span, .input .hint, .help-block, .input .error {
|
||||||
float: none;
|
float: none;
|
||||||
|
@ -43,8 +63,22 @@ footer {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
span.radio, span.checkbox {
|
||||||
|
padding-top: 0.4em;
|
||||||
|
|
||||||
strong {
|
label {
|
||||||
font-weight: 600;
|
display: inline;
|
||||||
|
padding-left: 0;
|
||||||
|
input {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span.radio + span.radio {
|
||||||
|
label {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
- form_url = @volunteer.new_record? ? volunteers_path : volunteer_path(@volunteer.unique_id)
|
||||||
|
|
||||||
|
= simple_form_for @volunteer, wrapper: :default, url: form_url do |f|
|
||||||
|
= f.error_notification
|
||||||
|
|
||||||
|
.form-inputs
|
||||||
|
.input
|
||||||
|
= attachment_image_tag(@volunteer, :picture, :fill, 150, 150) if @volunteer.picture.present?
|
||||||
|
= f.input :picture, as: :attachment, direct: true, wrapper: false
|
||||||
|
= f.input :name, autofocus: true
|
||||||
|
= f.input :email
|
||||||
|
= f.input :phone, input_html: {value: @volunteer.phone.try(:phony_formatted, format: :international)}
|
||||||
|
= f.association :volunteer_teams, as: :check_boxes, wrapper: :default
|
||||||
|
= f.input :language, as: :radio_buttons, collection: locale_collection, include_blank: false, wrapper: :default, checked: (@volunteer.language.presence || I18n.locale)
|
||||||
|
= f.input :tshirt_size, collection: Volunteer::TSHIRT_SIZES, as: :radio_buttons, wrapper: :default, checked: (@volunteer.tshirt_size.presence || :m)
|
||||||
|
= f.input :tshirt_cut, collection: Volunteer::TSHIRT_CUTS, as: :radio_buttons, wrapper: :default, checked: (@volunteer.tshirt_cut.presence || :unisex)
|
||||||
|
= f.input :food_preferences, collection: Volunteer::FOOD_PREFERENCES, as: :radio_buttons, wrapper: :default, checked: (@volunteer.food_preferences.presence || :none)
|
||||||
|
= f.input :previous_experience
|
||||||
|
= f.input :notes
|
||||||
|
.form-actions
|
||||||
|
= f.button :submit
|
|
@ -0,0 +1,5 @@
|
||||||
|
- content_for(:title) { t 'views.volunteers.edit_volunteer_title', name: @volunteer.name }
|
||||||
|
|
||||||
|
h1 = t 'views.volunteers.edit_volunteer_title', name: @volunteer.name
|
||||||
|
|
||||||
|
= render 'form'
|
|
@ -0,0 +1,5 @@
|
||||||
|
- content_for(:title) { t 'views.volunteers.new_volunteer_title' }
|
||||||
|
|
||||||
|
h1 = t 'views.volunteers.new_volunteer_title'
|
||||||
|
|
||||||
|
= render 'form'
|
Loading…
Reference in New Issue